import { test, expect } from '@playwright/test'; test.describe('Authentication Flow', () => { test.beforeEach(async ({ page }) => { // Navigate to homepage await page.goto('/'); }); test('user can register and login', async ({ page }) => { // Navigate to register await page.click('text=Register'); await expect(page).toHaveURL('/register'); // Fill registration form const testEmail = `test-e2e-${Date.now()}@example.com`; await page.fill('[name="email"]', testEmail); await page.fill('[name="username"]', `testuser${Date.now()}`); await page.fill('[name="password"]', 'SecurePass123!'); await page.fill('[name="confirmPassword"]', 'SecurePass123!'); // Submit await page.click('button[type="submit"]'); // Should redirect to dashboard await expect(page).toHaveURL('/dashboard', { timeout: 10000 }); await expect(page.locator('text=Bienvenido')).toBeVisible(); }); test('should reject weak passwords', async ({ page }) => { await page.goto('/register'); await page.fill('[name="email"]', 'weak@test.com'); await page.fill('[name="username"]', 'weakuser'); await page.fill('[name="password"]', '123'); await page.fill('[name="confirmPassword"]', '123'); await page.click('button[type="submit"]'); // Should show error await expect(page.locator('text=Password must be at least')).toBeVisible(); }); test('user can login with valid credentials', async ({ page }) => { await page.goto('/login'); await page.fill('[name="email"]', 'test@example.com'); await page.fill('[name="password"]', 'SecurePass123!'); await page.click('button[type="submit"]'); // Should redirect to dashboard await expect(page).toHaveURL('/dashboard', { timeout: 10000 }); }); test('should reject invalid credentials', async ({ page }) => { await page.goto('/login'); await page.fill('[name="email"]', 'wrong@example.com'); await page.fill('[name="password"]', 'WrongPass123!'); await page.click('button[type="submit"]'); // Should show error await expect(page.locator('text=Invalid credentials')).toBeVisible(); }); }); test.describe('Exercise Flow', () => { test.beforeEach(async ({ page }) => { // Login first await page.goto('/login'); await page.fill('[name="email"]', 'test@example.com'); await page.fill('[name="password"]', 'SecurePass123!'); await page.click('button[type="submit"]'); await expect(page).toHaveURL('/dashboard', { timeout: 10000 }); }); test('user can navigate to exercises', async ({ page }) => { // Go to modules await page.click('text=Módulos'); await expect(page).toHaveURL('/modules'); // Click on first module await page.click('[data-testid="module-card"]'); await expect(page).toHaveURL(/\/modules\//); }); test('user can solve an exercise', async ({ page }) => { // Navigate to an exercise await page.goto('/modules/fundamentos/exercises/ex-1'); // Wait for exercise to load await expect(page.locator('[data-testid="exercise-question"]')).toBeVisible(); // Fill answer await page.fill('[data-testid="answer-input"]', '4'); // Submit await page.click('button:has-text("Enviar")'); // Verify success await expect(page.locator('text=¡Correcto!')).toBeVisible({ timeout: 5000 }); }); test('should handle incorrect answers', async ({ page }) => { await page.goto('/modules/fundamentos/exercises/ex-1'); await expect(page.locator('[data-testid="exercise-question"]')).toBeVisible(); // Wrong answer await page.fill('[data-testid="answer-input"]', '5'); await page.click('button:has-text("Enviar")'); // Should show try again await expect(page.locator('text=Incorrecto')).toBeVisible({ timeout: 5000 }); await expect(page.locator('button:has-text("Intentar de nuevo")')).toBeVisible(); }); test('should prevent XSS in answer input', async ({ page }) => { await page.goto('/modules/fundamentos/exercises/ex-1'); await expect(page.locator('[data-testid="exercise-question"]')).toBeVisible(); // Try XSS await page.fill('[data-testid="answer-input"]', ''); await page.click('button:has-text("Enviar")'); // Should show security error or be sanitized await expect(page.locator('text=security|XSS|inválido', { hasText: /seguridad|security|XSS|inválido/i })).toBeVisible({ timeout: 5000 }); }); test('hint system works correctly', async ({ page }) => { await page.goto('/modules/fundamentos/exercises/ex-1'); await expect(page.locator('[data-testid="exercise-question"]')).toBeVisible(); // Click reveal hint await page.click('button:has-text("Mostrar pista")'); // Hint should be visible await expect(page.locator('[data-testid="hint-content"]')).toBeVisible(); }); }); test.describe('Progress Tracking', () => { test.beforeEach(async ({ page }) => { await page.goto('/login'); await page.fill('[name="email"]', 'test@example.com'); await page.fill('[name="password"]', 'SecurePass123!'); await page.click('button[type="submit"]'); await expect(page).toHaveURL('/dashboard', { timeout: 10000 }); }); test('user can view progress', async ({ page }) => { await page.goto('/progress'); await expect(page.locator('text=Progreso')).toBeVisible(); await expect(page.locator('[data-testid="progress-chart"]')).toBeVisible(); }); test('streak is displayed correctly', async ({ page }) => { await page.goto('/dashboard'); await expect(page.locator('[data-testid="streak-display"]')).toBeVisible(); }); }); test.describe('Admin Panel', () => { test('admin can access admin panel', async ({ page }) => { // Login as admin await page.goto('/login'); await page.fill('[name="email"]', 'admin@mathplatform.com'); await page.fill('[name="password"]', 'admin123'); await page.click('button[type="submit"]'); await expect(page).toHaveURL('/dashboard', { timeout: 10000 }); // Navigate to admin await page.goto('/admin'); await expect(page).toHaveURL('/admin'); }); test('non-admin cannot access admin panel', async ({ page }) => { // Login as regular user await page.goto('/login'); await page.fill('[name="email"]', 'test@example.com'); await page.fill('[name="password"]', 'SecurePass123!'); await page.click('button[type="submit"]'); // Try to access admin await page.goto('/admin'); // Should redirect or show forbidden await expect(page).not.toHaveURL('/admin'); }); }); test.describe('Responsive Design', () => { test('mobile menu works', async ({ page }) => { // Set mobile viewport await page.setViewportSize({ width: 375, height: 667 }); await page.goto('/'); // Open mobile menu await page.click('[data-testid="mobile-menu-button"]'); // Menu should be visible await expect(page.locator('[data-testid="mobile-nav"]')).toBeVisible(); }); });