From 6e3b59e58570e93dcfdb5dafe767053f395c5360 Mon Sep 17 00:00:00 2001 From: adamscybot Date: Thu, 1 May 2025 17:17:36 +0100 Subject: [PATCH] Fixes #31150. Portable stories for playwright CT now allow functions to be passed as props from the test. --- .../modules/store/csf/portable-stories.ts | 12 +++++++++--- .../react/stories/Button.playwright.tsx | 5 ++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/code/core/src/preview-api/modules/store/csf/portable-stories.ts b/code/core/src/preview-api/modules/store/csf/portable-stories.ts index 19ad350de0ea..3d5750e2a1c8 100644 --- a/code/core/src/preview-api/modules/store/csf/portable-stories.ts +++ b/code/core/src/preview-api/modules/store/csf/portable-stories.ts @@ -301,7 +301,9 @@ export function composeStories( return composedStories; } -type WrappedStoryRef = { __pw_type: 'jsx' | 'importRef' }; +type WrappedStoryRef = + | { __pw_type: 'jsx'; props: Record } + | { __pw_type: 'importRef' }; type UnwrappedJSXStoryRef = { __pw_type: 'jsx'; type: UnwrappedImportStoryRef; @@ -341,12 +343,16 @@ export function createPlaywrightTest( `); } + // Props are not necessarily serialisable and so can't be passed to browser via + // `page.evaluate`. Regardless they are not needed for storybook load/play steps. + const { props, ...storyRefWithoutProps } = storyRef; + await page.evaluate(async (wrappedStoryRef: WrappedStoryRef) => { const unwrappedStoryRef = await globalThis.__pwUnwrapObject?.(wrappedStoryRef); const story = '__pw_type' in unwrappedStoryRef ? unwrappedStoryRef.type : unwrappedStoryRef; return story?.load?.(); - }, storyRef); + }, storyRefWithoutProps); // mount the story const mountResult = await mount(storyRef, ...restArgs); @@ -358,7 +364,7 @@ export function createPlaywrightTest( '__pw_type' in unwrappedStoryRef ? unwrappedStoryRef.type : unwrappedStoryRef; const canvasElement = document.querySelector('#root'); return story?.play?.({ canvasElement }); - }, storyRef); + }, storyRefWithoutProps); return mountResult; }); diff --git a/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.playwright.tsx b/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.playwright.tsx index ee201e587159..02dcc25df7b9 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.playwright.tsx +++ b/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.playwright.tsx @@ -18,11 +18,14 @@ test('renders with composeStory (singular)', async ({ mount }) => { }); test('renders story with props', async ({ mount }) => { + let called = false const component = await mount( - child from test + { called = true }}>child from test ); await expect(component).toContainText('child from test'); await expect(component.getByRole('button')).toHaveClass(/storybook-button--primary/); + await component.getByRole('button').click() + await expect(called).toBe(true) }); test('renders story with custom render', async ({ mount }) => {