import { test, expect } from '@playwright/test'; test.describe('Authentication Flows', () => { test.describe('Registration', () => { test('can access registration page', async ({ page }) => { await page.goto('/users/register'); await expect(page).toHaveURL(/\/users\/register/); await expect(page.locator('body')).toBeVisible(); }); test('shows registration form fields', async ({ page }) => { await page.goto('/users/register'); // Look for email and password fields const emailField = page.locator('input[type="email"]').first(); const passwordField = page.locator('input[type="password"]').first(); if (await emailField.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(emailField).toBeVisible(); } if (await passwordField.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(passwordField).toBeVisible(); } }); }); test.describe('Login', () => { test('can access login page', async ({ page }) => { await page.goto('/users/log-in'); await expect(page).toHaveURL(/\/users\/log-in/); await expect(page.locator('body')).toBeVisible(); }); test('shows login form', async ({ page }) => { await page.goto('/users/log-in'); const emailField = page.locator('input[type="email"]').first(); const passwordField = page.locator('input[type="password"]').first(); const submitButton = page.locator('button[type="submit"]').first(); if (await emailField.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(emailField).toBeVisible(); } if (await passwordField.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(passwordField).toBeVisible(); } if (await submitButton.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(submitButton).toBeVisible(); } }); test('shows link to password reset', async ({ page }) => { await page.goto('/users/log-in'); const resetLink = page.locator('a[href*="reset-password"]').first(); if (await resetLink.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(resetLink).toBeVisible(); } }); test('shows link to registration', async ({ page }) => { await page.goto('/users/log-in'); const registerLink = page.locator('a[href*="register"]').first(); if (await registerLink.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(registerLink).toBeVisible(); } }); }); test.describe('Password Reset', () => { test('can access password reset page', async ({ page }) => { await page.goto('/users/reset-password'); await expect(page).toHaveURL(/\/users\/reset-password/); await expect(page.locator('body')).toBeVisible(); }); test('shows password reset form', async ({ page }) => { await page.goto('/users/reset-password'); const emailField = page.locator('input[type="email"]').first(); const submitButton = page.locator('button[type="submit"]').first(); if (await emailField.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(emailField).toBeVisible(); } if (await submitButton.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(submitButton).toBeVisible(); } }); }); test.describe('TOTP Enrollment', () => { test('can access TOTP enrollment page when authenticated', async ({ page }) => { await page.goto('/account/totp-enrollment'); // Will redirect to login if not authenticated const currentUrl = page.url(); if (currentUrl.includes('log-in')) { // Expected - not authenticated return; } await expect(page).toHaveURL(/\/account\/totp-enrollment/); await expect(page.locator('body')).toBeVisible(); }); test('shows QR code for TOTP setup', async ({ page }) => { await page.goto('/account/totp-enrollment'); // Skip if redirected to login if ((await page.url()).includes('log-in')) { return; } // Look for QR code or setup instructions const qrCode = page.locator('canvas, img[alt*="QR"], [data-qr]').first(); const setupInstructions = page.locator(':has-text("scan"), :has-text("authenticator")').first(); const qrVisible = await qrCode.isVisible({ timeout: 2000 }).catch(() => false); const instructionsVisible = await setupInstructions.isVisible({ timeout: 2000 }).catch(() => false); if (qrVisible || instructionsVisible) { // At least one should be visible expect(qrVisible || instructionsVisible).toBe(true); } }); }); test.describe('Email Confirmation', () => { test('can access confirmation page', async ({ page }) => { await page.goto('/users/confirm'); await expect(page).toHaveURL(/\/users\/confirm/); await expect(page.locator('body')).toBeVisible(); }); test('shows confirmation instructions', async ({ page }) => { await page.goto('/users/confirm'); const instructions = page.locator(':has-text("email"), :has-text("confirm")').first(); if (await instructions.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(instructions).toBeVisible(); } }); }); });