# Intégrer un audit d’accessibilité automatisé avec axe-core en CI WordPress

> Chaque merge request de notre thème maison passe désormais par un contrôle axe-core automatique, qui bloque la fusion en cas de régression d'accessibilité détectable.

- Auteur : Clément Hadrot
- Publié le : 2023-06-29
- Mis à jour le : 2023-06-29
- Catégorie : Accessibilité
- URL : https://wpmoderne.dev.wordpress-developpement.fr/accessibilite/integrer-axe-core-ci-wordpress/

## L’essentiel

- axe-core détecte les erreurs objectives, jamais les problèmes d'ergonomie fine
- Le seuil de tolérance doit être calibré pour ne pas noyer l'équipe d'alertes
- L'intégration se fait en quelques lignes avec Playwright

Notre équipe maintient un thème WordPress commun à une dizaine de projets clients, avec des contributions régulières de plusieurs développeurs. Un audit manuel d'accessibilité à chaque modification du thème n'était tout simplement plus tenable au rythme des livraisons. Nous avons intégré axe-core, moteur de règles d'accessibilité open source utilisé par de nombreux outils du secteur, directement dans notre pipeline d'intégration continue, pour bloquer automatiquement toute régression objective avant la fusion d'une branche.

## Étape 1 : installer axe-core avec Playwright

axe-core s'utilise facilement via le module `@axe-core/playwright`, qui injecte le moteur de règles directement dans le contexte de la page testée :

```
npm install --save-dev @axe-core/playwright
```

## Étape 2 : écrire le test d'audit

```
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';

const gabarits = ['/', '/blog/', '/contact/', '/boutique/'];

for (const url of gabarits) {
  test(`audit axe-core sur ${url}`, async ({ page }) => {
    await page.goto(url);
    const resultats = await new AxeBuilder({ page })
      .withTags(['wcag2a', 'wcag2aa'])
      .analyze();

    expect(resultats.violations).toEqual([]);
  });
}
```

Le filtre `withTags(['wcag2a', 'wcag2aa'])` restreint l'analyse aux critères correspondant aux niveaux A et AA des WCAG, en excluant les règles expérimentales moins consensuelles que le moteur propose également, pour éviter des faux positifs qui décourageraient rapidement l'équipe.

## Étape 3 : calibrer le seuil de tolérance

> L'essentiel à retenir : axe-core détecte les erreurs objectives, jamais les problèmes d'ergonomie fine ; Le seuil de tolérance doit être calibré pour ne pas noyer l'équipe d'alertes ; L'intégration se fait en quelques lignes avec Playwright

Notre première tentative, avec `expect(resultats.violations).toEqual([])` appliqué immédiatement sur le thème existant, a fait échouer la totalité des tests dès le premier lancement : le thème comptait déjà plusieurs dizaines de violations historiques non corrigées. Bloquer toute fusion tant que ce passif entier ne serait pas résorbé aurait paralysé l'équipe pendant des semaines. Nous avons donc procédé en deux temps : d'abord un inventaire complet des violations existantes, consignées dans un fichier de référence, puis une règle qui compare le nombre de violations avant et après chaque modification, en autorisant la stagnation mais en bloquant toute augmentation.

```
const referenceViolations = require('./axe-baseline.json');
const violationsActuelles = resultats.violations.length;
const violationsReference = referenceViolations[url] || 0;

expect(violationsActuelles).toBeLessThanOrEqual(violationsReference);
```

## Étape 4 : générer un rapport lisible pour l'équipe

Chaque violation détectée par axe-core inclut un identifiant de règle, une description en anglais, et un lien vers sa documentation détaillée. Nous avons ajouté une étape de formatage du rapport, qui traduit les identifiants les plus fréquents en phrases compréhensibles pour l'équipe de développement, sans obliger chacun à connaître par cœur la nomenclature interne d'axe-core.

| Identifiant axe-core | Signification en clair |
| --- | --- |
| color-contrast | Contraste de couleur insuffisant |
| label | Champ de formulaire sans étiquette associée |
| image-alt | Image sans texte alternatif |
| aria-required-attr | Attribut ARIA obligatoire manquant |

## Ce qu'axe-core ne détecte jamais

Il est important de rappeler à l'équipe, dès la mise en place de ce contrôle, ce que l'outil ne peut pas vérifier : la pertinence réelle d'un texte alternatif, la cohérence logique d'un ordre de tabulation, ou la clarté d'un message d'erreur. axe-core détecte des erreurs structurelles objectives, comme un attribut manquant ou un contraste insuffisant, jamais des problèmes de sens ou d'ergonomie fine, qui restent du ressort exclusif d'un test manuel humain, complémentaire et non remplacé par ce contrôle automatisé.

- Contrastes insuffisants : détectés systématiquement
- Champs sans étiquette : détectés systématiquement
- Pertinence d'un texte alternatif : jamais détectée
- Piège de focus dans une modale personnalisée : partiellement détecté selon la règle activée

> Un test automatisé qui passe au vert ne signifie jamais qu'un site est accessible : il signifie seulement qu'aucune des erreurs objectives que l'outil sait chercher n'a été introduite depuis la dernière vérification.

## En résumé

Depuis la mise en place de ce contrôle, aucune régression objective détectable par axe-core n'a franchi la fusion sur la branche principale du thème, ce qui a nettement réduit le nombre d'anomalies découvertes tardivement chez les clients. Ce contrôle reste un complément à l'audit manuel régulier, jamais un substitut, et nous continuons à planifier des sessions de test au clavier et au lecteur d'écran en parallèle, sur un rythme trimestriel.
