import { test, expect } from '@playwright/test'; test.describe('Authentication Flow', () => { test.beforeEach(async ({ page }) => { // Start fresh for each test await page.goto('/'); }); test('should display login form on unauthenticated access', async ({ page }) => { // Should redirect to login page await expect(page).toHaveURL(/.*\/login/); // Check login form elements await expect(page.getByRole('heading', { name: /sign in/i })).toBeVisible(); await expect(page.getByLabel(/email/i)).toBeVisible(); await expect(page.getByLabel(/password/i)).toBeVisible(); await expect(page.getByRole('button', { name: /sign in/i })).toBeVisible(); }); test('should show validation errors for empty login form', async ({ page }) => { await page.goto('/login'); // Try to submit empty form await page.getByRole('button', { name: /sign in/i }).click(); // Check for validation errors await expect(page.getByText(/email is required/i)).toBeVisible(); await expect(page.getByText(/password is required/i)).toBeVisible(); }); test('should show error for invalid email format', async ({ page }) => { await page.goto('/login'); // Enter invalid email await page.getByLabel(/email/i).fill('invalid-email'); await page.getByLabel(/password/i).fill('password123'); await page.getByRole('button', { name: /sign in/i }).click(); // Check for validation error await expect(page.getByText(/invalid email format/i)).toBeVisible(); }); test('should handle login failure gracefully', async ({ page }) => { await page.goto('/login'); // Mock failed login response await page.route('**/api/auth/login', async route => { await route.fulfill({ status: 401, contentType: 'application/json', body: JSON.stringify({ detail: 'Invalid credentials' }), }); }); // Fill and submit form await page.getByLabel(/email/i).fill('test@example.com'); await page.getByLabel(/password/i).fill('wrongpassword'); await page.getByRole('button', { name: /sign in/i }).click(); // Check for error message await expect(page.getByText(/invalid credentials/i)).toBeVisible(); // Should still be on login page await expect(page).toHaveURL(/.*\/login/); }); test('should successfully login with valid credentials', async ({ page }) => { await page.goto('/login'); // Mock successful login response await page.route('**/api/auth/login', async route => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ access_token: 'mock-jwt-token', token_type: 'bearer', user: { id: '123e4567-e89b-12d3-a456-426614174000', username: 'testuser', email: 'test@example.com', full_name: 'Test User', role: 'user', is_active: true, is_superuser: false, is_verified: true, }, }), }); }); // Mock the /me endpoint for authenticated user await page.route('**/api/auth/me', async route => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ id: '123e4567-e89b-12d3-a456-426614174000', username: 'testuser', email: 'test@example.com', full_name: 'Test User', role: 'user', is_active: true, is_superuser: false, is_verified: true, }), }); }); // Fill and submit form await page.getByLabel(/email/i).fill('test@example.com'); await page.getByLabel(/password/i).fill('password123'); await page.getByRole('button', { name: /sign in/i }).click(); // Should redirect to dashboard await expect(page).toHaveURL(/.*\/dashboard/); // Check that user is logged in (user menu should be visible) await expect(page.getByText('Test User')).toBeVisible(); }); test('should toggle password visibility', async ({ page }) => { await page.goto('/login'); const passwordInput = page.getByLabel(/password/i); const toggleButton = page.getByRole('button', { name: /toggle password visibility/i }); // Initially password should be hidden await expect(passwordInput).toHaveAttribute('type', 'password'); // Click toggle to show password await toggleButton.click(); await expect(passwordInput).toHaveAttribute('type', 'text'); // Click toggle again to hide password await toggleButton.click(); await expect(passwordInput).toHaveAttribute('type', 'password'); }); test('should logout successfully', async ({ page }) => { // First login await page.goto('/login'); // Mock successful login await page.route('**/api/auth/login', async route => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ access_token: 'mock-jwt-token', token_type: 'bearer', user: { id: '123e4567-e89b-12d3-a456-426614174000', username: 'testuser', email: 'test@example.com', full_name: 'Test User', }, }), }); }); await page.getByLabel(/email/i).fill('test@example.com'); await page.getByLabel(/password/i).fill('password123'); await page.getByRole('button', { name: /sign in/i }).click(); // Wait for dashboard await expect(page).toHaveURL(/.*\/dashboard/); // Click logout await page.getByRole('button', { name: /logout/i }).click(); // Should redirect to login page await expect(page).toHaveURL(/.*\/login/); }); });