--- name: e2e-a11y-testing description: >- Automate end-to-end accessibility (WCAG 2.2 AA) and visual regression testing using Playwright and @axe-core/playwright. Enforces automated gates for keyboard focus trapping, ARIA roles, and cross-viewport screenshot diffing. --- # E2E Accessibility & Visual Regression Testing Ce skill standardise les tests de bout en bout (E2E) pour garantir qu'aucune régression visuelle ou d'accessibilité (WCAG 2.2 AA) ne soit livrée en production. Il couple **Playwright** et le moteur d'analyse **Axe-core**. --- ## 🎯 Déclencheurs d'Activation Activez ce skill dès que : 1. Vous créez ou modifiez des composants interactifs critiques (modales, menus déroulants, formulaires d'inscription, flux d'achat). 2. Vous devez vérifier qu'une modale capture bien le focus clavier (*focus trap*) et se ferme avec la touche `Échap`. 3. Vous mettez en place des tests d'accessibilité automatisés dans un pipeline CI/CD (GitHub Actions). 4. Vous validez le comportement responsive sur les 3 résolutions de référence (Mobile 375px, Tablette 768px, Desktop 1440px). --- ## 🧪 1. Test d'Accessibilité Automatisé avec `@axe-core/playwright` Ce test injecte Axe-core directement dans la page rendue par Playwright pour détecter 100% des violations automatisables (contrastes, attributs ARIA orphelins, étiquettes de formulaires manquantes) : ```typescript // tests/a11y.spec.ts import { test, expect } from '@playwright/test'; import AxeBuilder from '@axe-core/playwright'; test.describe('Audit d\'accessibilité globale WCAG 2.2 AA', () => { test('La page d\'accueil ne doit présenter aucune violation critique ou sérieuse', async ({ page }) => { await page.goto('/'); // Attendre que la page et les polices soient stabilisées await page.waitForLoadState('networkidle'); const accessibilityScanResults = await new AxeBuilder({ page }) .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa']) .analyze(); expect(accessibilityScanResults.violations).toEqual([]); }); }); ``` --- ## ⌨️ 2. Test du Piège de Focus Clavier (*Focus Trap*) dans une Modale Ce test vérifie que le focus reste enfermé dans la boîte de dialogue et revient sur le bouton d'origine à la fermeture : ```typescript // tests/modal-keyboard.spec.ts import { test, expect } from '@playwright/test'; test('La modale respecte le flux clavier standard', async ({ page }) => { await page.goto('/dashboard'); const triggerButton = page.getByRole('button', { name: 'Nouvelle tâche' }); await triggerButton.click(); const dialog = page.getByRole('dialog'); await expect(dialog).toBeVisible(); // Le premier champ interactif de la modale doit avoir le focus const firstInput = dialog.getByRole('textbox', { name: 'Titre' }); await expect(firstInput).toBeFocused(); // Navigation avec la touche Tab await page.keyboard.press('Tab'); const closeButton = dialog.getByRole('button', { name: 'Fermer' }); await expect(closeButton).toBeFocused(); // Boucle : Tab depuis le dernier élément doit revenir au premier await page.keyboard.press('Tab'); await expect(firstInput).toBeFocused(); // Fermeture par la touche Échap (Escape) await page.keyboard.press('Escape'); await expect(dialog).toBeHidden(); // Le focus doit être restitué au bouton déclencheur initial await expect(triggerButton).toBeFocused(); }); ``` --- ## 📸 3. Test de Régression Visuelle Multi-Viewport Pour garantir que les ajustements CSS ne cassent pas le rendu visuel : ```typescript // tests/visual-regression.spec.ts import { test, expect } from '@playwright/test'; const viewports = [ { name: 'mobile', width: 375, height: 812 }, { name: 'tablet', width: 768, height: 1024 }, { name: 'desktop', width: 1440, height: 900 }, ]; for (const vp of viewports) { test(`Capture de référence responsive - ${vp.name}`, async ({ page }) => { await page.setViewportSize({ width: vp.width, height: vp.height }); await page.goto('/'); await page.waitForLoadState('networkidle'); await expect(page).toHaveScreenshot(`homepage-${vp.name}.png`, { maxDiffPixelRatio: 0.02, // Seuil de tolérance anti-bruit de 2% animations: 'disabled', // Neutralise les animations pour éviter les faux positifs }); }); } ``` --- ## 📋 Checklist de Conformité Tests E2E & A11y - [ ] La suite de tests `@axe-core/playwright` s'exécute sans violation sur toutes les pages publiques. - [ ] Les flux au clavier (`Tab`, `Shift+Tab`, `Escape`, `Enter`) sont couverts par des assertions explicites. - [ ] Les éléments cliquables possèdent un nom accessible vérifiable via `page.getByRole()`. - [ ] Les captures de régression visuelle couvrent à la fois les thèmes clair et sombre. - [ ] Les tests échouent immédiatement en CI si un contraste de couleur passe sous le seuil 4.5:1.