/** * Authentication Fixtures for Playwright Tests * * Manages authentication state for different user roles. * Creates reusable auth states to avoid logging in for every test. */ import { chromium, type FullConfig } from '@playwright/test'; import { setupTestUser, supabase } from './database'; import * as fs from 'fs'; import * as path from 'path'; const TEST_USERS = { user: { email: process.env.TEST_USER_EMAIL || 'test-user@thrillwiki.test', password: process.env.TEST_USER_PASSWORD || 'TestUser123!', role: 'user' as const, }, moderator: { email: process.env.TEST_MODERATOR_EMAIL || 'test-moderator@thrillwiki.test', password: process.env.TEST_MODERATOR_PASSWORD || 'TestModerator123!', role: 'moderator' as const, }, admin: { email: process.env.TEST_ADMIN_EMAIL || 'test-admin@thrillwiki.test', password: process.env.TEST_ADMIN_PASSWORD || 'TestAdmin123!', role: 'admin' as const, }, superuser: { email: process.env.TEST_SUPERUSER_EMAIL || 'test-superuser@thrillwiki.test', password: process.env.TEST_SUPERUSER_PASSWORD || 'TestSuperuser123!', role: 'superuser' as const, }, }; /** * Setup authentication states for all test users */ export async function setupAuthStates(config: FullConfig): Promise { const baseURL = config.projects[0].use.baseURL || 'http://localhost:8080'; // Ensure .auth directory exists const authDir = path.join(process.cwd(), '.auth'); if (!fs.existsSync(authDir)) { fs.mkdirSync(authDir, { recursive: true }); } const browser = await chromium.launch(); for (const [roleName, userData] of Object.entries(TEST_USERS)) { const context = await browser.newContext(); const page = await context.newPage(); try { // Create test user if doesn't exist await setupTestUser(userData.email, userData.password, userData.role); // Navigate to login page await page.goto(`${baseURL}/auth`); // Wait for page to load await page.waitForLoadState('networkidle'); // Fill login form await page.fill('input[type="email"]', userData.email); await page.fill('input[type="password"]', userData.password); // Click login button await page.click('button[type="submit"]'); // Wait for navigation to complete await page.waitForURL('**/', { timeout: 10000 }); // Save authenticated state const authFile = path.join(authDir, `${roleName}.json`); await context.storageState({ path: authFile }); console.log(`✓ Created auth state for ${roleName}`); } catch (error) { console.error(`✗ Failed to create auth state for ${roleName}:`, error); throw error; } finally { await context.close(); } } await browser.close(); } /** * Get auth credentials for a specific role */ export function getTestUserCredentials(role: keyof typeof TEST_USERS) { return TEST_USERS[role]; } /** * Login programmatically (for use within tests) */ export async function loginAsUser( email: string, password: string ): Promise<{ userId: string; accessToken: string }> { const { data, error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) throw error; if (!data.user || !data.session) throw new Error('Login failed'); return { userId: data.user.id, accessToken: data.session.access_token, }; } /** * Logout programmatically */ export async function logout(): Promise { await supabase.auth.signOut(); }