import { test, expect } from '@playwright/test' test.describe('Auth Components', () => { test.describe('SignInForm', () => { test('should render sign in form with all fields', async ({ page }) => { await page.goto('/login') await expect(page.locator('input[name="email"]')).toBeVisible() await expect(page.locator('input[name="password"]')).toBeVisible() await expect(page.locator('button[type="submit"]')).toBeVisible() await expect(page.locator('label[for="email"]')).toContainText('Email') await expect(page.locator('label[for="password"]')).toContainText('Password') }) test('should validate email format', async ({ page }) => { await page.goto('/login') await page.fill('input[name="email"]', 'invalid-email') await page.fill('input[name="password"]', 'password123') await page.click('button[type="submit"]') const emailField = page.locator('input[name="email"]') const validationMessage = await emailField.getAttribute('validationMessage') expect(validationMessage).toBeTruthy() }) test('should disable submit button when loading', async ({ page }) => { await page.goto('/login') await page.fill('input[name="email"]', 'test@example.com') await page.fill('input[name="password"]', 'password123') const submitButton = page.locator('button[type="submit"]') await submitButton.click() await expect(submitButton).toBeDisabled() await expect(submitButton).toContainText('Signing in...') }) }) test.describe('SignUpForm', () => { test('should render sign up form with all fields', async ({ page }) => { await page.goto('/signup') await expect(page.locator('input[name="email"]')).toBeVisible() await expect(page.locator('input[name="password"]')).toBeVisible() await expect(page.locator('input[name="confirmPassword"]')).toBeVisible() await expect(page.locator('button[type="submit"]')).toBeVisible() }) test('should validate password confirmation', async ({ page }) => { await page.goto('/signup') await page.fill('input[name="email"]', 'test@example.com') await page.fill('input[name="password"]', 'password123') await page.fill('input[name="confirmPassword"]', 'different') await page.click('button[type="submit"]') await expect(page.locator('.text-red-600')).toContainText('Passwords do not match') }) test('should show loading state during signup', async ({ page }) => { await page.goto('/signup') await page.fill('input[name="email"]', 'test@example.com') await page.fill('input[name="password"]', 'password123') await page.fill('input[name="confirmPassword"]', 'password123') const submitButton = page.locator('button[type="submit"]') await submitButton.click() await expect(submitButton).toBeDisabled() await expect(submitButton).toContainText('Creating account...') }) }) test.describe('UserMenu', () => { test.beforeEach(async ({ page }) => { await page.goto('/login') await page.fill('input[name="email"]', 'test@example.com') await page.fill('input[name="password"]', 'password123') await page.click('button[type="submit"]') await expect(page).toHaveURL(/.*dashboard/) }) test('should show user avatar and email', async ({ page }) => { const userMenu = page.locator('[data-testid="user-menu-button"]') await expect(userMenu).toBeVisible() await expect(userMenu).toContainText('test@example.com') }) test('should show dropdown menu when clicked', async ({ page }) => { await page.click('[data-testid="user-menu-button"]') await expect(page.locator('div:has-text("test@example.com")')).toBeVisible() await expect(page.locator('a:has-text("Profile")')).toBeVisible() await expect(page.locator('a:has-text("Settings")')).toBeVisible() await expect(page.locator('button:has-text("Sign Out")')).toBeVisible() }) test('should navigate to profile page', async ({ page }) => { await page.click('[data-testid="user-menu-button"]') await page.click('a:has-text("Profile")') await expect(page).toHaveURL(/.*profile/) }) test('should sign out when clicked', async ({ page }) => { await page.click('[data-testid="user-menu-button"]') await page.click('button:has-text("Sign Out")') await expect(page).toHaveURL(/.*login/) }) }) }) test.describe('Auth Guards', () => { test('should show loading spinner initially', async ({ page }) => { await page.goto('/dashboard') await expect(page.locator('.animate-spin')).toBeVisible() }) test('should redirect to login for unauthenticated users', async ({ page }) => { await page.goto('/dashboard') await expect(page).toHaveURL(/.*login/) }) test('should show access denied for insufficient permissions', async ({ page }) => { await page.goto('/login') await page.fill('input[name="email"]', 'user@example.com') await page.fill('input[name="password"]', 'password123') await page.click('button[type="submit"]') await page.goto('/admin/dashboard') await expect(page.locator('h2:has-text("Access Denied")')).toBeVisible() }) test('should allow access for authorized users', async ({ page }) => { await page.goto('/login') await page.fill('input[name="email"]', 'admin@example.com') await page.fill('input[name="password"]', 'password123') await page.click('button[type="submit"]') await page.goto('/admin/dashboard') await expect(page.locator('h1:has-text("Admin Dashboard")')).toBeVisible() }) }) test.describe('Error Handling', () => { test('should display error messages for failed auth', async ({ page }) => { await page.goto('/login') await page.fill('input[name="email"]', 'invalid@example.com') await page.fill('input[name="password"]', 'wrongpassword') await page.click('button[type="submit"]') await expect(page.locator('.text-red-600')).toContainText('Invalid email or password') }) test('should handle network errors gracefully', async ({ page }) => { await page.route('**/api/auth/login', route => route.abort()) await page.goto('/login') await page.fill('input[name="email"]', 'test@example.com') await page.fill('input[name="password"]', 'password123') await page.click('button[type="submit"]') await expect(page.locator('.text-red-600')).toBeVisible() }) })