From 2b29cfbce1401c59fc83f093aec123e029ea5972 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 2 Oct 2023 16:12:16 +0200 Subject: [PATCH 1/3] Add code to let the preview decide which story to view if the URL doesn't specify the full ID. Add e2e test for this behavior. --- code/e2e-tests/navigation.spec.ts | 18 ++++++++++++++++++ code/lib/manager-api/src/modules/stories.ts | 7 +++++-- 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 code/e2e-tests/navigation.spec.ts diff --git a/code/e2e-tests/navigation.spec.ts b/code/e2e-tests/navigation.spec.ts new file mode 100644 index 000000000000..a1ec56afedc1 --- /dev/null +++ b/code/e2e-tests/navigation.spec.ts @@ -0,0 +1,18 @@ +import { test, expect } from '@playwright/test'; +import process from 'process'; +import { SbPage } from './util'; + +const storybookUrl = process.env.STORYBOOK_URL || 'http://localhost:8001'; + +test.describe('navigating', () => { + test('a URL with a partial storyId will redirect to the first story', async ({ page }) => { + // this is purposefully not using the SbPage class, and the URL is a partial (it does not contain the full storyId) + await page.goto(`${storybookUrl}?path=/story/example-button`); + + const sbPage = new SbPage(page); + + await sbPage.waitUntilLoaded(); + + await expect(sbPage.page.waitForURL('?path=/docs/example-button--docs')).resolves.toBeTruthy(); + }); +}); diff --git a/code/lib/manager-api/src/modules/stories.ts b/code/lib/manager-api/src/modules/stories.ts index aff85aabcea3..7fa86bdff822 100644 --- a/code/lib/manager-api/src/modules/stories.ts +++ b/code/lib/manager-api/src/modules/stories.ts @@ -637,15 +637,18 @@ export const init: ModuleFn = ({ state.path === '/' || state.viewMode === 'story' || state.viewMode === 'docs'; const stateHasSelection = state.viewMode && state.storyId; const stateSelectionDifferent = state.viewMode !== viewMode || state.storyId !== storyId; + const { type } = state.index[state.storyId]; + const isStory = !(type === 'root' || type === 'component' || type === 'group'); + /** * When storybook starts, we want to navigate to the first story. * But there are a few exceptions: - * - If the current storyId and viewMode are already set/correct. + * - If the current storyId and viewMode are already set/correct AND the url section is a leaf-type. * - If the user has navigated away already. * - If the user started storybook with a specific page-URL like "/settings/about" */ if (isCanvasRoute) { - if (stateHasSelection && stateSelectionDifferent) { + if (stateHasSelection && stateSelectionDifferent && isStory) { // The manager state is correct, the preview state is lagging behind provider.channel.emit(SET_CURRENT_STORY, { storyId: state.storyId, From dee3552b367423f1ba02cf3bef4b52d06b193542 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 2 Oct 2023 17:09:46 +0200 Subject: [PATCH 2/3] fix unit test --- code/lib/manager-api/src/modules/stories.ts | 2 +- code/lib/manager-api/src/tests/stories.test.ts | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/code/lib/manager-api/src/modules/stories.ts b/code/lib/manager-api/src/modules/stories.ts index 7fa86bdff822..07d6fb702d30 100644 --- a/code/lib/manager-api/src/modules/stories.ts +++ b/code/lib/manager-api/src/modules/stories.ts @@ -637,7 +637,7 @@ export const init: ModuleFn = ({ state.path === '/' || state.viewMode === 'story' || state.viewMode === 'docs'; const stateHasSelection = state.viewMode && state.storyId; const stateSelectionDifferent = state.viewMode !== viewMode || state.storyId !== storyId; - const { type } = state.index[state.storyId]; + const { type } = state.index[state.storyId] || {}; const isStory = !(type === 'root' || type === 'component' || type === 'group'); /** diff --git a/code/lib/manager-api/src/tests/stories.test.ts b/code/lib/manager-api/src/tests/stories.test.ts index a93cd1df9a99..a6617bce9f41 100644 --- a/code/lib/manager-api/src/tests/stories.test.ts +++ b/code/lib/manager-api/src/tests/stories.test.ts @@ -542,7 +542,7 @@ describe('stories API', () => { describe('STORY_SPECIFIED event', () => { it('navigates to the story', async () => { - const moduleArgs = createMockModuleArgs({ initialState: { path: '/' } }); + const moduleArgs = createMockModuleArgs({ initialState: { path: '/', index: {} } }); initStories(moduleArgs as unknown as ModuleArgs); const { navigate, provider } = moduleArgs; @@ -550,7 +550,7 @@ describe('stories API', () => { expect(navigate).toHaveBeenCalledWith('/story/a--1'); }); it('DOES not navigate if the story was already selected', async () => { - const moduleArgs = createMockModuleArgs({ initialState: { path: '/story/a--1' } }); + const moduleArgs = createMockModuleArgs({ initialState: { path: '/story/a--1', index: {} } }); initStories(moduleArgs as unknown as ModuleArgs); const { navigate, provider } = moduleArgs; @@ -558,7 +558,9 @@ describe('stories API', () => { expect(navigate).not.toHaveBeenCalled(); }); it('DOES not navigate if a settings page was selected', async () => { - const moduleArgs = createMockModuleArgs({ initialState: { path: '/settings/about' } }); + const moduleArgs = createMockModuleArgs({ + initialState: { path: '/settings/about', index: {} }, + }); initStories(moduleArgs as unknown as ModuleArgs); const { navigate, provider } = moduleArgs; @@ -566,7 +568,9 @@ describe('stories API', () => { expect(navigate).not.toHaveBeenCalled(); }); it('DOES not navigate if a custom page was selected', async () => { - const moduleArgs = createMockModuleArgs({ initialState: { path: '/custom/page' } }); + const moduleArgs = createMockModuleArgs({ + initialState: { path: '/custom/page', index: {} }, + }); initStories(moduleArgs as unknown as ModuleArgs); const { navigate, provider } = moduleArgs; From 4c49a5ae380357a8629c64962b3cac52be3e77be Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 3 Oct 2023 09:53:19 +0200 Subject: [PATCH 3/3] change test, to hopefully also pass on CI --- code/e2e-tests/navigation.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/e2e-tests/navigation.spec.ts b/code/e2e-tests/navigation.spec.ts index a1ec56afedc1..a4c68bdaee36 100644 --- a/code/e2e-tests/navigation.spec.ts +++ b/code/e2e-tests/navigation.spec.ts @@ -13,6 +13,6 @@ test.describe('navigating', () => { await sbPage.waitUntilLoaded(); - await expect(sbPage.page.waitForURL('?path=/docs/example-button--docs')).resolves.toBeTruthy(); + await expect(sbPage.page.url()).toContain('/docs/example-button--docs'); }); });