All checks were successful
- Wire E2E_API_USERNAME/PASSWORD (admin) + E2E_API_VIEWER_USERNAME/PASSWORD (viewer) into the Gitea Actions e2e job so FastAPI-authed specs run in CI. - Add api.role-permissions.spec.ts: viewer 403 vs admin 200/200/200 on /api/v1/users, /api/v1/role-permissions, and /api/v1/photos/bulk-delete (safe no-op via a non-existent photo id — proves the gate, not deletion). - Add gallery.search-filters.spec.ts: tag_id and person_id filters on the public /api/search route return correct subsets, combined filters narrow results, and the /search UI tag-filter interaction updates the URL/count. - Update ROADMAP/README/.env.example for the new env vars and coverage.
2.7 KiB
2.7 KiB
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
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 | Prefer e2e@levkine.ca — not admin@admin.com |
E2E_ADMIN_PASSWORD |
for auth specs | Dedicated e2e password (Vaultwarden / Infisical) |
E2E_API_USERNAME / E2E_API_PASSWORD |
optional | FastAPI bearer login, admin role (separate DB from NextAuth; mirrors e2e@levkine.ca) |
E2E_API_VIEWER_USERNAME / E2E_API_VIEWER_PASSWORD |
optional | FastAPI bearer login, viewer role — role-permission gate specs only |
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
- Login page loads on the public hostname
- Sign-out stays on that hostname (never
10.x) - FastAPI
/health→{ "status": "ok" } - Forgot-password / reset-password email in Mailpit; links use public host
- Register → unverified block → verify email via Mailpit → login
- Idle logout (
?e2e_idle_ms=) stays on public host - Upload: submit a tiny fixture via
#file-upload(uses storageState) - Manage Users open/close then sign-out (Kolby #57 overlay path)
- API
/api/v1/auth/meand/api/v1/photosreturn 401 without token - API catalog: people/tags lists, login 422/401, users/roles 401, missing photo 404|401
- Viewer
/api/auth/sessionreturns email when storageState is loaded - FastAPI role-permission write gates: viewer 403 vs admin 200 on users, role-permissions, bulk-delete
- Public gallery search (
/api/search): tag filter, person filter, and combined-filter narrowing return correct subsets; UI tag-filter interaction updates URL + result count
See repo root ROADMAP.md for gaps and next steps.
Defaults for base URLs live in env-defaults.json (imported by env-defaults.ts,
fixtures.ts, playwright.config.ts, and the Gitea e2e job).