import { test, expect } from '@playwright/test'; import { navigateTo, assertPageLoads } from './helpers'; const PAGE_PATH = '/design-system'; test.describe('Démo du design system (/design-system)', () => { test.describe('Chargement & Rendu', () => { test('la page se charge sans crash', async ({ page }) => { await navigateTo(page, PAGE_PATH); await expect(page.locator('main#main-content')).toBeVisible(); }); test('pas d\'erreurs JS dans la console (hors 401 auth)', async ({ page }) => { const errors = await assertPageLoads(page, PAGE_PATH); const realErrors = errors.filter( (e) => !e.includes('/api/v1/auth/me') && !e.includes('401'), ); expect(realErrors).toHaveLength(0); }); test('tous les éléments visuels sont présents', async ({ page }) => { await navigateTo(page, PAGE_PATH); await expect(page.locator('h1')).toBeVisible(); await expect(page.locator('h1')).not.toBeEmpty(); // Subtitle paragraph await expect(page.locator('header p')).toBeVisible(); // Under construction message await expect(page.locator('section p')).toBeVisible(); // Back to home link await expect(page.locator('a[href="/"]')).toBeVisible(); }); test('document.title est mis à jour', async ({ page }) => { await navigateTo(page, PAGE_PATH); await expect(page).toHaveTitle(/Design System/); }); }); test.describe('Accessibilité', () => { test('le skip-to-content fonctionne (cible #main-content existe)', async ({ page }) => { await navigateTo(page, PAGE_PATH); const skipLink = page.locator('a[href="#main-content"]'); await expect(skipLink).toBeAttached(); const mainContent = page.locator('#main-content'); await expect(mainContent).toBeAttached(); }); test('landmark
est présent', async ({ page }) => { await navigateTo(page, PAGE_PATH); const main = page.locator('main'); await expect(main).toBeAttached(); await expect(main).toHaveAttribute('id', 'main-content'); }); test('hiérarchie des headings correcte (h1 unique)', async ({ page }) => { await navigateTo(page, PAGE_PATH); const h1s = page.locator('main h1'); await expect(h1s).toHaveCount(1); }); test('navigation au clavier logique (Tab order)', async ({ page }) => { await navigateTo(page, PAGE_PATH); // First Tab → skip link await page.keyboard.press('Tab'); const skipLink = page.locator('a[href="#main-content"]'); await expect(skipLink).toBeFocused(); // Next Tab → "Back to home" link await page.keyboard.press('Tab'); const backLink = page.locator('a[href="/"]'); await expect(backLink).toBeFocused(); }); test('le lien "Back to home" a un texte accessible', async ({ page }) => { await navigateTo(page, PAGE_PATH); const backLink = page.locator('a[href="/"]'); const text = await backLink.textContent(); expect(text?.trim().length).toBeGreaterThan(0); }); }); test.describe('i18n', () => { test('pas de clés i18n brutes affichées', async ({ page }) => { await navigateTo(page, PAGE_PATH); const bodyText = await page.locator('main').textContent(); // i18n keys look like "designSystem.title" — should not appear as rendered text expect(bodyText).not.toMatch(/designSystem\./); }); test('texte cohérent — pas de mélange avec du texte hardcodé', async ({ page }) => { await navigateTo(page, PAGE_PATH); const bodyText = await page.locator('main').textContent(); // The old hardcoded text should not appear expect(bodyText).not.toContain('Component under construction.'); }); }); test.describe('Responsive', () => { test('mobile 375px — pas d\'overflow horizontal', async ({ page }) => { await page.setViewportSize({ width: 375, height: 812 }); await navigateTo(page, PAGE_PATH); const hasOverflow = await page.evaluate( () => document.documentElement.scrollWidth > document.documentElement.clientWidth, ); expect(hasOverflow).toBe(false); }); test('tablet 768px — pas d\'overflow horizontal', async ({ page }) => { await page.setViewportSize({ width: 768, height: 1024 }); await navigateTo(page, PAGE_PATH); const hasOverflow = await page.evaluate( () => document.documentElement.scrollWidth > document.documentElement.clientWidth, ); expect(hasOverflow).toBe(false); }); test('desktop 1280px — layout correct', async ({ page }) => { await page.setViewportSize({ width: 1280, height: 800 }); await navigateTo(page, PAGE_PATH); const main = page.locator('main'); await expect(main).toBeVisible(); const hasOverflow = await page.evaluate( () => document.documentElement.scrollWidth > document.documentElement.clientWidth, ); expect(hasOverflow).toBe(false); }); }); test.describe('Régression', () => { test('BUG #1 — #main-content existe pour le skip link', async ({ page }) => { await navigateTo(page, PAGE_PATH); await expect(page.locator('#main-content')).toBeAttached(); }); test('BUG #2 — landmark
est présent', async ({ page }) => { await navigateTo(page, PAGE_PATH); await expect(page.locator('main')).toBeAttached(); }); test('BUG #3 — data-testid est présent', async ({ page }) => { await navigateTo(page, PAGE_PATH); await expect(page.locator('[data-testid="design-system-page"]')).toBeAttached(); }); test('BUG #4 — texte traduit via i18n (pas hardcodé)', async ({ page }) => { await navigateTo(page, PAGE_PATH); const h1 = await page.locator('h1').textContent(); // h1 should have actual translated content, not a raw key expect(h1).toBeTruthy(); expect(h1).not.toMatch(/^designSystem\./); }); test('BUG #5 — document.title est mis à jour', async ({ page }) => { await navigateTo(page, PAGE_PATH); const title = await page.title(); expect(title).toContain('Design System'); expect(title).not.toBe('Veza - Plateforme de streaming musical'); }); }); });