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 }) => {