Portable stories in Playwright CT

(⚠️ Experimental)

Portable stories are currently only supported in React and Vue projects.

The portable stories API for Playwright CT is experimental. Playwright CT itself is also experimental. Breaking changes might occur in either library in upcoming releases.

Portable stories are Storybook stories which can be used in external environments, such as Playwright Component Tests (CT).

Normally, Storybook composes a story and its annotations automatically, as part of the story pipeline. When using stories in Playwright CT, you can use the createTest function, which extends Playwright's test functionality to add a custom mount mechanism, to take care of the story pipeline for you.

Your project must be using React 18+ to use the portable stories API with Playwright CT.

Using Next.js? The portable stories API is not yet supported in Next.js with Playwright CT.

If your stories use template-based Vue components, you may need to alias the vue module to resolve correctly in the Playwright CT environment. You can do this via the ctViteConfig property:

Example Playwright configuration
playwright-config.ts
Loading...

createTest

(⚠️ Experimental)

Instead of using Playwright's own test function, you can use Storybook's special createTest function to extend Playwright's base fixture and override the mount function to load, render, and play the story. This function is experimental and is subject to changes.

The code which you write in your Playwright test file is transformed and orchestrated by Playwright, where part of the code executes in Node, while other parts execute in the browser.

Because of this, you have to compose the stories in a separate file than your own test file:

Button.stories.portable.ts
Loading...

You can then import the composed stories in your Playwright test file, as in the example above.

Type

Loading...

Parameters

baseTest

(Required)

Type: PlaywrightFixture

The base test function to use, e.g. test from Playwright.

Return

Type: PlaywrightFixture

A Storybook-specific test function with the custom mount mechanism.

setProjectAnnotations

This API should be called once, before the tests run, in playwright/index.ts. This will make sure that when mount is called, the project annotations are taken into account as well.

playwright/index.ts
Loading...

Sometimes a story can require an addon's decorator or loader to render properly. For example, an addon can apply a decorator that wraps your story in the necessary router context. In this case, you must include that addon's preview export in the project annotations set. See addonAnnotations in the example above.

Note: If the addon doesn't automatically apply the decorator or loader itself, but instead exports them for you to apply manually in .storybook/preview.js|ts (e.g. using withThemeFromJSXProvider from @storybook/addon-themes), then you do not need to do anything else. They are already included in the previewAnnotations in the example above.

Type

Loading...

Parameters

projectAnnotations

(Required)

Type: ProjectAnnotation | ProjectAnnotation[]

A set of project annotations (those defined in .storybook/preview.js|ts) or an array of sets of project annotations, which will be applied to all composed stories.

Annotations

Annotations are the metadata applied to a story, like args, decorators, loaders, and play functions. They can be defined for a specific story, all stories for a component, or all stories in the project.

Story pipeline

To preview your stories, Storybook runs a story pipeline, which includes applying project annotations, loading data, rendering the story, and playing interactions. This is a simplified version of the pipeline:

A flow diagram of the story pipeline. First, set project annotations. Storybook automatically collects decorators etc. which are exported by addons and the .storybook/preview file. .storybook/preview.js produces project annotations; some-addon/preview produces addon annotations. The rest of the steps are labeled as a group, Playwright test. Second, prepare. Storybook gathers all the metadata required for a story to be composed. Select.stories.js produces component annotations from the default export and story annotations from the named export. Third, load. Storybook executes all loaders (async). Fourth, render. Storybook renders the story as a component. Illustration of the rendered Select component. Fifth, play. Storybook runs the play function (interacting with component). Illustration of the renderer Select component, now open.

When you want to reuse a story in a different environment, however, it's crucial to understand that all these steps make a story. The portable stories API provides you with the mechanism to recreate that story pipeline in your external environment:

1. Apply project-level annotations

Annotations come from the story itself, that story's component, and the project. The project-level annotatations are those defined in your .storybook/preview.js file and by addons you're using. In portable stories, these annotations are not applied automatically—you must apply them yourself.

👉 For this, you use the setProjectAnnotations API.

2. Prepare, load, render, and play

The story pipeline includes preparing the story, loading data, rendering the story, and playing interactions. In portable stories within Playwright CT, the mount function takes care of these steps for you.

👉 For this, you use the createTest API.

If your play function contains assertions (e.g. expect calls), your test will fail when those assertions fail.

Overriding globals

If your stories behave differently based on globals (e.g. rendering text in English or Spanish), you can define those global values in portable stories by overriding project annotations when composing a story:

Button.portable.ts
Loading...

You can then use those composed stories in your Playwright test file using the createTest function.

Was this page helpful?

Markdown accepted ([link text](url), _italic_, **bold**, etc). Your anonymous feedback will be posted publicly on GitHub.

✍️ Edit on GitHub – PRs welcome!
Storybook
Join the community
6,623 developers and counting
WhyWhy StorybookComponent-driven UI
DocsGuidesTutorialsChangelogTelemetry
CommunityAddonsGet involvedBlog
ShowcaseExploreProjectsComponent glossary
Open source software
Storybook

Maintained by
Chromatic
Special thanks to Netlify and CircleCI