Skip to content

Commit

Permalink
Merge pull request #397 from storybookjs/fix/browser-crash-on-uncaugh…
Browse files Browse the repository at this point in the history
…t-error

Fix crash on uncaught page errors
  • Loading branch information
yannbf committed Nov 20, 2023
2 parents 7edc4f2 + 2d2bbcc commit 64c9b3b
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 207 deletions.
9 changes: 8 additions & 1 deletion playwright/jest-setup.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
const { getTestRunnerConfig, setPreVisit, setPostVisit, setupPage } = require('../dist');
const {
getTestRunnerConfig,
setPreVisit,
setPostVisit,
setupPage,
throwUncaughtPageError,
} = require('../dist');

const testRunnerConfig = getTestRunnerConfig(process.env.STORYBOOK_CONFIG_DIR);
if (testRunnerConfig) {
Expand All @@ -21,4 +27,5 @@ if (testRunnerConfig) {
// If the transformed tests need a dependency, it has to be globally available
// in order to work both in default (file transformation) and stories/index.json mode.
globalThis.__sbSetupPage = setupPage;
globalThis.__sbThrowUncaughtPageError = throwUncaughtPageError;
globalThis.__sbCollectCoverage = process.env.STORYBOOK_COLLECT_COVERAGE === 'true';
1 change: 1 addition & 0 deletions src/config/jest-playwright.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export const getJestConfig = () => {
.map((p) => p.trim().toLowerCase())
.filter(Boolean),
collectCoverage: STORYBOOK_COLLECT_COVERAGE === 'true',
exitOnPageError: false,
},
},
watchPlugins: [
Expand Down
16 changes: 16 additions & 0 deletions src/playwright/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { BrowserContext, Page } from 'playwright';
import type { StoryContext } from '@storybook/csf';
import dedent from 'ts-dedent';

export type TestContext = {
id: string;
Expand Down Expand Up @@ -80,3 +81,18 @@ export const waitForPageReady = async (page: Page) => {
await page.waitForLoadState('networkidle');
await page.evaluate(() => document.fonts.ready);
};

export const throwUncaughtPageError = (err: Error, context: TestContext) => {
const storybookUrl = process.env.REFERENCE_URL || process.env.TARGET_URL;
const storyUrl = `${storybookUrl}?path=/story/${context.id}`;

const errorMessage = dedent`
An uncaught error occurred when visiting the following story.
Please access the link and check the logs in the browser:
${storyUrl}
Message:
${err.stack || err.message}\n`;

throw new Error(errorMessage);
};
140 changes: 50 additions & 90 deletions src/playwright/transformPlaywright.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,10 @@ describe('Playwright', () => {
title: "Example/foo/bar",
name: "A"
};
page.on('pageerror', err => {
page.evaluate(({
id,
err
}) => __throwError(id, err), {
id: "example-foo-bar--a",
err: err.message
});
});
const onPageError = err => {
globalThis.__sbThrowUncaughtPageError(err, context);
};
page.on('pageerror', onPageError);
if (globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
}
Expand All @@ -96,6 +91,7 @@ describe('Playwright', () => {
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
try {
Expand All @@ -120,15 +116,10 @@ describe('Playwright', () => {
title: "Example/foo/bar",
name: "B"
};
page.on('pageerror', err => {
page.evaluate(({
id,
err
}) => __throwError(id, err), {
id: "example-foo-bar--b",
err: err.message
});
});
const onPageError = err => {
globalThis.__sbThrowUncaughtPageError(err, context);
};
page.on('pageerror', onPageError);
if (globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
}
Expand All @@ -150,6 +141,7 @@ describe('Playwright', () => {
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
try {
Expand Down Expand Up @@ -192,15 +184,10 @@ describe('Playwright', () => {
title: "Example/foo/bar",
name: "B"
};
page.on('pageerror', err => {
page.evaluate(({
id,
err
}) => __throwError(id, err), {
id: "example-foo-bar--b",
err: err.message
});
});
const onPageError = err => {
globalThis.__sbThrowUncaughtPageError(err, context);
};
page.on('pageerror', onPageError);
if (globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
}
Expand All @@ -222,6 +209,7 @@ describe('Playwright', () => {
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
try {
Expand Down Expand Up @@ -264,15 +252,10 @@ describe('Playwright', () => {
title: "Example/foo/bar",
name: "A"
};
page.on('pageerror', err => {
page.evaluate(({
id,
err
}) => __throwError(id, err), {
id: "example-foo-bar--a",
err: err.message
});
});
const onPageError = err => {
globalThis.__sbThrowUncaughtPageError(err, context);
};
page.on('pageerror', onPageError);
if (globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
}
Expand All @@ -294,6 +277,7 @@ describe('Playwright', () => {
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
try {
Expand All @@ -318,15 +302,10 @@ describe('Playwright', () => {
title: "Example/foo/bar",
name: "B"
};
page.on('pageerror', err => {
page.evaluate(({
id,
err
}) => __throwError(id, err), {
id: "example-foo-bar--b",
err: err.message
});
});
const onPageError = err => {
globalThis.__sbThrowUncaughtPageError(err, context);
};
page.on('pageerror', onPageError);
if (globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
}
Expand All @@ -348,6 +327,7 @@ describe('Playwright', () => {
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
try {
Expand Down Expand Up @@ -399,15 +379,10 @@ describe('Playwright', () => {
title: "Example/foo/bar",
name: "B"
};
page.on('pageerror', err => {
page.evaluate(({
id,
err
}) => __throwError(id, err), {
id: "example-foo-bar--b",
err: err.message
});
});
const onPageError = err => {
globalThis.__sbThrowUncaughtPageError(err, context);
};
page.on('pageerror', onPageError);
if (globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
}
Expand All @@ -429,6 +404,7 @@ describe('Playwright', () => {
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
try {
Expand All @@ -453,15 +429,10 @@ describe('Playwright', () => {
title: "Example/foo/bar",
name: "C"
};
page.on('pageerror', err => {
page.evaluate(({
id,
err
}) => __throwError(id, err), {
id: "example-foo-bar--c",
err: err.message
});
});
const onPageError = err => {
globalThis.__sbThrowUncaughtPageError(err, context);
};
page.on('pageerror', onPageError);
if (globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
}
Expand All @@ -483,6 +454,7 @@ describe('Playwright', () => {
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
try {
Expand Down Expand Up @@ -539,15 +511,10 @@ describe('Playwright', () => {
title: "Example/foo/bar",
name: "A"
};
page.on('pageerror', err => {
page.evaluate(({
id,
err
}) => __throwError(id, err), {
id: "example-foo-bar--a",
err: err.message
});
});
const onPageError = err => {
globalThis.__sbThrowUncaughtPageError(err, context);
};
page.on('pageerror', onPageError);
if (globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
}
Expand All @@ -569,6 +536,7 @@ describe('Playwright', () => {
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
try {
Expand Down Expand Up @@ -609,15 +577,10 @@ describe('Playwright', () => {
title: "Example/foo/bar",
name: "A"
};
page.on('pageerror', err => {
page.evaluate(({
id,
err
}) => __throwError(id, err), {
id: "example-foo-bar--a",
err: err.message
});
});
const onPageError = err => {
globalThis.__sbThrowUncaughtPageError(err, context);
};
page.on('pageerror', onPageError);
if (globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
}
Expand All @@ -639,6 +602,7 @@ describe('Playwright', () => {
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
try {
Expand Down Expand Up @@ -679,15 +643,10 @@ describe('Playwright', () => {
title: "Example/Header",
name: "A"
};
page.on('pageerror', err => {
page.evaluate(({
id,
err
}) => __throwError(id, err), {
id: "example-header--a",
err: err.message
});
});
const onPageError = err => {
globalThis.__sbThrowUncaughtPageError(err, context);
};
page.on('pageerror', onPageError);
if (globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
}
Expand All @@ -709,6 +668,7 @@ describe('Playwright', () => {
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
try {
Expand Down
12 changes: 8 additions & 4 deletions src/playwright/transformPlaywright.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ export const testPrefixer = template(
async () => {
const testFn = async() => {
const context = { id: %%id%%, title: %%title%%, name: %%name%% };
const onPageError = (err) => {
globalThis.__sbThrowUncaughtPageError(err, context);
}
page.on('pageerror', (err) => {
page.evaluate(({ id, err }) => __throwError(id, err), { id: %%id%%, err: err.message });
});
page.on('pageerror', onPageError);
if(globalThis.__sbPreVisit) {
await globalThis.__sbPreVisit(page, context);
Expand All @@ -37,14 +39,16 @@ export const testPrefixer = template(
}
if(globalThis.__sbCollectCoverage) {
const isCoverageSetupCorrectly = await page.evaluate(() => '__coverage__' in window);
const isCoverageSetupCorrectly = await page.evaluate(() => '__coverage__' in window);
if (!isCoverageSetupCorrectly) {
throw new Error(\`${coverageErrorMessage}\`);
}
await jestPlaywright.saveCoverage(page);
}
page.off('pageerror', onPageError);
return result;
};
Expand Down

0 comments on commit 64c9b3b

Please sign in to comment.