Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
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
2e84193
Merge pull request #574 from storybookjs/yann/bring-in-jest-playwrigh…
yannbf Aug 4, 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
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
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
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',
},
};
43 changes: 22 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "@storybook/test-runner",
"version": "0.22.1",
"description": "Test runner for Storybook stories",
"type": "module",
"keywords": [
"storybook-addons",
"test",
Expand All @@ -17,7 +18,7 @@
"license": "MIT",
"author": "shilman",
"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 Down Expand Up @@ -55,18 +56,20 @@
"@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",
"@types/node-fetch": "^2.6.12",
"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-runner": "^30.0.4",
"jest-serializer-html": "^7.1.0",
"jest-watch-typeahead": "^2.0.0",
"jest-watch-typeahead": "^3.0.1",
"node-fetch": "^3.3.2",
"nyc": "^15.1.0",
"playwright": "^1.14.0"
},
Expand All @@ -76,16 +79,15 @@
"@babel/preset-env": "^7.19.4",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@storybook/addon-a11y": "next",
"@storybook/addon-a11y": "0.0.0-pr-31819-sha-8b752a73",
"@storybook/addon-coverage": "^1.0.0",
"@storybook/addon-docs": "next",
"@storybook/react-vite": "next",
"@types/jest": "^29.0.0",
"@types/node": "^16.4.1",
"@types/node-fetch": "^2.6.11",
"@storybook/addon-docs": "0.0.0-pr-31819-sha-8b752a73",
"@storybook/react-vite": "0.0.0-pr-31819-sha-8b752a73",
"@types/jest": "^30.0.0",
"@types/node": "^24.0.10",
"@vitejs/plugin-react": "^4.0.3",
"auto": "^11.1.6",
"babel-jest": "^29.0.0",
"babel-jest": "^30.0.4",
"babel-loader": "^8.1.0",
"babel-plugin-istanbul": "^6.1.1",
"can-bind-to-host": "^1.1.1",
Expand All @@ -95,23 +97,22 @@
"husky": "^8.0.0",
"jest-image-snapshot": "^6.2.0",
"lint-staged": "^13.0.3",
"node-fetch": "^2",
"pkg-up": "^5.0.0",
"prettier": "^2.8.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"read-pkg-up": "^7.0.1",
"storybook": "next",
"storybook": "0.0.0-pr-31819-sha-8b752a73",
"tempy": "^1.0.1",
"ts-dedent": "^2.0.0",
"ts-jest": "^29.0.0",
"tsup": "^6.5.0",
"typescript": "~4.9.4",
"ts-jest": "^29.4.0",
"tsup": "^8.5.0",
"typescript": "^5.8.3",
"vite": "^6.3.2",
"wait-on": "^7.2.0"
},
"peerDependencies": {
"storybook": "^0.0.0-0 || ^8.2.0 || ^9.0.0 || ^9.1.0-0"
"storybook": "0.0.0-pr-31819-sha-8b752a73"
},
"engines": {
"node": ">=20.0.0"
Expand Down
8 changes: 5 additions & 3 deletions playwright/custom-environment.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const { setupPage } = require('../dist');
import { setupPage } from '../dist/index.js';
import _PlaywrightEnvironment from 'jest-playwright-preset/lib/PlaywrightEnvironment.js';

const PlaywrightEnvironment = require('jest-playwright-preset/lib/PlaywrightEnvironment').default;
// @ts-expect-error check later
const PlaywrightEnvironment = _PlaywrightEnvironment.default ?? _PlaywrightEnvironment;

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

module.exports = CustomEnvironment;
export default CustomEnvironment;
8 changes: 4 additions & 4 deletions playwright/global-setup.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// global-setup.js
const { globalSetup: playwrightGlobalSetup } = require('jest-playwright-preset');
// global-setup.mjs
import { globalSetup as playwrightGlobalSetup } from 'jest-playwright-preset';

module.exports = async function globalSetup(globalConfig) {
export default async function globalSetup(globalConfig) {
return playwrightGlobalSetup(globalConfig);
};
}
8 changes: 4 additions & 4 deletions playwright/global-teardown.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// global-teardown.js
const { globalTeardown: playwrightGlobalTeardown } = require('jest-playwright-preset');
// global-teardown.mjs
import { globalTeardown as playwrightGlobalTeardown } from 'jest-playwright-preset';

module.exports = async function globalTeardown(globalConfig) {
export default async function globalTeardown(globalConfig) {
// Your global teardown
await playwrightGlobalTeardown(globalConfig);
};
}
2 changes: 1 addition & 1 deletion playwright/jest-setup.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { getTestRunnerConfig, setPreVisit, setPostVisit, setupPage } = require('../dist');
import { getTestRunnerConfig, setPreVisit, setPostVisit, setupPage } from '../dist/index.js';

const testRunnerConfig = getTestRunnerConfig(process.env.STORYBOOK_CONFIG_DIR);
if (testRunnerConfig) {
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,
};
12 changes: 6 additions & 6 deletions src/config/jest-playwright.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('getJestConfig', () => {
transform: {
'^.+\\.(story|stories)\\.[jt]sx?$': `${path.dirname(
require.resolve('@storybook/test-runner/playwright/transform')
)}/transform.js`,
)}/transform.mjs`,
'^.+\\.[jt]sx?$': path.resolve('../test-runner/node_modules/@swc/jest'),
},
snapshotSerializers: [path.resolve('../test-runner/node_modules/jest-serializer-html')],
Expand All @@ -30,11 +30,11 @@ describe('getJestConfig', () => {
watchPathIgnorePatterns: ['coverage', '.nyc_output', '.cache'],
roots: undefined,
runner: path.resolve('../test-runner/node_modules/jest-playwright-preset/runner.js'),
globalSetup: path.resolve('playwright/global-setup.js'),
globalTeardown: path.resolve('playwright/global-teardown.js'),
testEnvironment: path.resolve('playwright/custom-environment.js'),
globalSetup: path.resolve('playwright/global-setup.mjs'),
globalTeardown: path.resolve('playwright/global-teardown.mjs'),
testEnvironment: path.resolve('playwright/custom-environment.mjs'),
setupFilesAfterEnv: [
path.resolve('playwright/jest-setup.js'),
path.resolve('playwright/jest-setup.mjs'),
path.resolve('../test-runner/node_modules/expect-playwright/lib'),
path.resolve('../test-runner/node_modules/jest-playwright-preset/lib/extends.js'),
],
Expand Down Expand Up @@ -82,7 +82,7 @@ describe('getJestConfig', () => {
transform: {
'^.+\\.(story|stories)\\.[jt]sx?$': `${path.dirname(
require.resolve('@storybook/test-runner/playwright/transform')
)}/transform.js`,
)}/transform.mjs`,
'^.+\\.[jt]sx?$': path.dirname(require.resolve('@swc/jest')),
},
snapshotSerializers: [path.dirname(require.resolve('jest-serializer-html'))],
Expand Down
44 changes: 15 additions & 29 deletions src/config/jest-playwright.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import path from 'path';
// @ts-ignore
import { getProjectRoot } from 'storybook/internal/common';
import type { Config } from '@jest/types';

Expand All @@ -9,25 +10,17 @@ const getTestRunnerPath = () => process.env.STORYBOOK_TEST_RUNNER_PATH ?? '@stor
* Depending on the user's project and package manager, it's possible that jest-playwright-preset
* is going to be located in @storybook/test-runner/node_modules OR in the root node_modules
*
* By setting `preset: 'jest-playwright-preset` the change of resolution issues is higher, because
* By setting `preset: 'jest-playwright-preset' the change of resolution issues is higher, because
* the lib might be installed inside of @storybook/test-runner/node_modules but references as if it was
* in the root node_modules.
*
* This function does the same thing as `preset: 'jest-playwright-preset` but makes sure that the
* This function does the same thing as `preset: 'jest-playwright-preset' but makes sure that the
* necessary moving parts are all required within the correct path.
* */
const getJestPlaywrightConfig = (): Config.InitialOptions => {
const TEST_RUNNER_PATH = getTestRunnerPath();
const presetBasePath = path.dirname(
require.resolve('jest-playwright-preset', {
paths: [path.join(__dirname, '../node_modules')],
})
);
const expectPlaywrightPath = path.dirname(
require.resolve('expect-playwright', {
paths: [path.join(__dirname, '../node_modules')],
})
);
const presetBasePath = path.dirname(require.resolve('jest-playwright-preset'));
const expectPlaywrightPath = path.dirname(require.resolve('expect-playwright'));
return {
runner: path.join(presetBasePath, 'runner.js'),
globalSetup: require.resolve(`${TEST_RUNNER_PATH}/playwright/global-setup.js`),
Expand All @@ -51,23 +44,15 @@ export const getJestConfig = (): Config.InitialOptions => {
STORYBOOK_JUNIT,
} = process.env;

const jestJunitPath = path.dirname(
require.resolve('jest-junit', {
paths: [path.join(__dirname, '../node_modules')],
})
);
const jestJunitPath = path.dirname(require.resolve('jest-junit'));

const jestSerializerHtmlPath = path.dirname(
require.resolve('jest-serializer-html', {
paths: [path.join(__dirname, '../node_modules')],
})
);
const jestSerializerHtmlPath = path.dirname(require.resolve('jest-serializer-html'));

const swcJestPath = path.dirname(
require.resolve('@swc/jest', {
paths: [path.join(__dirname, '../node_modules')],
})
);
// const swcJestPath = path.dirname(
// require.resolve('@swc/jest', {
// paths: [path.join(import.meta.dirname, '../node_modules')],
// })
// );

const reporters = STORYBOOK_JUNIT ? ['default', jestJunitPath] : ['default'];

Expand All @@ -81,10 +66,11 @@ export const getJestConfig = (): Config.InitialOptions => {
testMatch,
transform: {
'^.+\\.(story|stories)\\.[jt]sx?$': require.resolve(
`${TEST_RUNNER_PATH}/playwright/transform`
`${TEST_RUNNER_PATH}/playwright/transform.js`
),
'^.+\\.[jt]sx?$': swcJestPath,
'^.+\\.[jt]sx?$': 'babel-jest',
},
extensionsToTreatAsEsm: ['.jsx', '.ts', '.tsx'],
snapshotSerializers: [jestSerializerHtmlPath],
testEnvironmentOptions: {
'jest-playwright': {
Expand Down
Loading
Loading