From 2c4616a677dc72680952c656e42d2fa549cb07e1 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 29 Nov 2022 12:59:21 +0100 Subject: [PATCH 1/8] add aria label to addon-interactions elements --- .../src/components/Interaction.tsx | 1 + .../src/components/InteractionsPanel.tsx | 31 +++++++++---------- .../src/components/StatusBadge.tsx | 6 +++- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/code/addons/interactions/src/components/Interaction.tsx b/code/addons/interactions/src/components/Interaction.tsx index 814db0dc99e6..bacaea0fe358 100644 --- a/code/addons/interactions/src/components/Interaction.tsx +++ b/code/addons/interactions/src/components/Interaction.tsx @@ -155,6 +155,7 @@ export const Interaction = ({ controls.goto(call.id)} disabled={isInteractive} diff --git a/code/addons/interactions/src/components/InteractionsPanel.tsx b/code/addons/interactions/src/components/InteractionsPanel.tsx index 60491fbd02a5..a3478fc23fd9 100644 --- a/code/addons/interactions/src/components/InteractionsPanel.tsx +++ b/code/addons/interactions/src/components/InteractionsPanel.tsx @@ -98,22 +98,21 @@ export const InteractionsPanel: React.FC = React.memo( return ( - {controlStates.debugger && - (interactions.length > 0 || hasException || isRerunAnimating) && ( - - )} -
+ {controlStates.debugger && (interactions.length > 0 || hasException || isRerunAnimating) && ( + + )} +
{interactions.map((call) => ( = ({ status }) => { [CallStates.ACTIVE]: 'Runs', [CallStates.WAITING]: 'Runs', }[status]; - return {badgeText}; + return ( + + {badgeText} + + ); }; From 492f7304ffe1fe5f77863743c9549e8acb4a154b Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 29 Nov 2022 13:00:17 +0100 Subject: [PATCH 2/8] fix instrumenter story id logic --- code/lib/instrumenter/src/instrumenter.test.ts | 2 +- code/lib/instrumenter/src/instrumenter.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/lib/instrumenter/src/instrumenter.test.ts b/code/lib/instrumenter/src/instrumenter.test.ts index 17b4bd2ddc3f..cb4cc645c14b 100644 --- a/code/lib/instrumenter/src/instrumenter.test.ts +++ b/code/lib/instrumenter/src/instrumenter.test.ts @@ -34,7 +34,7 @@ global.window.location = { reload: jest.fn() }; global.window.HTMLElement = HTMLElement; const storyId = 'kind--story'; -global.window.__STORYBOOK_PREVIEW__ = { urlStore: { selection: { storyId } } }; +global.window.__STORYBOOK_PREVIEW__ = { selectionStore: { selection: { storyId } } }; const setRenderPhase = (newPhase: string) => addons.getChannel().emit(STORY_RENDER_PHASE_CHANGED, { newPhase, storyId }); diff --git a/code/lib/instrumenter/src/instrumenter.ts b/code/lib/instrumenter/src/instrumenter.ts index 8085f16b1f24..c29b1a6fbd9b 100644 --- a/code/lib/instrumenter/src/instrumenter.ts +++ b/code/lib/instrumenter/src/instrumenter.ts @@ -333,7 +333,8 @@ export class Instrumenter { // returns the original result. track(method: string, fn: Function, args: any[], options: Options) { const storyId: StoryId = - args?.[0]?.__storyId__ || global.window.__STORYBOOK_PREVIEW__?.urlStore?.selection?.storyId; + args?.[0]?.__storyId__ || + global.window.__STORYBOOK_PREVIEW__.selectionStore.selection.storyId; const { cursor, ancestors } = this.getState(storyId); this.setState(storyId, { cursor: cursor + 1 }); const id = `${ancestors.slice(-1)[0] || storyId} [${cursor}] ${method}`; From 51c2459ca627109b275410c82fb5d72c9b55a80d Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 29 Nov 2022 13:00:37 +0100 Subject: [PATCH 3/8] add interactions debugger on sandbox templates --- scripts/tasks/sandbox-parts.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/tasks/sandbox-parts.ts b/scripts/tasks/sandbox-parts.ts index 6e1600d02bde..21e6f367d09e 100644 --- a/scripts/tasks/sandbox-parts.ts +++ b/scripts/tasks/sandbox-parts.ts @@ -69,6 +69,10 @@ export const create: Task['run'] = async ( } const mainConfig = await readMainConfig({ cwd }); + // Enable or disable Storybook features + mainConfig.setFieldValue(['features'], { + interactionsDebugger: true, + }); if (template.expected.builder === '@storybook/builder-vite') setSandboxViteFinal(mainConfig); await writeConfig(mainConfig); From bd9e2f5441dffb8c6d84f9148bafadf84cf497b6 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 29 Nov 2022 13:01:09 +0100 Subject: [PATCH 4/8] add e2e tests for the interactions debugger --- .../template/stories/basics.stories.ts | 9 +++ code/e2e-tests/addon-interactions.spec.ts | 59 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/code/addons/interactions/template/stories/basics.stories.ts b/code/addons/interactions/template/stories/basics.stories.ts index 9a1919e748c9..a26a733d92b4 100644 --- a/code/addons/interactions/template/stories/basics.stories.ts +++ b/code/addons/interactions/template/stories/basics.stories.ts @@ -28,6 +28,15 @@ export const Step = { }, }; +export const TypeAndClear = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await userEvent.type(canvas.getByTestId('value'), 'initial value'); + await userEvent.clear(canvas.getByTestId('value')); + await userEvent.type(canvas.getByTestId('value'), 'final value'); + }, +}; + export const Callback = { play: async ({ args, canvasElement, step }) => { const canvas = within(canvasElement); diff --git a/code/e2e-tests/addon-interactions.spec.ts b/code/e2e-tests/addon-interactions.spec.ts index 22b189b7217b..836f620f86de 100644 --- a/code/e2e-tests/addon-interactions.spec.ts +++ b/code/e2e-tests/addon-interactions.spec.ts @@ -34,10 +34,69 @@ test.describe('addon-interactions', () => { await expect(interactionsTab).toBeVisible(); const panel = sbPage.panelContent(); + await expect(panel).toContainText(/Pass/); await expect(panel).toContainText(/userEvent.click/); await expect(panel).toBeVisible(); const done = await panel.locator('[data-testid=icon-done]'); await expect(done).toBeVisible(); }); + + test('should step through interactions', async ({ page }) => { + // templateName is e.g. 'Vue-CLI (Default JS)' + test.skip( + // eslint-disable-next-line jest/valid-title + /^(lit)/i.test(`${templateName}`), + `Skipping ${templateName}, which does not support addon-interactions` + ); + + const sbPage = new SbPage(page); + + await sbPage.navigateToStory('addons/interactions/basics', 'type-and-clear'); + await sbPage.viewAddonPanel('Interactions'); + + const formInput = await sbPage.previewRoot().locator('#interaction-test-form input'); + await expect(formInput).toHaveValue('final value'); + + const interactionsTab = await page.locator('#tabbutton-interactions'); + await expect(interactionsTab).toContainText(/(3)/); + await expect(interactionsTab).toBeVisible(); + + const panel = sbPage.panelContent(); + const runStatusBadge = await panel.locator('[aria-label="Status of the test run"]'); + await expect(runStatusBadge).toContainText(/Pass/); + await expect(panel).toContainText(/initial value/); + await expect(panel).toContainText(/userEvent.clear/); + await expect(panel).toContainText(/final value/); + await expect(panel).toBeVisible(); + + const interactionsRow = await panel.locator('[aria-label="Interaction step"]'); + + await interactionsRow.first().isVisible(); + + await expect(await interactionsRow.count()).toEqual(3); + const firstInteraction = interactionsRow.first(); + await firstInteraction.click(); + + await expect(runStatusBadge).toContainText(/Runs/); + await expect(formInput).toHaveValue('initial value'); + + const goForwardBtn = await panel.locator('[aria-label="Go forward"]'); + await goForwardBtn.click(); + await expect(formInput).toHaveValue(''); + await goForwardBtn.click(); + await expect(formInput).toHaveValue('final value'); + + await expect(runStatusBadge).toContainText(/Pass/); + + const rerunInteractionButton = await panel.locator('[aria-label="Rerun"]'); + await rerunInteractionButton.click(); + await interactionsRow.first().isVisible(); + await expect(await interactionsRow.count()).toEqual(3); + + const remountComponentButton = await page.locator('[title="Remount component"]'); + await remountComponentButton.click(); + await interactionsRow.first().isVisible(); + await expect(await interactionsRow.count()).toEqual(3); + }); }); From 529e75d464b28b33869c29cd423153e1e6c921e8 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 29 Nov 2022 13:03:47 +0100 Subject: [PATCH 5/8] add extra assertion in e2e test --- code/e2e-tests/addon-interactions.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/e2e-tests/addon-interactions.spec.ts b/code/e2e-tests/addon-interactions.spec.ts index 836f620f86de..548cd0564751 100644 --- a/code/e2e-tests/addon-interactions.spec.ts +++ b/code/e2e-tests/addon-interactions.spec.ts @@ -93,10 +93,12 @@ test.describe('addon-interactions', () => { await rerunInteractionButton.click(); await interactionsRow.first().isVisible(); await expect(await interactionsRow.count()).toEqual(3); + await expect(interactionsTab).toContainText(/(3)/); const remountComponentButton = await page.locator('[title="Remount component"]'); await remountComponentButton.click(); await interactionsRow.first().isVisible(); await expect(await interactionsRow.count()).toEqual(3); + await expect(interactionsTab).toContainText(/(3)/); }); }); From 9a1fce82226af8d7961bc136d4cef7c00ea6b2f2 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 29 Nov 2022 13:06:22 +0100 Subject: [PATCH 6/8] add comments --- code/e2e-tests/addon-interactions.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/e2e-tests/addon-interactions.spec.ts b/code/e2e-tests/addon-interactions.spec.ts index 548cd0564751..ea90e1db06ac 100644 --- a/code/e2e-tests/addon-interactions.spec.ts +++ b/code/e2e-tests/addon-interactions.spec.ts @@ -55,6 +55,7 @@ test.describe('addon-interactions', () => { await sbPage.navigateToStory('addons/interactions/basics', 'type-and-clear'); await sbPage.viewAddonPanel('Interactions'); + // Test initial state - Interactions have run, count is correct and values are as expected const formInput = await sbPage.previewRoot().locator('#interaction-test-form input'); await expect(formInput).toHaveValue('final value'); @@ -70,6 +71,7 @@ test.describe('addon-interactions', () => { await expect(panel).toContainText(/final value/); await expect(panel).toBeVisible(); + // Test interactions debugger - Stepping through works, count is correct and values are as expected const interactionsRow = await panel.locator('[aria-label="Interaction step"]'); await interactionsRow.first().isVisible(); @@ -89,12 +91,14 @@ test.describe('addon-interactions', () => { await expect(runStatusBadge).toContainText(/Pass/); + // Test rerun state (from addon panel) - Interactions have rerun, count is correct and values are as expected const rerunInteractionButton = await panel.locator('[aria-label="Rerun"]'); await rerunInteractionButton.click(); await interactionsRow.first().isVisible(); await expect(await interactionsRow.count()).toEqual(3); await expect(interactionsTab).toContainText(/(3)/); + // Test remount state (from toolbar) - Interactions have rerun, count is correct and values are as expected const remountComponentButton = await page.locator('[title="Remount component"]'); await remountComponentButton.click(); await interactionsRow.first().isVisible(); From 30642d29134f80e9ea30b03a8e29b0cda055adb6 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Wed, 30 Nov 2022 14:24:25 +0100 Subject: [PATCH 7/8] revamp tests --- .../addons/interactions/template/stories/basics.stories.ts | 7 ++++--- code/e2e-tests/addon-interactions.spec.ts | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/code/addons/interactions/template/stories/basics.stories.ts b/code/addons/interactions/template/stories/basics.stories.ts index a26a733d92b4..08de4183d9c1 100644 --- a/code/addons/interactions/template/stories/basics.stories.ts +++ b/code/addons/interactions/template/stories/basics.stories.ts @@ -31,9 +31,10 @@ export const Step = { export const TypeAndClear = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - await userEvent.type(canvas.getByTestId('value'), 'initial value'); - await userEvent.clear(canvas.getByTestId('value')); - await userEvent.type(canvas.getByTestId('value'), 'final value'); + // TODO: seems like userEvent.type + userEvent.clear + userEvent.type is not working for Svelte and Vue2/3. We should probably investigate, might be a bug in userEvent or in our implementation. + await fireEvent.input(canvas.getByTestId('value'), { target: { value: 'initial value' } }); + await fireEvent.input(canvas.getByTestId('value'), { target: { value: '' } }); + await fireEvent.input(canvas.getByTestId('value'), { target: { value: 'final value' } }); }, }; diff --git a/code/e2e-tests/addon-interactions.spec.ts b/code/e2e-tests/addon-interactions.spec.ts index ea90e1db06ac..a44f386bed57 100644 --- a/code/e2e-tests/addon-interactions.spec.ts +++ b/code/e2e-tests/addon-interactions.spec.ts @@ -66,9 +66,9 @@ test.describe('addon-interactions', () => { const panel = sbPage.panelContent(); const runStatusBadge = await panel.locator('[aria-label="Status of the test run"]'); await expect(runStatusBadge).toContainText(/Pass/); - await expect(panel).toContainText(/initial value/); - await expect(panel).toContainText(/userEvent.clear/); - await expect(panel).toContainText(/final value/); + await expect(panel).toContainText(/value: "initial value"/); + await expect(panel).toContainText(/value: ""/); + await expect(panel).toContainText(/value: "final value"/); await expect(panel).toBeVisible(); // Test interactions debugger - Stepping through works, count is correct and values are as expected From 084546bb301b83467c4bf78f51e853f1522a56f2 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Wed, 30 Nov 2022 15:28:02 +0100 Subject: [PATCH 8/8] fix prettier issue even though it seems like it's not fixing, it's actually breaking it --- .../src/components/InteractionsPanel.tsx | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/code/addons/interactions/src/components/InteractionsPanel.tsx b/code/addons/interactions/src/components/InteractionsPanel.tsx index a3478fc23fd9..c1a523cf2b38 100644 --- a/code/addons/interactions/src/components/InteractionsPanel.tsx +++ b/code/addons/interactions/src/components/InteractionsPanel.tsx @@ -98,20 +98,21 @@ export const InteractionsPanel: React.FC = React.memo( return ( - {controlStates.debugger && (interactions.length > 0 || hasException || isRerunAnimating) && ( - - )} + {controlStates.debugger && + (interactions.length > 0 || hasException || isRerunAnimating) && ( + + )}
{interactions.map((call) => (