test: playkit v0.3.1 adoption, Zod widening, PROD smoke, NextAuth write gates #68

Merged
ilia merged 8 commits from feat/admin-manage-users-e2e into dev 2026-07-14 22:24:07 -05:00
Owner

Summary

  • Bump @levkin/playkit to v0.3.1 and land the network-interception work it unblocked: startNetworkErrorMonitor on gallery/search/upload/manage-users, plus real interceptNetworkCall spies replacing brittle waitForResponse/text-scraping on upload and the search-filter UI.
  • Favorites + People filter UI e2e (storageState-based).
  • Widen Zod schemas: FastAPI login TokenResponse + /auth/me UserResponse, and the Prisma-backed gallery SearchResponse.
  • New PROD smoke spec (prod.smoke.spec.ts) — opt-in via PROD_BASE_URL; verified against a real public host, stays a no-op skip until the PROD LXC exists.
  • New NextAuth (browser-session) write-gate spec (viewer.write-gates.spec.ts) — provisioned a third, independent auth-DB viewer user (hasWriteAccess=false) via ansible's provision-punimtag-e2e-user.py; viewer 403s vs admin passes-through on POST /api/faces/{id}/identify.
  • admin-frontend Vitest coverage + CI job (previously had no test infra).
  • Fixed lingering res.data: unknown / Mailpit-vs-Mailtrap TS errors in mail/catalog specs.
  • ROADMAP.md updated; documented that DEV (LXC 9101) is ~19 commits behind dev HEAD, which blocks two other uncommitted specs left as-is (not part of this PR).

Test plan

  • Full local e2e run against DEV (npx playwright test --project=setup --project=chromium): 35 passed, 6 skipped (mail specs need Mailpit env)
  • tsc --noEmit clean across e2e/
  • CI green on this PR (Gitea Actions)
## Summary - Bump `@levkin/playkit` to `v0.3.1` and land the network-interception work it unblocked: `startNetworkErrorMonitor` on gallery/search/upload/manage-users, plus real `interceptNetworkCall` spies replacing brittle `waitForResponse`/text-scraping on upload and the search-filter UI. - Favorites + People filter UI e2e (storageState-based). - Widen Zod schemas: FastAPI login `TokenResponse` + `/auth/me` `UserResponse`, and the Prisma-backed gallery `SearchResponse`. - New PROD smoke spec (`prod.smoke.spec.ts`) — opt-in via `PROD_BASE_URL`; verified against a real public host, stays a no-op skip until the PROD LXC exists. - New NextAuth (browser-session) write-gate spec (`viewer.write-gates.spec.ts`) — provisioned a third, independent auth-DB viewer user (`hasWriteAccess=false`) via ansible's `provision-punimtag-e2e-user.py`; viewer 403s vs admin passes-through on `POST /api/faces/{id}/identify`. - `admin-frontend` Vitest coverage + CI job (previously had no test infra). - Fixed lingering `res.data: unknown` / Mailpit-vs-Mailtrap TS errors in mail/catalog specs. - ROADMAP.md updated; documented that DEV (LXC 9101) is ~19 commits behind `dev` HEAD, which blocks two other uncommitted specs left as-is (not part of this PR). ## Test plan - [x] Full local e2e run against DEV (`npx playwright test --project=setup --project=chromium`): 35 passed, 6 skipped (mail specs need Mailpit env) - [x] `tsc --noEmit` clean across `e2e/` - [ ] CI green on this PR (Gitea Actions)
ilia added 2 commits 2026-07-14 21:08:26 -05:00
Bump @levkin/playkit to v0.3.1 (network interception helpers) and land the
work it unblocked: startNetworkErrorMonitor on gallery/search/upload/manage-
users, Favorites + People filter UI e2e (storageState), and a fix for the
lingering `res.data: unknown` / Mailpit-vs-Mailtrap type errors in the mail
and catalog specs. Also adds Vitest coverage + a CI job for admin-frontend,
which had no test infra before this.
test: interceptNetworkCall + Zod widening, PROD smoke, NextAuth write gates
Some checks failed
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 6s
CI / secret-scan (pull_request) Successful in 11s
CI / viewer-unit (pull_request) Failing after 1m3s
CI / admin-unit (pull_request) Failing after 1m1s
CI / e2e (pull_request) Failing after 59s
4273162d9e
- upload.smoke.spec.ts / gallery.search-filters.spec.ts: replace
  waitForResponse/text-scrape with typed interceptNetworkCall spies (status
  + JSON shape) on the real upload POST and the filtered /api/search GET.
- api.fastapi-login.spec.ts: Zod-validate the FastAPI TokenResponse and
  /auth/me UserResponse instead of loose casts. gallery.search-filters.spec.ts
  gets the same treatment for the Prisma-backed SearchResponse.
- prod.smoke.spec.ts: opt-in (PROD_BASE_URL) health + login-page check on a
  real PROD host; skips as a no-op until the PROD LXC exists (none does yet
  per `pct list` — see ROADMAP).
- viewer.write-gates.spec.ts: NextAuth (browser-session) hasWriteAccess gate
  on POST /api/faces/{id}/identify — viewer 403s, admin passes through.
  Provisioned a third, independent auth-DB user (e2e-viewer@levkine.ca,
  hasWriteAccess=false) for this via ansible's provision-punimtag-e2e-user.py
  (see that repo for the vault/Infisical/Gitea/Vaultwarden side).
ilia added 1 commit 2026-07-14 21:09:36 -05:00
test: Manage Users real CRUD + causal cross-session e2e coverage
Some checks failed
CI / skip-ci-check (pull_request) Successful in 5s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 14s
CI / viewer-unit (pull_request) Successful in 54s
CI / admin-unit (pull_request) Successful in 2m35s
CI / e2e (pull_request) Failing after 4m31s
37f565dd04
admin.manage-users.spec.ts only opened/closed the panel; the actual
create/edit/delete flow through the UI was untested. Adds a page object
(ManageUsersPanel) and two specs: full CRUD through the panel, and a
causal cross-session check that deactivating a user via the admin UI
immediately revokes that user's already-open session (NextAuth jwt
callback re-checks isActive on every request, per issue #57's fix).

Every run creates and tears down its own disposable e2e-manage-test-*
account since punimtagdev shares its Postgres DB with MirrorMatch.
ilia added 1 commit 2026-07-14 21:22:51 -05:00
fix: locate manage-users row action buttons positionally
Some checks failed
CI / skip-ci-check (pull_request) Successful in 5s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 12s
CI / admin-unit (pull_request) Successful in 35s
CI / e2e (pull_request) Failing after 2m59s
CI / viewer-unit (pull_request) Failing after 3m3s
f080a0cdb1
CI's first run showed the Edit button's aria-label exact-match locator
timing out against the live table even though the same row resolved
fine for badge-text reads moments earlier — switch to positional
lookup (Edit is always the first action button, Deactivate/Delete the
last) instead of relying on exact accessible-name matching.
ilia added 1 commit 2026-07-14 21:28:06 -05:00
ci: retrigger e2e run (prior run hit unrelated setup/login timeout)
Some checks failed
CI / skip-ci-check (pull_request) Successful in 5s
CI / docker-ci (pull_request) Successful in 6s
CI / secret-scan (pull_request) Successful in 11s
CI / admin-unit (pull_request) Successful in 29s
CI / e2e (pull_request) Failing after 52s
CI / viewer-unit (pull_request) Failing after 56s
a38cc359d8
ilia added 1 commit 2026-07-14 21:37:43 -05:00
ci: retrigger after clearing corrupted act_runner cache on git-ci-01/02
Some checks failed
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 6s
CI / secret-scan (pull_request) Successful in 12s
CI / e2e (pull_request) Failing after 41s
CI / admin-unit (pull_request) Successful in 43s
CI / viewer-unit (pull_request) Failing after 45s
9ffaec7cf7
ilia added 1 commit 2026-07-14 21:44:55 -05:00
ci: retrigger after bumping git-ci-01 to 8GB (was OOM-killing act_runner)
Some checks failed
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 12s
CI / admin-unit (pull_request) Successful in 1m18s
CI / viewer-unit (pull_request) Successful in 2m12s
CI / e2e (pull_request) Failing after 3m3s
262e7348d6
ilia added 1 commit 2026-07-14 22:19:50 -05:00
fix: causal cross-session test hung on Active-only filter, not a real bug
All checks were successful
CI / skip-ci-check (pull_request) Successful in 4s
CI / docker-ci (pull_request) Successful in 7s
CI / secret-scan (pull_request) Successful in 14s
CI / admin-unit (pull_request) Successful in 1m21s
CI / viewer-unit (pull_request) Successful in 1m48s
CI / e2e (pull_request) Successful in 2m38s
317a135daa
statusBadgeText(email) after deactivating a user hung for the full test
timeout: ManageUsersContent.handleEditUser() refetches the list with the
current statusFilter ('active' by default) after every save, so the
just-deactivated row silently drops out of view — the locator then waits
forever for a row that filter will never show again (no actionTimeout is
configured, so only the outer test timeout eventually kills it).

Add ManageUsersPanel.showAllUsers() and switch to it before reading the
badge. Also gave the test more headroom (60s -> 120s) since it drives two
full UI logins plus create/edit/verify against a shared-CI DEV LXC.

Verified: full local suite green (37 passed, 6 skipped) against DEV.
ilia merged commit 96351288f0 into dev 2026-07-14 22:24:07 -05:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ilia/punimtag#68
No description provided.