import { expect, type Page } from "@playwright/test"; /** Dev-system credentials — these exist in the planarchy.dev seed data */ export const DEV_USERS = { admin: { email: "admin@planarchy.dev", password: "admin123" }, manager: { email: "manager@planarchy.dev", password: "manager123" }, viewer: { email: "viewer@planarchy.dev", password: "viewer123" }, } as const; export async function signIn(page: Page, email: string, password: string) { await page.goto("/auth/signin"); await page.fill('input[type="email"]', email); await page.fill('input[type="password"]', password); await page.click('button[type="submit"]'); await expect(page).toHaveURL(/\/(dashboard|resources)/, { timeout: 15000 }); } export async function signOut(page: Page) { await page.goto("/auth/signout"); // Auth.js v5 renders a confirmation page at /auth/signout before signing out. // Click the submit button if a form is present. const confirmBtn = page.locator('button[type="submit"]').first(); if (await confirmBtn.isVisible({ timeout: 3000 }).catch(() => false)) { await confirmBtn.click(); } await page.waitForURL(/\/auth\/signin/, { timeout: 10000 }); } /** * Intercept all tRPC batch responses and assert none return HTTP 401. * Returns a list of intercepted tRPC paths that were called. */ export async function assertNoTrpc401s(page: Page, action: () => Promise) { const failures: string[] = []; page.on("response", (response) => { if (response.url().includes("/api/trpc/") && response.status() === 401) { const url = new URL(response.url()); failures.push(url.pathname + url.search.slice(0, 80)); } }); await action(); if (failures.length > 0) { throw new Error( `tRPC 401 responses detected (session registry / auth broken):\n${failures.join("\n")}`, ); } }