4.8 KiB
4.8 KiB
| name | description |
|---|---|
| e2e-a11y-testing | 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 :
- Vous créez ou modifiez des composants interactifs critiques (modales, menus déroulants, formulaires d'inscription, flux d'achat).
- Vous devez vérifier qu'une modale capture bien le focus clavier (focus trap) et se ferme avec la touche
Échap. - Vous mettez en place des tests d'accessibilité automatisés dans un pipeline CI/CD (GitHub Actions).
- 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) :
// 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 :
// 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 :
// 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/playwrights'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.