import { expect, type Page } from "@playwright/test"; import { clearMailpit, waitForMagicLink } from "./mailpit"; export const ROLE_EMAIL = { admin: "admin@touchbase.local", therapist: "mei@touchbase.local", customer: "alex@example.com", } as const; export type RoleKey = keyof typeof ROLE_EMAIL; export async function signInAs(page: Page, role: RoleKey, callbackUrl = "/"): Promise { await clearMailpit(); const email = ROLE_EMAIL[role]; await page.goto(`/login?callbackUrl=${encodeURIComponent(callbackUrl)}`); await page.getByLabel("Email").fill(email); // Auth.js v5 server-action signIn() redirects to either our /login/check-email // page or its internal /api/auth/verify-request. Either is fine — the email // is sent regardless. Just wait for any nav off /login. await Promise.all([ page.waitForURL((url) => !/\/login(\?|$)/.test(url.pathname + url.search)), page.getByRole("button", { name: /send sign-in link/i }).click(), ]); const link = await waitForMagicLink(email); await page.goto(link); // After callback, NextAuth redirects to callbackUrl. Verify session cookie present. await expect.poll(async () => { const cookies = await page.context().cookies(); return cookies.some((c) => /authjs.*session-token/i.test(c.name) || /next-auth.*session-token/i.test(c.name)); }).toBeTruthy(); }