# PunimTag e2e (Playwright + @levkin/playkit) Smoke tests against the **public** DEV URL so we catch LAN-redirect bugs (e.g. `NEXTAUTH_URL=http://10.0.10.121:3001` → Kolby #57). ## Quick start ```bash cd e2e cp .env.example .env # edit credentials npm ci npx playwright install chromium npm test ``` Private Gitea installs need auth once: set a local git `insteadOf` with a token before `npm ci`, then unset it. CI does this in `.gitea/workflows/ci.yml`. Never commit lockfile URLs that embed tokens. ## Environment | Variable | Required | Purpose | |----------|----------|---------| | `PLAYKIT_BASE_URL` | yes (default in `env-defaults.json`) | Public viewer host | | `PLAYKIT_API_BASE_URL` | no | LAN API (see `env-defaults.json`) | | `E2E_ADMIN_EMAIL` | for auth specs | Dedicated e2e user (not a human password) | | `E2E_ADMIN_PASSWORD` | for auth specs | Dedicated e2e password | | `PLAYKIT_MAIL_PROVIDER` | for mail specs | `mailpit` (homelab) | | `MAILPIT_BASE_URL` | for mail specs | `http://10.0.10.45:8025` | | `MAILPIT_USER` / `MAILPIT_PASSWORD` | for mail specs | Mailpit basic auth | **Secrets:** Infisical `LevkinOps` → `dev` → `/playkit/punimtag` + Gitea Actions. See ansible `docs/hardening/SECRETS.md`. ## What we assert 1. Login page loads on the public hostname 2. Sign-out stays on that hostname (never `10.x`) 3. FastAPI `/health` → `{ "status": "ok" }` 4. Forgot-password / reset-password email in Mailpit; links use public host 5. Register → unverified block → verify email via Mailpit → login 6. Idle logout (`?e2e_idle_ms=`) stays on public host 7. Upload page loads when authenticated 8. Manage Users open/close then sign-out (Kolby #57 overlay path) 9. API `/api/v1/auth/me` and `/api/v1/photos` return 401 without token 10. API catalog: people/tags lists, login 422/401, users/roles 401, missing photo 404|401 Defaults for base URLs live in `env-defaults.json` (imported by `env-defaults.ts`, `fixtures.ts`, `playwright.config.ts`, and the Gitea `e2e` job).