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( 'map tile', ); 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], ); });