Compare commits

...

1 Commits

Author SHA1 Message Date
Mathias Fredriksson e26c46a7e2 fix(e2e): reload page on failed dynamic import
When parallel e2e tests trigger ERR_NETWORK_CHANGED, React
Router's dynamic import for the page chunk can fail, rendering
the error boundary instead of the expected page content. This
caused createWorkspace to time out waiting for the name input.

After navigating, race the expected content against the error
boundary. If the error boundary wins, reload the page to retry
the chunk load.
2026-03-10 00:03:41 +00:00
+36
View File
@@ -126,6 +126,11 @@ export const createWorkspace = async (
});
await expectUrl(page).toHavePathName(`/templates/${templatePath}/workspace`);
// Dynamic imports can fail with ERR_NETWORK_CHANGED during
// parallel test execution. Reload the page if the error
// boundary appears instead of the form.
await reloadPageIfDynamicImportFailed(page, "form");
const name = randomName();
await page.getByLabel("name").fill(name);
@@ -815,6 +820,37 @@ export const randomName = (annotation?: string) => {
return annotation ? `${annotation}-${base}` : base;
};
/**
* Reload the page if a dynamic import failed (e.g. due to
* ERR_NETWORK_CHANGED). When React Router catches a failed chunk
* load it renders the GlobalErrorBoundary with the heading
* "Something went wrong". Detecting that and reloading is enough
* to recover.
*/
async function reloadPageIfDynamicImportFailed(
page: Page,
expectedSelector: string,
) {
const errorHeading = page.getByRole("heading", {
name: "Something went wrong",
});
// Race the expected content against the error boundary. Suppress
// the timeout rejection from whichever side loses.
const result = await Promise.race([
page
.waitForSelector(expectedSelector, { timeout: 10_000 })
.then(() => "ok" as const)
.catch(() => "timeout" as const),
errorHeading
.waitFor({ state: "visible", timeout: 10_000 })
.then(() => "error" as const)
.catch(() => "timeout" as const),
]);
if (result === "error") {
await page.reload({ waitUntil: "domcontentloaded" });
}
}
/**
* Awaiter is a helper that allows you to wait for a callback to be called. It
* is useful for waiting for events to occur.