Skip to content

Commit

Permalink
test(storybook): add optional breakpoints screenshoting (#3748)
Browse files Browse the repository at this point in the history
* test(storybook): add optional breakpoints screenshoting

* test: mark components that need screenshotting on all breakpoints

* test: enable breakpoint screenshots only on storybook
  • Loading branch information
Augusto Moura authored Jul 31, 2023
1 parent be827f9 commit 834327f
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 43 deletions.
40 changes: 35 additions & 5 deletions .happo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
const { RemoteBrowserTarget } = require('happo.io')
const happoStorybookPlugin = require('happo-plugin-storybook')

const breakpoints = {
xs: 0,
sm: 480,
md: 768,
lg: 1024,
xl: 1440,
}

const sortBy = field => (a, b) => a[field] - b[field]

const checkpoints = Object.entries(breakpoints)
.map(([name, minWidth]) => ({ name, minWidth }))
.sort(sortBy('minWidth'))
.map((breakpoint, idx, breakpoints) => {
const nextBreakpoint = breakpoints[idx + 1]

const viewportWidth = nextBreakpoint
? nextBreakpoint.minWidth - 1 // Either next 1px lower than next breakpoint minimum
: breakpoint.minWidth + 1 // Or 1px higher than current breakpoint, when the last one

return {
[`chrome-desktop-${breakpoint.name}`]: new RemoteBrowserTarget('chrome', {
viewport: `${viewportWidth}x1024`,
applyPseudoClasses: true,
}),
}
})
.reduce((a, b) => Object.assign(a, b))

module.exports = {
project: process.env.HAPPO_PROJECT,
apiKey: process.env.HAPPO_API_KEY,
Expand All @@ -9,12 +38,13 @@ module.exports = {
targets: {
'chrome-desktop': new RemoteBrowserTarget('chrome', {
viewport: '1280x1024',
applyPseudoClasses: true
})
applyPseudoClasses: true,
}),
...process.env.SCREENSHOT_BREAKPOINTS && checkpoints,
},
plugins: [
happoStorybookPlugin({
outputDir: '.happo'
})
]
outputDir: '.happo',
}),
],
}
21 changes: 11 additions & 10 deletions .storybook/components/PicassoBook/Chapter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import React, { Fragment, ReactNode } from 'react'
import DocumentationGenerator, {
PropDocumentation,
PropDocumentationMap,
Documentable
Documentable,
} from '~/.storybook/utils/documentation-generator'
import {
generateUrl,
getHost,
normalize
normalize,
} from '../../../src/utils/url-generator'
import { Typography } from '@toptal/picasso'

Expand Down Expand Up @@ -44,6 +44,7 @@ type Options = {
extra?: string
description?: string
takeScreenshot?: boolean
screenshotBreakpoints?: boolean
} & Record<string, string | boolean>

class Chapter extends Base {
Expand Down Expand Up @@ -76,8 +77,8 @@ class Chapter extends Base {
options: {
decorator: (story: () => ReactNode) => (
<div className='text-section-container'>{story()}</div>
)
}
),
},
})

return this
Expand All @@ -91,7 +92,7 @@ class Chapter extends Base {
const render = () => <PropsTable documentation={documentation} />

this.createSection({
sectionFn: render
sectionFn: render,
})

return this
Expand Down Expand Up @@ -136,7 +137,7 @@ class Chapter extends Base {
this.createSection({
sectionFn: render,
title: name,
subtitle: description
subtitle: description,
})

return this
Expand All @@ -146,7 +147,7 @@ class Chapter extends Base {
const finalOptions: Options =
typeof options === 'string'
? {
title: options
title: options,
}
: options

Expand All @@ -167,7 +168,7 @@ class Chapter extends Base {
host: getHost(),
kind: this.page.section,
type: this.page.title,
section: anchor
section: anchor,
})

const render = () => (
Expand All @@ -191,7 +192,7 @@ class Chapter extends Base {
sectionFn: render,
...finalOptions,
subtitle: description,
info: extra
info: extra,
})

return this
Expand All @@ -200,7 +201,7 @@ class Chapter extends Base {
toStoryBook() {
return {
...this.options,
sections: this.collection.map(section => section.toStoryBook())
sections: this.collection.map(section => section.toStoryBook()),
}
}
}
Expand Down
19 changes: 15 additions & 4 deletions .storybook/components/PicassoBook/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import TabChapter from './TabChapter'

const COMPONENTS_SECTION = 'Components'

const DEFAULT_HAPPO_TARGET = 'chrome-desktop'

class Page extends Base {
type = 'Page'
title = ''
Expand All @@ -20,14 +22,14 @@ class Page extends Base {
info = null,
sectionFn = null,
section = COMPONENTS_SECTION,
alwaysOnTop = false
alwaysOnTop = false,
}) {
super({
title,
subtitle,
info,
section,
sectionFn
sectionFn,
})

this.title = title
Expand Down Expand Up @@ -59,7 +61,7 @@ class Page extends Base {
toStoryBook() {
return {
...this.options,
chapters: this.collection.map(chapter => chapter.toStoryBook())
chapters: this.collection.map(chapter => chapter.toStoryBook()),
}
}

Expand Down Expand Up @@ -92,7 +94,16 @@ class Page extends Base {

const stories = storiesOf(storyName, module)
chapter.sections.forEach(section => {
const parameters = { happo: section.takeScreenshot }
const happoConfig = {}

if (!section.screenshotBreakpoints) {
happoConfig.targets = [DEFAULT_HAPPO_TARGET]
}

const parameters = {
happo: section.takeScreenshot && happoConfig,
}

stories.add(section.title || section.id, section.sectionFn, parameters)
})
})
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
"generate:svg-components": "yarn generate:icons && yarn generate:pictograms",
"generate:icons": "./bin/generate-components-from-svg icon",
"generate:pictograms": "./bin/generate-components-from-svg pictogram",
"happo": "cross-env TEST_ENV=visual HAPPO_PROJECT=Picasso/Storybook happo",
"happo:storybook": "cross-env TEST_ENV=visual HAPPO_IS_ASYNC=false happo-ci-github-actions",
"happo": "cross-env SCREENSHOT_BREAKPOINTS=true TEST_ENV=visual HAPPO_PROJECT=Picasso/Storybook happo",
"happo:storybook": "cross-env SCREENSHOT_BREAKPOINTS=true TEST_ENV=visual HAPPO_IS_ASYNC=false happo-ci-github-actions",
"lint": "davinci-syntax lint code --check .",
"lint:fix": "davinci-syntax lint code .",
"release": "yarn build:package && changeset publish",
Expand Down
16 changes: 13 additions & 3 deletions packages/picasso/src/Grid/story/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,23 @@ page

page
.createChapter()
.addExample('Grid/story/Alignment.example.tsx', 'Alignment')
.addExample('Grid/story/Direction.example.tsx', 'Direction')
.addExample('Grid/story/Wrapping.example.tsx', 'Wrapping')
.addExample('Grid/story/Alignment.example.tsx', {
title: 'Alignment',
screenshotBreakpoints: true,
})
.addExample('Grid/story/Direction.example.tsx', {
title: 'Direction',
screenshotBreakpoints: true,
})
.addExample('Grid/story/Wrapping.example.tsx', {
title: 'Wrapping',
screenshotBreakpoints: true,
})
.addExample('Grid/story/ResponsiveSpacing.example.tsx', {
title: 'Responsive spacing',
description:
'When `spacing` is not explicitly specified by consumer, grid adjusts it according to the screen size (please see the property description for details). You can try to resize screen, to see how different spacing is applied.',
screenshotBreakpoints: true,
})

page.connect(gridItemStory.chapter)
5 changes: 4 additions & 1 deletion packages/picasso/src/PageArticle/story/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import PicassoBook from '~/.storybook/components/PicassoBook'
const chapter = PicassoBook.connectToPage(page =>
page
.createChapter('Page.Article', 'Use as a page content container')
.addExample('PageArticle/story/Default.example.tsx', 'Default')
.addExample('PageArticle/story/Default.example.tsx', {
title: 'Default',
screenshotBreakpoints: true,
})
)

const componentDocs = PicassoBook.createComponentDocs(
Expand Down
18 changes: 12 additions & 6 deletions packages/picasso/src/PageFooter/story/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ const componentDocs = PicassoBook.createComponentDocs(PageFooter, 'Page.Footer')
const chapter = PicassoBook.connectToPage(page =>
page
.createChapter('Page.Footer', 'A Footer component')
.addExample('PageFooter/story/Default.example.tsx', 'Default')
.addExample('PageFooter/story/RightContent.example.tsx', 'Right content')
.addExample(
'PageFooter/story/CopyrightContent.example.tsx',
'Copyright content'
)
.addExample('PageFooter/story/Default.example.tsx', {
title: 'Default',
screenshotBreakpoints: true,
})
.addExample('PageFooter/story/RightContent.example.tsx', {
title: 'Right content',
screenshotBreakpoints: true,
})
.addExample('PageFooter/story/CopyrightContent.example.tsx', {
title: 'Copyright content',
screenshotBreakpoints: true,
})
)

export default {
Expand Down
1 change: 1 addition & 0 deletions packages/picasso/src/PageSidebar/story/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ page
})
.addExample('PageSidebar/story/Size.example.tsx', {
title: 'Sizes',
screenshotBreakpoints: true,
})

page.connect(sidebarItemStory.chapter)
48 changes: 36 additions & 12 deletions packages/picasso/src/PageTopBar/story/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,41 @@ page

page
.createChapter()
.addExample('PageTopBar/story/Default.example.tsx', 'Default')
.addExample('PageTopBar/story/Variants.example.tsx', 'Variants')
.addExample('PageTopBar/story/LeftContent.example.tsx', 'Left content')
.addExample('PageTopBar/story/RightContent.example.tsx', 'Right content')
.addExample('PageTopBar/story/CenterContent.example.tsx', 'Center content')
.addExample(
'PageTopBar/story/ExtraMenuContent.example.tsx',
'Extra header menu content'
)
.addExample('PageTopBar/story/Link.example.tsx', 'With link')
.addExample('PageTopBar/story/WithoutTitle.example.tsx', 'Without title')
.addExample('PageTopBar/story/Logo.example.tsx', 'With custom logo')
.addExample('PageTopBar/story/Default.example.tsx', {
title: 'Default',
screenshotBreakpoints: true,
})
.addExample('PageTopBar/story/Variants.example.tsx', {
title: 'Variants',
screenshotBreakpoints: true,
})
.addExample('PageTopBar/story/LeftContent.example.tsx', {
title: 'Left content',
screenshotBreakpoints: true,
})
.addExample('PageTopBar/story/RightContent.example.tsx', {
title: 'Right content',
screenshotBreakpoints: true,
})
.addExample('PageTopBar/story/CenterContent.example.tsx', {
title: 'Center content',
screenshotBreakpoints: true,
})
.addExample('PageTopBar/story/ExtraMenuContent.example.tsx', {
title: 'Extra header menu content',
screenshotBreakpoints: true,
})
.addExample('PageTopBar/story/Link.example.tsx', {
title: 'With link',
screenshotBreakpoints: true,
})
.addExample('PageTopBar/story/WithoutTitle.example.tsx', {
title: 'Without title',
screenshotBreakpoints: true,
})
.addExample('PageTopBar/story/Logo.example.tsx', {
title: 'With custom logo',
screenshotBreakpoints: true,
})

page.connect(topBarMenuStory.chapter)
1 change: 1 addition & 0 deletions packages/picasso/src/Tabs/story/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ page
})
.addExample('Tabs/story/FullWidth.example.tsx', {
title: 'Full Width',
screenshotBreakpoints: true,
})
page.connect(tabStory.chapter)

0 comments on commit 834327f

Please sign in to comment.