Repository navigation
v2.12.1 - Production Build Tests
v2.12.1 — Production Build Test Mode
This release adds a production test mode: TEST_BUILD=prod builds and runs the full production app image — fingerprinted assets, minified bundles, hash-locked CSP, Trusted Types enforcement, HSTS via TLS — behind a TLS reverse proxy, and runs the entire Playwright suite against it. Dev-mode tests keep running exactly as before; prod mode exists to verify that what real users get is actually what we ship. The subtle build-vs-runtime dependencies this required are documented in Testing Architecture — Subtle Dependencies.
New
- Production test pipeline —
npm run test:prod(plustest:prod:firefoxandtest:prod:webkit) builds a production Docker image, serves it under TLS (Caddy in the devcontainer), and runs the full Playwright suite against it. A newruntime-prod-coverDockerfile stage ships the production build with devDependencies so the server can run underc8(npm run start:cover) and server-side coverage is collected from a production-like app, not just the instrumented dev build. - Mode-distinct image tags — dev and prod test images use separate tags (
jam-build-test/jam-build-test-prod), so switching modes never silently reuses a stale, wrong-mode image.FORCE_BUILD=1rebuilds either; in build-only runs it also short-circuits teardown for bare hosts. - Pre-build endpoint validation — prod mode resolves the authorizer and app endpoints before building (they are baked into the client bundle and CSP at build time) and validates them up front, failing fast with a clear message instead of a mysterious CSP violation later.
- Testing architecture documentation — docs/testing-architecture.md documents the multi-tier testing dependencies: build-time vs runtime endpoint resolution,
__authorizerOverrides, dev-vs-prod CSP enforcement differences, and the coverage pipeline.
Changed
- Trusted Types rule for prod test mode — prod pages enforce
require-trusted-types-for 'script'with a hash-locked CSP, which blocks DOM<script>injection into app pages (and the reserveddefaultpolicy deliberately has nocreateScripthook, so no named policy can satisfy the sink either). The harness now runs all page-side code throughpage.evaluate()/page.addInitScript()— the browser automation protocol, which sits outside bothscript-srcand Trusted Types enforcement. This is a standing rule: the test image's CSP stays byte-identical to a real deployment; we never weaken it to make tests pass. - Service worker coverage instrumentation is mode-gated — the production SW is now instrumented with
SW_INSTRUMENTonly when building a prod test image (Dockerfile:SW_INSTRUMENT=${TEST_BUILD:+1}, passed as a build arg byservices.js). Real deployments never setTEST_BUILD, so they ship a clean, uninstrumented worker. - Brittle webspecs assertions made mode-agnostic — the "assets do not carry page-only security headers" test now reads stylesheet URLs from the rendered DOM (
el.href) instead of regexing raw HTML, since prod minification strips attribute quotes; the web-manifest tests read the manifest link from the DOM and accept fingerprinted filenames. - Fingerprinting exclusions —
llms.txtand everything under.well-known/are now excluded from asset revisioning insrc/build/revision.js, alongside the existingrobots.txt/sitemap.xmlexclusions, so well-known protocol endpoints keep their stable URLs in prod builds.
Housekeeping
- Dev dependency updates:
@playwright/test1.63.x,eslint10.10.x,sass1.104.x,stylelint17.15.x,autoprefixer10.5.5,@localnerve/sass-asset-functions7.17.x; assorted doc link fixes.
Deployment Notes
- No changes to real deployments: production builds are untouched unless
TEST_BUILD=prodis explicitly set, and that flag only affects the test image (SW instrumentation). The fingerprinting exclusions do change prod output —llms.txtand.well-known/*paths are no longer fingerprinted, which is the intended behavior. - Prod test mode requires TLS (HSTS and secure-context APIs are part of what it verifies): in the devcontainer the existing Caddy sites are used as-is; elsewhere, point
BASE_URLandAUTHZ_URLat your TLS proxy's https URLs. Only one app container (dev or prod) can run at a time — they share a network alias and port.
What's Changed
- @2.12.1 - Production Build Test Mode, fixes, updates by @localnerve in #117
Full Changelog: v2.12.0...v2.12.1