import { test, expect } from '@playwright/test'; import { execSync } from 'child_process'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const baseUrl = process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:4173'; const urlMatch = baseUrl.match(/:(\d+)$/); const PORT = urlMatch ? urlMatch[1] : '4173'; const ALPHA_URL = `http://ecole-alpha.classeo.local:${PORT}`; const STUDENT_EMAIL = 'e2e-dash-nav-student@example.com'; const STUDENT_PASSWORD = 'DashNavStudent123'; const projectRoot = join(__dirname, '../..'); const composeFile = join(projectRoot, 'compose.yaml'); async function loginAsStudent(page: import('@playwright/test').Page) { await page.goto(`${ALPHA_URL}/login`); await page.locator('#email').fill(STUDENT_EMAIL); await page.locator('#password').fill(STUDENT_PASSWORD); await Promise.all([ page.waitForURL(/\/dashboard/, { timeout: 60000 }), page.getByRole('button', { name: /se connecter/i }).click() ]); } test.describe('Dashboard Responsive Navigation', () => { test.beforeAll(async () => { execSync( `docker compose -f "${composeFile}" exec -T php php bin/console app:dev:create-test-user --tenant=ecole-alpha --email=${STUDENT_EMAIL} --password=${STUDENT_PASSWORD} --role=ROLE_ELEVE 2>&1`, { encoding: 'utf-8' } ); }); // ========================================================================= // MOBILE (375x667) // ========================================================================= test.describe('Mobile (375x667)', () => { test.use({ viewport: { width: 375, height: 667 } }); test('shows hamburger button and hides desktop nav', async ({ page }) => { await loginAsStudent(page); const hamburger = page.getByRole('button', { name: /ouvrir le menu/i }); await expect(hamburger).toBeVisible({ timeout: 10000 }); const desktopNav = page.locator('.desktop-nav'); await expect(desktopNav).not.toBeVisible(); }); test('opens drawer via hamburger and shows nav links', async ({ page }) => { await loginAsStudent(page); await page.getByRole('button', { name: /ouvrir le menu/i }).click(); const drawer = page.locator('[role="dialog"][aria-modal="true"]'); await expect(drawer).toBeVisible(); // Should show navigation links await expect(drawer.getByText('Tableau de bord')).toBeVisible(); await expect(drawer.getByText('Mon emploi du temps')).toBeVisible(); await expect(drawer.getByText('Paramètres')).toBeVisible(); }); test('closes drawer via close button', async ({ page }) => { await loginAsStudent(page); await page.getByRole('button', { name: /ouvrir le menu/i }).click(); const drawer = page.locator('[role="dialog"][aria-modal="true"]'); await expect(drawer).toBeVisible(); await page.getByRole('button', { name: /fermer le menu/i }).click(); await expect(drawer).not.toBeVisible(); }); test('closes drawer on overlay click', async ({ page }) => { await loginAsStudent(page); await page.getByRole('button', { name: /ouvrir le menu/i }).click(); const drawer = page.locator('[role="dialog"][aria-modal="true"]'); await expect(drawer).toBeVisible(); const overlay = page.locator('.mobile-overlay'); await overlay.click({ position: { x: 350, y: 300 } }); await expect(drawer).not.toBeVisible(); }); test('navigates via mobile drawer and closes it', async ({ page }) => { await loginAsStudent(page); await page.getByRole('button', { name: /ouvrir le menu/i }).click(); const drawer = page.locator('[role="dialog"][aria-modal="true"]'); await expect(drawer).toBeVisible(); await drawer.getByText('Mon emploi du temps').click(); await expect(drawer).not.toBeVisible(); await expect(page).toHaveURL(/\/dashboard\/schedule/); }); test('shows logout button in drawer footer', async ({ page }) => { await loginAsStudent(page); await page.getByRole('button', { name: /ouvrir le menu/i }).click(); const drawer = page.locator('[role="dialog"][aria-modal="true"]'); await expect(drawer).toBeVisible(); const logoutButton = drawer.locator('.mobile-logout'); await expect(logoutButton).toBeVisible(); await expect(logoutButton).toHaveText(/déconnexion/i); }); }); // ========================================================================= // DESKTOP (1280x800) // ========================================================================= test.describe('Desktop (1280x800)', () => { test.use({ viewport: { width: 1280, height: 800 } }); test('hides hamburger and shows desktop nav', async ({ page }) => { await loginAsStudent(page); const hamburger = page.getByRole('button', { name: /ouvrir le menu/i }); await expect(hamburger).not.toBeVisible(); const desktopNav = page.locator('.desktop-nav'); await expect(desktopNav).toBeVisible({ timeout: 10000 }); }); test('desktop nav shows schedule link for student', async ({ page }) => { await loginAsStudent(page); const desktopNav = page.locator('.desktop-nav'); await expect(desktopNav.getByText('Mon EDT')).toBeVisible({ timeout: 10000 }); await expect(desktopNav.getByText('Tableau de bord')).toBeVisible(); }); }); });