diff --git a/code/lib/store/template/stories/rendering.stories.ts b/code/lib/store/template/stories/rendering.stories.ts index 71e2f1a025cd..eae4c11f4d9d 100644 --- a/code/lib/store/template/stories/rendering.stories.ts +++ b/code/lib/store/template/stories/rendering.stories.ts @@ -2,6 +2,7 @@ import { global as globalThis } from '@storybook/global'; import type { PlayFunctionContext } from '@storybook/types'; import { within, waitFor } from '@storybook/testing-library'; import { expect } from '@storybook/jest'; +import { FORCE_REMOUNT, RESET_STORY_ARGS, UPDATE_STORY_ARGS } from '@storybook/core-events'; export default { component: globalThis.Components.Button, @@ -9,17 +10,30 @@ export default { label: 'Click me', }, }; -// this is the story should be remove it will always fail, because forceReRender Api is removed in V7 -export const ForceReRender = { - play: async ({ canvasElement }: PlayFunctionContext) => { + +export const ForceRemount = { + /** + * This play function runs in an infinite loop, because the final FORCE_REMOUNT event retriggers the function + * Because of this, it is disabled in both Chromatic and the test runner. + * To test it manually, inspect that the button alternates being focused and blurred every 3 seconds. + * If the button ALWAYS has focus it means the renderer didn't correctly remount the tree at the FORCE_REMOUNT event + */ + parameters: { chromatic: { disableSnapshot: true } }, + play: async ({ canvasElement, id }: PlayFunctionContext) => { + if (window?.navigator.userAgent.match(/StorybookTestRunner/)) { + return; + } const channel = globalThis.__STORYBOOK_ADDONS_CHANNEL__; const button = await within(canvasElement).findByRole('button'); + + await waitFor(() => expect(button).not.toHaveFocus()); + await new Promise((resolve) => setTimeout(resolve, 3000)); + await button.focus(); await expect(button).toHaveFocus(); - // forceRender is not called in V7 - // By forcing the component to rerender, we reset the focus state - await channel.emit('forceReRender'); - await waitFor(() => expect(button).not.toHaveFocus()); + await new Promise((resolve) => setTimeout(resolve, 3000)); + // By forcing the component to remount, we reset the focus state + await channel.emit(FORCE_REMOUNT, { storyId: id }); }, }; @@ -30,17 +44,16 @@ export const ChangeArgs = { await button.focus(); await expect(button).toHaveFocus(); - // Vue3: https://github.com/storybookjs/storybook/issues/13913 // Web-components: https://github.com/storybookjs/storybook/issues/19415 // Preact: https://github.com/storybookjs/storybook/issues/19504 - if (['vue3', 'web-components', 'html', 'preact'].includes(globalThis.storybookRenderer)) return; + if (['web-components', 'html', 'preact'].includes(globalThis.storybookRenderer)) return; - // When we change the args to the button, it should not rerender - await channel.emit('updateStoryArgs', { storyId: id, updatedArgs: { label: 'New Text' } }); + // When we change the args to the button, it should not remount + await channel.emit(UPDATE_STORY_ARGS, { storyId: id, updatedArgs: { label: 'New Text' } }); await within(canvasElement).findByText(/New Text/); await expect(button).toHaveFocus(); - await channel.emit('resetStoryArgs', { storyId: id }); + await channel.emit(RESET_STORY_ARGS, { storyId: id }); await within(canvasElement).findByText(/Click me/); await expect(button).toHaveFocus(); },