Files
computer-playbook/tests/unit/javascript
kevinveenbirkenbachandClaude Opus 5 43ec22ee20 fix(e2e): read the CSP off the response, not a second fetch
readCspString re-fetched the current URL through the Playwright API
request context and, when that failed, waited actionTimeout (30s) for a
<meta http-equiv="Content-Security-Policy"> that no template in this
repo emits. On a healthy runner that path works and costs one extra
request; when name resolution degrades it collapses, because the API
request context resolves DNS separately from the browser: the re-fetch
burns its 10s cap and the meta wait then drains whatever is left of the
caller's test budget.

That is what killed web-svc-logout's guest persona in run 32597248629,
job Pretix#0, whose swarm manager had a single resolver on 127.0.0.1
with dnsmasq no longer answering. Every guest test on that host inflated
to ~40s and the logout one, loading two external assets on top, died on
its 60s timeout having asserted nothing. The same role in Bluesky#0 and
YOURLS#0 of the same run, same role set, finished in 0.85s and 0.82s -
so this is a resilience fix, not a repair of a broken assertion.

gotoOnion now installs a page.on("response") recorder, so the header is
taken from the document the browser already received. That also covers
the surface reached through an SSO round trip, where no navigation
Response is in scope at the assertion - only guest.js holds one, biber,
admin and the suitecrm saml spec discard theirs. The re-fetch stays as
the fallback for a spec that navigates without gotoOnion; the meta
fallback is deleted.

The suite pins the header precedence (enforced over report-only) and
every guard in assertCspInjections: a disabled injector, a gate that
throws, an enabled injector without a base URL, a missing gate, a second
enabled injector, and the case-insensitive host match. Inverting the
precedence or dropping toLowerCase each trips exactly one test.

Verified against a headless Chromium and a local server counting
requests: the header survives a 302, no extra request is issued, a
missing injector host still fails the assertion, and a header-less page
falls back to exactly one re-fetch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 04:31:55 +02:00
..