Storybook 7 has deprecated the storyshots plugin, which was commonly used to set up a visual regression testing workflow with jest-image-snapshot (as an alternative to their paid Chromatic service, which offers storybook hosting and visual regression testing).
However, at the time of writing (13/5/2023), Storybook are yet to update their documentation to say this is deprecated, with it only being mentioned in Github issues, and no alternative workflow documented with their new test-runner yet. It is even broken in v7, with recommendations to use workarounds instead of a mainline fix yet.
Overview
The new test-runner functionality uses playwright
and jest
under the hood to run in-browser tests against each of your stories. We can hook this new functionality and run a visual snapshot test with jest-image-snapshot
.
Each story in your storybook is transformed into a test using babel
, and you can add render assertions with a play()
function in your story.
We will customise the underlying test-runner configuration to add a post-test hook to create a snapshot with jest-image-snapshot
.
Install dependencies
yarn install jest-image-snapshot @storybook/test-runner -D
Creating a test-runner config
Storybook have thankfully provided useful jest configuration hooks we can use to install jest-image-snapshot
and run it after each generated story test.
Create a file in your storybook directory at .storybook/test-runner.ts
with this configuration:
import { TestRunnerConfig } from '@storybook/test-runner'
import { toMatchImageSnapshot } from 'jest-image-snapshot'
const config: TestRunnerConfig = {
setup: () => {
expect.extend({ toMatchImageSnapshot })
},
postRender: async (page, context) => {
// Add a post-render delay in case page is still animating
await new Promise((resolve) => setTimeout(resolve, 500))
const screenshot = await page.screenshot()
expect(screenshot).toMatchImageSnapshot({})
},
}
export default config
Add a babel configuration
If you don't already have a .babelrc
(or equivalent), you will need to create one (e.g. if you use swc
already, you will still need to create a babel configuration as unfortunately Storybook test-runner needs it to read your
.stories.tsx
files and create jest unit tests out of them).
.babelrc
{
"presets": ["@babel/preset-typescript", "@babel/preset-env"]
}
Running visual regression tests
The visual regression tests can be setup in your package.json
scripts
section:
"scripts": {
...
"test-storybook": "yarn run storybook-test"
}
When running the test-runner
you need an instance of storybook running in the background:
yarn run storybook &
and then run test-storybook
:
yarn run test-storybook
Establish a baseline
When you run your visual regression tests for the first time, storybook-test
will create a baseline. This will save image files under __image_snapshot__
in your source code folder, which you should check in.
Updating your snapshots
You will need to update your snapshots when there has been a valid change to the layout of your story or there has been a regression.
When a regression is found, the test-runner will fail and it will give you an image path on your filesystem you can reference to see what the regression was.
Once you have fixed and validated your stories and are satisfied they are working correctly, you can update your
baseline snapshots by running:
yarn run test-storybook -u
and check in the resulting changes to git.
Running visual regression tests in CI/CD
You can use the method above (running storybook) to execute the visual regression tests in a CI/CD pipeline.
If you build your storybook for deployment to a server, you can also execute the tests against that server or against the built artifacts with a local http server.
For example, to run them locally after building the storybook with yarn build
:
yarn add wait-on concurrently http-server -D
npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
"npx http-server storybook-static --port 6006 --silent" \
"npx wait-on tcp:6006 && yarn test-storybook
Top comments (0)