The mood grade was dropped while a morph played (busy): the WebGL canvas set filter 'none' and the fallback set #vid's filter 'none' on morph load, so the transition showed ungraded and the grade snapped back only on landing. Now the grade rides through the morph on both paths (the painterly DREAM stays off mid- morph, as before, to keep it crisp). +1 e2e (mood-grade.spec.ts). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Simulator E2E (Playwright)
Browser end-to-end tests for the Human Experience Filter simulator. The §9 pipeline requires an E2E browser tier for any UI surface; this is that tier.
What it covers
tests/altitude-lock.spec.ts drives the real simulator and asserts the
altitude-morph behavior:
- Zooming to a new altitude plays the morph that matches the clip it lands on
(forward zoom-in, and
.revzoom-out). - After landing, the clip is locked — it does not change while parked (no secondary swap, no re-roll).
The played morph paths are read from window.__hefMorphs (a diagnostic array
populated by advance() in static/app.js), which is reliable even when a morph
is served from the in-memory blob cache. The locked clip is read from the
Dev-Mode #scale-name readout.
Running
Prerequisites: the project Python venv on PATH (the Playwright webServer boots
uvicorn simulator.app:app from the repo root), Node, and the Chromium browser.
# from this directory (simulator/e2e)
npm install
npx playwright install chromium
npm test
playwright.config.ts starts uvicorn on port 8099 automatically (reuseExistingServer
locally) and points the tests at it.
Static-build E2E (Cloudflare publish)
tests/static-build.spec.ts verifies the built static site (Cloudflare publish
— see deploy/cloudflare/README.md): it boots with NO /api/* server (baked JSON),
and the WebGL dream shader runs on cross-origin media without tainting the GL
texture (the CORS path R2 will use in production).
It uses playwright.static.config.ts (no uvicorn webServer) and a dual static
server, serve-static.mjs, that serves the built dist/ (app, :8077) and
dist-media/ (media with CORS + Range, :8078):
# from the repo root: build with the media base pointed at the local CORS server
.venv/bin/python -m tools.build_static --media-base http://localhost:8078/
# from this directory (simulator/e2e): start the dual server, then run the spec
DIST_DIR="$PWD/../../dist" MEDIA_DIR_E2E="$PWD/../../dist-media" node serve-static.mjs &
npx playwright test --config playwright.static.config.ts