Skip to content

Commit

Permalink
Storybook: Set up local visual regression testing
Browse files Browse the repository at this point in the history
  • Loading branch information
mirka committed Aug 18, 2022
1 parent 2b99bd3 commit 9854cbe
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ phpcs.xml
phpunit.xml
phpunit-watcher.yml
.tool-versions
test/storybook-playwright/test-results
test/storybook-playwright/index.spec.ts-snapshots
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@
"test:e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js",
"test:e2e:debug": "wp-scripts --inspect-brk test-e2e --config packages/e2e-tests/jest.config.js --puppeteer-devtools",
"test:e2e:playwright": "playwright test --config test/e2e/playwright.config.ts",
"test:e2e:storybook": "playwright test --config test/storybook-playwright/playwright.config.ts",
"test:e2e:watch": "npm run test:e2e -- --watch",
"test:performance": "wp-scripts test-e2e --config packages/e2e-tests/jest.performance.config.js",
"test:php": "npm-run-all lint:php test:unit:php",
Expand Down
7 changes: 5 additions & 2 deletions packages/components/src/date-time/stories/date-time.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,14 @@ const Template: ComponentStory< typeof DateTimePicker > = ( {
export const Default: ComponentStory< typeof DateTimePicker > = Template.bind(
{}
);
Default.args = {
currentDate: new Date( 'December 17, 2022 03:24:00' ),
};

export const WithEvents: ComponentStory< typeof DateTimePicker > =
Template.bind( {} );
WithEvents.args = {
currentDate: new Date(),
...Default.args,
events: [
{ date: daysFromNow( 2 ) },
{ date: daysFromNow( 4 ) },
Expand All @@ -68,6 +71,6 @@ WithEvents.args = {
export const WithInvalidDates: ComponentStory< typeof DateTimePicker > =
Template.bind( {} );
WithInvalidDates.args = {
currentDate: new Date(),
...Default.args,
isInvalidDate: isWeekend,
};
3 changes: 3 additions & 0 deletions packages/components/src/date-time/stories/time.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ const Template: ComponentStory< typeof TimePicker > = ( {
};

export const Default: ComponentStory< typeof TimePicker > = Template.bind( {} );
Default.args = {
currentTime: new Date( 'December 17, 2022 03:24:00' ),
};
1 change: 1 addition & 0 deletions storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = {
features: {
babelModeV7: true,
emotionAlias: false,
buildStoriesJson: true,
},
// Workaround:
// https://github.com/storybookjs/storybook/issues/12270
Expand Down
33 changes: 33 additions & 0 deletions test/storybook-playwright/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Storybook Playwright Tests

This is currently set up for testing visual regressions in the `components` package. The tests do not run on CI, and is meant as a testing tool for local development.

## How to run

First, prepare a static build of the Storybook. This is required to generate the `stories.json` file, which contains metadata for every story.

```sh
npm run storybook:build
```

Then serve the Storybook locally, using either the static build prepared in the previous step, or the dev server if you want to iterate in watch mode.

```sh
# Using the static build
npx http-server storybook/build -p 50240

# Using the dev server
npm run storybook:dev
```

You are now ready to run the tests. The first run will generate the reference images, and subsequent runs will compare against them.

```sh
npm run test:e2e:storybook
```

To update the reference images, pass the `--update-snapshots` flag.

```sh
npm run test:e2e:storybook -- --update-snapshots
```
45 changes: 45 additions & 0 deletions test/storybook-playwright/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* External dependencies
*/
import { test, expect } from '@playwright/test';
import { readFileSync } from 'fs';
import { resolve } from 'path';
import type { StoryIndex, StoryIndexEntry } from '@storybook/store';

const STORYBOOK_PORT = '50240';
const STORYBOOK_DIR = resolve( __dirname, '../../storybook/build' );

const { stories }: StoryIndex = JSON.parse(
readFileSync( resolve( STORYBOOK_DIR, 'stories.json' ) ).toString()
);

const includeIds = [ /^components-/ ];
const excludeIds = [ /animate/, /zstack/ ];

const filterMatches = ( story: StoryIndexEntry ) => {
const isIncluded = includeIds.some( ( includeRegex ) =>
includeRegex.test( story.id )
);
const isExcluded = excludeIds.some( ( excludeRegex ) =>
excludeRegex.test( story.id )
);
return isIncluded && ! isExcluded;
};

test.describe.parallel( 'Storybook visual regressions', () => {
Object.values( stories )
.filter( filterMatches )
.forEach( ( story ) => {
test( `${ story.title }: ${ story.name }`, async ( { page } ) => {
await page.goto(
`http://localhost:${ STORYBOOK_PORT }/iframe.html?id=${ story.id }`,
{ waitUntil: 'load' }
);
expect(
await page
.locator( '#root' )
.screenshot( { animations: 'disabled' } )
).toMatchSnapshot( [ story.title, `${ story.id }.png` ] );
} );
} );
} );
13 changes: 13 additions & 0 deletions test/storybook-playwright/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* External dependencies
*/
import { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
outputDir: 'test-results/output',
reporter: [
[ 'html', { open: 'on-failure', outputFolder: 'test-results/report' } ],
],
};

export default config;

0 comments on commit 9854cbe

Please sign in to comment.