import { test as setup, expect } from '@playwright/test'; import { authenticator } from 'otplib'; const authFile = 'tests/.auth/user.json'; /** * Authentication setup * * This runs before all other tests to authenticate once and save the session state. * Other tests will reuse this authentication state instead of logging in each time. * * Setup: * 1. Create a test user in your database * 2. Enable TOTP for that user * 3. Set TEST_USER_EMAIL, TEST_USER_PASSWORD, and TEST_USER_TOTP_SECRET in .env */ setup('authenticate', async ({ page }) => { const email = process.env.TEST_USER_EMAIL || 'test@example.com'; const password = process.env.TEST_USER_PASSWORD || 'password'; const totpSecret = process.env.TEST_USER_TOTP_SECRET; if (!totpSecret) { throw new Error( 'TEST_USER_TOTP_SECRET is not set. ' + 'Create a test user with TOTP enabled and set the secret in .env' ); } console.log(`Authenticating as ${email}...`); // Navigate to login page await page.goto('/users/log_in'); // Fill in email and password await page.getByLabel('Email').fill(email); await page.getByLabel('Password').fill(password); // Submit login form await page.getByRole('button', { name: 'Sign in' }).click(); // Wait for TOTP page await page.waitForURL('**/users/log_in/totp'); // Generate TOTP code const token = authenticator.generate(totpSecret); console.log(`Generated TOTP token: ${token}`); // Fill in TOTP code await page.getByLabel(/authentication code|totp|code/i).fill(token); // Submit TOTP form await page.getByRole('button', { name: /verify|submit|continue/i }).click(); // Wait for redirect to dashboard/home await page.waitForURL('**/orgs'); // Verify we're logged in by checking for user menu or organization elements await expect(page.getByRole('link', { name: /organizations|dashboard/i })).toBeVisible(); console.log('Authentication successful!'); // Save authenticated state await page.context().storageState({ path: authFile }); });