who_need_help/e2e/tests/browser-failure-policy.spec.ts

121 lines
3.4 KiB
TypeScript

import { expect, test } from "@playwright/test";
import {
installDeterministicMapTileRoute,
isTransientNavigationError,
isTransientOpenStreetMapTileFailure,
reconcileTransientOpenStreetMapConsoleFailures,
} from "./helpers";
test("the production browser verifier uses a decodable deterministic raster tile", async ({
browser,
}) => {
const context = await browser.newContext({ serviceWorkers: "block" });
await installDeterministicMapTileRoute(context);
const page = await context.newPage();
await page.setContent(
'<img alt="map tile" src="https://tile.openstreetmap.org/0/0/0.png">',
);
await expect(page.getByAltText("map tile")).toHaveJSProperty(
"complete",
true,
);
await expect(page.getByAltText("map tile")).toHaveJSProperty(
"naturalWidth",
1,
);
await context.close();
});
test("navigation retry covers bounded goto timeouts without treating application errors as transient", () => {
expect(
isTransientNavigationError(
"TimeoutError: page.goto: Timeout 20000ms exceeded.",
),
).toBe(true);
expect(
isTransientNavigationError(
"TimeoutError: locator.click: Timeout 20000ms exceeded.",
),
).toBe(false);
expect(isTransientNavigationError("Unhandled application exception")).toBe(
false,
);
});
test("only transient failures from the configured public OSM tile origin are recoverable", () => {
expect(
isTransientOpenStreetMapTileFailure(
"https://tile.openstreetmap.org/6/36/20.png",
"net::ERR_NETWORK_CHANGED",
),
).toBe(true);
expect(
isTransientOpenStreetMapTileFailure(
"https://whoneedhelp.com/assets/js/app.js",
"net::ERR_NETWORK_CHANGED",
),
).toBe(false);
expect(
isTransientOpenStreetMapTileFailure(
"https://tile.openstreetmap.org/6/36/20.png",
"net::ERR_NAME_NOT_RESOLVED",
),
).toBe(false);
expect(
isTransientOpenStreetMapTileFailure(
"https://tiles.example.test/6/36/20.png",
"net::ERR_NETWORK_CHANGED",
),
).toBe(false);
});
test("duplicate Chromium and MapLibre messages are reconciled without hiding app errors", () => {
const remaining = reconcileTransientOpenStreetMapConsoleFailures(
[
{
text: "Failed to load resource: net::ERR_NETWORK_CHANGED",
locationURL: "https://tile.openstreetmap.org/6/36/20.png",
},
{
text: "AJAXError: Failed to fetch (0): https://tile.openstreetmap.org/6/36/20.png",
locationURL: "https://whoneedhelp.com/assets/js/app.js",
},
{
text: "TypeError: Failed to fetch",
locationURL: "https://whoneedhelp.com/assets/js/app.js",
},
{
text: "Unhandled application exception",
locationURL: "https://whoneedhelp.com/assets/js/app.js",
},
],
[
{
url: "https://tile.openstreetmap.org/6/36/20.png",
failure: "net::ERR_NETWORK_CHANGED",
},
],
);
expect(remaining).toEqual([
{
text: "Unhandled application exception",
locationURL: "https://whoneedhelp.com/assets/js/app.js",
},
]);
});
test("tile console errors remain fatal without a matching transient request failure", () => {
const failure = {
text: "AJAXError: Failed to fetch (0): https://tile.openstreetmap.org/6/36/20.png",
locationURL: "https://whoneedhelp.com/assets/js/app.js",
};
expect(reconcileTransientOpenStreetMapConsoleFailures([failure], [])).toEqual(
[failure],
);
});