121 lines
3.4 KiB
TypeScript
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],
|
|
);
|
|
});
|