Skills/e2e-a11y-testing/SKILL.md

130 lines
4.8 KiB
Markdown

---
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.