import { test, expect, Page } from '@playwright/test'; import path from 'path'; const DEMO_ACCOUNTS = { admin: { email: 'admin@example.com', password: 'demo123' }, organizer: { email: 'organizer@example.com', password: 'demo123' }, staff: { email: 'staff@example.com', password: 'demo123' }, }; async function takeScreenshot(page: Page, name: string) { const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const fileName = `navigation_${name}_${timestamp}.png`; await page.screenshot({ path: path.join('screenshots', fileName), fullPage: true }); return fileName; } async function loginAsAdmin(page: Page) { await page.goto('/login'); await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.admin.email); await page.fill('[data-testid="password-input"]', DEMO_ACCOUNTS.admin.password); await page.click('[data-testid="login-button"]'); await expect(page).toHaveURL('/dashboard', { timeout: 10000 }); } test.describe('Navigation and Routing', () => { test.beforeEach(async ({ page }) => { // Clear auth storage await page.evaluate(() => { localStorage.removeItem('bct_auth_user'); localStorage.removeItem('bct_auth_remember'); }); }); test('should navigate through all main sections', async ({ page }) => { await loginAsAdmin(page); // Take screenshot of dashboard await takeScreenshot(page, 'dashboard-page'); // Navigate to Events await page.click('[data-testid="nav-events"]'); await expect(page).toHaveURL('/events'); await expect(page.locator('h1')).toContainText('Events'); await takeScreenshot(page, 'events-page'); // Check active navigation state await expect(page.locator('[data-testid="nav-events"]')).toHaveClass(/active|bg-/); // Navigate to Dashboard await page.click('[data-testid="nav-dashboard"]'); await expect(page).toHaveURL('/dashboard'); await expect(page.locator('h1')).toContainText('Dashboard'); await takeScreenshot(page, 'dashboard-page-return'); // Check active navigation state await expect(page.locator('[data-testid="nav-dashboard"]')).toHaveClass(/active|bg-/); }); test('should show different navigation options based on user role', async ({ page }) => { // Test admin navigation await page.goto('/login'); await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.admin.email); await page.fill('[data-testid="password-input"]', DEMO_ACCOUNTS.admin.password); await page.click('[data-testid="login-button"]'); await expect(page).toHaveURL('/dashboard', { timeout: 10000 }); // Admin should see all navigation options await expect(page.locator('[data-testid="nav-dashboard"]')).toBeVisible(); await expect(page.locator('[data-testid="nav-events"]')).toBeVisible(); await takeScreenshot(page, 'admin-navigation'); // Logout and login as staff await page.click('[data-testid="user-menu"]'); await page.click('[data-testid="logout-button"]'); await expect(page).toHaveURL('/login', { timeout: 10000 }); await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.staff.email); await page.fill('[data-testid="password-input"]', DEMO_ACCOUNTS.staff.password); await page.click('[data-testid="login-button"]'); await expect(page).toHaveURL('/dashboard', { timeout: 10000 }); // Staff should see limited navigation options await expect(page.locator('[data-testid="nav-dashboard"]')).toBeVisible(); await expect(page.locator('[data-testid="nav-events"]')).toBeVisible(); await takeScreenshot(page, 'staff-navigation'); }); test('should handle mobile navigation menu', async ({ page }) => { // Set mobile viewport await page.setViewportSize({ width: 375, height: 667 }); await loginAsAdmin(page); await takeScreenshot(page, 'mobile-dashboard-closed-menu'); // Mobile menu button should be visible await expect(page.locator('[data-testid="mobile-menu-button"]')).toBeVisible(); // Sidebar should be hidden on mobile await expect(page.locator('[data-testid="sidebar"]')).not.toBeVisible(); // Open mobile menu await page.click('[data-testid="mobile-menu-button"]'); // Sidebar should now be visible await expect(page.locator('[data-testid="sidebar"]')).toBeVisible(); await takeScreenshot(page, 'mobile-menu-open'); // Navigate to events via mobile menu await page.click('[data-testid="nav-events"]'); await expect(page).toHaveURL('/events'); // Menu should close after navigation await expect(page.locator('[data-testid="sidebar"]')).not.toBeVisible(); await takeScreenshot(page, 'mobile-events-page'); // Test menu overlay close await page.click('[data-testid="mobile-menu-button"]'); await expect(page.locator('[data-testid="sidebar"]')).toBeVisible(); // Click overlay to close await page.click('[data-testid="mobile-overlay"]'); await expect(page.locator('[data-testid="sidebar"]')).not.toBeVisible(); await takeScreenshot(page, 'mobile-menu-overlay-close'); }); test('should handle desktop navigation properly', async ({ page }) => { // Set desktop viewport await page.setViewportSize({ width: 1280, height: 720 }); await loginAsAdmin(page); // Mobile menu button should not be visible on desktop await expect(page.locator('[data-testid="mobile-menu-button"]')).not.toBeVisible(); // Sidebar should be visible on desktop await expect(page.locator('[data-testid="sidebar"]')).toBeVisible(); await takeScreenshot(page, 'desktop-navigation'); // Test navigation without mobile menu await page.click('[data-testid="nav-events"]'); await expect(page).toHaveURL('/events'); await expect(page.locator('[data-testid="sidebar"]')).toBeVisible(); await takeScreenshot(page, 'desktop-events-navigation'); }); test('should display user menu and profile information', async ({ page }) => { await loginAsAdmin(page); // User menu should show user name and avatar await expect(page.locator('[data-testid="user-menu"]')).toBeVisible(); await expect(page.locator('[data-testid="user-name"]')).toContainText('Sarah Admin'); await expect(page.locator('[data-testid="user-avatar"]')).toBeVisible(); // Click user menu to open dropdown await page.click('[data-testid="user-menu"]'); // Dropdown should show profile options await expect(page.locator('[data-testid="user-dropdown"]')).toBeVisible(); await expect(page.locator('[data-testid="profile-link"]')).toBeVisible(); await expect(page.locator('[data-testid="settings-link"]')).toBeVisible(); await expect(page.locator('[data-testid="logout-button"]')).toBeVisible(); await takeScreenshot(page, 'user-menu-dropdown'); // Click outside to close dropdown await page.click('body'); await expect(page.locator('[data-testid="user-dropdown"]')).not.toBeVisible(); }); test('should show breadcrumb navigation', async ({ page }) => { await loginAsAdmin(page); // Navigate to events await page.click('[data-testid="nav-events"]'); await expect(page).toHaveURL('/events'); // Should show breadcrumb await expect(page.locator('[data-testid="breadcrumb"]')).toBeVisible(); await expect(page.locator('[data-testid="breadcrumb"]')).toContainText('Events'); await takeScreenshot(page, 'breadcrumb-events'); // Navigate back to dashboard await page.click('[data-testid="nav-dashboard"]'); await expect(page).toHaveURL('/dashboard'); await expect(page.locator('[data-testid="breadcrumb"]')).toContainText('Dashboard'); await takeScreenshot(page, 'breadcrumb-dashboard'); }); test('should handle keyboard navigation', async ({ page }) => { await loginAsAdmin(page); // Test tab navigation through main navigation await page.keyboard.press('Tab'); // Skip to content link should be focused first await expect(page.locator('[data-testid="skip-to-content"]')).toBeFocused(); await page.keyboard.press('Tab'); // Navigation items should be focusable await expect(page.locator('[data-testid="nav-dashboard"]')).toBeFocused(); await takeScreenshot(page, 'keyboard-nav-dashboard-focus'); await page.keyboard.press('Tab'); await expect(page.locator('[data-testid="nav-events"]')).toBeFocused(); await takeScreenshot(page, 'keyboard-nav-events-focus'); // Test Enter key navigation await page.keyboard.press('Enter'); await expect(page).toHaveURL('/events'); await takeScreenshot(page, 'keyboard-nav-events-activated'); }); test('should handle skip to content functionality', async ({ page }) => { await loginAsAdmin(page); // Focus skip to content link await page.keyboard.press('Tab'); await expect(page.locator('[data-testid="skip-to-content"]')).toBeFocused(); await takeScreenshot(page, 'skip-to-content-focused'); // Activate skip to content await page.keyboard.press('Enter'); // Main content should be focused await expect(page.locator('[data-testid="main-content"]')).toBeFocused(); await takeScreenshot(page, 'skip-to-content-activated'); }); test('should maintain navigation state across page refreshes', async ({ page }) => { await loginAsAdmin(page); // Navigate to events await page.click('[data-testid="nav-events"]'); await expect(page).toHaveURL('/events'); // Refresh page await page.reload(); // Should stay on events page with correct navigation state await expect(page).toHaveURL('/events'); await expect(page.locator('[data-testid="nav-events"]')).toHaveClass(/active|bg-/); await takeScreenshot(page, 'navigation-state-after-refresh'); }); test('should handle navigation with browser back/forward buttons', async ({ page }) => { await loginAsAdmin(page); // Navigate to events await page.click('[data-testid="nav-events"]'); await expect(page).toHaveURL('/events'); // Use browser back button await page.goBack(); await expect(page).toHaveURL('/dashboard'); await expect(page.locator('[data-testid="nav-dashboard"]')).toHaveClass(/active|bg-/); await takeScreenshot(page, 'browser-back-navigation'); // Use browser forward button await page.goForward(); await expect(page).toHaveURL('/events'); await expect(page.locator('[data-testid="nav-events"]')).toHaveClass(/active|bg-/); await takeScreenshot(page, 'browser-forward-navigation'); }); test('should show loading states during navigation', async ({ page }) => { await loginAsAdmin(page); // Slow down network to see loading states await page.route('**/*', (route) => { setTimeout(() => route.continue(), 500); }); // Navigate to events await page.click('[data-testid="nav-events"]'); // Should show loading state await expect(page.locator('[data-testid="loading-spinner"]')).toBeVisible(); await takeScreenshot(page, 'navigation-loading-state'); // Wait for navigation to complete await expect(page).toHaveURL('/events'); await expect(page.locator('[data-testid="loading-spinner"]')).not.toBeVisible(); await takeScreenshot(page, 'navigation-complete'); }); });