Skip to content

Commit b8d7747

Browse files
bjohansebasclaude
andcommitted
test(e2e): accumulate runtime errors in the browser and settle on webpack 5.109
Runtime-error accumulation (two errors paging "1 / 2" ↔ "2 / 2") and unhandled promise rejections now run against real page errors — the rejection fixture rejects from the page's own script so the event carries the real reason. Their jsdom equivalents are removed. The branch also settles on webpack 5.109: the lockfile catches up with the already-bumped range, and the assertions and console snapshots adopt 5.109's parse-error format (numbered code-frame gutter, caret line, and the "File was parsed as module type" note) instead of normalizing it away. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 847721e commit b8d7747

6 files changed

Lines changed: 85 additions & 52 deletions

File tree

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/e2e/__snapshots__/logging.test.js.snap.webpack5

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ exports[`client logging (browser) logging=error keeps errors only 1`] = `
55
"[webpack-dev-middleware] bundle has 1 errors",
66
"[webpack-dev-middleware] ./app.js 1:7
77
Module parse failed: Unexpected token (1:7)
8+
File was parsed as module type 'javascript/auto'.
89
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
9-
> broken {{{",
10+
> 1 | broken {{{
11+
| ^",
1012
]
1113
`;
1214

test/e2e/__snapshots__/overlay.test.js.snap.webpack5

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ exports[`error overlay (browser) paginates multiple problems with a counter 1`]
66
"[webpack-dev-middleware] bundle has 2 errors",
77
"[webpack-dev-middleware] ./a.js 1:7
88
Module parse failed: Unexpected token (1:7)
9+
File was parsed as module type 'javascript/auto'.
910
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
10-
> broken a {{{
11+
> 1 | broken a {{{
12+
| ^
1113
./b.js 1:7
1214
Module parse failed: Unexpected token (1:7)
15+
File was parsed as module type 'javascript/auto'.
1316
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
14-
> broken b {{{",
17+
> 1 | broken b {{{
18+
| ^",
1519
]
1620
`;

test/e2e/multi-compiler.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ describe("multi-compiler (browser)", () => {
190190
const secondPage = await frame.evaluate(() => document.body.textContent);
191191
const union = firstPage + secondPage;
192192

193-
expect(union).toContain("> broken app");
194-
expect(union).toContain("> broken widget");
193+
expect(union).toContain("broken app {{{");
194+
expect(union).toContain("broken widget {{{");
195195
});
196196

197197
it("keeps one bundle's overlay errors while a sibling rebuilds successfully", async () => {

test/e2e/overlay.test.js

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ describe("error overlay (browser)", () => {
300300

301301
// Both errors also reach the console, joined into a single error call —
302302
// snapshotted once the second one's code frame is in.
303-
await console_.waitFor("> broken b");
303+
await console_.waitFor("broken b {{{");
304304
expect(normalizeConsole(console_.messages)).toMatchSnapshot();
305305

306306
// One problem at a time, with a counter.
@@ -318,6 +318,77 @@ describe("error overlay (browser)", () => {
318318
);
319319
});
320320

321+
it("accumulates runtime errors and pages between them", async () => {
322+
hotApp = await createHotApp({
323+
code: `
324+
document.getElementById("app").textContent = "v1";
325+
globalThis.boom = (message) => {
326+
setTimeout(() => {
327+
throw new Error(message);
328+
}, 0);
329+
};
330+
`,
331+
});
332+
({ page, browser } = await runBrowser());
333+
334+
await page.goto(hotApp.url);
335+
await page.waitForFunction(
336+
() => document.getElementById("app")?.textContent === "v1",
337+
);
338+
339+
await page.evaluate(() => globalThis.boom("boom-one"));
340+
const frame = await waitForOverlay(page);
341+
await frame.waitForFunction(() =>
342+
document.body.textContent.includes("boom-one"),
343+
);
344+
345+
// A second error joins the pager; the newest one is shown.
346+
await page.evaluate(() => globalThis.boom("boom-two"));
347+
await frame.waitForFunction(
348+
() =>
349+
document.body.textContent.includes("boom-two") &&
350+
document.body.textContent.includes("2 / 2"),
351+
);
352+
353+
// The previous error stays reachable.
354+
await frame.click('[aria-label="Previous problem"]');
355+
await frame.waitForFunction(() =>
356+
document.body.textContent.includes("boom-one"),
357+
);
358+
expect(await frame.evaluate(() => document.body.textContent)).toContain(
359+
"1 / 2",
360+
);
361+
});
362+
363+
it("shows unhandled promise rejections", async () => {
364+
hotApp = await createHotApp({
365+
// The rejection must originate from the page's own script so the
366+
// unhandledrejection event carries the real reason.
367+
code: `
368+
document.getElementById("app").textContent = "v1";
369+
globalThis.rejectSoon = (message) => {
370+
setTimeout(() => {
371+
Promise.reject(new Error(message));
372+
}, 0);
373+
};
374+
`,
375+
});
376+
({ page, browser } = await runBrowser());
377+
378+
await page.goto(hotApp.url);
379+
await page.waitForFunction(
380+
() => document.getElementById("app")?.textContent === "v1",
381+
);
382+
383+
await page.evaluate(() => globalThis.rejectSoon("rejected-boom"));
384+
385+
const frame = await waitForOverlay(page);
386+
387+
expect(await frame.evaluate(() => document.body.textContent)).toContain(
388+
"rejected-boom",
389+
);
390+
});
391+
321392
it("does not appear when overlay=false", async () => {
322393
hotApp = await createHotApp({ query: "?overlay=false", code: app("v1") });
323394
({ page, browser } = await runBrowser());

test/overlay.test.js

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -133,50 +133,6 @@ describe("overlay", () => {
133133
});
134134

135135
describe("runtime errors", () => {
136-
it("shows uncaught errors in the overlay and accumulates them", () => {
137-
configureOverlay({ catchRuntimeError: true });
138-
139-
globalThis.dispatchEvent(
140-
new ErrorEvent("error", {
141-
error: new Error("boom-runtime"),
142-
message: "boom-runtime",
143-
}),
144-
);
145-
146-
expect(getOverlay()).not.toBeNull();
147-
expect(getCard().textContent).toContain(
148-
"Uncaught runtime error: boom-runtime",
149-
);
150-
151-
globalThis.dispatchEvent(
152-
new ErrorEvent("error", {
153-
error: new Error("boom-2"),
154-
message: "boom-2",
155-
}),
156-
);
157-
158-
// With pagination (default) the newest runtime error is shown, and the
159-
// previous one stays reachable.
160-
expect(getCard().textContent).toContain("boom-2");
161-
expect(getCard().textContent).toContain("2 / 2");
162-
163-
getOverlay().contentDocument.dispatchEvent(
164-
new KeyboardEvent("keydown", { key: "ArrowLeft" }),
165-
);
166-
expect(getCard().textContent).toContain("boom-runtime");
167-
});
168-
169-
it("shows unhandled promise rejections", () => {
170-
configureOverlay({ catchRuntimeError: true });
171-
172-
const event = new Event("unhandledrejection");
173-
/** @type {EXPECTED_ANY} */ (event).reason = new Error("rejected-boom");
174-
globalThis.dispatchEvent(event);
175-
176-
expect(getOverlay()).not.toBeNull();
177-
expect(getCard().textContent).toContain("rejected-boom");
178-
});
179-
180136
it("ignores errors already caught by a React error boundary", () => {
181137
configureOverlay({ catchRuntimeError: true });
182138

0 commit comments

Comments
 (0)