Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
cde40cf
adjust versions
yannbf Jun 11, 2025
8c39869
wip
yannbf Jun 30, 2025
4720a97
wip
yannbf Jul 7, 2025
659e613
fix
yannbf Jul 7, 2025
217b308
fix
yannbf Jul 7, 2025
f910288
experiment
yannbf Jul 7, 2025
70a2f93
fix
yannbf Jul 7, 2025
8fd8132
more experiments
yannbf Jul 7, 2025
10734a1
experiment
yannbf Jul 7, 2025
6833c21
wip
yannbf Jul 7, 2025
9d2bec5
remove transformIgnorePatterns
yannbf Jul 9, 2025
7cffe9e
Update package.json
ndelangen Jul 9, 2025
93dc6cc
Update storybook peerDependencies version in yarn.lock
ndelangen Jul 9, 2025
bd1811a
dedupe lockfile
ndelangen Jul 23, 2025
5476b85
use latest canary of esm build of storybook
ndelangen Jul 23, 2025
12b71b1
Refactor Babel configuration to ESM syntax, update package.json to en…
ndelangen Jul 23, 2025
c4a1f20
Remove unused SWC Jest path from Jest configuration and update snapsh…
ndelangen Jul 23, 2025
f536e8a
wip
ndelangen Jul 23, 2025
17a1bcd
Upgrade Vite to version 7.0.5, remove unused Jest Playwright test fil…
yannbf Jul 23, 2025
d326828
fix lockfile
yannbf Jul 23, 2025
71f31ea
add vitest coverage
yannbf Jul 23, 2025
1ec7c6d
fix
yannbf Jul 23, 2025
fe87de1
fix
yannbf Jul 24, 2025
501055a
bundle jest-playwright-preset in
yannbf Jul 25, 2025
8803e9c
fix tests
yannbf Jul 25, 2025
52b7622
fix
yannbf Jul 25, 2025
a94ed75
Update peerDependencies to include storybook version ^9.2.0-0
yannbf Aug 1, 2025
7649ac8
Merge pull request #575 from storybookjs/feat/support-sb-9-2
yannbf Aug 1, 2025
2e84193
Merge pull request #574 from storybookjs/yann/bring-in-jest-playwrigh…
yannbf Aug 4, 2025
ed8fede
Do not use "_" in testTimeout examples
IanVS Sep 12, 2025
9fc3f61
Clarify wording slightly
IanVS Sep 12, 2025
ec458b7
Merge pull request #579 from storybookjs/timeout-docs
yannbf Sep 23, 2025
cefc1d2
upgrade to Storybook 10 beta
yannbf Oct 14, 2025
af6bf62
Merge branch 'next' into yann/experiment-with-esm
yannbf Oct 14, 2025
8ec6db1
fix path
yannbf Oct 17, 2025
fe81472
fixes
yannbf Oct 17, 2025
e482a2f
fix constants
yannbf Oct 20, 2025
9def1de
Merge pull request #571 from storybookjs/yann/experiment-with-esm
yannbf Oct 20, 2025
960fcb6
[skip ci] update viewports recipe
yannbf Oct 28, 2025
d4f1af6
allow for canaries
yannbf Oct 28, 2025
75679c4
Merge pull request #585 from storybookjs/yann/allow-canaries
yannbf Oct 28, 2025
e40d2c6
Merge branch 'main' into release/v0.24.0
yannbf Oct 28, 2025
bb124bd
update compatibility version table
yannbf Oct 28, 2025
058b048
fix compat table
yannbf Oct 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .babelrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
export default {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
Expand Down
4 changes: 2 additions & 2 deletions .storybook/test-runner.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { toMatchImageSnapshot } from 'jest-image-snapshot';

import { getStoryContext, waitForPageReady } from '../dist';
import type { TestRunnerConfig } from '../dist';
import { getStoryContext, waitForPageReady } from '../dist/index.js';
import type { TestRunnerConfig } from '../dist/index.js';

const snapshotsDir = process.env.SNAPSHOTS_DIR || '__snapshots__';
const customSnapshotsDir = `${process.cwd()}/${snapshotsDir}`;
Expand Down
49 changes: 44 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Storybook test runner turns all of your stories into executable tests.

> [!WARNING]
> If you're using Storybook in a Vite-based project, you might want to use [Storybook's Vitest integration](https://storybook.js.org/docs/writing-tests/integrations/vitest-addon?ref=test-runner-migration) instead. It's faster, provides features out of the box such as a11y and coverage, and integrates well with all Storybook's latest features.

<h2>Table of Contents</h2>

- [Features](#features)
Expand Down Expand Up @@ -44,8 +47,10 @@ Storybook test runner turns all of your stories into executable tests.
- [StorybookTestRunner user agent](#storybooktestrunner-user-agent)
- [Recipes](#recipes)
- [Preconfiguring viewport size](#preconfiguring-viewport-size)
- [Accessibility testing](#accessibility-testing)
- [With Storybook 10](#with-storybook-10)
- [With Storybook 9](#with-storybook-9)
- [Accessibility testing](#accessibility-testing)
- [With Storybook 9](#with-storybook-9-1)
- [With Storybook 8](#with-storybook-8)
- [DOM snapshot (HTML)](#dom-snapshot-html)
- [Image snapshot](#image-snapshot)
Expand Down Expand Up @@ -93,7 +98,8 @@ Use the following table to use the correct version of this package, based on the

| Test runner version | Storybook version |
| ------------------- | ----------------- |
| ^0.19.0 | ^8.2.0 |
| ^0.24.0 | ^10.0.0 |
| ^0.19.0 | ^8.2.0 or ^9.0.0 |
| ~0.17.0 | ^8.0.0 |
| ~0.16.0 | ^7.0.0 |
| ~0.9.4 | ^6.4.0 |
Expand Down Expand Up @@ -158,7 +164,7 @@ Usage: test-storybook [options]
| `--url` | Define the URL to run tests in. Useful for custom Storybook URLs <br/>`test-storybook --url http://the-storybook-url-here.com` |
| `--browsers` | Define browsers to run tests in. One or multiple of: chromium, firefox, webkit <br/>`test-storybook --browsers firefox chromium` |
| `--maxWorkers [amount]` | Specifies the maximum number of workers the worker-pool will spawn for running tests <br/>`test-storybook --maxWorkers=2` |
| `--testTimeout [number]` | This option sets the default timeouts of test cases <br/>`test-storybook --testTimeout=15_000` |
| `--testTimeout [number]` | This option sets the timeout of each test case <br/>`test-storybook --testTimeout=15000` |
| `--no-cache` | Disable the cache <br/>`test-storybook --no-cache` |
| `--clearCache` | Deletes the Jest cache directory and then exits without running tests <br/>`test-storybook --clearCache` |
| `--verbose` | Display individual test results with the test suite hierarchy <br/>`test-storybook --verbose` |
Expand Down Expand Up @@ -852,6 +858,39 @@ Below you will find recipes that use both the hooks and the utility functions to

You can use [Playwright's Page viewport utility](https://playwright.dev/docs/api/class-page#page-set-viewport-size) to programatically change the viewport size of your test. If you use [@storybook/addon-viewports](https://storybook.js.org/addons/@storybook/addon-viewport), you can reuse its parameters and make sure that the tests match in configuration.

#### With Storybook 10

```ts
import { TestRunnerConfig, getStoryContext } from '@storybook/test-runner';
import { MINIMAL_VIEWPORTS } from 'storybook/viewport';

const DEFAULT_VIEWPORT_SIZE = { width: 1280, height: 720 };

const config: TestRunnerConfig = {
async preVisit(page, story) {
const context = await getStoryContext(page, story);
const viewportName = context.storyGlobals?.viewport?.value;
const viewportParameter = MINIMAL_VIEWPORTS[viewportName];

if (viewportParameter) {
const viewportSize = Object.fromEntries(
Object.entries(viewportParameter.styles).map(([screen, size]) => [
screen,
Number.parseInt(size),
])
);

page.setViewportSize(viewportSize);
} else {
page.setViewportSize(DEFAULT_VIEWPORT_SIZE);
}
},
};
export default config;
```

#### With Storybook 9

```ts
// .storybook/test-runner.ts
import { TestRunnerConfig, getStoryContext } from '@storybook/test-runner';
Expand Down Expand Up @@ -1073,10 +1112,10 @@ In either way, to fix it you should limit the amount of workers that run in para
}
```

Another option is trying to increase the test timeout by passing the [--testTimeout](https://jestjs.io/docs/cli#--testtimeoutnumber) option to your command (adding `--testTimeout=60_000` will increase test timeouts to 1 minute):
Another option is trying to increase the test timeout by passing the [--testTimeout](https://jestjs.io/docs/cli#--testtimeoutnumber) option to your command (adding `--testTimeout=60000` will increase test timeouts to 1 minute):

```json
"test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"yarn build-storybook --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && yarn test-storybook --maxWorkers=2 --testTimeout=60_000\""
"test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"yarn build-storybook --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && yarn test-storybook --maxWorkers=2 --testTimeout=60000\""
```

#### The test runner reports "No tests found" running on a Windows CI
Expand Down
10 changes: 10 additions & 0 deletions jest-preset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"globalSetup": "@storybook/test-runner/dist/jest-playwright-entries/setup.js",
"globalTeardown": "@storybook/test-runner/dist/jest-playwright-entries/teardown.js",
"testEnvironment": "@storybook/test-runner/dist/jest-playwright-entries",
"runner": "@storybook/test-runner/dist/jest-playwright-entries/runner.js",
"setupFilesAfterEnv": [
"expect-playwright",
"@storybook/test-runner/dist/jest-playwright-entries/lib/extends.js"
]
}
12 changes: 6 additions & 6 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module.exports = {
export default {
testMatch: ['**/*.test.ts'],
moduleNameMapper: {
'@storybook/test-runner/playwright/global-setup': '<rootDir>/playwright/global-setup',
'@storybook/test-runner/playwright/global-teardown': '<rootDir>/playwright/global-teardown',
'@storybook/test-runner/playwright/global-setup': '<rootDir>/playwright/global-setup.js',
'@storybook/test-runner/playwright/global-teardown': '<rootDir>/playwright/global-teardown.js',
'@storybook/test-runner/playwright/custom-environment':
'<rootDir>/playwright/custom-environment',
'@storybook/test-runner/playwright/jest-setup': '<rootDir>/playwright/jest-setup',
'@storybook/test-runner/playwright/transform': '<rootDir>/playwright/transform',
'<rootDir>/playwright/custom-environment.js',
'@storybook/test-runner/playwright/jest-setup': '<rootDir>/playwright/jest-setup.js',
'@storybook/test-runner/playwright/transform': '<rootDir>/playwright/transform.js',
},
};
69 changes: 42 additions & 27 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
},
"license": "MIT",
"author": "shilman",
"type": "module",
"main": "dist/index.js",
"module": "dist/index.mjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"bin": {
"test-storybook": "./dist/test-storybook.js"
Expand All @@ -26,6 +27,7 @@
"dist",
"README.md",
"playwright",
"jest-preset.json",
"*.d.ts"
],
"scripts": {
Expand All @@ -37,7 +39,7 @@
"release": "yarn build && auto shipit",
"start": "concurrently \"yarn build:watch\" \"yarn storybook -- --quiet\"",
"storybook": "storybook dev -p 6006",
"test": "jest",
"test": "vitest",
"test-storybook": "node dist/test-storybook",
"test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"yarn build-storybook --quiet && npx serve storybook-static -l 6006\" \"wait-on tcp:6006 && yarn test-storybook\"",
"test-storybook:ci-coverage": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"yarn build-storybook --quiet && npx serve storybook-static -l 6006\" \"wait-on tcp:6006 && yarn test-storybook --coverage\"",
Expand All @@ -55,64 +57,78 @@
"@babel/generator": "^7.22.5",
"@babel/template": "^7.22.5",
"@babel/types": "^7.22.5",
"@jest/types": "^29.6.3",
"@jest/types": "^30.0.1",
"@swc/core": "^1.5.22",
"@swc/jest": "^0.2.23",
"@swc/jest": "^0.2.38",
"expect-playwright": "^0.8.0",
"jest": "^29.6.4",
"jest-circus": "^29.6.4",
"jest-environment-node": "^29.6.4",
"jest": "^30.0.4",
"jest-circus": "^30.0.4",
"jest-environment-node": "^30.0.4",
"jest-junit": "^16.0.0",
"jest-playwright-preset": "^4.0.0",
"jest-runner": "^29.6.4",
"jest-process-manager": "^0.4.0",
"jest-runner": "^30.0.4",
"jest-serializer-html": "^7.1.0",
"jest-watch-typeahead": "^2.0.0",
"jest-watch-typeahead": "^3.0.1",
"nyc": "^15.1.0",
"playwright": "^1.14.0"
"playwright": "^1.14.0",
"playwright-core": ">=1.2.0",
"rimraf": "^3.0.2",
"uuid": "^8.3.2"
},
"devDependencies": {
"@auto-it/released": "^11.1.6",
"@babel/cli": "^7.12.1",
"@babel/preset-env": "^7.19.4",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@storybook/addon-a11y": "^9.0.0",
"@storybook/addon-a11y": "^10.0.0",
"@storybook/addon-coverage": "^1.0.0",
"@storybook/addon-docs": "^9.0.0",
"@storybook/react-vite": "^9.0.0",
"@types/jest": "^29.0.0",
"@types/node": "^16.4.1",
"@types/node-fetch": "^2.6.11",
"@storybook/addon-docs": "^10.0.0",
"@storybook/react-vite": "^10.0.0",
"@types/jest": "^30.0.0",
"@types/node": "^24.0.10",
"@types/rimraf": "^3.0.2",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "5.30.7",
"@typescript-eslint/parser": "5.30.7",
"@vitejs/plugin-react": "^4.0.3",
"@vitest/coverage-v8": "^3.2.4",
"auto": "^11.1.6",
"babel-jest": "^29.0.0",
"babel-loader": "^8.1.0",
"babel-plugin-istanbul": "^6.1.1",
"can-bind-to-host": "^1.1.1",
"commander": "^9.0.0",
"concurrently": "^7.0.0",
"glob": "^10.2.2",
"husky": "^8.0.0",
"jest": "^30.0.0",
"jest-circus": "^30.0.0",
"jest-environment-node": "^30.0.0",
"jest-image-snapshot": "^6.2.0",
"jest-runner": "^30.0.0",
"lint-staged": "^13.0.3",
"node-fetch": "^2",
"pathe": "^2.0.3",
"pkg-up": "^5.0.0",
"playwright": ">=1.24.0",
"playwright-chromium": ">=1.24.0",
"prettier": "^2.8.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"read-pkg-up": "^7.0.1",
"storybook": "^9.0.0",
"storybook": "^10.0.0",
"tempy": "^1.0.1",
"ts-dedent": "^2.0.0",
"ts-jest": "^29.0.0",
"tsup": "^6.5.0",
"typescript": "~4.9.4",
"vite": "^6.3.2",
"ts-jest": "^29.4.0",
"tsup": "^8.5.0",
"typescript": "^5.8.3",
"vite": "^7.0.5",
"vitest": "^3.2.4",
"wait-on": "^7.2.0"
},
"peerDependencies": {
"storybook": "^0.0.0-0 || ^8.2.0 || ^9.0.0 || ^9.1.0-0 || ^9.2.0-0"
"storybook": "^0.0.0-0 || ^10.0.0 || ^10.0.0-0"
},
"packageManager": "yarn@4.5.1",
"engines": {
"node": ">=20.0.0"
},
Expand All @@ -136,6 +152,5 @@
"react-native"
],
"icon": "https://user-images.githubusercontent.com/321738/63501763-88dbf600-c4cc-11e9-96cd-94adadc2fd72.png"
},
"packageManager": "yarn@4.5.1"
}
}
7 changes: 3 additions & 4 deletions playwright/custom-environment.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const { setupPage } = require('../dist');

const PlaywrightEnvironment = require('jest-playwright-preset/lib/PlaywrightEnvironment').default;
import { setupPage } from '../dist/index.js';
import PlaywrightEnvironment from '../dist/jest-playwright-entries/test-environment.js';

class CustomEnvironment extends PlaywrightEnvironment {
async setup() {
Expand All @@ -17,4 +16,4 @@ class CustomEnvironment extends PlaywrightEnvironment {
}
}

module.exports = CustomEnvironment;
export default CustomEnvironment;
6 changes: 0 additions & 6 deletions playwright/global-setup.js

This file was deleted.

7 changes: 0 additions & 7 deletions playwright/global-teardown.js

This file was deleted.

4 changes: 2 additions & 2 deletions playwright/jest-setup.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { getTestRunnerConfig, setPreVisit, setPostVisit, setupPage } = require('../dist');
import { getTestRunnerConfig, setPreVisit, setPostVisit, setupPage } from '../dist/index.js';

const testRunnerConfig = getTestRunnerConfig(process.env.STORYBOOK_CONFIG_DIR);
const testRunnerConfig = await getTestRunnerConfig(process.env.STORYBOOK_CONFIG_DIR);
if (testRunnerConfig) {
// hooks set up
if (testRunnerConfig.setup) {
Expand Down
4 changes: 2 additions & 2 deletions playwright/test-runner-jest.config.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const { getJestConfig } = require('../dist');
import { getJestConfig } from '../dist/index.js';

// The default Jest configuration comes from @storybook/test-runner
const testRunnerConfig = getJestConfig();

/**
* @type {import('@jest/types').Config.InitialOptions}
*/
module.exports = {
export default {
...testRunnerConfig,
/** Add your own overrides below, and make sure
* to merge testRunnerConfig properties with your own
Expand Down
34 changes: 25 additions & 9 deletions playwright/transform.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
const { transformSync: swcTransform } = require('@swc/core');
const { transformPlaywright } = require('../dist');
import { transform as swcTransform } from '@swc/core';
import { transformPlaywright } from '../dist/index.js';

module.exports = {
process(src, filename) {
const csfTest = transformPlaywright(src, filename);

const result = swcTransform(csfTest, {
// Only export async version - force Jest to use it
async function processAsync(src, filename) {
try {
const csfTest = await transformPlaywright(src, filename);
// This swc transform might not be needed
const result = await swcTransform(csfTest, {
filename,
isModule: true,
module: {
type: 'commonjs',
type: 'es6',
},
jsc: {
parser: {
syntax: 'typescript',
tsx: true,
},
target: 'es2015',
},
});

return { code: result ? result.code : src };
},
} catch (error) {
console.error('Transform error:', error);
return { code: src };
}
}

export default {
processAsync,
};
Loading
Loading