From 1f25446d70995c41b38733f893dba13dfdac38bb Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Sat, 22 Jun 2024 12:46:59 +0200 Subject: [PATCH] apply error formatting to all error events --- .storybook/test-runner.ts | 5 ++- src/setup-page-script.ts | 56 ++++++++++++++++++-------------- src/setup-page.ts | 2 +- stories/atoms/Button.stories.tsx | 3 +- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/.storybook/test-runner.ts b/.storybook/test-runner.ts index 3a698a13..c1038230 100644 --- a/.storybook/test-runner.ts +++ b/.storybook/test-runner.ts @@ -8,9 +8,8 @@ const skipSnapshots = process.env.SKIP_SNAPSHOTS === 'true'; const config: TestRunnerConfig = { logLevel: 'verbose', - errorMessageFormatter: (error) => { - // DO NOT MERGE WITH THIS CHANGE - return 'FORMATTED! ' + error.substring(0, 10); + errorMessageFormatter: (message) => { + return message; }, tags: { exclude: ['exclude'], diff --git a/src/setup-page-script.ts b/src/setup-page-script.ts index 99cd3053..6e9d1244 100644 --- a/src/setup-page-script.ts +++ b/src/setup-page-script.ts @@ -31,7 +31,7 @@ const TEST_RUNNER_DEBUG_PRINT_LIMIT = parseInt('{{debugPrintLimit}}', 10); declare global { // this is defined in setup-page.ts and can be used for logging from the browser to node, helpful for debugging var logToPage: (message: string) => void; - var getFormattedMessage: (message: string) => Promise; + var testRunner_errorMessageFormatter: (message: string) => Promise; } // Type definitions for function parameters and return types @@ -212,11 +212,12 @@ class StorybookTestRunnerError extends Error { logs: string[] = [], isMessageFormatted: boolean = false ) { - super(errorMessage); - this.name = 'StorybookTestRunnerError'; - this.message = isMessageFormatted + const message = isMessageFormatted ? errorMessage : StorybookTestRunnerError.buildErrorMessage(storyId, errorMessage, logs); + super(message); + + this.name = 'StorybookTestRunnerError'; } public static buildErrorMessage( @@ -369,13 +370,32 @@ async function __test(storyId: string): Promise { }; return new Promise((resolve, reject) => { + const rejectWithFormattedError = (storyId: string, message: string) => { + const errorMessage = StorybookTestRunnerError.buildErrorMessage(storyId, message, logs); + + testRunner_errorMessageFormatter(errorMessage) + .then((formattedMessage) => { + reject(new StorybookTestRunnerError(storyId, formattedMessage, logs, true)); + }) + .catch((error) => { + reject( + new StorybookTestRunnerError( + storyId, + 'There was an error when executing the errorMessageFormatter defiend in your Storybook test-runner config file. Please fix it and rerun the tests:\n\n' + + error.message + ) + ); + }); + }; + const listeners = { [TEST_RUNNER_RENDERED_EVENT]: () => { cleanup(listeners); if (hasErrors) { - reject(new StorybookTestRunnerError(storyId, 'Browser console errors', logs)); + rejectWithFormattedError(storyId, 'Browser console errors'); + } else { + resolve(document.getElementById('root')); } - resolve(document.getElementById('root')); }, storyUnchanged: () => { @@ -385,43 +405,29 @@ async function __test(storyId: string): Promise { storyErrored: ({ description }: { description: string }) => { cleanup(listeners); - reject(new StorybookTestRunnerError(storyId, description, logs)); + rejectWithFormattedError(storyId, description); }, storyThrewException: (error: Error) => { cleanup(listeners); - reject(new StorybookTestRunnerError(storyId, error.message, logs)); + rejectWithFormattedError(storyId, error.message); }, playFunctionThrewException: (error: Error) => { cleanup(listeners); - const errorMessage = StorybookTestRunnerError.buildErrorMessage( - storyId, - error.message, - logs - ); - - getFormattedMessage(errorMessage).then((message) => { - reject(new StorybookTestRunnerError(storyId, message, logs, true)); - }); + rejectWithFormattedError(storyId, error.message); }, unhandledErrorsWhilePlaying: ([error]: Error[]) => { cleanup(listeners); - reject(new StorybookTestRunnerError(storyId, error.message, logs)); + rejectWithFormattedError(storyId, error.message); }, storyMissing: (id: string) => { cleanup(listeners); if (id === storyId) { - reject( - new StorybookTestRunnerError( - storyId, - 'The story was missing when trying to access it.', - logs - ) - ); + rejectWithFormattedError(storyId, 'The story was missing when trying to access it.'); } }, }; diff --git a/src/setup-page.ts b/src/setup-page.ts index 4f82f557..c96394ec 100644 --- a/src/setup-page.ts +++ b/src/setup-page.ts @@ -61,7 +61,7 @@ export const setupPage = async (page: Page, browserContext: BrowserContext) => { // if we ever want to log something from the browser to node await page.exposeBinding('logToPage', (_, message) => console.log(message)); - await page.exposeBinding('getFormattedMessage', (_, message: string) => { + await page.exposeBinding('testRunner_errorMessageFormatter', (_, message: string) => { if (testRunnerConfig.errorMessageFormatter) { return testRunnerConfig.errorMessageFormatter(message); } diff --git a/stories/atoms/Button.stories.tsx b/stories/atoms/Button.stories.tsx index 57a63267..ed66dab6 100644 --- a/stories/atoms/Button.stories.tsx +++ b/stories/atoms/Button.stories.tsx @@ -124,8 +124,7 @@ export const WithLoaders = { const canvas = within(canvasElement); const todoItem = await canvas.findByText('Todo: delectus aut autem'); await userEvent.click(todoItem); - // DO NOT MERGE WITH THIS CHANGE - await expect(args.onSubmit).not.toHaveBeenCalledWith('delectus aut autem'); + await expect(args.onSubmit).toHaveBeenCalledWith('delectus aut autem'); }, };