diff --git a/code/frameworks/nextjs/src/swc/loader.ts b/code/frameworks/nextjs/src/swc/loader.ts
index 201bdc52e0d8..687f60d8aefe 100644
--- a/code/frameworks/nextjs/src/swc/loader.ts
+++ b/code/frameworks/nextjs/src/swc/loader.ts
@@ -6,7 +6,7 @@ import type { NextConfig } from 'next';
import path from 'path';
import type { RuleSetRule } from 'webpack';
import semver from 'semver';
-import { NextjsSWCNotSupportedError } from 'lib/core-events/src/errors/server-errors';
+import { NextjsSWCNotSupportedError } from '@storybook/core-events/server-errors';
import { getNextjsVersion } from '../utils';
export const configureSWCLoader = async (
diff --git a/docs/api/cli-options.md b/docs/api/cli-options.md
index a89d55a94d14..1ccbb4d1f124 100644
--- a/docs/api/cli-options.md
+++ b/docs/api/cli-options.md
@@ -61,19 +61,20 @@ storybook build [options]
Options include:
-| Option | Description |
-| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `-h`, `--help` | Output usage information
`storybook build --help` |
-| `-V`, `--version` | Output the version number
`storybook build -V` |
-| `-s`, `--static-dir` | **Deprecated** [see note](#static-dir-deprecation).
Directory where to load static files from, comma-separated list
`storybook build -s public` |
-| `-o`, `--output-dir [dir-name]` | Directory where to store built files
`storybook build -o /my-deployed-storybook` |
-| `-c`, `--config-dir [dir-name]` | Directory where to load Storybook configurations from
`storybook build -c .storybook` |
-| `--loglevel [level]` | Controls level of logging during build.
Available options: `silly`, `verbose`, `info` (default), `warn`, `error`, `silent`
`storybook build --loglevel warn` |
-| `--quiet` | Suppress verbose build output
`storybook build --quiet` |
-| `--debug-webpack` | Display final webpack configurations for debugging purposes
`storybook build --debug-webpack` |
-| `--webpack-stats-json` | Write Webpack Stats JSON to disk
`storybook build --webpack-stats-json /my-storybook/webpack-stats` |
-| `--docs` | Builds Storybook in documentation mode. Learn more about it in [here](../writing-docs/build-documentation.md#publish-storybooks-documentation)
`storybook build --docs` |
-| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook build --disable-telemetry` |
+| Option | Description |
+| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `-h`, `--help` | Output usage information
`storybook build --help` |
+| `-V`, `--version` | Output the version number
`storybook build -V` |
+| `-s`, `--static-dir` | **Deprecated** [see note](#static-dir-deprecation).
Directory where to load static files from, comma-separated list
`storybook build -s public` |
+| `-o`, `--output-dir [dir-name]` | Directory where to store built files
`storybook build -o /my-deployed-storybook` |
+| `-c`, `--config-dir [dir-name]` | Directory where to load Storybook configurations from
`storybook build -c .storybook` |
+| `--loglevel [level]` | Controls level of logging during build.
Available options: `silly`, `verbose`, `info` (default), `warn`, `error`, `silent`
`storybook build --loglevel warn` |
+| `--quiet` | Suppress verbose build output
`storybook build --quiet` |
+| `--debug-webpack` | Display final webpack configurations for debugging purposes
`storybook build --debug-webpack` |
+| `--webpack-stats-json` | Write Webpack Stats JSON to disk
`storybook build --webpack-stats-json /my-storybook/webpack-stats` |
+| `--docs` | Builds Storybook in documentation mode. Learn more about it in [here](../writing-docs/build-documentation.md#publish-storybooks-documentation)
`storybook build --docs` |
+| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook build --disable-telemetry` |
+| `--test` | Optimize Storybook's production build for performance and tests by removing unnecessary features with the `test` option. Learn more [here](../api/main-config-build.md).
`storybook build --test` |
diff --git a/docs/api/main-config-build.md b/docs/api/main-config-build.md
new file mode 100644
index 000000000000..a206662bae4a
--- /dev/null
+++ b/docs/api/main-config-build.md
@@ -0,0 +1,153 @@
+---
+title: 'build'
+---
+
+Parent: [main.js|ts configuration](./main-config.md)
+
+Type: `TestBuildConfig`
+
+Provides configuration options to optimize Storybook's production build output.
+
+## `test`
+
+Type: `TestBuildFlags`
+
+```ts
+{
+ disableBlocks?: boolean;
+ disabledAddons?: string[];
+ disableMDXEntries?: boolean;
+ disableAutoDocs?: boolean;
+ disableDocgen?: boolean;
+ disableSourcemaps?: boolean;
+ disableTreeShaking?: boolean;
+
+}
+```
+
+Configures Storybook's production builds for performance testing purposes by disabling certain features from the build. When running ' build-storybook ', this feature is enabled by setting the `--test` [flag](./cli-options.md#build).
+
+
+
+Enabling these features can cause build or runtime errors with Storybook. We recommend enabling only the features you need for your project.
+
+
+
+### `test.disableBlocks`
+
+Type: `boolean`
+
+Excludes the `@storybook/blocks` package from the build, which generates automatic documentation with [Docs Blocks](../writing-docs/doc-blocks.md).
+
+
+
+
+
+
+
+### `test.disabledAddons`
+
+Type: `string[]`
+
+Sets the list of addons that will disabled in the build output.
+
+
+
+
+
+
+
+### `test.disableMDXEntries`
+
+Type: `boolean`
+
+Enabling this option removes user-written documentation entries in MDX format from the build.
+
+
+
+
+
+
+
+### `test.disableAutoDocs`
+
+Type: `boolean`
+
+Prevents automatic documentation generated with the [autodocs](../writing-docs/autodocs.md) feature from being included in the build.
+
+
+
+
+
+
+
+### `test.disableDocgen`
+
+Type: `boolean`
+
+Disables [automatic argType](./arg-types.md#automatic-argtype-inference) and component property inference with any of the supported static analysis tools based on the framework you are using.
+
+
+
+
+
+
+
+### `test.disableSourcemaps`
+
+Type: `boolean`
+
+Overrides the default behavior of generating source maps for the build.
+
+
+
+
+
+
+
+### `test.disableTreeShaking`
+
+Type: `boolean`
+
+Disables [tree shaking](https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking) in the build.
+
+
+
+
+
+
diff --git a/docs/api/main-config.md b/docs/api/main-config.md
index 69372067bdf8..e0988eec381f 100644
--- a/docs/api/main-config.md
+++ b/docs/api/main-config.md
@@ -30,6 +30,7 @@ An object to configure Storybook containing the following properties:
- [`addons`](./main-config-addons.md)
- [`babel`](./main-config-babel.md)
- [`babelDefault`](./main-config-babel-default.md)
+- [`build`](./main-config-build.md)
- [`core`](./main-config-core.md)
- [`docs`](./main-config-docs.md)
- [`env`](./main-config-env.md)
diff --git a/docs/configure/overview.md b/docs/configure/overview.md
index 4e11a8f5c440..ee38fd9a4569 100644
--- a/docs/configure/overview.md
+++ b/docs/configure/overview.md
@@ -31,21 +31,22 @@ This configuration file is a [preset](../addons/addon-types.md) and, as such, ha
-| Configuration element | Description |
-| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `stories` | The array of globs that indicates the [location of your story files](#configure-story-loading), relative to `main.js` |
-| `staticDirs` | Sets a list of directories of [static files](./images-and-assets.md#serving-static-files-via-storybook-configuration) to be loaded by Storybook
`staticDirs: ['../public']` |
-| `addons` | Sets the list of [addons](https://storybook.js.org/integrations) loaded by Storybook
`addons: ['@storybook/addon-essentials']` |
-| `typescript` | Configures how Storybook handles [TypeScript files](./typescript.md)
`typescript: { check: false, checkOptions: {} }` |
-| `framework` | Configures Storybook based on a set of [framework-specific](./frameworks.md) settings
`framework: { name: '@storybook/svelte-vite', options:{} }` |
-| `core` | Configures Storybook's [internal features](../api/main-config-core.md)
`core: { disableTelemetry: true, }` |
-| `docs` | Configures Storybook's [auto-generated documentation](../writing-docs/autodocs.md)
`docs: { autodocs: 'tag' }` |
-| `features` | Enables Storybook's [additional features](../api/main-config-features.md)
See table below for a list of available features `features: { storyStoreV7: true }` |
-| `refs` | Configures [Storybook composition](../sharing/storybook-composition.md)
`refs:{ example: { title: 'ExampleStorybook', url:'https://your-url.com' } }` |
-| `logLevel` | Configures Storybook's logs in the browser terminal. Useful for debugging
`logLevel: 'debug'` |
-| `webpackFinal` | Customize Storybook's [Webpack](../builders/webpack.md) setup
`webpackFinal: async (config:any) => { return config; }` |
-| `viteFinal` | Customize Storybook's Vite setup when using the [vite builder](https://github.com/storybookjs/builder-vite)
`viteFinal: async (config: Vite.InlineConfig, options: Options) => { return config; }` |
-| `env` | Defines custom Storybook [environment variables](./environment-variables.md#using-storybook-configuration).
`env: (config) => ({...config, EXAMPLE_VAR: 'Example var' }),` |
+| Configuration element | Description |
+| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `stories` | The array of globs that indicates the [location of your story files](#configure-story-loading), relative to `main.js` |
+| `staticDirs` | Sets a list of directories of [static files](./images-and-assets.md#serving-static-files-via-storybook-configuration) to be loaded by Storybook
`staticDirs: ['../public']` |
+| `addons` | Sets the list of [addons](https://storybook.js.org/integrations) loaded by Storybook
`addons: ['@storybook/addon-essentials']` |
+| `typescript` | Configures how Storybook handles [TypeScript files](./typescript.md)
`typescript: { check: false, checkOptions: {} }` |
+| `framework` | Configures Storybook based on a set of [framework-specific](./frameworks.md) settings
`framework: { name: '@storybook/svelte-vite', options:{} }` |
+| `core` | Configures Storybook's [internal features](../api/main-config-core.md)
`core: { disableTelemetry: true, }` |
+| `docs` | Configures Storybook's [auto-generated documentation](../writing-docs/autodocs.md)
`docs: { autodocs: 'tag' }` |
+| `features` | Enables Storybook's [additional features](../api/main-config-features.md)
See table below for a list of available features `features: { storyStoreV7: true }` |
+| `refs` | Configures [Storybook composition](../sharing/storybook-composition.md)
`refs:{ example: { title: 'ExampleStorybook', url:'https://your-url.com' } }` |
+| `logLevel` | Configures Storybook's logs in the browser terminal. Useful for debugging
`logLevel: 'debug'` |
+| `webpackFinal` | Customize Storybook's [Webpack](../builders/webpack.md) setup
`webpackFinal: async (config:any) => { return config; }` |
+| `viteFinal` | Customize Storybook's Vite setup when using the [vite builder](https://github.com/storybookjs/builder-vite)
`viteFinal: async (config: Vite.InlineConfig, options: Options) => { return config; }` |
+| `env` | Defines custom Storybook [environment variables](./environment-variables.md#using-storybook-configuration).
`env: (config) => ({...config, EXAMPLE_VAR: 'Example var' }),` |
+| `build` | Optimizes Storybook's production [build](../api/main-config-build.md) for performance by excluding specific features from the bundle. Useful when decreased build times are a priority.
`build:Â { test: {} }` |
### Feature flags
diff --git a/docs/faq.md b/docs/faq.md
index 6539f6a3431f..387986d9cfbc 100644
--- a/docs/faq.md
+++ b/docs/faq.md
@@ -344,6 +344,30 @@ We're only covering versions 5.3 and 5.0 as they were important milestones for S
| | @storybook/blocks/useOf | [See current documentation](./api/doc-block-useof.md) | Non existing feature or undocumented | Non existing feature or undocumented |
| | Stories/Component Story Format | [See current documentation](./api/csf.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/formats/component-story-format) | Non existing feature or undocumented |
| | Stories/StoriesOF format (see note below) | [See current documentation](https://github.com/storybookjs/storybook/blob/main/code/lib/preview-api/docs/storiesOf.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/formats/storiesof-api) | Non existing feature or undocumented |
+| | ArgTypes | [See current documentation](./api/arg-types.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/Overview | [See current documentation](./api/main-config.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/framework | [See current documentation](./api/main-config-framework.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/stories | [See current documentation](./api/main-config-stories.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/addons | [See current documentation](./api/main-config-addons.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/babel | [See current documentation](./api/main-config-babel.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/babelDefault | [See current documentation](./api/main-config-babel-default.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/build | [See current documentation](./api/main-config-build.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/core | [See current documentation](./api/main-config-core.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/docs | [See current documentation](./api/main-config-docs.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/env | [See current documentation](./api/main-config-env.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/features | [See current documentation](./api/main-config-features.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/indexers | [See current documentation](./api/main-config-indexers.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/logLevel | [See current documentation](./api/main-config-log-level.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/managerHead | [See current documentation](./api/main-config-manager-head.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/previewAnnotations | [See current documentation](./api/main-config-preview-annotations.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/previewBody | [See current documentation](./api/main-config-preview-body.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/previewHead | [See current documentation](./api/main-config-preview-head.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/refs | [See current documentation](./api/main-config-refs.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/staticDirs | [See current documentation](./api/main-config-static-dirs.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/typescript | [See current documentation](./api/main-config-typescript.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/viteFinal | [See current documentation](./api/main-config-vite-final.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/webpackFinal | [See current documentation](./api/main-config-webpack-final.md) | Non existing feature or undocumented | Non existing feature or undocumented |
+| | `main.js` configuration/config | [See current documentation](./api/main-config-config.md) | Non existing feature or undocumented | Non existing feature or undocumented |
| | Frameworks | [See current documentation](./api/new-frameworks.md) | Non existing feature or undocumented | Non existing feature or undocumented |
| | CLI options | [See current documentation](./api/cli-options.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/cli-options) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/cli-options) |
diff --git a/docs/sharing/design-integrations.md b/docs/sharing/design-integrations.md
index d2211a7b52d9..ca0842f18b10 100644
--- a/docs/sharing/design-integrations.md
+++ b/docs/sharing/design-integrations.md
@@ -57,7 +57,7 @@ Once they're connected, you'll be able to view the story by clicking the link in
### Embed Figma in Storybook with the addon
-[Design addon](https://storybook.js.org/addons/storybook-addon-designs) allows you to embed Figma files and prototypes in Storybook.
+[Designs addon](https://storybook.js.org/addons/@storybook/addon-designs) allows you to embed Figma files and prototypes in Storybook.
![Storybook addon figma](./storybook-figma-addon.png)
diff --git a/docs/sharing/publish-storybook.md b/docs/sharing/publish-storybook.md
index ca98bb2d8264..cf6b20b2e1bf 100644
--- a/docs/sharing/publish-storybook.md
+++ b/docs/sharing/publish-storybook.md
@@ -50,6 +50,22 @@ Storybook will create a static web application capable of being served by any we
+### Customizing the build for performance
+
+By default, Storybook's production build will encapsulate all stories and documentation into the production bundle. This is ideal for small projects but can cause performance issues for larger projects or when decreased build times are a priority (e.g., testing, CI/CD). If you need, you can customize the production build with the [`test` option](../api/main-config-build.md#test) in your `main.js|ts` configuration file and adjust your build script to enable the optimizations with the `--test` [flag](../api/cli-options.md#build).
+
+
+
+
+
+
+
## Publish Storybook with Chromatic
Once you've built your Storybook as a static web application, you can publish it to your web host. We recommend [Chromatic](https://www.chromatic.com/?utm_source=storybook_website&utm_medium=link&utm_campaign=storybook), a free publishing service made for Storybook that documents, versions, and indexes your UI components securely in the cloud.
@@ -137,7 +153,6 @@ Since Storybook is built as a static web application, you can also publish it to
To deploy Storybook on GitHub Pages, use the community-built [Deploy Storybook to GitHub Pages](https://github.com/bitovi/github-actions-storybook-to-github-pages) Action. To enable it, create a new workflow file inside your `.github/workflows` directory with the following content:
-
-
Component Publishing Protocol (CPP)
diff --git a/docs/snippets/common/main-config-test-disable-autodocs.js.mdx b/docs/snippets/common/main-config-test-disable-autodocs.js.mdx
new file mode 100644
index 000000000000..86b7de8fb7b3
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-autodocs.js.mdx
@@ -0,0 +1,14 @@
+```js
+// .storybook/main.js
+
+export default {
+ // Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableAutoDocs: true,
+ },
+ },
+};
+```
diff --git a/docs/snippets/common/main-config-test-disable-autodocs.ts.mdx b/docs/snippets/common/main-config-test-disable-autodocs.ts.mdx
new file mode 100644
index 000000000000..1eb9e7218197
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-autodocs.ts.mdx
@@ -0,0 +1,18 @@
+```ts
+// .storybook/main.ts
+
+// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+import type { StorybookConfig } from '@storybook/your-framework';
+
+const config: StorybookConfig = {
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableAutoDocs: true,
+ },
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/main-config-test-disable-blocks.js.mdx b/docs/snippets/common/main-config-test-disable-blocks.js.mdx
new file mode 100644
index 000000000000..9b4aa8c9a478
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-blocks.js.mdx
@@ -0,0 +1,14 @@
+```js
+// .storybook/main.js
+
+export default {
+ // Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableBlocks: true,
+ },
+ },
+};
+```
diff --git a/docs/snippets/common/main-config-test-disable-blocks.ts.mdx b/docs/snippets/common/main-config-test-disable-blocks.ts.mdx
new file mode 100644
index 000000000000..0cb4b4235bba
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-blocks.ts.mdx
@@ -0,0 +1,18 @@
+```ts
+// .storybook/main.ts
+
+// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+import type { StorybookConfig } from '@storybook/your-framework';
+
+const config: StorybookConfig = {
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableBlocks: true,
+ },
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/main-config-test-disable-disableaddons.js.mdx b/docs/snippets/common/main-config-test-disable-disableaddons.js.mdx
new file mode 100644
index 000000000000..62edb30799b6
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-disableaddons.js.mdx
@@ -0,0 +1,20 @@
+```js
+// .storybook/main.js
+
+export default {
+ // Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ addons: [
+ '@storybook/addon-links',
+ '@storybook/addon-essentials',
+ '@storybook/addon-interactions',
+ '@storybook/addon-a11y',
+ ],
+ build: {
+ test: {
+ disabledAddons: ['@storybook/addon-a11y'],
+ },
+ },
+};
+```
diff --git a/docs/snippets/common/main-config-test-disable-disableaddons.ts.mdx b/docs/snippets/common/main-config-test-disable-disableaddons.ts.mdx
new file mode 100644
index 000000000000..eb05b42ec95c
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-disableaddons.ts.mdx
@@ -0,0 +1,24 @@
+```ts
+// .storybook/main.ts
+
+// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+import type { StorybookConfig } from '@storybook/your-framework';
+
+const config: StorybookConfig = {
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ addons: [
+ '@storybook/addon-links',
+ '@storybook/addon-essentials',
+ '@storybook/addon-interactions',
+ '@storybook/addon-a11y',
+ ],
+ build: {
+ test: {
+ disabledAddons: ['@storybook/addon-a11y'],
+ },
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/main-config-test-disable-docgen.js.mdx b/docs/snippets/common/main-config-test-disable-docgen.js.mdx
new file mode 100644
index 000000000000..ffe4bdc2f866
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-docgen.js.mdx
@@ -0,0 +1,14 @@
+```js
+// .storybook/main.js
+
+export default {
+ // Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableDocgen: true,
+ },
+ },
+};
+```
diff --git a/docs/snippets/common/main-config-test-disable-docgen.ts.mdx b/docs/snippets/common/main-config-test-disable-docgen.ts.mdx
new file mode 100644
index 000000000000..1d0eb3c10d9d
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-docgen.ts.mdx
@@ -0,0 +1,18 @@
+```ts
+// .storybook/main.ts
+
+// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+import type { StorybookConfig } from '@storybook/your-framework';
+
+const config: StorybookConfig = {
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableDocgen: true,
+ },
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/main-config-test-disable-mdx.js.mdx b/docs/snippets/common/main-config-test-disable-mdx.js.mdx
new file mode 100644
index 000000000000..f6204594c1ef
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-mdx.js.mdx
@@ -0,0 +1,14 @@
+```js
+// .storybook/main.js
+
+export default {
+ // Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableMDXEntries: true,
+ },
+ },
+};
+```
diff --git a/docs/snippets/common/main-config-test-disable-mdx.ts.mdx b/docs/snippets/common/main-config-test-disable-mdx.ts.mdx
new file mode 100644
index 000000000000..e5327602aed8
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-mdx.ts.mdx
@@ -0,0 +1,18 @@
+```ts
+// .storybook/main.ts
+
+// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+import type { StorybookConfig } from '@storybook/your-framework';
+
+const config: StorybookConfig = {
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableMDXEntries: true,
+ },
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/main-config-test-disable-sourcemaps.js.mdx b/docs/snippets/common/main-config-test-disable-sourcemaps.js.mdx
new file mode 100644
index 000000000000..9207b9317099
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-sourcemaps.js.mdx
@@ -0,0 +1,14 @@
+```js
+// .storybook/main.js
+
+export default {
+ // Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableSourcemaps: true,
+ },
+ },
+};
+```
diff --git a/docs/snippets/common/main-config-test-disable-sourcemaps.ts.mdx b/docs/snippets/common/main-config-test-disable-sourcemaps.ts.mdx
new file mode 100644
index 000000000000..79b0abab693d
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-sourcemaps.ts.mdx
@@ -0,0 +1,18 @@
+```ts
+// .storybook/main.ts
+
+// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+import type { StorybookConfig } from '@storybook/your-framework';
+
+const config: StorybookConfig = {
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableSourcemaps: true,
+ },
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/main-config-test-disable-treeshaking.js.mdx b/docs/snippets/common/main-config-test-disable-treeshaking.js.mdx
new file mode 100644
index 000000000000..f0957f7e5536
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-treeshaking.js.mdx
@@ -0,0 +1,14 @@
+```js
+// .storybook/main.js
+
+export default {
+ // Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableTreeShaking: true,
+ },
+ },
+};
+```
diff --git a/docs/snippets/common/main-config-test-disable-treeshaking.ts.mdx b/docs/snippets/common/main-config-test-disable-treeshaking.ts.mdx
new file mode 100644
index 000000000000..b053cfa03435
--- /dev/null
+++ b/docs/snippets/common/main-config-test-disable-treeshaking.ts.mdx
@@ -0,0 +1,18 @@
+```ts
+// .storybook/main.ts
+
+// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
+import type { StorybookConfig } from '@storybook/your-framework';
+
+const config: StorybookConfig = {
+ framework: '@storybook/your-framework',
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
+ build: {
+ test: {
+ disableTreeShaking: true,
+ },
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/my-component-exclude-tags.story.js.mdx b/docs/snippets/common/my-component-exclude-tags.story.js.mdx
new file mode 100644
index 000000000000..32eebb42518d
--- /dev/null
+++ b/docs/snippets/common/my-component-exclude-tags.story.js.mdx
@@ -0,0 +1,15 @@
+```js
+// MyComponent.stories.js|jsx
+
+import { MyComponent } from './MyComponent';
+
+export default {
+ component: MyComponent,
+ tags: ['no-tests'], // đ Provides the `no-tests` tag to all stories in this file
+};
+
+export const ExcludeStory = {
+ //đ Adds the `no-tests` tag to this story to exclude it from the tests when enabled in the test-runner configuration
+ tags: ['no-tests'],
+};
+```
diff --git a/docs/snippets/common/my-component-exclude-tags.story.ts.mdx b/docs/snippets/common/my-component-exclude-tags.story.ts.mdx
new file mode 100644
index 000000000000..79a62510ad3b
--- /dev/null
+++ b/docs/snippets/common/my-component-exclude-tags.story.ts.mdx
@@ -0,0 +1,21 @@
+```ts
+// MyComponent.stories.ts|tsx
+
+// Replace your-framework with the name of your framework
+import type { Meta, StoryObj } from '@storybook/your-framework';
+
+import { MyComponent } from './MyComponent';
+
+const meta: Meta = {
+ component: MyComponent,
+ tags: ['no-tests'], // đ Provides the `no-tests` tag to all stories in this file
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const ExcludeStory: Story = {
+ //đ Adds the `no-tests` tag to this story to exclude it from the tests when enabled in the test-runner configuration
+ tags: ['no-tests'],
+};
+```
diff --git a/docs/snippets/common/my-component-include-tags.story.js.mdx b/docs/snippets/common/my-component-include-tags.story.js.mdx
new file mode 100644
index 000000000000..1e667e43c716
--- /dev/null
+++ b/docs/snippets/common/my-component-include-tags.story.js.mdx
@@ -0,0 +1,15 @@
+```js
+// MyComponent.stories.js|jsx
+
+import { MyComponent } from './MyComponent';
+
+export default {
+ component: MyComponent,
+ tags: ['test-only'], // đ Provides the `test-only` tag to all stories in this file
+};
+
+export const IncludeStory = {
+ //đ Adds the `test-only` tag to this story to be included in the tests when enabled in the test-runner configuration
+ tags: ['test-only'],
+};
+```
diff --git a/docs/snippets/common/my-component-include-tags.story.ts.mdx b/docs/snippets/common/my-component-include-tags.story.ts.mdx
new file mode 100644
index 000000000000..6b3f71446d8f
--- /dev/null
+++ b/docs/snippets/common/my-component-include-tags.story.ts.mdx
@@ -0,0 +1,21 @@
+```ts
+// MyComponent.stories.ts|tsx
+
+// Replace your-framework with the name of your framework
+import type { Meta, StoryObj } from '@storybook/your-framework';
+
+import { MyComponent } from './MyComponent';
+
+const meta: Meta = {
+ component: MyComponent,
+ tags: ['test-only'], // đ Provides the `test-only` tag to all stories in this file
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const IncludeStory: Story = {
+ //đ Adds the `test-only` tag to this story to be included in the tests when enabled in the test-runner configuration
+ tags: ['test-only'],
+};
+```
diff --git a/docs/snippets/common/my-component-skip-tags.story.js.mdx b/docs/snippets/common/my-component-skip-tags.story.js.mdx
new file mode 100644
index 000000000000..c59991aace99
--- /dev/null
+++ b/docs/snippets/common/my-component-skip-tags.story.js.mdx
@@ -0,0 +1,15 @@
+```js
+// MyComponent.stories.js|jsx
+
+import { MyComponent } from './MyComponent';
+
+export default {
+ component: MyComponent,
+ tags: ['skip-test'], // đ Provides the `skip-test` tag to all stories in this file
+};
+
+export const SkipStory = {
+ //đ Adds the `skip-test` tag to this story to allow it to be skipped in the tests when enabled in the test-runner configuration
+ tags: ['skip-test'],
+};
+```
diff --git a/docs/snippets/common/my-component-skip-tags.story.ts.mdx b/docs/snippets/common/my-component-skip-tags.story.ts.mdx
new file mode 100644
index 000000000000..3513e3d33c43
--- /dev/null
+++ b/docs/snippets/common/my-component-skip-tags.story.ts.mdx
@@ -0,0 +1,21 @@
+```ts
+// MyComponent.stories.ts|tsx
+
+// Replace your-framework with the name of your framework
+import type { Meta, StoryObj } from '@storybook/your-framework';
+
+import { MyComponent } from './MyComponent';
+
+const meta: Meta = {
+ component: MyComponent,
+ tags: ['skip-test'], // đ Provides the `skip-test` tag to all stories in this file
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const SkipStory: Story = {
+ //đ Adds the `skip-test` tag to this story to allow it to be skipped in the tests when enabled in the test-runner configuration
+ tags: ['skip-test'],
+};
+```
diff --git a/docs/snippets/common/storybook-build-test-flag.npm.js.mdx b/docs/snippets/common/storybook-build-test-flag.npm.js.mdx
new file mode 100644
index 000000000000..202b2cdb3188
--- /dev/null
+++ b/docs/snippets/common/storybook-build-test-flag.npm.js.mdx
@@ -0,0 +1,3 @@
+```shell
+npm run build-storybook -- --test
+```
diff --git a/docs/snippets/common/storybook-build-test-flag.pnpm.js.mdx b/docs/snippets/common/storybook-build-test-flag.pnpm.js.mdx
new file mode 100644
index 000000000000..ae1a481577d1
--- /dev/null
+++ b/docs/snippets/common/storybook-build-test-flag.pnpm.js.mdx
@@ -0,0 +1,3 @@
+```shell
+pnpm run build-storybook --test
+```
diff --git a/docs/snippets/common/storybook-build-test-flag.yarn.js.mdx b/docs/snippets/common/storybook-build-test-flag.yarn.js.mdx
new file mode 100644
index 000000000000..cb2007d3e8b8
--- /dev/null
+++ b/docs/snippets/common/storybook-build-test-flag.yarn.js.mdx
@@ -0,0 +1,3 @@
+```shell
+yarn build-storybook --test
+```
diff --git a/docs/snippets/common/test-runner-a11y-config.js.mdx b/docs/snippets/common/test-runner-a11y-config.js.mdx
index d7afb9b77456..9ce64c1e3f09 100644
--- a/docs/snippets/common/test-runner-a11y-config.js.mdx
+++ b/docs/snippets/common/test-runner-a11y-config.js.mdx
@@ -4,14 +4,14 @@
const { injectAxe, checkA11y } = require('axe-playwright');
/*
- * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api-experimental
+ * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api
* to learn more about the test-runner hooks API.
*/
module.exports = {
- async preRender(page) {
+ async preVisit(page) {
await injectAxe(page);
},
- async postRender(page) {
+ async postVisit(page) {
await checkA11y(page, '#storybook-root', {
detailedReport: true,
detailedReportOptions: {
diff --git a/docs/snippets/common/test-runner-a11y-config.ts.mdx b/docs/snippets/common/test-runner-a11y-config.ts.mdx
index 9339eb7e2ae0..4bc91082506f 100644
--- a/docs/snippets/common/test-runner-a11y-config.ts.mdx
+++ b/docs/snippets/common/test-runner-a11y-config.ts.mdx
@@ -1,19 +1,18 @@
```ts
// .storybook/test-runner.ts
-import { injectAxe, checkA11y } from 'axe-playwright';
-
import type { TestRunnerConfig } from '@storybook/test-runner';
+import { injectAxe, checkA11y } from 'axe-playwright';
/*
- * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api-experimental
+ * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api
* to learn more about the test-runner hooks API.
*/
-const a11yConfig: TestRunnerConfig = {
- async preRender(page) {
+const config: TestRunnerConfig = {
+ async preVisit(page) {
await injectAxe(page);
},
- async postRender(page) {
+ async postVisit(page) {
await checkA11y(page, '#storybook-root', {
detailedReport: true,
detailedReportOptions: {
@@ -23,5 +22,5 @@ const a11yConfig: TestRunnerConfig = {
},
};
-module.exports = a11yConfig;
+export default config;
```
diff --git a/docs/snippets/common/test-runner-a11y-configure.js.mdx b/docs/snippets/common/test-runner-a11y-configure.js.mdx
index e7ddb352d5ea..abd0a20b4089 100644
--- a/docs/snippets/common/test-runner-a11y-configure.js.mdx
+++ b/docs/snippets/common/test-runner-a11y-configure.js.mdx
@@ -6,14 +6,14 @@ const { injectAxe, checkA11y, configureAxe } = require('axe-playwright');
const { getStoryContext } = require('@storybook/test-runner');
/*
- * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api-experimental
+ * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api
* to learn more about the test-runner hooks API.
*/
module.exports = {
- async preRender(page) {
+ async preVisit(page) {
await injectAxe(page);
},
- async postRender(page, context) {
+ async postVisit(page, context) {
// Get the entire context of a story, including parameters, args, argTypes, etc.
const storyContext = await getStoryContext(page, context);
diff --git a/docs/snippets/common/test-runner-a11y-configure.ts.mdx b/docs/snippets/common/test-runner-a11y-configure.ts.mdx
index 8b1f4d31037e..5af07ea7d760 100644
--- a/docs/snippets/common/test-runner-a11y-configure.ts.mdx
+++ b/docs/snippets/common/test-runner-a11y-configure.ts.mdx
@@ -1,21 +1,20 @@
```ts
// .storybook/test-runner.ts
-import { injectAxe, checkA11y, configureAxe } from 'axe-playwright';
-
+import type { TestRunnerConfig } from '@storybook/test-runner';
import { getStoryContext } from '@storybook/test-runner';
-import type { TestRunnerConfig } from '@storybook/test-runner';
+import { injectAxe, checkA11y, configureAxe } from 'axe-playwright';
/*
- * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api-experimental
+ * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api
* to learn more about the test-runner hooks API.
*/
-const a11yConfig: TestRunnerConfig = {
- async preRender(page) {
+const config: TestRunnerConfig = {
+ async preVisit(page) {
await injectAxe(page);
},
- async postRender(page, context) {
+ async postVisit(page, context) {
// Get the entire context of a story, including parameters, args, argTypes, etc.
const storyContext = await getStoryContext(page, context);
@@ -33,5 +32,5 @@ const a11yConfig: TestRunnerConfig = {
},
};
-module.exports = a11yConfig;
+export default config;
```
diff --git a/docs/snippets/common/test-runner-a11y-disable.js.mdx b/docs/snippets/common/test-runner-a11y-disable.js.mdx
index edb12dab0bfa..d6177c9ce38f 100644
--- a/docs/snippets/common/test-runner-a11y-disable.js.mdx
+++ b/docs/snippets/common/test-runner-a11y-disable.js.mdx
@@ -1,19 +1,18 @@
```js
// .storybook/test-runner.js
-const { injectAxe, checkA11y } = require('axe-playwright');
-
const { getStoryContext } = require('@storybook/test-runner');
+const { injectAxe, checkA11y } = require('axe-playwright');
/*
- * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api-experimental
+ * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api
* to learn more about the test-runner hooks API.
*/
module.exports = {
- async preRender(page) {
+ async preVisit(page) {
await injectAxe(page);
},
- async postRender(page, context) {
+ async postVisit(page, context) {
// Get the entire context of a story, including parameters, args, argTypes, etc.
const storyContext = await getStoryContext(page, context);
diff --git a/docs/snippets/common/test-runner-a11y-disable.ts.mdx b/docs/snippets/common/test-runner-a11y-disable.ts.mdx
index 3297e8ea0b7b..1be273fee210 100644
--- a/docs/snippets/common/test-runner-a11y-disable.ts.mdx
+++ b/docs/snippets/common/test-runner-a11y-disable.ts.mdx
@@ -1,21 +1,20 @@
```ts
// .storybook/test-runner.ts
-import { injectAxe, checkA11y } from 'axe-playwright';
-
+import type { TestRunnerConfig } from '@storybook/test-runner';
import { getStoryContext } from '@storybook/test-runner';
-import type { TestRunnerConfig } from '@storybook/test-runner';
+import { injectAxe, checkA11y } from 'axe-playwright';
/*
- * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api-experimental
+ * See https://storybook.js.org/docs/react/writing-tests/test-runner#test-hook-api
* to learn more about the test-runner hooks API.
*/
-const a11yConfig: TestRunnerConfig = {
- async preRender(page) {
+const config: TestRunnerConfig = {
+ async preVisit(page) {
await injectAxe(page);
},
- async postRender(page, context) {
+ async postVisit(page, context) {
// Get the entire context of a story, including parameters, args, argTypes, etc.
const storyContext = await getStoryContext(page, context);
@@ -32,5 +31,5 @@ const a11yConfig: TestRunnerConfig = {
},
};
-module.exports = a11yConfig;
+export default config;
```
diff --git a/docs/snippets/common/test-runner-auth.js.mdx b/docs/snippets/common/test-runner-auth.js.mdx
new file mode 100644
index 000000000000..d4858de23165
--- /dev/null
+++ b/docs/snippets/common/test-runner-auth.js.mdx
@@ -0,0 +1,12 @@
+```js
+// .storybook/test-runner.js
+
+module.exports = {
+ getHttpHeaders: async (url) => {
+ const token = url.includes('prod') ? 'XYZ' : 'ABC';
+ return {
+ Authorization: `Bearer ${token}`,
+ };
+ },
+};
+```
diff --git a/docs/snippets/common/test-runner-auth.ts.mdx b/docs/snippets/common/test-runner-auth.ts.mdx
new file mode 100644
index 000000000000..c4fd82d8726e
--- /dev/null
+++ b/docs/snippets/common/test-runner-auth.ts.mdx
@@ -0,0 +1,16 @@
+```ts
+// .storybook/test-runner.ts
+
+import type { TestRunnerConfig } from '@storybook/test-runner';
+
+const config: TestRunnerConfig = {
+ getHttpHeaders: async (url) => {
+ const token = url.includes('prod') ? 'prod-token' : 'dev-token';
+ return {
+ Authorization: `Bearer ${token}`,
+ };
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/test-runner-custom-page-viewport.js.mdx b/docs/snippets/common/test-runner-custom-page-viewport.js.mdx
new file mode 100644
index 000000000000..b334755d1f74
--- /dev/null
+++ b/docs/snippets/common/test-runner-custom-page-viewport.js.mdx
@@ -0,0 +1,32 @@
+```js
+// .storybook/test-runner.js
+
+const { getStoryContext } = require('@storybook/test-runner');
+const { MINIMAL_VIEWPORTS } = require('@storybook/addon-viewport');
+
+const DEFAULT_VIEWPORT_SIZE = { width: 1280, height: 720 };
+
+module.exports = {
+ async preVisit(page, story) {
+ // Accesses the story's parameters and retrieves the viewport used to render it
+ 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,
+ // Converts the viewport size from percentages to numbers
+ [screen]: parseInt(size),
+ }),
+ {}
+ );
+ // Configures the Playwright page to use the viewport size
+ page.setViewportSize(viewportSize);
+ } else {
+ page.setViewportSize(DEFAULT_VIEWPORT_SIZE);
+ }
+ },
+};
+```
diff --git a/docs/snippets/common/test-runner-custom-page-viewport.ts.mdx b/docs/snippets/common/test-runner-custom-page-viewport.ts.mdx
new file mode 100644
index 000000000000..5db491a51335
--- /dev/null
+++ b/docs/snippets/common/test-runner-custom-page-viewport.ts.mdx
@@ -0,0 +1,36 @@
+```ts
+// .storybook/test-runner.js
+
+import type { TestRunnerConfig } from '@storybook/test-runner';
+import { getStoryContext } from '@storybook/test-runner';
+
+const { MINIMAL_VIEWPORTS } = require('@storybook/addon-viewport');
+
+const DEFAULT_VIEWPORT_SIZE = { width: 1280, height: 720 };
+
+const config: TestRunnerConfig = {
+ async preVisit(page, story) {
+ // Accesses the story's parameters and retrieves the viewport used to render it
+ 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,
+ // Converts the viewport size from percentages to numbers
+ [screen]: parseInt(size),
+ }),
+ {}
+ );
+ // Configures the Playwright page to use the viewport size
+ page.setViewportSize(viewportSize);
+ } else {
+ page.setViewportSize(DEFAULT_VIEWPORT_SIZE);
+ }
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/test-runner-helper-function.js.mdx b/docs/snippets/common/test-runner-helper-function.js.mdx
index 6ce0e1bf4123..9e7827f029ab 100644
--- a/docs/snippets/common/test-runner-helper-function.js.mdx
+++ b/docs/snippets/common/test-runner-helper-function.js.mdx
@@ -1,28 +1,31 @@
```js
// .storybook/test-runner.js
-const { getStoryContext } = require('@storybook/test-runner');
+const { getStoryContext, waitForPageReady } = require('@storybook/test-runner');
module.exports = {
// Hook that is executed before the test runner starts running tests
setup() {
// Add your configuration here.
},
- /* Hook to execute before a story is rendered.
+ /* Hook to execute before a story is initially visited before being rendered in the browser.
* The page argument is the Playwright's page object for the story.
* The context argument is a Storybook object containing the story's id, title, and name.
*/
- async preRender(page, context) {
+ async preVisit(page, context) {
// Add your configuration here.
},
- /* Hook to execute after a story is rendered.
+ /* Hook to execute after a story is visited and fully rendered.
* The page argument is the Playwright's page object for the story
* The context argument is a Storybook object containing the story's id, title, and name.
*/
- async postRender(page, context) {
+ async postVisit(page, context) {
// Get the entire context of a story, including parameters, args, argTypes, etc.
const storyContext = await getStoryContext(page, context);
+ // This utility function is designed for image snapshot testing. It will wait for the page to be fully loaded, including all the async items (e.g., images, fonts, etc.).
+ await waitForPageReady(page);
+
// Add your configuration here.
},
};
diff --git a/docs/snippets/common/test-runner-helper-function.ts.mdx b/docs/snippets/common/test-runner-helper-function.ts.mdx
index 94a9824a68a0..af40e58b2dee 100644
--- a/docs/snippets/common/test-runner-helper-function.ts.mdx
+++ b/docs/snippets/common/test-runner-helper-function.ts.mdx
@@ -2,32 +2,34 @@
// .storybook/test-runner.ts
import type { TestRunnerConfig } from '@storybook/test-runner';
-
-import { getStoryContext } from '@storybook/test-runner';
+import { getStoryContext, waitForPageReady } from '@storybook/test-runner';
const config: TestRunnerConfig = {
// Hook that is executed before the test runner starts running tests
setup() {
// Add your configuration here.
},
- /* Hook to execute before a story is rendered.
+ /* Hook to execute before a story is initially visited before being rendered in the browser.
* The page argument is the Playwright's page object for the story.
* The context argument is a Storybook object containing the story's id, title, and name.
*/
- async preRender(page, context) {
+ async preVisit(page, context) {
// Add your configuration here.
},
- /* Hook to execute after a story is rendered.
+ /* Hook to execute after a story is visited and fully rendered.
* The page argument is the Playwright's page object for the story
* The context argument is a Storybook object containing the story's id, title, and name.
*/
- async postRender(page, context) {
+ async postVisit(page, context) {
// Get the entire context of a story, including parameters, args, argTypes, etc.
const storyContext = await getStoryContext(page, context);
+ // This utility function is designed for image snapshot testing. It will wait for the page to be fully loaded, including all the async items (e.g., images, fonts, etc.).
+ await waitForPageReady(page);
+
// Add your configuration here.
},
};
-module.exports = config;
+export default config;
```
diff --git a/docs/snippets/common/test-runner-hooks-example.js.mdx b/docs/snippets/common/test-runner-hooks-example.js.mdx
index e3d52b738645..18876266bf31 100644
--- a/docs/snippets/common/test-runner-hooks-example.js.mdx
+++ b/docs/snippets/common/test-runner-hooks-example.js.mdx
@@ -6,18 +6,18 @@ module.exports = {
setup() {
// Add your configuration here.
},
- /* Hook to execute before a story is rendered.
+ /* Hook to execute before a story is initially visited before being rendered in the browser.
* The page argument is the Playwright's page object for the story.
* The context argument is a Storybook object containing the story's id, title, and name.
*/
- async preRender(page, context) {
+ async preVisit(page, context) {
// Add your configuration here.
},
- /* Hook to execute after a story is rendered.
+ /* Hook to execute after a story is visited and fully rendered.
* The page argument is the Playwright's page object for the story
* The context argument is a Storybook object containing the story's id, title, and name.
*/
- async postRender(page, context) {
+ async postVisit(page, context) {
// Add your configuration here.
},
};
diff --git a/docs/snippets/common/test-runner-hooks-example.ts.mdx b/docs/snippets/common/test-runner-hooks-example.ts.mdx
index d05ddb64801c..f06d4c71b063 100644
--- a/docs/snippets/common/test-runner-hooks-example.ts.mdx
+++ b/docs/snippets/common/test-runner-hooks-example.ts.mdx
@@ -8,21 +8,21 @@ const config: TestRunnerConfig = {
setup() {
// Add your configuration here.
},
- /* Hook to execute before a story is rendered.
+ /* Hook to execute before a story is initially visited before being rendered in the browser.
* The page argument is the Playwright's page object for the story.
* The context argument is a Storybook object containing the story's id, title, and name.
*/
- async preRender(page, context) {
+ async preVisit(page, context) {
// Add your configuration here.
},
- /* Hook to execute after a story is rendered.
+ /* Hook to execute after a story is visited and fully rendered.
* The page argument is the Playwright's page object for the story
* The context argument is a Storybook object containing the story's id, title, and name.
*/
- async postRender(page, context) {
+ async postVisit(page, context) {
// Add your configuration here.
},
};
-module.exports = config;
+export default config;
```
diff --git a/docs/snippets/common/test-runner-tags-config.js.mdx b/docs/snippets/common/test-runner-tags-config.js.mdx
new file mode 100644
index 000000000000..6ebfbb6c9fb4
--- /dev/null
+++ b/docs/snippets/common/test-runner-tags-config.js.mdx
@@ -0,0 +1,11 @@
+```js
+// .storybook/test-runner.js
+
+module.exports = {
+ tags: {
+ include: ['test-only', 'pages'],
+ exclude: ['no-tests', 'tokens'],
+ skip: ['skip-test', 'layout'],
+ },
+};
+```
diff --git a/docs/snippets/common/test-runner-tags-config.ts.mdx b/docs/snippets/common/test-runner-tags-config.ts.mdx
new file mode 100644
index 000000000000..023b13e77cc9
--- /dev/null
+++ b/docs/snippets/common/test-runner-tags-config.ts.mdx
@@ -0,0 +1,15 @@
+```ts
+// .storybook/test-runner.ts
+
+import type { TestRunnerConfig } from '@storybook/test-runner';
+
+const config: TestRunnerConfig = {
+ tags: {
+ include: ['test-only', 'pages'],
+ exclude: ['no-tests', 'tokens'],
+ skip: ['skip-test', 'layout'],
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/test-runner-tags-exclude.config.js.mdx b/docs/snippets/common/test-runner-tags-exclude.config.js.mdx
new file mode 100644
index 000000000000..5b73bb9bdf60
--- /dev/null
+++ b/docs/snippets/common/test-runner-tags-exclude.config.js.mdx
@@ -0,0 +1,9 @@
+```js
+// .storybook/test-runner.js
+
+module.exports = {
+ tags: {
+ exclude: ['no-tests'],
+ },
+};
+```
diff --git a/docs/snippets/common/test-runner-tags-exclude.config.ts.mdx b/docs/snippets/common/test-runner-tags-exclude.config.ts.mdx
new file mode 100644
index 000000000000..9712292fe33c
--- /dev/null
+++ b/docs/snippets/common/test-runner-tags-exclude.config.ts.mdx
@@ -0,0 +1,13 @@
+```ts
+// .storybook/test-runner.ts
+
+import type { TestRunnerConfig } from '@storybook/test-runner';
+
+const config: TestRunnerConfig = {
+ tags: {
+ exclude: ['no-tests'],
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/test-runner-tags-include.config.js.mdx b/docs/snippets/common/test-runner-tags-include.config.js.mdx
new file mode 100644
index 000000000000..2b51222fed40
--- /dev/null
+++ b/docs/snippets/common/test-runner-tags-include.config.js.mdx
@@ -0,0 +1,9 @@
+```js
+// .storybook/test-runner.js
+
+module.exports = {
+ tags: {
+ include: ['test-only'],
+ },
+};
+```
diff --git a/docs/snippets/common/test-runner-tags-include.config.ts.mdx b/docs/snippets/common/test-runner-tags-include.config.ts.mdx
new file mode 100644
index 000000000000..b69e402aff92
--- /dev/null
+++ b/docs/snippets/common/test-runner-tags-include.config.ts.mdx
@@ -0,0 +1,13 @@
+```ts
+// .storybook/test-runner.ts
+
+import type { TestRunnerConfig } from '@storybook/test-runner';
+
+const config: TestRunnerConfig = {
+ tags: {
+ include: ['test-only'],
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/test-runner-tags-skip.config.js.mdx b/docs/snippets/common/test-runner-tags-skip.config.js.mdx
new file mode 100644
index 000000000000..bc82ef46d752
--- /dev/null
+++ b/docs/snippets/common/test-runner-tags-skip.config.js.mdx
@@ -0,0 +1,9 @@
+```js
+// .storybook/test-runner.js
+
+module.exports = {
+ tags: {
+ skip: ['skip-test'],
+ },
+};
+```
diff --git a/docs/snippets/common/test-runner-tags-skip.config.ts.mdx b/docs/snippets/common/test-runner-tags-skip.config.ts.mdx
new file mode 100644
index 000000000000..37a03bf7b1c4
--- /dev/null
+++ b/docs/snippets/common/test-runner-tags-skip.config.ts.mdx
@@ -0,0 +1,13 @@
+```ts
+// .storybook/test-runner.ts
+
+import type { TestRunnerConfig } from '@storybook/test-runner';
+
+const config: TestRunnerConfig = {
+ tags: {
+ skip: ['skip-test'],
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/common/test-runner-waitpageready.js.mdx b/docs/snippets/common/test-runner-waitpageready.js.mdx
new file mode 100644
index 000000000000..1bb3df563c00
--- /dev/null
+++ b/docs/snippets/common/test-runner-waitpageready.js.mdx
@@ -0,0 +1,25 @@
+```js
+// .storybook/test-runner.js
+
+const { waitForPageReady } = require('@storybook/test-runner');
+const { toMatchImageSnapshot } = require('jest-image-snapshot');
+
+const customSnapshotsDir = `${process.cwd()}/__snapshots__`;
+
+module.exports = {
+ setup() {
+ expect.extend({ toMatchImageSnapshot });
+ },
+ async postVisit(page, context) {
+ // Awaits for the page to be loaded and available including assets (e.g., fonts)
+ await waitForPageReady(page);
+
+ // Generates a snapshot file based on the story identifier
+ const image = await page.screenshot();
+ expect(image).toMatchImageSnapshot({
+ customSnapshotsDir,
+ customSnapshotIdentifier: context.id,
+ });
+ },
+};
+```
diff --git a/docs/snippets/common/test-runner-waitpageready.ts.mdx b/docs/snippets/common/test-runner-waitpageready.ts.mdx
new file mode 100644
index 000000000000..2da14b2c7185
--- /dev/null
+++ b/docs/snippets/common/test-runner-waitpageready.ts.mdx
@@ -0,0 +1,29 @@
+```ts
+// .storybook/test-runner.ts
+
+import type { TestRunnerConfig } from '@storybook/test-runner';
+import { 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) {
+ // Awaits for the page to be loaded and available including assets (e.g., fonts)
+ await waitForPageReady(page);
+
+ // Generates a snapshot file based on the story identifier
+ const image = await page.screenshot();
+ expect(image).toMatchImageSnapshot({
+ customSnapshotsDir,
+ customSnapshotIdentifier: context.id,
+ });
+ },
+};
+
+export default config;
+```
diff --git a/docs/toc.js b/docs/toc.js
index 9c773a493244..13d66fee3bab 100644
--- a/docs/toc.js
+++ b/docs/toc.js
@@ -506,6 +506,11 @@ module.exports = {
title: 'babelDefault',
pathSegment: 'main-config-babel-default',
type: 'link',
+ },
+ {
+ title: 'build',
+ pathSegment: 'main-config-build',
+ type: 'link',
},
{
title: 'core',
diff --git a/docs/writing-tests/accessibility-testing.md b/docs/writing-tests/accessibility-testing.md
index 5d404fb3248f..36c17f89860c 100644
--- a/docs/writing-tests/accessibility-testing.md
+++ b/docs/writing-tests/accessibility-testing.md
@@ -89,7 +89,7 @@ Out of the box, Storybook's accessibility addon includes a set of accessibility
#### Global a11y configuration
-If you need to dismiss an accessibility rule or modify its settings across all stories, you can add the following to your [storybook/preview.js](../configure/overview.md#configure-story-rendering):
+If you need to dismiss an accessibility rule or modify its settings across all stories, you can add the following to your [`storybook/preview.js|ts`](../configure/overview.md#configure-story-rendering):
@@ -170,7 +170,7 @@ Disable accessibility testing for stories or components by adding the following
The most accurate way to check accessibility is manually on real devices. However, you can use automated tools to catch common accessibility issues. For example, [Axe](https://www.deque.com/axe/), on average, catches upwards to [57% of WCAG issues](https://www.deque.com/blog/automated-testing-study-identifies-57-percent-of-digital-accessibility-issues/) automatically.
-These tools work by auditing the rendered DOM against heuristics based on [WCAG](https://www.w3.org/WAI/standards-guidelines/wcag/) rules and other industry-accepted best practices. You can then integrate these tools into your test automation pipeline using the Storybook [test runner](./test-runner.md#test-hook-api-experimental) and [axe-playwright](https://github.com/abhinaba-ghosh/axe-playwright).
+These tools work by auditing the rendered DOM against heuristics based on [WCAG](https://www.w3.org/WAI/standards-guidelines/wcag/) rules and other industry-accepted best practices. You can then integrate these tools into your test automation pipeline using the Storybook [test runner](./test-runner.md#test-hook-api) and [axe-playwright](https://github.com/abhinaba-ghosh/axe-playwright).
### Setup
@@ -190,7 +190,7 @@ Run the following command to install the required dependencies.
-Add a new [configuration file](./test-runner.md#test-hook-api-experimental) inside your Storybook directory with the following inside:
+Add a new [configuration file](./test-runner.md#test-hook-api) inside your Storybook directory with the following inside:
@@ -205,7 +205,7 @@ Add a new [configuration file](./test-runner.md#test-hook-api-experimental) insi
-`preRender` and `postRender` are convenient hooks that allow you to extend the test runner's default configuration. They are **experimental** and subject to changes. Read more about them [here](./test-runner.md#test-hook-api-experimental).
+`preVisit` and `postVisit` are convenient hooks that allow you to extend the test runner's default configuration. Read more about them [here](./test-runner.md#test-hook-api).
diff --git a/docs/writing-tests/test-runner.md b/docs/writing-tests/test-runner.md
index 96b08331cd75..cf9c7d3b851e 100644
--- a/docs/writing-tests/test-runner.md
+++ b/docs/writing-tests/test-runner.md
@@ -81,30 +81,33 @@ Test runner offers zero-config support for Storybook. However, you can run `test
The test-runner is powered by [Jest](https://jestjs.io/) and accepts a subset of its [CLI options](https://jestjs.io/docs/cli) (for example, `--watch`, `--maxWorkers`).
If you're already using any of those flags in your project, you should be able to migrate them into Storybook's test-runner without any issues. Listed below are all the available flags and examples of using them.
-| Options | Description |
-| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `--help` | Output usage information
`test-storybook --help` |
-| `-s`, `--index-json` | Run in index json mode. Automatically detected (requires a compatible Storybook)
`test-storybook --index-json` |
-| `--no-index-json` | Disables index json mode
`test-storybook --no-index-json` |
-| `-c`, `--config-dir [dir-name]` | Directory where to load Storybook configurations from
`test-storybook -c .storybook` |
-| `--watch` | Run in watch mode
`test-storybook --watch` |
-| `--watchAll` | Watch files for changes and rerun all tests when something changes.
`test-storybook --watchAll` |
-| `--coverage` | Runs [coverage tests](./test-coverage.md) on your stories and components
`test-storybook --coverage` |
-| `--coverageDirectory` | Directory where to write coverage report output
`test-storybook --coverage --coverageDirectory coverage/ui/storybook` |
-| `--url` | Define the URL to run tests in. Useful for custom Storybook URLs
`test-storybook --url http://the-storybook-url-here.com` |
-| `--browsers` | Define browsers to run tests in. One or multiple of: chromium, firefox, webkit
`test-storybook --browsers firefox chromium` |
-| `--maxWorkers [amount]` | Specifies the maximum number of workers the worker-pool will spawn for running tests
`test-storybook --maxWorkers=2` |
-| `--no-cache` | Disable the cache
`test-storybook --no-cache` |
-| `--clearCache` | Deletes the Jest cache directory and then exits without running tests
`test-storybook --clearCache` |
-| `--verbose` | Display individual test results with the test suite hierarchy
`test-storybook --verbose` |
-| `-u`, `--updateSnapshot` | Use this flag to re-record every snapshot that fails during this test run
`test-storybook -u` |
-| `--eject` | Creates a local configuration file to override defaults of the test-runner
`test-storybook --eject` |
-| `--json` | Prints the test results in JSON. This mode will send all other test output and user messages to stderr.
`test-storybook --json` |
-| `--outputFile` | Write test results to a file when the --json option is also specified.
`test-storybook --json --outputFile results.json` |
-| `--junit` | Indicates that test information should be reported in a junit file.
`test-storybook --**junit**` |
-| `--ci` | Instead of the regular behavior of storing a new snapshot automatically, it will fail the test and require Jest to be run with `--updateSnapshot`.
`test-storybook --ci` |
-| `--shard [index/count]` | Requires CI. Splits the test suite execution into multiple machines
`test-storybook --shard=1/8` |
-| `--failOnConsole` | Makes tests fail on browser console errors
`test-storybook --failOnConsole` |
+| Options | Description |
+| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `--help` | Output usage information
`test-storybook --help` |
+| `-s`, `--index-json` | Run in index json mode. Automatically detected (requires a compatible Storybook)
`test-storybook --index-json` |
+| `--no-index-json` | Disables index json mode
`test-storybook --no-index-json` |
+| `-c`, `--config-dir [dir-name]` | Directory where to load Storybook configurations from
`test-storybook -c .storybook` |
+| `--watch` | Run in watch mode
`test-storybook --watch` |
+| `--watchAll` | Watch files for changes and rerun all tests when something changes.
`test-storybook --watchAll` |
+| `--coverage` | Runs [coverage tests](./test-coverage.md) on your stories and components
`test-storybook --coverage` |
+| `--coverageDirectory` | Directory where to write coverage report output
`test-storybook --coverage --coverageDirectory coverage/ui/storybook` |
+| `--url` | Define the URL to run tests in. Useful for custom Storybook URLs
`test-storybook --url http://the-storybook-url-here.com` |
+| `--browsers` | Define browsers to run tests in. One or multiple of: chromium, firefox, webkit
`test-storybook --browsers firefox chromium` |
+| `--maxWorkers [amount]` | Specifies the maximum number of workers the worker-pool will spawn for running tests
`test-storybook --maxWorkers=2` |
+| `--no-cache` | Disable the cache
`test-storybook --no-cache` |
+| `--clearCache` | Deletes the Jest cache directory and then exits without running tests
`test-storybook --clearCache` |
+| `--verbose` | Display individual test results with the test suite hierarchy
`test-storybook --verbose` |
+| `-u`, `--updateSnapshot` | Use this flag to re-record every snapshot that fails during this test run
`test-storybook -u` |
+| `--eject` | Creates a local configuration file to override defaults of the test-runner
`test-storybook --eject` |
+| `--json` | Prints the test results in JSON. This mode will send all other test output and user messages to stderr.
`test-storybook --json` |
+| `--outputFile` | Write test results to a file when the --json option is also specified.
`test-storybook --json --outputFile results.json` |
+| `--junit` | Indicates that test information should be reported in a junit file.
`test-storybook --**junit**` |
+| `--ci` | Instead of the regular behavior of storing a new snapshot automatically, it will fail the test and require Jest to be run with `--updateSnapshot`.
`test-storybook --ci` |
+| `--shard [index/count]` | Requires CI. Splits the test suite execution into multiple machines
`test-storybook --shard=1/8` |
+| `--failOnConsole` | Makes tests fail on browser console errors
`test-storybook --failOnConsole` |
+| `--includeTags` | Experimental feature
Defines a subset of stories to be tested if they match the enabled [tags](#experimental-filter-tests).
`test-storybook --includeTags="test-only, pages"` |
+| `--excludeTags` | Experimental feature
Prevents stories from being tested if they match the provided [tags](#experimental-filter-tests).
`test-storybook --excludeTags="no-tests, tokens"` |
+| `--skipTags` | Experimental feature
Configures the test runner to skip running tests for stories that match the provided [tags](#experimental-filter-tests).
`test-storybook --skipTags="skip-test, layout"` |
@@ -175,7 +178,7 @@ You can use your CI provider (for example, [GitHub Actions](https://github.com/f
-By default Storybook outputs the [build](../sharing/publish-storybook.md#build-storybook-as-a-static-web-application) to the `storybook-static` directory. If you're using a different build directory, you'll need to adjust the recipe accordingly.
+By default, Storybook outputs the [build](../sharing/publish-storybook.md#build-storybook-as-a-static-web-application) to the `storybook-static` directory. If you're using a different build directory, you'll need to adjust the recipe accordingly.
@@ -192,19 +195,19 @@ However, you might want to pair the test runner and Chromatic in some cases.
## Advanced configuration
-### Test hook API (experimental)
+### Test hook API
The test-runner renders a story and executes its [play function](../writing-stories/play-function.md) if one exists. However, certain behaviors are impossible to achieve via the play function, which executes in the browser. For example, if you want the test-runner to take visual snapshots for you, this is possible via Playwright/Jest but must be executed in Node.
The test-runner exports test hooks that can be overridden globally to enable use cases like visual or DOM snapshots. These hooks give you access to the test lifecycle _before_ and _after_ the story is rendered.
Listed below are the available hooks and an overview of how to use them.
-| Hook | Description |
-| ------------ | -------------------------------------------------------------------------------------------------- |
-| `prepare` | Prepares the browser for tests
`async prepare({ page, browserContext, testRunnerConfig }) {}` |
-| `setup` | Executes once before all the tests run
`setup() {}` |
-| `preRender` | Executes before a story is rendered
`async preRender(page, context) {}` |
-| `postRender` | Executes after the story is rendered
`async postRender(page, context) {}` |
+| Hook | Description |
+| ----------- | --------------------------------------------------------------------------------------------------------------- |
+| `prepare` | Prepares the browser for tests
`async prepare({ page, browserContext, testRunnerConfig }) {}` |
+| `setup` | Executes once before all the tests run
`setup() {}` |
+| `preVisit` | Executes before a story is initially visited and rendered in the browser
`async preVisit(page, context) {}` |
+| `postVisit` | Executes after the story is is visited and fully rendered
`async postVisit(page, context) {}` |
@@ -227,7 +230,7 @@ To enable the hooks API, you'll need to add a new configuration file inside your
-Except for the `setup` function, all other functions run asynchronously. Both `preRender` and `postRender` functions include two additional arguments, a [Playwright page](https://playwright.dev/docs/pages) and a context object which contains the `id`, `title`, and the `name` of the story.
+Except for the `setup` function, all other functions run asynchronously. Both `preVisit` and `postVisit` functions include two additional arguments, a [Playwright page](https://playwright.dev/docs/pages) and a context object which contains the `id`, `title`, and the `name` of the story.
@@ -236,9 +239,108 @@ When the test-runner executes, your existing tests will go through the following
- The `setup` function is executed before all the tests run.
- The context object is generated containing the required information.
- Playwright navigates to the story's page.
-- The `preRender` function is executed.
+- The `preVisit` function is executed.
- The story is rendered, and any existing `play` functions are executed.
-- The `postRender` function is executed.
+- The `postVisit` function is executed.
+
+### (Experimental) Filter tests
+
+When you run the test-runner on Storybook, it tests every story by default. However, if you want to filter the tests, you can use the `tags` configuration option. Storybook originally introduced this feature to generate [automatic documentation](../writing-docs/autodocs.md) for stories. But it can be further extended to configure the test-runner to run tests according to the provided tags using a similar configuration option or via CLI flags (e.g., `--includeTags`, `--excludeTags`, `--skipTags`), only available with the latest stable release (`0.15` or higher). Listed below are the available options and an overview of how to use them.
+
+| Option | Description |
+| --------- | ----------------------------------------------------------------------------- |
+| `exclude` | Prevents stories if they match the provided tags from being tested. |
+| `include` | Defines a subset of stories only to be tested if they match the enabled tags. |
+| `skip` | Skips testing on stories if they match the provided tags. |
+
+
+
+
+
+
+
+
+
+Running tests with the CLI flags takes precedence over the options provided in the configuration file and will override the available options in the configuration file.
+
+
+
+#### Disabling tests
+
+If you want to prevent specific stories from being tested by the test-runner, you can configure your story with a custom tag, enable it to the test-runner configuration file or run the test-runner with the `--excludeTags` [CLI](#cli-options) flag and exclude them from testing. This is helpful when you want to exclude stories that are not yet ready for testing or are irrelevant to your tests. For example:
+
+
+
+
+
+
+
+#### Run tests for a subset of stories
+
+To allow the test-runner only to run tests on a specific story or subset of stories, you can configure the story with a custom tag, enable it in the test-runner configuration file or run the test-runner with the `--includeTags` [CLI](#cli-options) flag and include them in your tests. For example, if you wanted to run tests based on the `test-only` tag, you can adjust your configuration as follows:
+
+
+
+
+
+
+
+
+
+Applying tags for the component's stories should either be done at the component level (using `meta`) or at the story level. Importing tags across stories is not supported in Storybook and won't work as intended.
+
+
+
+#### Skip tests
+
+If you want to skip running tests on a particular story or subset of stories, you can configure your story with a custom tag, enable it in the test-runner configuration file, or run the test-runner with the `--skipTags` [CLI](#cli-options) flag. Running tests with this option will cause the test-runner to ignore and flag them accordingly in the test results, indicating that the tests are temporarily disabled. For example:
+
+
+
+
+
+
+
+### Authentication for deployed Storybooks
+
+If you use a secure hosting provider that requires authentication to host your Storybook, you may need to set HTTP headers. This is mainly because of how the test runner checks the status of the instance and the index of its stories through fetch requests and Playwright. To do this, you can modify the test-runner configuration file to include the `getHttpHeaders` function. This function takes the URL of the fetch calls and page visits as input and returns an object containing the headers that need to be set.
+
+
+
+
+
+
### Helpers
@@ -255,6 +357,36 @@ The test-runner exports a few helpers that can be used to make your tests more r
+#### Accessing story information with the test-runner
+
+If you need to access information about the story, such as its parameters, the test-runner includes a helper function named `getStoryContext` that you can use to retrieve it. You can then use it to customize your tests further as needed. For example, if you need to configure Playwright's page [viewport size](https://playwright.dev/docs/api/class-page#page-set-viewport-size) to use the viewport size defined in the story's parameters, you can do so as follows:
+
+
+
+
+
+
+
+#### Working with assets
+
+If you're running a specific set of tests (e.g., image snapshot testing), the test-runner provides a helper function named `waitForPageReady` that you can use to ensure the page is fully loaded and ready before running the test. For example:
+
+
+
+
+
+
+
### Index.json mode
The test-runner transforms your story files into tests when testing a local Storybook. For a remote Storybook, it uses the Storybook's [index.json](../configure/overview.md#feature-flags) (formerly `stories.json`) file (a static index of all the stories) to run the tests.
@@ -277,7 +409,7 @@ Suppose you run into a situation where the local and remote Storybooks appear ou
-The `index.json` mode is not compatible with watch mode.
+The `index.json` mode is not compatible with the watch mode.
@@ -329,6 +461,10 @@ By default, the test runner truncates error outputs at 1000 characters, and you
As the test runner is based on Playwright, you might need to use specific docker images or other configurations depending on your CI setup. In that case, you can refer to the [Playwright CI docs](https://playwright.dev/docs/ci) for more information.
+### Tests filtered by tags are incorrectly executed
+
+If you've enabled filtering tests with tags and provided similar tags to the `include` and `exclude` lists, the test-runner will execute the tests based on the `exclude` list and ignore the `include` list. To avoid this, make sure the tags provided to the `include` and `exclude` lists differ.
+
#### Learn about other UI tests
- Test runner to automate test execution