Articlepar DevBlog

Automatiser l'accessibilité avec axe dans la CI

Intégrer axe-core à Playwright pour détecter les violations WCAG à chaque build, avec un exemple réel : les cases à cocher GFM sans libellé.

  • #accessibilite
  • #playwright
  • #axe
  • #ci

Pourquoi automatiser ?

L'accessibilité se dégrade sans bruit : un contraste modifié, un bouton sans nom, un champ sans libellé. Un outil comme axe-core détecte automatiquement une partie des problèmes WCAG. Il ne remplace pas un test manuel au clavier ou au lecteur d'écran, mais il attrape les régressions les plus courantes.

Intégration avec Playwright

typescript
import AxeBuilder from "@axe-core/playwright";

test("la page d'accueil n'a pas de violation grave", async ({ page }) => {
  await page.goto("/");

  const results = await new AxeBuilder({ page })
    .withTags(["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"])
    .analyze();

  const blocking = results.violations.filter(
    (v) => v.impact === "serious" || v.impact === "critical",
  );
  expect(blocking).toEqual([]);
});

On fait échouer le test sur les violations graves ou critiques ; les autres restent à traiter progressivement.

Tester les deux thèmes

Un contraste correct en thème sombre peut être insuffisant en thème clair. Lancez axe dans chacun des thèmes, en forçant l'attribut data-theme avant l'analyse.

Un cas concret

En lançant axe sur un article contenant une liste de tâches GitHub (- [ ] …), une violation est apparue : les cases à cocher n'avaient aucun libellé associé. Un lecteur d'écran annonçait « case à cocher » sans dire de quoi il s'agissait.

La correction : envelopper chaque élément de liste de tâches dans un <label>.

tsx
li: ({ children, className }) =>
  className?.includes("task-list-item") ? (
    <li className={className}>
      <label>{children}</label>
    </li>
  ) : (
    <li className={className}>{children}</li>
  ),

Les limites d'axe

Les outils automatiques couvrent à peu près un tiers des critères. Ils ne savent pas dire si un texte alternatif est pertinent, si l'ordre de lecture est logique ou si un composant est utilisable au clavier. Complétez avec :

  • une navigation complète au clavier seul ;
  • un test avec un lecteur d'écran ;
  • le respect de prefers-reduced-motion.

À retenir

  • axe dans la CI : filet de sécurité contre les régressions.
  • Testez les deux thèmes.
  • Un état n'est jamais porté par la couleur seule.