# 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.

```bash
# 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):

```bash
# 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
```

