import { expect, test, type Page } from '@playwright/test'; import { PASSWORD, USERNAME } from './credentials'; // UI-interactive boot-gate flows (ersatztv#445), deferred from #363 because they cannot be expressed // as curl calls. `scripts/e2e-functional.sh` already asserts the auth *HTTP* contracts (setup-claim // 200/409, login 401/200, CSRF 403, security-stamp rotation). What it CANNOT reach, and what these // specs exist for: // // 1. Client-side form validation — the Setup card's confirm-password gate is pure React state. // No request is made, so there is no HTTP contract to assert. // 2. AuthGate's state machine as rendered — that `setupRequired` yields the Setup card, a // configured server yields the Login card, and a 401 yields neither. // 3. The session cookie authenticating the SPA's OWN fetch layer. curl proves the cookie works for // curl; it cannot prove the browser sends it on the app's `/api/v1/*` XHRs, which is the thing // that actually breaks for a user. // 4. Sign-out wired through the UserMenu back to the login gate. // // SERVER STATE IS SHARED AND PARTLY ONE-SHOT. The setup-claim can happen exactly once per config // dir, so these tests are `serial` and the claim must run first. `scripts/e2e-ui.sh` boots a FRESH // instance so the first test always finds `setupRequired: true`. // // Each `test` gets its own browser context (so its own cookie jar) — that is deliberate: it gives // tests 2 and 3 a genuinely signed-out browser without a logout dance. Anything that depends on // holding a session across steps must therefore stay INSIDE one test. // The Setup/Login cards use the shared , which wraps its in a