diff --git a/code/e2e-tests/module-mocking.spec.ts b/code/e2e-tests/module-mocking.spec.ts new file mode 100644 index 000000000000..8b6b43713b61 --- /dev/null +++ b/code/e2e-tests/module-mocking.spec.ts @@ -0,0 +1,49 @@ +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('module-mocking', () => { + test.beforeEach(async ({ page }) => { + await page.goto(storybookUrl); + + await new SbPage(page).waitUntilLoaded(); + }); + + test('should assert story lifecycle order', async ({ page }) => { + const sbPage = new SbPage(page); + + await sbPage.navigateToStory('lib/test/before-each', 'before-each-order'); + + await sbPage.viewAddonPanel('Actions'); + const logItem = await page.locator('#storybook-panel-root #panel-tab-content'); + await expect(logItem).toBeVisible(); + + const expectedTexts = [ + '1 - [from loaders]', + '2 - [from meta beforeEach]', + '3 - [from story beforeEach]', + '4 - [from decorator]', + '5 - [from onClick]', + ]; + + // Assert that each LI text content contains the expected text in order + for (let i = 0; i < expectedTexts.length; i++) { + const nthText = await logItem.locator(`li >> nth=${i}`).innerText(); + expect(nthText).toMatch(expectedTexts[i]); + } + }); + + test('should assert that utils import is mocked', async ({ page }) => { + const sbPage = new SbPage(page); + + await sbPage.navigateToStory('lib/test/module-mocking', 'basic'); + + await sbPage.viewAddonPanel('Actions'); + const logItem = await page.locator('#storybook-panel-root #panel-tab-content', { + hasText: 'foo: []', + }); + await expect(logItem).toBeVisible(); + }); +}); diff --git a/code/lib/test/template/stories/before-each.stories.ts b/code/lib/test/template/stories/before-each.stories.ts index 9af203a7baaf..a6f613e7698c 100644 --- a/code/lib/test/template/stories/before-each.stories.ts +++ b/code/lib/test/template/stories/before-each.stories.ts @@ -2,9 +2,12 @@ import { expect, mocked, getByRole, spyOn, userEvent } from '@storybook/test'; const meta = { component: globalThis.Components.Button, - beforeEach() { + loaders() { spyOn(console, 'log').mockName('console.log'); - console.log('first'); + console.log('1 - [from loaders]'); + }, + beforeEach() { + console.log('2 - [from meta beforeEach]'); }, }; @@ -15,17 +18,27 @@ export const BeforeEachOrder = { chromatic: { disable: true }, }, beforeEach() { - console.log('second'); + console.log('3 - [from story beforeEach]'); + }, + decorators: (StoryFn: any) => { + console.log('4 - [from decorator]'); + return StoryFn(); }, args: { label: 'Button', onClick: () => { - console.log('third'); + console.log('5 - [from onClick]'); }, }, - async play({ canvasElement }) { + async play({ canvasElement }: any) { await userEvent.click(getByRole(canvasElement, 'button')); - await expect(mocked(console.log).mock.calls).toEqual([['first'], ['second'], ['third']]); + await expect(mocked(console.log).mock.calls).toEqual([ + ['1 - [from loaders]'], + ['2 - [from meta beforeEach]'], + ['3 - [from story beforeEach]'], + ['4 - [from decorator]'], + ['5 - [from onClick]'], + ]); }, }; diff --git a/code/lib/test/template/stories/utils.mock.ts b/code/lib/test/template/stories/utils.mock.ts index 15c648e88c00..80fac1f308f2 100644 --- a/code/lib/test/template/stories/utils.mock.ts +++ b/code/lib/test/template/stories/utils.mock.ts @@ -1,4 +1,4 @@ import { fn } from '@storybook/test'; import * as utils from './utils'; -export const foo = fn(utils.foo); +export const foo = fn(utils.foo).mockName('foo'); diff --git a/code/presets/create-react-app/src/index.ts b/code/presets/create-react-app/src/index.ts index 2fc78a1cfa0d..a6664fded0e7 100644 --- a/code/presets/create-react-app/src/index.ts +++ b/code/presets/create-react-app/src/index.ts @@ -126,6 +126,14 @@ const webpack = async ( ...getModulePath(CWD), ], plugins: [PnpWebpackPlugin as any], + // manual copy from builder-webpack because defaults are disabled in this CRA preset + conditionNames: [ + ...(webpackConfig.resolve?.conditionNames ?? []), + 'storybook', + 'stories', + 'test', + '...', + ], }, resolveLoader, } as Configuration;