Files
human-experience-filter-art/simulator/e2e
BenStullsBets 2f8641cb28 fix(mood): keep the Dark/Light grade applied through altitude morphs
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>
2026-07-02 05:38:19 -07:00
..

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 .rev zoom-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