import { type Page, test } from "@playwright/test"; import * as fs from "fs"; import * as path from "path"; export const ADMIN_EMAIL = "admin"; export const ADMIN_PASSWORD = "wZW64CUbXbv9679dmR1FIbz3"; export const BASE = "https://localhost"; const AUTH_FILE = path.join(__dirname, ".auth-state.json"); interface AuthState { available: boolean; accessToken?: string; refreshToken?: string; user?: { id: number; role: string; email: string }; } export function loadAuth(): AuthState { try { return JSON.parse(fs.readFileSync(AUTH_FILE, "utf-8")) as AuthState; } catch { return { available: false }; } } /** Skip this test if auth is not available (CAPTCHA not exposed). */ export function requireAuth(): AuthState { const auth = loadAuth(); if (!auth.available) { test.skip(true, "Auth not available — restart API with CAPTCHA_EXPOSE_ANSWER=true"); } return auth; } /** Inject cached auth cookies into the page context. */ export async function injectAuth(page: Page): Promise { const auth = requireAuth(); // Seed Zustand persist store so the app hydrates with a valid user (skips redirect) await page.addInitScript(({ user }) => { try { localStorage.setItem( "pargar.auth", JSON.stringify({ state: { user }, version: 0 }), ); } catch {} }, { user: auth.user }); await page.context().addCookies([ { name: "pargar_access", value: auth.accessToken!, domain: "localhost", path: "/", secure: true, sameSite: "Lax" }, { name: "pargar_refresh", value: auth.refreshToken!, domain: "localhost", path: "/", secure: true, httpOnly: true, sameSite: "Lax" }, ]); return auth; } export async function loginAs(page: Page, identity: string, password: string) { const captchaRes = await page.request.get(`${BASE}/api/auth/captcha`); const captchaData = await captchaRes.json(); const answer: string = captchaData.answer ?? ""; const challengeId: string = captchaData.challengeId ?? ""; const loginRes = await page.request.post(`${BASE}/api/auth/login`, { data: { username: identity, password, challengeId, captchaAnswer: answer, rememberMe: false }, }); const loginBody = await loginRes.json(); if (!loginBody.accessToken) { throw new Error(`Login failed for ${identity}: ${JSON.stringify(loginBody)}`); } await page.context().addCookies([ { name: "access_token", value: loginBody.accessToken, domain: "localhost", path: "/", secure: true, sameSite: "Lax" }, { name: "refresh_token", value: loginBody.refreshToken, domain: "localhost", path: "/", secure: true, httpOnly: true, sameSite: "Lax" }, ]); return loginBody; } export async function apiLogin(page: Page, identity: string, password: string) { const captchaRes = await page.request.get(`${BASE}/api/auth/captcha`); const { challengeId, answer } = await captchaRes.json(); const res = await page.request.post(`${BASE}/api/auth/login`, { data: { username: identity, password, challengeId, captchaAnswer: answer, rememberMe: false }, }); return res.json(); }