From 903c5cb19a012bdfc5ac7f7adbb6171c725db272 Mon Sep 17 00:00:00 2001 From: Coracle-Bot Date: Wed, 16 Sep 2026 06:48:40 +0000 Subject: [PATCH] Name the resource in a console line that carries only its status --- e2e/harness/faults.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/e2e/harness/faults.ts b/e2e/harness/faults.ts index a4b29df0..6c628d08 100644 --- a/e2e/harness/faults.ts +++ b/e2e/harness/faults.ts @@ -1,5 +1,5 @@ import {inspect} from "node:util" -import type {BrowserContext} from "@playwright/test" +import type {BrowserContext, ConsoleMessage} from "@playwright/test" // A CSP refusal reaches the console and nothing else, so a policy that has rotted past the script // it names is invisible to every spec: app.html's requestIdleCallback shim was refused on every @@ -12,6 +12,16 @@ const isRefusal = (text: string) => text.includes("Content Security Policy") // log and out of the fault set until #529 stops the churn. const isChunkLoss = (text: string) => text.includes("Failed to fetch dynamically imported module") +// Chrome reports a failed request as "Failed to load resource: the server responded with a status +// of 404 (Not Found)" and carries the url nowhere but the message's location, so a line built from +// the text alone cannot say which resource went missing. +const locate = (message: ConsoleMessage) => { + const text = message.text() + const {url} = message.location() + + return url && !text.includes(url) ? `${text} ${url}` : text +} + // Playwright builds this from the page's exception details, and a page that throws something other // than an Error leaves it with neither message nor stack — which is how a fault used to reach the // console log as a bare "uncaught:". @@ -45,7 +55,7 @@ export const watchFaults = (): FaultWatch => { observe(context, who) { context.on("console", message => { const type = message.type() - const text = message.text() + const text = locate(message) if (["error", "warning"].includes(type)) { record(`[${who}] ${type}: ${text}`, type === "error" && isRefusal(text))