import fs from "fs" import path from "path" import { expect, test as setup } from "@playwright/test" import { SEED } from "./seed-constants" /** * Global setup — authenticates as admin and saves the session state * so all authenticated tests can reuse it without logging in again. * * Runs as a Playwright "setup project" that other projects depend on. */ const authDir = path.join(__dirname, ".auth") const authFile = path.join(authDir, "admin.json") setup("authenticate as admin", async ({ page, context }) => { const baseURL = process.env.BASE_URL || "http://localhost:3000" const apiUrl = process.env.API_URL || "http://localhost:8080" // Use seed credentials (from seed-constants), overridable via env vars const email = process.env.TEST_ADMIN_EMAIL || SEED.admin.email const password = process.env.TEST_ADMIN_PASSWORD || SEED.admin.password // Ensure .auth directory exists if (!fs.existsSync(authDir)) { fs.mkdirSync(authDir, { recursive: true }) } // Wait for backend health (up to 60s) let healthy = false for (let i = 0; i < 30; i++) { try { const res = await fetch(`${apiUrl}/actuator/health`) if (res.ok) { healthy = true break } } catch { /* retry */ } await new Promise((r) => setTimeout(r, 2000)) } if (!healthy) throw new Error("Backend health check failed after 60s") // Navigate to login page await page.goto(`${baseURL}/login`) await page.waitForLoadState("domcontentloaded") // Fill credentials and submit await page.fill('input[name="email"], input[type="email"]', email) await page.fill('input[name="password"], input[type="password"]', password) await page.click('button[type="submit"]') // Wait for successful redirect away from login await page.waitForURL((url) => !url.pathname.includes("/login"), { timeout: 15000, }) // Wait for session cookies to settle await page.waitForLoadState("domcontentloaded") await page.waitForTimeout(1000) // Verify we're authenticated (sanity check) const url = page.url() expect(url).not.toContain("/login") // Save the authenticated state (cookies + localStorage) await context.storageState({ path: authFile }) })