What is @storybook/test-runner?
@storybook/test-runner is a tool designed to run automated tests for Storybook stories. It allows developers to ensure that their UI components behave as expected by running tests in a headless browser environment. This package integrates seamlessly with Storybook, making it easier to test components in isolation.
What are @storybook/test-runner's main functionalities?
Running Tests for Stories
This configuration allows you to run tests for all your Storybook stories. By specifying the testRunner as '@storybook/test-runner', you enable the test runner to execute tests for the stories defined in your project.
module.exports = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: ['@storybook/addon-essentials'],
testRunner: '@storybook/test-runner',
};
Custom Test Configuration
You can customize the test setup by using the 'setup' function. The 'getStoryContext' function from '@storybook/test-runner' provides the context of the story being tested, allowing you to perform custom setup actions before running the tests.
const { getStoryContext } = require('@storybook/test-runner');
module.exports = {
async setup(page) {
const context = await getStoryContext(page);
// Custom setup code here
},
};
Integration with CI/CD
You can integrate @storybook/test-runner with your CI/CD pipeline to automate the testing of your Storybook stories. This example shows a GitHub Actions workflow that installs dependencies and runs the Storybook tests.
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: npm install
- name: Run Storybook tests
run: npm run test-storybook
Other packages similar to @storybook/test-runner
jest
Jest is a popular JavaScript testing framework developed by Facebook. It provides a comprehensive solution for testing JavaScript applications, including support for mocking, code coverage, and snapshot testing. While Jest is not specifically designed for Storybook, it can be used to test Storybook stories with additional configuration.
cypress
Cypress is an end-to-end testing framework that allows developers to write tests for web applications. It provides a powerful and user-friendly interface for writing and running tests. Cypress can be used to test Storybook stories by navigating to the Storybook instance and interacting with the components.
puppeteer
Puppeteer is a Node library that provides a high-level API to control Chrome or Chromium over the DevTools Protocol. It is often used for web scraping, automated testing, and generating screenshots. Puppeteer can be used to test Storybook stories by programmatically interacting with the Storybook UI.
Storybook Test Runner
Storybook test runner turns all of your stories into executable tests.
It's currently a prototype that configures Jest to run smoke tests on your stories in either:
- JSDOM - render stories to JSDOM using TestingLibrary
- Playwright - render stories in a browser using Playwright
The goal of this prototype is to help evaluate both approaches: primarily for performance, but also to understand the general strengths and weaknesses.
Install
The package has not yet been published so you'll have to link it for now.
In the test-runner
package:
yarn && yarn build
yarn link
In your project directory:
yarn link @storybook/test-runner
yarn add jest babel-jest @testing-library/react @storybook/testing-react --dev
For JSDOM (React-only for now):
yarn add jest-environment-jsdom --dev
For Playwright:
yarn add jest-playwright-preset playwright --dev
This simply installs the package in node_modules
. Using the package is fully manual at this point.
Configure
To use the addon, you need to manually configure it:
- Create a script in
package.json
- Create a jest config for your use case
JSDOM
Add a script to package.json
:
{
"scripts": {
"test-storybook:jsdom": "jest --config ./jsdom-jest.config.js"
}
}
Then create a config file jsdom-jest.config.js
that sets up your environment. For example:
module.exports = {
cacheDirectory: '.cache/jest',
testMatch: ['**/*.stories.[jt]s(x)?'],
moduleNameMapper: {
'\\.(jpg|jpeg|png|apng|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'@storybook/test-runner/mocks/fileMock.js',
'\\.(css|scss|stylesheet)$': '@storybook/test-runner/mocks/styleMock.js',
},
transform: {
'^.+\\.stories\\.[jt]sx?$': '@storyboook/test-runner/jsdom/transform',
'^.+\\.[jt]sx?$': 'babel-jest',
},
testEnvironment: 'jest-environment-jsdom',
};
Playwright
Add a script to package.json
:
{
"scripts": {
"test-storybook:playwright": "jest --config ./playwright-jest.config.js"
}
}
Then create a config file playwright-jest.config.js
that sets up your environment. For example:
module.exports = {
cacheDirectory: '.cache/jest',
testMatch: ['**/*.stories.[jt]s(x)?'],
moduleNameMapper: {
'\\.(jpg|jpeg|png|apng|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'@storybook/test-runner/mocks/fileMock.js',
'\\.(css|scss|stylesheet)$': '@storybook/test-runner/mocks/styleMock.js',
},
transform: {
'^.+\\.stories\\.[jt]sx?$': '@storybook/test-runner/playwright/transform',
'^.+\\.[jt]sx?$': 'babel-jest',
},
preset: 'jest-playwright-preset',
testEnvironment: '@storybook/test-runner/playwright/custom-environment.js',
};
NOTE: The code currently assumes that your Storybook is ALREADY running on process.env.STORYBOOK_PORT
which defaults to 6006
.
Running against a deployed Storybook
By default, the playwright assumes that you're running it against a locally served Storybook.
If you want to define a target url so it runs against deployed Storybooks, you can do so by passing the TARGET_URL
environment variable:
{
"scripts": {
"test-storybook:playwright": "TARGET_URL=the-storybook-url-here jest --config ./playwright-jest.config.js"
}
}
Future work
In the future it will support the following features:
- 💨 Smoke test all stories
- ▶️ Test CSF3 play functions
- 🧪 Custom test functions
- 📄 Run addon reports
- ⚡️ Zero config setup