### Setup Function for Test Runner Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-test-runner-config.md Use the `setup` function to perform Node-level setup before all tests run, such as extending Jest matchers. ```typescript const config: TestRunnerConfig = { async setup() { expect.extend({ toHaveAccessibility: myMatcher }); }, }; ``` -------------------------------- ### setup Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-test-runner-config.md Executes once before all tests run. Use for Node-level setup like extending Jest matchers. ```APIDOC ## setup ### Description Executes once before all tests run. Use for Node-level setup like extending Jest matchers. ### Type `() => void` (optional) ### Example ```typescript const config: TestRunnerConfig = { async setup() { expect.extend({ toHaveAccessibility: myMatcher }); }, }; ``` ``` -------------------------------- ### Install Storybook Test Runner Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/README.md Install the Storybook test runner as a development dependency. ```bash yarn add --dev @storybook/test-runner ``` -------------------------------- ### Install @storybook/test-runner Source: https://github.com/storybookjs/test-runner/blob/next/MIGRATION.test-runner.md Remove the old addon and install the new test-runner package using yarn. ```sh yarn remove @storybook/addon-storyshots yarn add --save-dev @storybook/test-runner ``` -------------------------------- ### Configuration Precedence Example Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/architecture.md Shows the order of priority for configuration settings, from CLI flags to default values. ```text 1. CLI Flags (highest priority) test-storybook --url http://custom.com 2. Environment Variables TARGET_URL=http://custom.com test-storybook 3. Configuration File .storybook/test-runner.ts (TestRunnerConfig) 4. Default Values (lowest priority) http://127.0.0.1:6006 ``` -------------------------------- ### Global Setup Hook Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/test-lifecycle.md The setup hook runs once before all tests. It's used for global setup tasks in the Node.js environment, such as extending Jest matchers or initializing test utilities. It cannot access the browser page or story context. ```typescript import expect from 'expect'; import { toHaveAccessibility } from 'some-a11y-library'; const config: TestRunnerConfig = { async setup() { // Extend Jest matchers expect.extend({ toHaveAccessibility }); // Initialize global test helpers globalThis.testUtils = { mockAPI() { /* ... */ }, }; // Set up environment process.env.TEST_MODE = 'true'; }, }; ``` -------------------------------- ### Install @storybook/addon-coverage Source: https://github.com/storybookjs/test-runner/blob/next/README.md Install the @storybook/addon-coverage package as a development dependency using yarn. ```sh yarn add -D @storybook/addon-coverage ``` -------------------------------- ### Import Project-Level Annotations in Setup File Source: https://github.com/storybookjs/test-runner/blob/next/MIGRATION.portable-stories.md Import project-level annotations like decorators and styles from your Storybook preview file into your test setup file. This ensures global configurations are applied to your tests. ```typescript // your-setup-file.ts // Adjust the import based on the supported framework or Storybook's testing libraries (e.g., react, testing-vue3) import { setProjectAnnotations } from '@storybook/your-framework'; import * as projectAnnotations from './.storybook/preview'; // Apply the global annotations from the Storybook preview file setProjectAnnotations(projectAnnotations); ``` ```diff - import * as projectAnnotations from './.storybook/preview' + import projectAnnotations from './.storybook/preview' ``` -------------------------------- ### Test Runner Setup Hook Configuration Source: https://github.com/storybookjs/test-runner/blob/next/README.md Configure the global setup hook in `.storybook/test-runner.ts` to run Node.js code once before all tests. ```typescript // .storybook/test-runner.ts import type { TestRunnerConfig } from '@storybook/test-runner'; const config: TestRunnerConfig = { async setup() { // execute whatever you like, in Node, once before all tests run }, }; export default config; ``` -------------------------------- ### Vitest Setup for Multi-Snapshot Files Source: https://github.com/storybookjs/test-runner/blob/next/MIGRATION.portable-stories.md Adapt the Vitest setup to use `toMatchFileSnapshot` for generating individual snapshot files per story. This is useful if you previously used a multi-snapshot configuration with Storyshots. ```typescript // ...Code omitted for brevity describe(options.suite, () => { // 👇 Add storyDir in the arguments list getAllStoryFiles().forEach(({ filePath, storyFile, storyDir }) => { // ...Previously existing code describe(title, () => { // ...Previously existing code stories.forEach(({ name, story }) => { // ...Previously existing code testFn(name, async () => { // ...Previously existing code // 👇 Define the path to save the snapshot to: const snapshotPath = path.join( storyDir, options.snapshotsDirName, `${componentName}${options.snapshotExtension}` ); expect(mounted.container).toMatchFileSnapshot(snapshotPath); }); }); }); }); }); ``` -------------------------------- ### Extend Jest Matchers with Setup Hook Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/configuration.md Illustrates how to use the `setup` hook to extend Jest matchers before tests run. This is useful for adding custom assertion logic. ```typescript import expect from 'expect'; const config: TestRunnerConfig = { async setup() { // Extend Jest matchers expect.extend({ customMatcher(received) { return { message: () => 'custom assertion failed', pass: received === true, }; }, }); }, }; ``` -------------------------------- ### Basic Setup for Test Runner Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/configuration.md Configure the test runner to set a standard viewport before visiting pages. This is useful for ensuring consistent test environments. ```typescript // .storybook/test-runner.ts import type { TestRunnerConfig } from '@storybook/test-runner'; const config: TestRunnerConfig = { async preVisit(page) { // Set a standard viewport await page.setViewportSize({ width: 1280, height: 720 }); }, }; export default config; ``` -------------------------------- ### Setup Playwright Page for Testing Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-utility-functions.md Prepares a Playwright Page for testing by injecting setup scripts and configuring the environment. Used internally by the test-runner; normally does not need to be called directly. ```typescript setupPage(page: Page, browserContext: BrowserContext): Promise ``` -------------------------------- ### setupPage Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Configures the Playwright page for testing by navigating to the Storybook iframe, injecting setup scripts, exposing Node-to-browser APIs, and applying custom logic. ```APIDOC ## setupPage ### Description Configure Playwright page for testing. ### Method function ### Signature ```typescript function setupPage(page: Page, browserContext: BrowserContext): Promise ``` ### Details 1. Navigating to Storybook iframe 2. Injecting setup script 3. Exposing Node-to-browser APIs 4. Applying HTTP headers and custom prepare logic ``` -------------------------------- ### Setup Playwright Page Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Configures a Playwright page for testing by navigating to the Storybook iframe, injecting a setup script, exposing Node-to-browser APIs, and applying HTTP headers and custom prepare logic. ```typescript function setupPage(page: Page, browserContext: BrowserContext): Promise ``` -------------------------------- ### Vitest Setup for Portable Stories Source: https://github.com/storybookjs/test-runner/blob/next/MIGRATION.portable-stories.md Configure your `storybook.test.ts` file to use `composeStories` for migrating snapshot tests. Ensure correct imports for your framework and testing library. This setup generates a single snapshot file for all stories. ```typescript // storybook.test.ts // @vitest-environment jsdom // Replace your-framework with one of the supported Storybook frameworks (react, vue3) import type { Meta, StoryFn } from '@storybook/your-framework'; import { describe, expect, test } from 'vitest'; // Replace your-testing-library with one of the supported testing libraries (e.g., react, vue) import { render } from '@testing-library/your-testing-library'; // Adjust the import based on the supported framework or Storybook's testing libraries (e.g., react, testing-vue3) import { composeStories } from '@storybook/your-framework'; type StoryFile = { default: Meta; [name: string]: StoryFn | Meta; }; const compose = (entry: StoryFile): ReturnType> => { try { return composeStories(entry); } catch (e) { throw new Error( `There was an issue composing stories for the module: ${JSON.stringify(entry)}, ${e}` ); } }; function getAllStoryFiles() { // Place the glob you want to match your story files const storyFiles = Object.entries( import.meta.glob('./stories/**/*.(stories|story).@(js|jsx|mjs|ts|tsx)', { eager: true, }) ); return storyFiles.map(([filePath, storyFile]) => { const storyDir = path.dirname(filePath); const componentName = path.basename(filePath).replace(/\.(stories|story)\.[^/.]+$/, ''); return { filePath, storyFile, componentName, storyDir }; }); } // Recreate similar options to storyshots. Place your configuration below const options = { suite: 'Storybook Tests', storyKindRegex: /^.*?DontTest$/, storyNameRegex: /UNSET/, snapshotsDirName: '__snapshots__', snapshotExtension: '.storyshot', }; describe(options.suite, () => { getAllStoryFiles().forEach(({ storyFile, componentName, storyDir }) => { const meta = storyFile.default; const title = meta.title || componentName; if (options.storyKindRegex.test(title) || meta.parameters?.storyshots?.disable) { // Skip component tests if they are disabled return; } describe(title, () => { const stories = Object.entries(compose(storyFile)) .map(([name, story]) => ({ name, story })) .filter(({ name, story }) => { // Implements a filtering mechanism to avoid running stories that are disabled via parameters or that match a specific regex mirroring the default behavior of Storyshots. return !options.storyNameRegex?.test(name) && !story.parameters.storyshots?.disable; }); if (stories.length <= 0) { throw new Error( `No stories found for this module: ${title}. Make sure there is at least one valid story for this module, without a disable parameter, or add parameters.storyshots.disable in the default export of this file.` ); } stories.forEach(({ name, story }) => { // Instead of not running the test, you can create logic to skip it, flagging it accordingly in the test results. const testFn = story.parameters.storyshots?.skip ? test.skip : test; testFn(name, async () => { const mounted = render(story()); // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. await new Promise((resolve) => setTimeout(resolve, 1)); expect(mounted.container).toMatchSnapshot(); }); }); }); }); }); ``` -------------------------------- ### Custom Browser Preparation with prepare Hook Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/configuration.md Explains the `prepare` hook for overriding default browser preparation, including setting cookies, navigating to iframes, applying custom headers, and initiating page navigation. Use this only for custom authentication or environment setup. ```typescript const config: TestRunnerConfig = { async prepare({ page, browserContext, testRunnerConfig }) { const targetURL = process.env.TARGET_URL || 'http://127.0.0.1:6006'; // Set cookies before visiting await browserContext.addCookies([ { name: 'sessionId', value: 'abc123xyz', url: targetURL, }, ]); // Navigate to iframe const iframeURL = new URL('iframe.html', targetURL).toString(); // Apply custom headers if (testRunnerConfig?.getHttpHeaders) { const headers = await testRunnerConfig.getHttpHeaders(iframeURL); await browserContext.setExtraHTTPHeaders(headers); } // Go to page await page.goto(iframeURL, { waitUntil: 'load' }); }, }; ``` -------------------------------- ### CircleCI Example for Sharded Tests Source: https://github.com/storybookjs/test-runner/blob/next/README.md Set up CircleCI to run tests in parallel with sharding and handle coverage file management. ```yml test: parallelism: 4 steps: - run: command: yarn test-storybook --coverage --shard=$(expr $CIRCLE_NODE_INDEX + 1)/$CIRCLE_NODE_TOTAL command: mv coverage/storybook/coverage-storybook.json coverage/storybook/coverage-storybook-${CIRCLE_NODE_INDEX + 1}.json report-coverage: steps: - run: command: yarn nyc merge coverage/storybook merged-output/merged-coverage.json command: yarn nyc report --reporter=text -t merged-output --report-dir merged-output ``` -------------------------------- ### Configure Storybook Test Runner Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-test-runner-config.md Define custom logic for setup, pre-visit, post-visit, and HTTP headers in the test runner configuration file. ```typescript // .storybook/test-runner.ts import type { TestRunnerConfig } from '@storybook/test-runner'; const config: TestRunnerConfig = { setup() { // Node-side setup }, async preVisit(page, context) { // Before story renders }, async postVisit(page, context) { // After story renders }, getHttpHeaders(url) { // Custom headers for requests }, }; export default config; ``` -------------------------------- ### Configure Test Hooks Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/README.md Set up preVisit and postVisit hooks to execute code before and after a story renders. This is useful for custom setup or teardown logic during testing. ```typescript import type { TestRunnerConfig } from '@storybook/test-runner'; const config: TestRunnerConfig = { async preVisit(page, context) { // Before story renders }, async postVisit(page, context) { // After story renders }, }; export default config; ``` -------------------------------- ### Configure Storybook Test Runner with TypeScript Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/README.md Use this TypeScript file to define global setup, pre/post visit hooks, HTTP headers, and tag filtering for your tests. ```typescript import type { TestRunnerConfig } from '@storybook/test-runner'; const config: TestRunnerConfig = { async setup() { // Global setup (Node-side) }, async preVisit(page, context) { // Before each story renders }, async postVisit(page, context) { // After each story renders }, getHttpHeaders: async (url) => ({ Authorization: `Bearer token`, }), tags: { include: ['test'], exclude: ['design'], }, }; export default config; ``` -------------------------------- ### Run Storybook and Test Runner Source: https://github.com/storybookjs/test-runner/blob/next/MIGRATION.test-runner.md Start your Storybook instance in one terminal and then run the test-runner in a separate terminal. ```sh yarn storybook ``` ```sh yarn test-storybook ``` -------------------------------- ### GitLab CI Example for Sharded Tests Source: https://github.com/storybookjs/test-runner/blob/next/README.md Configure GitLab CI for parallel test execution using sharding and manage coverage reporting. ```yml test: parallel: 4 script: - yarn test-storybook --coverage --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL - mv coverage/storybook/coverage-storybook.json coverage/storybook/coverage-storybook-${CI_NODE_INDEX}.json report-coverage: script: - yarn nyc merge coverage/storybook merged-output/merged-coverage.json - yarn nyc report --reporter=text -t merged-output --report-dir merged-output ``` -------------------------------- ### GitHub CI Example for Sharded Tests Source: https://github.com/storybookjs/test-runner/blob/next/README.md Configure GitHub Actions to run tests in parallel using the --shard flag and manage coverage file renaming and merging. ```yml test: name: Running Test-storybook (${{ matrix.shard }}) strategy: matrix: shard: [1, 2, 3, 4] steps: - name: Testing storybook run: yarn test-storybook --coverage --shard=${{ matrix.shard }}/${{ strategy.job-total }} - name: Renaming coverage file run: mv coverage/storybook/coverage-storybook.json coverage/storybook/coverage-storybook-${matrix.shard}.json report-coverage: name: Reporting storybook coverage steps: - name: Merging coverage run: yarn nyc merge coverage/storybook merged-output/merged-coverage.json - name: Report coverage run: yarn nyc report --reporter=text -t merged-output --report-dir merged-output ``` -------------------------------- ### CI/CD Pipeline Test with Dynamic URL Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/index-json-mode.md Integrate Storybook testing into a CI/CD pipeline, such as GitHub Actions. This example dynamically fetches the Storybook URL from deployment status and includes coverage and JUnit reporting. ```yaml # GitHub Actions example - name: Test Storybook run: | test-storybook \ --index-json \ --url ${{ github.event.deployment_status.target_url }} \ --coverage \ --junit ``` -------------------------------- ### Run Storybook Instance Source: https://github.com/storybookjs/test-runner/blob/next/README.md Ensure your Storybook instance is running before executing the test runner. This command starts Storybook using Yarn. ```jsx yarn storybook ``` -------------------------------- ### Module Dependencies Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/architecture.md Illustrates the flow of execution and dependencies between different modules within the Test Runner, starting from CLI parsing to Jest execution. ```text test-storybook (entry) ↓ ├─ getCliOptions → CLI parsing ├─ getStorybookMetadata → Project discovery ├─ getStorybookMain → Config loading ├─ transformPlaywright → Test generation └─ Jest execution ↓ ├─ PlaywrightEnvironment → Browser lifecycle ├─ PlaywrightRunner → Test execution ├─ setupPage → Page preparation └─ TestRunnerConfig → User hooks ``` -------------------------------- ### Storybook Test Runner Configuration File Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Example of a TypeScript configuration file for the Storybook Test Runner. This file should export a TestRunnerConfig object. ```typescript // .storybook/test-runner.ts import type { TestRunnerConfig } from '@storybook/test-runner'; const config: TestRunnerConfig = { // configuration }; export default config; ``` -------------------------------- ### Jest Configuration for Test Runner Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Example of a Jest configuration file using CommonJS, which extends the default Jest configuration provided by the test runner. ```javascript // test-runner-jest.config.js const { getJestConfig } = require('@storybook/test-runner'); module.exports = { ...getJestConfig(), // overrides }; ``` -------------------------------- ### Merge code coverage reports Source: https://github.com/storybookjs/test-runner/blob/next/README.md Configure npm scripts to merge coverage from different tools. This example copies the Storybook coverage file and then runs `nyc report` to generate an HTML report, merging it with other coverage data in the `coverage` directory. ```json { "scripts": { "test:coverage": "jest --coverage", "test-storybook:coverage": "test-storybook --coverage", "coverage-report": "cp coverage/storybook/coverage-storybook.json coverage/coverage-storybook.json && nyc report --reporter=html -t coverage --report-dir coverage" } } ``` -------------------------------- ### GitHub Actions Workflow for Local Storybook Tests Source: https://github.com/storybookjs/test-runner/blob/next/README.md A GitHub Actions workflow to run Storybook tests in CI. This workflow checks out code, sets up Node.js, installs dependencies, and executes the 'test-storybook:ci' script. ```yaml name: Storybook Tests on: push jobs: test: timeout-minutes: 60 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '18.x' - name: Install dependencies run: yarn - name: Run Storybook tests run: yarn test-storybook:ci ``` -------------------------------- ### Get Jest Configuration Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Retrieves the Jest configuration, including Playwright environment setup, SWC transpilation, story file matching, coverage collection, and reporter configuration. ```typescript function getJestConfig(): Config.InitialOptions ``` -------------------------------- ### Generate Individual Snapshots with jest-specific-snapshot Source: https://github.com/storybookjs/test-runner/blob/next/MIGRATION.portable-stories.md Adapt the previous example to generate individual snapshot files per story using `jest-specific-snapshot`. This requires importing 'jest-specific-snapshot' and using `toMatchSpecificSnapshot` with a dynamically generated path. ```typescript // storybook.test.ts // 👇 Augment expect with jest-specific-snapshot import 'jest-specific-snapshot'; // ...Code omitted for brevity describe(options.suite, () => { //👇 Add storyDir in the arguments list getAllStoryFiles().forEach(({ filePath, storyFile, storyDir }) => { // ...Previously existing code describe(title, () => { // ...Previously existing code stories.forEach(({ name, story }) => { // ...Previously existing code testFn(name, async () => { // ...Previously existing code //👇 Define the path to save the snapshot to: const snapshotPath = path.join( storyDir, options.snapshotsDirName, `${componentName}${options.snapshotExtension}` ); expect(mounted.container).toMatchSpecificSnapshot(snapshotPath); }); }); }); }); }); ``` -------------------------------- ### Display Help for test-storybook CLI Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-cli-options.md View all available command-line options and their descriptions for the test-storybook command. ```bash test-storybook --help ``` -------------------------------- ### Display Help Information Source: https://github.com/storybookjs/test-runner/blob/next/README.md Use the --help flag to display usage information for the test-storybook command. ```plaintext test-storybook --help ``` -------------------------------- ### Custom Browser Preparation with prepare() Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/test-lifecycle.md Use this snippet to override the default browser preparation behavior. It demonstrates custom authentication, applying HTTP headers, navigating to Storybook, and performing custom initialization on the page. ```typescript const config: TestRunnerConfig = { async prepare({ page, browserContext, testRunnerConfig }) { const targetURL = process.env.TARGET_URL || 'http://127.0.0.1:6006'; // Custom authentication const token = await fetchAuthToken(); await browserContext.addCookies([ { name: 'auth_token', value: token, url: targetURL, }, ]); // Apply custom headers if (testRunnerConfig?.getHttpHeaders) { const headers = await testRunnerConfig.getHttpHeaders( `${targetURL}iframe.html` ); await browserContext.setExtraHTTPHeaders(headers); } // Navigate to Storybook const iframeURL = new URL('iframe.html', targetURL).toString(); await page.goto(iframeURL, { waitUntil: 'load' }); // Custom initialization await page.evaluate(() => { window.customTestSetup = true; }); }, }; ``` -------------------------------- ### Get Test Runner Configuration Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Loads the test-runner configuration from `.storybook/test-runner.ts` or a custom directory. ```typescript function getTestRunnerConfig(configDir?: string): Promise ``` -------------------------------- ### Correct Usage for Index Mode Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/index-json-mode.md Demonstrates the correct way to run test-storybook in index.json mode. Avoid using watch flags when index mode is enabled, as they are incompatible. ```bash # Wrong test-storybook --index-json --watch # Correct test-storybook --index-json ``` -------------------------------- ### CI Recipe for Locally Built Storybooks Source: https://github.com/storybookjs/test-runner/blob/next/README.md This JSON configuration defines a script for CI environments that builds Storybook, serves it locally, and then runs tests against it. It uses concurrently, http-server, and wait-on for orchestration. ```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\"" } ``` -------------------------------- ### Storybook Test Execution Lifecycle Source: https://github.com/storybookjs/test-runner/blob/next/README.md Illustrates the sequence of operations during a Storybook test, including setup, pre-visit, rendering, and post-visit hooks. ```typescript // executed once, before the tests await setup(); it('button--basic', async () => { // filled in with data for the current story const context = { id: 'button--basic', title: 'Button', name: 'Basic' }; // playwright page https://playwright.dev/docs/pages await page.goto(STORYBOOK_URL); // pre-visit hook if (preVisit) await preVisit(page, context); // render the story and watch its play function (if applicable) await page.execute('render', context); // post-visit hook if (postVisit) await postVisit(page, context); }); ``` -------------------------------- ### List all tests to be run Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-cli-options.md Use the --listTests flag to see all test files that will be executed, then the command will exit. This is helpful for verifying test discovery. ```bash test-storybook --listTests ``` -------------------------------- ### Local Testing After Building Storybook Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/index-json-mode.md Build the Storybook locally, serve the static files, and then run tests using index mode. This workflow is useful for testing the built output before deployment. ```bash # Build Storybook with index yarn build-storybook # Serve it locally npx http-server storybook-static -p 6006 & # Test using index mode test-storybook --index-json # Kill server pkill -f http-server ``` -------------------------------- ### Override Jest Snapshot Settings Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/configuration.md Customize how Jest snapshots are formatted. This example disables the printing of basic prototypes in snapshot output. ```javascript module.exports = { ...getJestConfig(), snapshotFormat: { printBasicPrototype: false, }, }; ``` -------------------------------- ### TestRunnerConfig Interface Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/types.md Main configuration interface for test-runner hooks and settings. Use this to customize setup, rendering, visiting, HTTP headers, and logging. ```typescript interface TestRunnerConfig { setup?: () => void; preRender?: TestHook; // deprecated postRender?: TestHook; // deprecated preVisit?: TestHook; postVisit?: TestHook; getHttpHeaders?: HttpHeaderSetter; prepare?: PrepareSetter; tags?: { include?: string[]; exclude?: string[]; skip?: string[]; }; logLevel?: 'info' | 'warn' | 'error' | 'verbose' | 'none'; errorMessageFormatter?: (error: string) => string; } ``` -------------------------------- ### Configure Browser State with preVisit Hook Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/configuration.md Demonstrates using the `preVisit` hook to configure the browser state before each story renders. This includes setting viewport size, local storage, and mocking API responses. ```typescript const config: TestRunnerConfig = { async preVisit(page, context) { // Set viewport size await page.setViewportSize({ width: 1280, height: 720 }); // Set local storage await page.evaluate(() => { localStorage.setItem('user', JSON.stringify({ id: 1, role: 'admin' })); }); // Mock API responses await page.route('**/api/**', (route) => { route.abort(); }); }, }; ``` -------------------------------- ### getStorybookMain Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Loads the Storybook `main.js` configuration. Also provides a function to clear the configuration cache. ```APIDOC ## getStorybookMain ### Description Load Storybook main.js config. ### Method function ### Signature ```typescript function getStorybookMain(configDir?: string): Promise ``` ## resetStorybookMainCache ### Description Clear the config cache. ### Method function ### Signature ```typescript function resetStorybookMainCache(): void ``` ``` -------------------------------- ### prepare Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-test-runner-config.md Overrides the default browser preparation. Allows custom authentication, cookie setting, or URL manipulation before visiting stories. ```APIDOC ## prepare ### Description Overrides the default browser preparation. Allows custom authentication, cookie setting, or URL manipulation before visiting stories. ### Type `PrepareSetter` (optional) ### Default Behavior Navigates to iframe.html and injects the setup script. ### Warning If overridden, you are responsible for properly preparing the browser. Future default changes will not be included. ### Example ```typescript const config: TestRunnerConfig = { async prepare({ page, browserContext, testRunnerConfig }) { const targetURL = process.env.TARGET_URL; await browserContext.addCookies([ { name: 'auth_token', value: 'xyz', url: targetURL }, ]); const iframeURL = new URL('iframe.html', targetURL).toString(); await page.goto(iframeURL, { waitUntil: 'load' }); }, }; ``` ``` -------------------------------- ### Equivalent Import Paths for getStoryContext Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Demonstrates the preferred direct import path and an equivalent source import path for the `getStoryContext` function from `@storybook/test-runner`. ```typescript // These are equivalent: // Direct import (preferred) import { getStoryContext } from '@storybook/test-runner'; // Source import (same symbols) import { getStoryContext } from '@storybook/test-runner/src/playwright/hooks'; ``` -------------------------------- ### Run Tests with Custom Target and Reference URLs Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/configuration.md Specify both the target Storybook URL and a reference URL for error reporting. Useful for local testing against a deployed instance. ```bash TARGET_URL=http://localhost:6006 \ REFERENCE_URL=https://storybook.example.com \ test-storybook ``` -------------------------------- ### getJestConfig Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Retrieves the Jest configuration, including Playwright environment setup, SWC transpilation, Story file matching, coverage collection, and reporter configuration. ```APIDOC ## getJestConfig ### Description Get Jest configuration. ### Method function ### Signature ```typescript function getJestConfig(): Config.InitialOptions ``` ``` -------------------------------- ### Run Test Runner Against Deployed Storybook with --url flag Source: https://github.com/storybookjs/test-runner/blob/next/README.md Alternatively, use the --url flag to specify the deployed Storybook URL. This achieves the same result as using the TARGET_URL environment variable. ```bash yarn test-storybook --url https://the-storybook-url-here.com ``` -------------------------------- ### Run tests in watch mode Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-cli-options.md Use the --watch flag to automatically rerun tests when files change. This is useful for development to get quick feedback. ```bash test-storybook --watch ``` -------------------------------- ### List All Test Files Source: https://github.com/storybookjs/test-runner/blob/next/README.md Display a list of all test files that will be executed and then exit the program using the --listTests flag. ```plaintext test-storybook --listTests ``` -------------------------------- ### Get Story Context in Test Hooks Source: https://github.com/storybookjs/test-runner/blob/next/README.md Utilize the getStoryContext utility function within postVisit hooks to retrieve the context of a story, including its parameters, args, and argTypes. ```typescript // .storybook/test-runner.ts import { TestRunnerConfig, getStoryContext } from '@storybook/test-runner'; const config: TestRunnerConfig = { async postVisit(page, context) { // Get entire context of a story, including parameters, args, argTypes, etc. const storyContext = await getStoryContext(page, context); if (storyContext.parameters.theme === 'dark') { // do something } else { // do something else } }, }; export default config; ``` -------------------------------- ### CI/CD Pipeline Options for test-storybook Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-cli-options.md Configure test runs for CI/CD environments, including coverage reports, JUnit output, and test sharding for parallel execution. ```bash test-storybook --coverage --ci --junit ``` ```bash test-storybook --shard=1/4 --coverage ``` ```bash test-storybook --shard=2/4 --coverage ``` ```bash test-storybook --shard=3/4 --coverage ``` ```bash test-storybook --shard=4/4 --coverage ``` -------------------------------- ### Increase Test Runner Timeout Source: https://github.com/storybookjs/test-runner/blob/next/README.md To address timeouts, increase the test timeout duration by passing the --testTimeout option. This example sets the timeout to 60 seconds. ```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=60000" ``` -------------------------------- ### getJestConfig Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-utility-functions.md Generates the complete Jest configuration object for the test-runner, including test match patterns, Playwright environment setup, SWC transformation, coverage settings, and Jest plugins. ```APIDOC ## getJestConfig ### Description Generates the complete Jest configuration object for the test-runner, including test match patterns, Playwright environment setup, SWC transformation, coverage settings, and Jest plugins. ### Signature ```typescript getJestConfig(): Config.InitialOptions ``` ### Returns Complete Jest configuration object including: - Test match patterns - Playwright environment setup - SWC transformation - Coverage collection settings - Jest plugins and reporters ### Example ```typescript // test-runner-jest.config.js const { getJestConfig } = require('@storybook/test-runner'); module.exports = { ...getJestConfig(), testTimeout: 20000, // Add custom overrides }; ``` ### Usage Notes - Used when ejecting test-runner configuration - Can be extended with custom Jest options - Handles environment variable configuration for browsers, coverage, etc. ``` -------------------------------- ### Output test results as JSON Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-cli-options.md Use the --json flag to get test results in JSON format. All other output will be redirected to stderr, making it suitable for programmatic processing. ```bash test-storybook --json ``` -------------------------------- ### Get Storybook Metadata Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Retrieves Storybook project metadata, including the project root directory, stories paths and patterns, framework name, build configuration, and telemetry settings. ```typescript function getStorybookMetadata(): Promise ``` -------------------------------- ### Fetch Index with Custom URLs Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/index-json-mode.md Configure custom URLs for fetching the index and for reporting. This allows testing against different Storybook instances or reporting to specific endpoints. ```bash # Custom Storybook URL TARGET_URL=https://storybook.example.com test-storybook --index-json ``` ```bash # Different reporting URL TARGET_URL=http://localhost:6006 \ REFERENCE_URL=https://storybook.example.com \ test-storybook --index-json ``` -------------------------------- ### Test Runner CLI Usage Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md The basic command to run the test runner. Options can be appended for customization. ```bash test-storybook [options] ``` -------------------------------- ### TestRunnerConfig Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/types.md Main configuration interface for test-runner hooks and settings. It allows customization of setup, lifecycle hooks, HTTP headers, preparation steps, tag filtering, logging, and error message formatting. ```APIDOC ## TestRunnerConfig ### Description Main configuration interface for test-runner hooks and settings. It allows customization of setup, lifecycle hooks, HTTP headers, preparation steps, tag filtering, logging, and error message formatting. ### Type Definition ```typescript interface TestRunnerConfig { setup?: () => void; preRender?: TestHook; // deprecated postRender?: TestHook; // deprecated preVisit?: TestHook; postVisit?: TestHook; getHttpHeaders?: HttpHeaderSetter; prepare?: PrepareSetter; tags?: { include?: string[]; exclude?: string[]; skip?: string[]; }; logLevel?: 'info' | 'warn' | 'error' | 'verbose' | 'none'; errorMessageFormatter?: (error: string) => string; } ``` ``` -------------------------------- ### postVisit Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-test-runner-config.md Runs after a story finishes rendering and executing its play function. Useful for assertions, snapshots, and cleanup. ```APIDOC ## postVisit ### Description Runs after a story finishes rendering and executing its play function. Useful for assertions, snapshots, and cleanup. ### Type `TestHook` (optional) ### Example ```typescript const config: TestRunnerConfig = { async postVisit(page, context) { await expect(page).toHaveScreenshot(`${context.id}.png`); }, }; ``` ``` -------------------------------- ### preVisit Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-test-runner-config.md Runs before each story is rendered. Useful for configuring the browser environment. ```APIDOC ## preVisit ### Description Runs before each story is rendered. Useful for configuring the browser environment. ### Type `TestHook` (optional) ### Example ```typescript const config: TestRunnerConfig = { async preVisit(page, context) { await page.setViewportSize({ width: 1280, height: 720 }); }, }; ``` ``` -------------------------------- ### Image Snapshot Testing Configuration Source: https://github.com/storybookjs/test-runner/blob/next/README.md Configure the test runner for image snapshot testing by extending Jest's expectations with `jest-image-snapshot`. This setup waits for the page to be ready and then takes a screenshot for comparison. ```typescript // .storybook/test-runner.ts import { TestRunnerConfig, waitForPageReady } from '@storybook/test-runner'; import { toMatchImageSnapshot } from 'jest-image-snapshot'; const customSnapshotsDir = `${process.cwd()}/__snapshots__`; const config: TestRunnerConfig = { setup() { expect.extend({ toMatchImageSnapshot }); }, async postVisit(page, context) { // use the test-runner utility to wait for fonts to load, etc. await waitForPageReady(page); // If you want to take screenshot of multiple browsers, use // page.context().browser().browserType().name() to get the browser name to prefix the file name const image = await page.screenshot(); expect(image).toMatchImageSnapshot({ customSnapshotsDir, customSnapshotIdentifier: context.id, }); }, }; export default config; ``` -------------------------------- ### Integrate axe-playwright for Accessibility Testing (Storybook 8) Source: https://github.com/storybookjs/test-runner/blob/next/README.md Set up the Storybook Test Runner with `axe-playwright` for accessibility testing. This involves injecting Axe utilities and checking accessibility after each story visit. Ensure `axe-playwright` is installed. ```typescript // .storybook/test-runner.ts import { TestRunnerConfig, getStoryContext } from '@storybook/test-runner'; import { injectAxe, checkA11y, configureAxe } from 'axe-playwright'; const config: TestRunnerConfig = { async preVisit(page, context) { // Inject Axe utilities in the page before the story renders await injectAxe(page); }, async postVisit(page, context) { // Get entire context of a story, including parameters, args, argTypes, etc. const storyContext = await getStoryContext(page, context); // Do not test a11y for stories that disable a11y if (storyContext.parameters?.a11y?.disable) { return; } // Apply story-level a11y rules await configureAxe(page, { rules: storyContext.parameters?.a11y?.config?.rules, }); // in Storybook 6.x, the selector is #root await checkA11y(page, '#storybook-root', { detailedReport: true, detailedReportOptions: { html: true, }, // pass axe options defined in @storybook/addon-a11y axeOptions: storyContext.parameters?.a11y?.options, }); }, }; export default config; ``` -------------------------------- ### Specify Storybook Config Directory Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-cli-options.md Set a custom directory for Storybook configuration files. ```bash test-storybook --config-dir .storybook ``` ```bash test-storybook -c custom-config ``` -------------------------------- ### Run Storybook Tests Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/README.md Execute automated tests against a local Storybook instance running on the default port. ```bash yarn test-storybook ``` -------------------------------- ### Run Storybook Tests with Coverage Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/README.md Execute tests and collect code coverage information. ```bash yarn test-storybook --coverage ``` -------------------------------- ### Get Story Context in PostVisit Hook Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-utility-functions.md Use getStoryContext to retrieve the complete story context, including args and parameters, within the postVisit hook. This is useful for implementing conditional logic based on story metadata. ```typescript import { TestRunnerConfig, getStoryContext } from '@storybook/test-runner'; const config: TestRunnerConfig = { async postVisit(page, context) { // Get full context of the story const storyContext = await getStoryContext(page, context); // Access story parameters if (storyContext.parameters?.theme === 'dark') { // do something for dark theme } // Access story args console.log('Story args:', storyContext.args); // Access custom parameters if (storyContext.parameters?.a11y?.disable) { // skip accessibility test for this story return; } }, }; export default config; ``` -------------------------------- ### Specify Storybook Configuration Directory Source: https://github.com/storybookjs/test-runner/blob/next/README.md Set the directory for Storybook configurations using the -c or --config-dir option, followed by the directory name. ```plaintext test-storybook -c .storybook ``` -------------------------------- ### Specify Browsers for Testing Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-cli-options.md Define which browsers to run tests in. Can specify one or multiple. ```bash test-storybook --browsers chromium ``` ```bash test-storybook --browsers chromium firefox webkit ``` -------------------------------- ### Test Deployed Storybook with Coverage and JUnit Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/index-json-mode.md Run tests against a production deployment of Storybook, enabling coverage reports and JUnit output for CI integration. Ensure the Storybook URL is correctly provided. ```bash # Run against production deployment test-storybook \ --url https://prod.storybook.example.com \ --index-json \ --coverage \ --junit ``` -------------------------------- ### Run Storybook Tests Against Custom URL Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/README.md Run tests against a Storybook instance deployed at a custom URL. ```bash yarn test-storybook --url http://localhost:9009 ``` -------------------------------- ### CLI Options Flow Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/architecture.md Details the process of parsing command-line arguments and separating them into runner and Jest options. ```text Process.argv ↓ Commander.js parser ↓ getParsedCliOptions() ↓ getCliOptions() → separates runner vs jest options ↓ ┌─────────────────┬─────────────────┐ │ runnerOptions │ jestOptions │ │ - url │ - watch │ │ - configDir │ - testTimeout │ │ - coverage │ - maxWorkers │ │ etc. │ etc. │ └─────────────────┴─────────────────┘ ↓ Environment variables set ↓ Jest executed with jestOptions ``` -------------------------------- ### Perform Assertions and Cleanup with postVisit Hook Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/configuration.md Shows how to use the `postVisit` hook for post-rendering tasks like waiting for page assets, taking screenshots for visual regression, and running accessibility checks. ```typescript import { waitForPageReady } from '@storybook/test-runner'; const config: TestRunnerConfig = { async postVisit(page, context) { // Wait for assets to load await waitForPageReady(page); // Take screenshot for visual regression await page.screenshot({ path: `screenshots/${context.id}.png`, }); // Run accessibility check const violations = await page.evaluate(() => { // Custom a11y check return []; }); if (violations.length > 0) { throw new Error(`Accessibility violations: ${violations.join(', ')}`); } }, }; ``` -------------------------------- ### Prepare Function for Test Runner Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-test-runner-config.md Override the default browser preparation with the `prepare` function to customize authentication, cookie setting, or URL manipulation before visiting stories. If overridden, you are responsible for preparing the browser. ```typescript const config: TestRunnerConfig = { async prepare({ page, browserContext, testRunnerConfig }) { const targetURL = process.env.TARGET_URL; await browserContext.addCookies([ { name: 'auth_token', value: 'xyz', url: targetURL }, ]); const iframeURL = new URL('iframe.html', targetURL).toString(); await page.goto(iframeURL, { waitUntil: 'load' }); }, }; ``` -------------------------------- ### Load Storybook Main Config Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/modules-and-exports.md Loads the Storybook `main.js` configuration and provides a function to reset the configuration cache. ```typescript function getStorybookMain(configDir?: string): Promise ``` ```typescript function resetStorybookMainCache(): void ``` -------------------------------- ### PrepareSetter Type Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-test-runner-config.md Defines the signature for a function that prepares the browser environment before test execution. ```APIDOC ## PrepareSetter Type ### Description The `PrepareSetter` type defines a function that is executed to prepare the browser environment before the test runner begins its execution. It receives a `PrepareContext` object containing the Playwright page, browser context, and the test runner configuration. ### Signature ```typescript type PrepareSetter = (context: PrepareContext) => Promise; ``` ### Parameters - **context** ( PrepareContext ) - The context object containing `page`, `browserContext`, and `testRunnerConfig`. ``` -------------------------------- ### Enable Code Coverage Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-cli-options.md Collect and report code coverage for tested stories. Requires components to be instrumented with Istanbul. ```bash test-storybook --coverage ``` -------------------------------- ### Basic Usage of test-storybook CLI Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-cli-options.md Run tests against a default or custom Storybook URL. Supports running tests in multiple browsers. ```bash test-storybook ``` ```bash test-storybook --url http://localhost:9009 ``` ```bash test-storybook --browsers chromium firefox webkit ``` -------------------------------- ### Configure Viewport for Storybook 9 Source: https://github.com/storybookjs/test-runner/blob/next/README.md Configure viewport settings for Storybook 9 using `getStoryContext` and `MINIMAL_VIEWPORTS`. Ensure viewport configurations use numbers, not percentages. ```typescript // .storybook/test-runner.ts import { TestRunnerConfig, getStoryContext } from '@storybook/test-runner'; import { MINIMAL_VIEWPORTS } from '@storybook/addon-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.parameters?.viewport?.defaultViewport; const viewportParameter = MINIMAL_VIEWPORTS[viewportName]; if (viewportParameter) { const viewportSize = Object.entries(viewportParameter.styles).reduce( (acc, [screen, size]) => ({ ...acc, // make sure your viewport config in Storybook only uses numbers, not percentages [screen]: parseInt(size), }), {} ); page.setViewportSize(viewportSize); } else { page.setViewportSize(DEFAULT_VIEWPORT_SIZE); } }, }; export default config; ``` -------------------------------- ### Set REFERENCE_URL Environment Variable Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/api-reference-cli-options.md Configure both TARGET_URL and REFERENCE_URL. REFERENCE_URL is used in error messages instead of TARGET_URL, useful for local testing with remote reporting. ```bash TARGET_URL=http://localhost:6006 REFERENCE_URL=https://storybook.example.com test-storybook ``` -------------------------------- ### PrepareSetter Source: https://github.com/storybookjs/test-runner/blob/next/_autodocs/types.md Function type for custom browser preparation logic. It takes a PrepareContext and returns a promise that resolves to void. ```APIDOC ## PrepareSetter ### Description Function type for custom browser preparation logic. ### Parameters - `context` (PrepareContext) - Required - Context object passed to the prepare hook ### Returns Promise ``` -------------------------------- ### Include Stories by Tag Source: https://github.com/storybookjs/test-runner/blob/next/README.md Run only stories matching specific tags with the experimental `--includeTags` option. Tags are comma-separated. ```bash test-storybook --includeTags="test-only" ```