import type { Page } from '@playwright/test'; /** * A demo identity the fake DigiD login accepts. Auth is faked (CLAUDE.md) — the * form only ever emits `bsn` on submit, so `wachtwoord` is never actually checked; * it's filled in anyway because the field is marked required in the UI. */ export interface Actor { readonly bsn: string; readonly wachtwoord: string; } /** * The demo identities e2e specs log in as. The BRP/registration data every one of * them sees on the dashboard comes from static `SeedData` and is identity-independent * (only `DocumentStore.DemoOwner`'s owner-keyed Applications/Documents/Briefs differ * per BSN — see `subject.interceptor.ts`), so any elfproef-valid BSN works here; these * are just distinct, not otherwise special. * * Named for the ROLE the identity plays in a spec, not its BSN, so a spec reads as * "log in as the zorgverlener", not "log in as 123456782". **A spec that mutates * owner-keyed state (creates a Concept, composes a brief, …) should use its own * BSN** (WP-74) — `subject.interceptor.ts` stamps it as `X-Subject`, so two specs * sharing a BSN would collide on the same backend rows across the same run and * across reruns. A read-only spec (nothing created/submitted) can keep using * `zorgverlener`. * * `briefOpsteller` is the one exception, currently unused: `brief-v2.spec.ts` stays * on `zorgverlener` despite mutating state, because giving it its own BSN tripped a * real backend bug (a stale/watermarked `GET /brief/preview` response for the SENT * letter under a non-`DemoOwner` owner — see that spec's header comment and * `letter-preview.adapter.ts`'s "KNOWN GAP" note). Kept defined, not deleted, so * whoever fixes that backend issue has the identity ready to switch the spec onto. * * Every BSN below passed the elfproef (`libs/shared/src/kernel/bsn.ts`'s checksum) — * required, or `DigidAdapter.authenticate` rejects it and login never completes: * 123456782 ✓ (9·1+8·2+7·3+6·4+5·5+4·6+3·7+2·8−1·2 = 154, 154 mod 11 = 0) * 111222333 ✓ (9·1+8·1+7·1+6·2+5·2+4·2+3·3+2·3−1·3 = 66, 66 mod 11 = 0) * 111111110 ✓ (9+8+7+6+5+4+3+2−0 = 44, 44 mod 11 = 0) */ export const Actors = { /** The one seeded citizen (`SeedData.cs`'s `Person`/`Registration`) — read-only specs, and (for now — see above) `brief-v2.spec.ts` too. */ zorgverlener: { bsn: '123456782', wachtwoord: 'demo' }, /** `smoke.spec.ts`'s own identity — it creates+submits a registratie-aanvraag. */ registratieAanvrager: { bsn: '111222333', wachtwoord: 'demo' }, /** Reserved for `brief-v2.spec.ts` once the backend bug above is fixed — not currently used by any spec. */ briefOpsteller: { bsn: '111111110', wachtwoord: 'demo' }, } as const satisfies Record; /** * The shared DigiD-style mock login sequence every e2e spec starts from. Navigating * to `/login?subject=` (rather than plain `/login`) primes `subject.interceptor.ts`'s * sticky sessionStorage the same way `?role=` primes `roleInterceptor` (WP-33) — the * BSN typed into the form and the one the interceptor stamps as `X-Subject` are the * same value by construction, they just can't share a single read (see * `subject.interceptor.ts`'s doc comment for why not). */ export async function loginAs(page: Page, actor: Actor): Promise { await page.goto(`/login?subject=${actor.bsn}`); await page.getByLabel('BSN').fill(actor.bsn); await page.getByLabel('Wachtwoord').fill(actor.wachtwoord); await page.getByRole('button', { name: 'Inloggen met DigiD' }).click(); } /** * Seeded fixtures specs depend on by id, named by * `backend/src/BigRegister.Api/Data/SeedData.cs`'s seed order — reseeding that * file in a different order silently breaks these with no compile error, so give * the raw id a name instead of leaving it a bare literal in each spec. */ export const SeedRefs = { /** * The first DUO diploma (id "d1": Geneeskunde, Universiteit Leiden, non-English). * Chosen deliberately, not arbitrarily: it's the one seeded diploma that carries * zero policy questions, so it drives the wizard down its minimum required path * — the only required upload is identiteit. */ diplomaZonderPolicyVragen: 'd1', /** The seeded registration's BIG-nummer (`SeedData.Registration`). */ bigNummer: '19012345601', } as const;