diff --git a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts index 41e50393f58e..57e8fcda9a2b 100644 --- a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts +++ b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts @@ -199,6 +199,8 @@ export function createPlaywrightTest( do: await mount() + + More info: https://storybook.js.org/docs/api/portable-stories-playwright `); } diff --git a/docs/api/portable-stories-playwright.md b/docs/api/portable-stories-playwright.md index 1089a1159aee..f4b3b423e9fe 100644 --- a/docs/api/portable-stories-playwright.md +++ b/docs/api/portable-stories-playwright.md @@ -10,6 +10,8 @@ export const SUPPORTED_RENDERERS = ['react', 'vue']; +The portable stories API for Playwright CT is experimental. Playwright CT itself is also experimental. Breaking changes might occur on either libraries in upcoming releases. + Portable stories are currently only supported in [React](?renderer=react) and [Vue](?renderer=vue) projects. @@ -38,7 +40,7 @@ Normally, Storybok composes a story and its [annotations](#annotations) automati -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](https://playwright.dev/docs/test-components#i-have-a-project-that-already-uses-vite-can-i-reuse-the-config): +If your stories use template-based Vue components, you may need to [alias the `vue` module](https://vuejs.org/guide/scaling-up/tooling#note-on-in-browser-template-compilation) to resolve correctly in the Playwright CT environment. You can do this via the [`ctViteConfig` property](https://playwright.dev/docs/test-components#i-have-a-project-that-already-uses-vite-can-i-reuse-the-config):
Example Playwright configuration @@ -160,7 +162,7 @@ The code which you write in your Playwright test file is transformed and orchest Because of this, you have to compose the stories _in a separate file than your own test file_: ```ts -// Button.portable.ts +// Button.stories.portable.ts // Replace with your renderer, e.g. react, vue3 import { composeStories } from '@storybook/'; @@ -173,6 +175,8 @@ export default composeStories(stories); You can then import the composed stories in your Playwright test file, as in the [example above](#createtest). +## createTest + [Read more about Playwright's component testing](https://playwright.dev/docs/test-components#test-stories). diff --git a/docs/snippets/react/portable-stories-playwright-ct.ts.mdx b/docs/snippets/react/portable-stories-playwright-ct.ts.mdx index 3b6b9a213eba..40552ea42d5d 100644 --- a/docs/snippets/react/portable-stories-playwright-ct.ts.mdx +++ b/docs/snippets/react/portable-stories-playwright-ct.ts.mdx @@ -3,7 +3,7 @@ import { createTest } from '@storybook/react/experimental-playwright'; import { test as base } from '@playwright/experimental-ct-react'; -import stories from './Button.portable'; +import stories from './Button.stories.portable'; const test = createTest(base); @@ -12,4 +12,11 @@ test('renders primary button', async ({ mount }) => { // such as loaders, render, and play function await mount(); }); + +test('renders primary button with overriden props', async ({ mount }) => { + // You can pass custom props to your component via JSX + const component = await mount(); + await expect(component).toContainText('label from test'); + await expect(component.getByRole('button')).toHaveClass(/storybook-button--primary/); +}); ``` diff --git a/docs/snippets/vue/portable-stories-playwright-ct.ts.mdx b/docs/snippets/vue/portable-stories-playwright-ct.ts.mdx index 8421d82cdcdc..252b3de70f5d 100644 --- a/docs/snippets/vue/portable-stories-playwright-ct.ts.mdx +++ b/docs/snippets/vue/portable-stories-playwright-ct.ts.mdx @@ -3,13 +3,22 @@ import { createTest } from '@storybook/vue3/experimental-playwright'; import { test as base } from '@playwright/experimental-ct-vue'; -import stories from './Button.portable'; +import stories from './Button.stories.portable'; const test = createTest(base); +// 👉 Important: Due to current limitations, you can only reference your stories as JSX elements. + test('renders primary button', async ({ mount }) => { // The mount function will execute all the necessary steps in the story, // such as loaders, render, and play function - await mount(stories.Primary); + await mount(); +}); + +test('renders primary button with overriden props', async ({ mount }) => { + // You can pass custom props to your component via JSX + const component = await mount(); + await expect(component).toContainText('label from test'); + await expect(component.getByRole('button')).toHaveClass(/storybook-button--primary/); }); ``` diff --git a/test-storybooks/portable-stories-kitchen-sink/vue3/stories/Button.playwright.tsx b/test-storybooks/portable-stories-kitchen-sink/vue3/stories/Button.playwright.tsx index dc27dd997aab..6251fcc24006 100644 --- a/test-storybooks/portable-stories-kitchen-sink/vue3/stories/Button.playwright.tsx +++ b/test-storybooks/portable-stories-kitchen-sink/vue3/stories/Button.playwright.tsx @@ -1,7 +1,6 @@ import { test as base, expect } from '@playwright/experimental-ct-vue'; import { createTest } from '@storybook/vue3/experimental-playwright'; import stories, { SingleComposedStory, WithSpanishGlobal } from './Button.stories.portable'; -import Button from './Button.vue'; const test = createTest(base);