Files
homelab-monitor/e2e
jhodgkin e5ace7692a
CI / web (push) Successful in 16s
CI / api (push) Successful in 22s
Add Fingerbank e2e coverage; fix two test races found along the way
- deep-check.spec.ts: new test asserting a Fingerbank ID + confidence
  label appears (targets the Nintendo device specifically, skips if
  it's not currently on the network -- not something the test suite
  controls). First run false-skipped because it checked row.count()
  before waiting for the device table to actually render.
- device-ratio.spec.ts: badge counts and displayed text were read as
  two separate one-shot queries (.count()/.textContent() don't
  auto-retry like expect() matchers), which raced a background poll
  once and failed. Wrapped the whole comparison in expect().toPass()
  so it retries atomically instead. Confirmed fixed: 4/4 clean runs
  with retries disabled.

15/15 e2e tests green across 8 spec files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 23:40:47 -06:00
..

E2E tests

Playwright tests that drive a real browser against the live deployment (https://monitor.jerodrigged.com by default) — not a local dev server or mocked backend. They exist specifically because curl-based verification missed real bugs that only show up with an actual browser (cookies, redirects, DOM interaction).

Setup

cd e2e
npm install
npx playwright install chromium
cp .env.example .env   # fill in LOCAL_PASSWORD and OIDC_PASSWORD
npm test

OIDC_USERNAME/OIDC_PASSWORD should be the dedicated playwright-test Authentik account (blueprint-provisioned on CT121, path users/service-accounts) — never a real personal login. See docs/oidc-setup.md.

Not wired into CI

These hit the live production dashboard and a live Authentik instance, and need credentials as secrets — deliberately not run automatically on every push. Run by hand after auth-related changes.

Coverage

  • local-login.spec.ts — happy path (login/logout), wrong password rejected, session survives a page reload.
  • oidc-login.spec.ts — happy path through a real Authentik login, wrong password rejected (stays on Authentik, never reaches the dashboard).
  • api-auth.spec.ts/api/hosts, /api/devices, /api/auth/me all reject unauthenticated requests; a failed login grants no access even though a session cookie gets issued (that's normal @fastify/session behavior, not a leak — what matters is whether the cookie carries authentication, which it doesn't).

9 tests, confirmed stable across repeated full-suite runs with parallel workers.

Bugs these caught on first write (all fixed, kept as regression coverage)

  1. Local logout silently failed. Frontend always sent Content-Type: application/json even for logout's bodyless POST; Fastify's default JSON parser rejects that combination (400). curl testing missed it — curl doesn't set that header without -d.
  2. OIDC login redirected to a LAN IP. OIDC_ISSUER_URL used Authentik's internal address; its discovery document echoes back whichever host you query it through, so that LAN IP ended up as the browser-facing authorization_endpoint.
  3. OIDC token exchange rejected with invalid_client. The callback handler hardcoded http:// when reconstructing the current URL (Fastify never sees HTTPS — it terminates upstream), which sent the wrong scheme as redirect_uri in the token exchange. Authentik's own event log said plainly "Invalid redirect URI used by provider"; the error surfaced to the app as a generic invalid_client.

None of these were caught by earlier curl-based verification — browser-driven auth flows (cookies, real redirect chains, a real IdP's login form) need a real browser.