From 7b8edc5142c2c3093a6c9a78182c7c0077d631a2 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Wed, 22 Nov 2023 23:30:11 +0100 Subject: [PATCH 1/5] SvelteKit: default to actions for goto, invalidate, invalidateall --- code/e2e-tests/framework-svelte.spec.ts | 37 +++++++++++++++++++ code/frameworks/sveltekit/src/preview.ts | 31 +++++++++++----- .../navigation.stories.js | 2 + .../navigation.stories.js | 2 + 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/code/e2e-tests/framework-svelte.spec.ts b/code/e2e-tests/framework-svelte.spec.ts index ceffacc525d7..7d4e94856a73 100644 --- a/code/e2e-tests/framework-svelte.spec.ts +++ b/code/e2e-tests/framework-svelte.spec.ts @@ -91,4 +91,41 @@ test.describe('SvelteKit', () => { }); await expect(complexLogItem).toBeVisible(); }); + + test('goto are logged in Actions panel', async ({ page }) => { + const sbPage = new SbPage(page); + + await sbPage.navigateToStory('stories/sveltekit/modules/navigation', 'default-actions'); + const root = sbPage.previewRoot(); + await sbPage.viewAddonPanel('Actions'); + + const goto = root.locator('button', { hasText: 'goto' }); + await goto.click(); + + const gotoLogItem = await page.locator('#storybook-panel-root #panel-tab-content', { + hasText: `/storybook`, + }); + await expect(gotoLogItem).toBeVisible(); + + const clear = root.locator('button', { hasText: 'Clear' }); + await clear.click(); + + const invalidate = root.locator('button', { hasText: 'invalidate' }); + await invalidate.click(); + + const invalidateLogItem = await page.locator('#storybook-panel-root #panel-tab-content', { + hasText: `/storybook`, + }); + await expect(invalidateLogItem).toBeVisible(); + + await clear.click(); + + const invalidateAll = root.locator('button', { hasText: 'invalidateAll' }); + await invalidateAll.click(); + + const invalidateAllLogItem = await page.locator('#storybook-panel-root #panel-tab-content', { + hasText: `invalidateAll`, + }); + await expect(invalidateAllLogItem).toBeVisible(); + }); }); diff --git a/code/frameworks/sveltekit/src/preview.ts b/code/frameworks/sveltekit/src/preview.ts index a43431b5103d..10affca46fc4 100644 --- a/code/frameworks/sveltekit/src/preview.ts +++ b/code/frameworks/sveltekit/src/preview.ts @@ -63,9 +63,14 @@ export const decorators: Decorator[] = [ * eg. storybook:goto, storybook:invalidateAll * @param baseModule the base module where the function lives (navigation|forms) * @param functions the list of functions in that module that emit events + * @param {boolean} [defaultToAction] the list of functions in that module that emit events * @returns a function to remove all the listener added */ - function createListeners(baseModule: keyof SvelteKitParameters, functions: string[]) { + function createListeners( + baseModule: keyof SvelteKitParameters, + functions: string[], + defaultToAction?: boolean + ) { // the array of every added listener, we can use this in the return function // to clean them const toRemove: Array<{ @@ -75,10 +80,11 @@ export const decorators: Decorator[] = [ functions.forEach((func) => { // we loop over every function and check if the user actually passed // a function in sveltekit_experimental[baseModule][func] eg. sveltekit_experimental.navigation.goto - if ( + const hasFunction = (svelteKitParameters as any)[baseModule]?.[func] && - (svelteKitParameters as any)[baseModule][func] instanceof Function - ) { + (svelteKitParameters as any)[baseModule][func] instanceof Function; + // if we default to an action we still add the listener (this will be the case for goto, invalidate, invalidateAll) + if (hasFunction || defaultToAction) { // we create the listener that will just get the detail array from the custom element // and call the user provided function spreading this args in...this will basically call // the function that the user provide with the same arguments the function is invoked to @@ -87,7 +93,12 @@ export const decorators: Decorator[] = [ // it provided to storybook will be called with "/my-route" const listener = ({ detail = [] as any[] }) => { const args = Array.isArray(detail) ? detail : []; - (svelteKitParameters as any)[baseModule][func](...args); + // if it has a function in the parameters we call that function + // otherwise we invoke the action + const fnToCall = hasFunction + ? (svelteKitParameters as any)[baseModule][func] + : action(func); + fnToCall(...args); }; const eventType = `storybook:${func}`; toRemove.push({ eventType, listener }); @@ -104,11 +115,11 @@ export const decorators: Decorator[] = [ }; } - const removeNavigationListeners = createListeners('navigation', [ - 'goto', - 'invalidate', - 'invalidateAll', - ]); + const removeNavigationListeners = createListeners( + 'navigation', + ['goto', 'invalidate', 'invalidateAll'], + true + ); const removeFormsListeners = createListeners('forms', ['enhance']); window.addEventListener('click', globalClickListener); diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js index 529997126f7c..4023bf4a41f2 100644 --- a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js @@ -25,6 +25,8 @@ export const Goto = { }, }; +export const DefaultActions = {}; + const invalidate = fn(); export const Invalidate = { diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js index 529997126f7c..4023bf4a41f2 100644 --- a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js @@ -25,6 +25,8 @@ export const Goto = { }, }; +export const DefaultActions = {}; + const invalidate = fn(); export const Invalidate = { From d0f87c74ef756fc4831d88f0fcd635ecdf6599ac Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Wed, 22 Nov 2023 23:37:23 +0100 Subject: [PATCH 2/5] update docs --- code/frameworks/sveltekit/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/code/frameworks/sveltekit/README.md b/code/frameworks/sveltekit/README.md index d9242efcdbf1..20248ce0d3f3 100644 --- a/code/frameworks/sveltekit/README.md +++ b/code/frameworks/sveltekit/README.md @@ -130,16 +130,16 @@ export const MyStory = { You can add the name of the module you want to mock to `parameters.sveltekit_experimental` (in the example above we are mocking the `stores` module which correspond to `$app/stores`) and then pass the following kind of objects: -| Module | Path in parameters | Kind of objects | -| ------------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- | -| `import { page } from "$app/stores"` | `parameters.sveltekit_experimental.stores.page` | A Partial of the page store | -| `import { navigating } from "$app/stores"` | `parameters.sveltekit_experimental.stores.navigating` | A Partial of the navigating store | -| `import { updated } from "$app/stores"` | `parameters.sveltekit_experimental.stores.updated` | A boolean representing the value of updated (you can also access `check()` which will be a noop) | -| `import { goto } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.goto` | A callback that will be called whenever goto is called | -| `import { invalidate } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidate` | A callback that will be called whenever invalidate is called | -| `import { invalidateAll } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidateAll` | A callback that will be called whenever invalidateAll is called | -| `import { afterNavigate } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.afterNavigate` | An object that will be passed to the afterNavigate function (which will be invoked onMount) called | -| `import { enhance } from "$app/forms"` | `parameters.sveltekit_experimental.forms.enhance` | A callback that will called when a form with `use:enhance` is submitted | +| Module | Path in parameters | Kind of objects | +| ------------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `import { page } from "$app/stores"` | `parameters.sveltekit_experimental.stores.page` | A Partial of the page store | +| `import { navigating } from "$app/stores"` | `parameters.sveltekit_experimental.stores.navigating` | A Partial of the navigating store | +| `import { updated } from "$app/stores"` | `parameters.sveltekit_experimental.stores.updated` | A boolean representing the value of updated (you can also access `check()` which will be a noop) | +| `import { goto } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.goto` | A callback that will be called whenever goto is called, in no function is provided an action will be logged to the Actions panel | +| `import { invalidate } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidate` | A callback that will be called whenever invalidate is called, in no function is provided an action will be logged to the Actions panel | +| `import { invalidateAll } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidateAll` | A callback that will be called whenever invalidateAll is called, in no function is provided an action will be logged to the Actions panel | +| `import { afterNavigate } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.afterNavigate` | An object that will be passed to the afterNavigate function (which will be invoked onMount) called | +| `import { enhance } from "$app/forms"` | `parameters.sveltekit_experimental.forms.enhance` | A callback that will called when a form with `use:enhance` is submitted | All the other functions are still exported as `noop` from the mocked modules so that your application will still work. From a76cd247b206f0d6876d1ffd03d1f6be824d91fa Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Thu, 23 Nov 2023 10:39:09 +0100 Subject: [PATCH 3/5] fix tests --- code/e2e-tests/framework-svelte.spec.ts | 9 ++------- .../stories_svelte-kit-skeleton-js/Navigation.svelte | 4 ++-- .../stories_svelte-kit-skeleton-js/navigation.stories.js | 4 ++-- .../stories_svelte-kit-skeleton-ts/Navigation.svelte | 4 ++-- .../stories_svelte-kit-skeleton-ts/navigation.stories.js | 4 ++-- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/code/e2e-tests/framework-svelte.spec.ts b/code/e2e-tests/framework-svelte.spec.ts index 7d4e94856a73..b80a23708ce5 100644 --- a/code/e2e-tests/framework-svelte.spec.ts +++ b/code/e2e-tests/framework-svelte.spec.ts @@ -103,23 +103,18 @@ test.describe('SvelteKit', () => { await goto.click(); const gotoLogItem = await page.locator('#storybook-panel-root #panel-tab-content', { - hasText: `/storybook`, + hasText: `/storybook-goto`, }); await expect(gotoLogItem).toBeVisible(); - const clear = root.locator('button', { hasText: 'Clear' }); - await clear.click(); - const invalidate = root.locator('button', { hasText: 'invalidate' }); await invalidate.click(); const invalidateLogItem = await page.locator('#storybook-panel-root #panel-tab-content', { - hasText: `/storybook`, + hasText: `/storybook-invalidate`, }); await expect(invalidateLogItem).toBeVisible(); - await clear.click(); - const invalidateAll = root.locator('button', { hasText: 'invalidateAll' }); await invalidateAll.click(); diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte index f857ae36a843..b923b8ee78d8 100644 --- a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte @@ -9,13 +9,13 @@ diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js index 4023bf4a41f2..ded12268e03c 100644 --- a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js @@ -14,7 +14,7 @@ export const Goto = { const canvas = within(canvasElement); const button = canvas.getByText('goto'); button.click(); - expect(goto).toHaveBeenCalledWith('/storybook'); + expect(goto).toHaveBeenCalledWith('/storybook-goto'); }, parameters: { sveltekit_experimental: { @@ -34,7 +34,7 @@ export const Invalidate = { const canvas = within(canvasElement); const button = canvas.getByText('invalidate', { exact: true }); button.click(); - expect(invalidate).toHaveBeenCalledWith('/storybook'); + expect(invalidate).toHaveBeenCalledWith('/storybook-invalidate'); }, parameters: { sveltekit_experimental: { diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Navigation.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Navigation.svelte index d97b6fe8a2df..4bcb7d0e6fc9 100644 --- a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Navigation.svelte +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Navigation.svelte @@ -8,13 +8,13 @@ diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js index 4023bf4a41f2..ded12268e03c 100644 --- a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js @@ -14,7 +14,7 @@ export const Goto = { const canvas = within(canvasElement); const button = canvas.getByText('goto'); button.click(); - expect(goto).toHaveBeenCalledWith('/storybook'); + expect(goto).toHaveBeenCalledWith('/storybook-goto'); }, parameters: { sveltekit_experimental: { @@ -34,7 +34,7 @@ export const Invalidate = { const canvas = within(canvasElement); const button = canvas.getByText('invalidate', { exact: true }); button.click(); - expect(invalidate).toHaveBeenCalledWith('/storybook'); + expect(invalidate).toHaveBeenCalledWith('/storybook-invalidate'); }, parameters: { sveltekit_experimental: { From 911f48a3545dd41ba9cf016b1fb931cfb4dc20de Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Thu, 23 Nov 2023 11:02:12 +0100 Subject: [PATCH 4/5] fix tests again --- code/e2e-tests/framework-svelte.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/e2e-tests/framework-svelte.spec.ts b/code/e2e-tests/framework-svelte.spec.ts index b80a23708ce5..e9744fcfa806 100644 --- a/code/e2e-tests/framework-svelte.spec.ts +++ b/code/e2e-tests/framework-svelte.spec.ts @@ -102,7 +102,7 @@ test.describe('SvelteKit', () => { const goto = root.locator('button', { hasText: 'goto' }); await goto.click(); - const gotoLogItem = await page.locator('#storybook-panel-root #panel-tab-content', { + const gotoLogItem = page.locator('#storybook-panel-root #panel-tab-content', { hasText: `/storybook-goto`, }); await expect(gotoLogItem).toBeVisible(); @@ -110,7 +110,7 @@ test.describe('SvelteKit', () => { const invalidate = root.locator('button', { hasText: 'invalidate' }); await invalidate.click(); - const invalidateLogItem = await page.locator('#storybook-panel-root #panel-tab-content', { + const invalidateLogItem = page.locator('#storybook-panel-root #panel-tab-content', { hasText: `/storybook-invalidate`, }); await expect(invalidateLogItem).toBeVisible(); @@ -118,8 +118,8 @@ test.describe('SvelteKit', () => { const invalidateAll = root.locator('button', { hasText: 'invalidateAll' }); await invalidateAll.click(); - const invalidateAllLogItem = await page.locator('#storybook-panel-root #panel-tab-content', { - hasText: `invalidateAll`, + const invalidateAllLogItem = page.locator('#storybook-panel-root #panel-tab-content', { + hasText: `"invalidateAll"`, }); await expect(invalidateAllLogItem).toBeVisible(); }); From 3546b4549e028759b04b960d48e89edced5de44a Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Thu, 23 Nov 2023 11:07:25 +0100 Subject: [PATCH 5/5] fix tests once again --- code/e2e-tests/framework-svelte.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/e2e-tests/framework-svelte.spec.ts b/code/e2e-tests/framework-svelte.spec.ts index e9744fcfa806..40d2b7f817dd 100644 --- a/code/e2e-tests/framework-svelte.spec.ts +++ b/code/e2e-tests/framework-svelte.spec.ts @@ -107,7 +107,7 @@ test.describe('SvelteKit', () => { }); await expect(gotoLogItem).toBeVisible(); - const invalidate = root.locator('button', { hasText: 'invalidate' }); + const invalidate = root.getByRole('button', { name: 'invalidate', exact: true }); await invalidate.click(); const invalidateLogItem = page.locator('#storybook-panel-root #panel-tab-content', { @@ -115,7 +115,7 @@ test.describe('SvelteKit', () => { }); await expect(invalidateLogItem).toBeVisible(); - const invalidateAll = root.locator('button', { hasText: 'invalidateAll' }); + const invalidateAll = root.getByRole('button', { name: 'invalidateAll' }); await invalidateAll.click(); const invalidateAllLogItem = page.locator('#storybook-panel-root #panel-tab-content', {