import { APIRequestContext, Browser, BrowserContext, Page } from '@playwright/test'; type AuthRole = 'auth' | 'admin' | 'sponsor'; type Credentials = { email: string; password: string; }; export interface AuthContext { context: BrowserContext; page: Page; role: AuthRole; } export class WebsiteAuthManager { static async createAuthContext(browser: Browser, role: AuthRole): Promise; static async createAuthContext(browser: Browser, request: APIRequestContext, role: AuthRole): Promise; static async createAuthContext( browser: Browser, requestOrRole: APIRequestContext | AuthRole, maybeRole?: AuthRole, ): Promise { const baseURL = process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:3000'; const apiBaseUrl = process.env.API_BASE_URL || 'http://localhost:3101'; const role = (typeof requestOrRole === 'string' ? requestOrRole : maybeRole) as AuthRole; const request = typeof requestOrRole === 'string' ? null : requestOrRole; const context = await browser.newContext({ baseURL }); if (request) { const token = await WebsiteAuthManager.loginViaApi(request, apiBaseUrl, role); // Critical: the website (localhost:3000) must receive `gp_session` so middleware can forward it. await context.addCookies([ { name: 'gp_session', value: token, url: baseURL, path: '/', httpOnly: true, sameSite: 'Lax', }, ]); } const page = await context.newPage(); if (!request) { await WebsiteAuthManager.loginViaUi(page, role); } return { context, page, role, }; } private static async loginViaApi( request: APIRequestContext, apiBaseUrl: string, role: AuthRole, ): Promise { const credentials = WebsiteAuthManager.getCredentials(role); const res = await request.post(`${apiBaseUrl}/auth/login`, { data: { email: credentials.email, password: credentials.password, }, }); const setCookie = res.headers()['set-cookie'] ?? ''; const cookiePart = setCookie.split(';')[0] ?? ''; const token = cookiePart.startsWith('gp_session=') ? cookiePart.slice('gp_session='.length) : ''; if (!token) { throw new Error(`Expected gp_session cookie from ${apiBaseUrl}/auth/login`); } return token; } private static async loginViaUi(page: Page, role: AuthRole): Promise { const credentials = WebsiteAuthManager.getCredentials(role); await page.goto('/auth/login'); await page.getByLabel('Email Address').fill(credentials.email); await page.getByLabel('Password').fill(credentials.password); await Promise.all([ page.getByRole('button', { name: 'Sign In' }).click(), page.waitForURL((url) => !url.pathname.startsWith('/auth/login'), { timeout: 15_000 }), ]); } private static getCredentials(role: AuthRole): Credentials { if (role === 'admin') { return { email: 'demo.admin@example.com', password: 'Demo1234!' }; } if (role === 'sponsor') { return { email: 'demo.sponsor@example.com', password: 'Demo1234!' }; } return { email: 'demo.driver@example.com', password: 'Demo1234!' }; } }