Files
thrilltrack-explorer/tests/fixtures/auth.ts
2025-10-30 15:42:28 +00:00

124 lines
3.4 KiB
TypeScript

/**
* 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<void> {
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<void> {
await supabase.auth.signOut();
}