Lancer des tests d’accessibilité avec Pa11y

Créé le 23/06/2019

Dernière mise à jour le 23/06/2019

Contexte

Sur le chantier de refonte en Drupal 8 du site https://drupal.fr, Pa11y a été utilisé pour faire un audit d’accessibilité (https://github.com/Drupal-FR/site-drupalfr/issues/51#issuecomment-491448105).

Pa11y est une suite d’outils libres pour auditer l’accessibilité des sites internet.

Je ne connaissais pas cet outil auparavant et étant dans une période où j’améliore ma stack Docker pour Drupal https://github.com/FlorentTorregrosa/docker-drupal-project, j’ai donc voulu la doter de cet outil.

Comme cette solution n’a aucun rapport avec Drupal et peut être utilisée pour n’importe quel type de site, j’ai donc fait un dépôt à part https://github.com/FlorentTorregrosa/docker-pa11y-ci afin d’avoir une image Docker facilement utilisable pour lancer les tests. Cette image peut ensuite facilement être intégrée dans une chaîne d’intégration continue sur un projet.

La suite de l’article décrit le cheminement pour l’obtention de cette image.

Recherche de solutions existantes

Partant du site de Pa11y, l’outil Pa11y-ci encapsule Pa11y pour justement une utilisation massive et automatisée en permettant par exemple d’indiquer un sitemap XML et scanner toutes les pages dedans ou en lançant les tests en précisant dans un fichier de configuration toutes les URLs à scanner.

J’ai donc ensuite cherché si des versions Docker existaient.

Je suis tombé sur :

  1. https://hub.docker.com/r/digitalist/pa11y-ci qui avait l’air de correspondre parfaitement à ce que je recherchais, mais impossible de trouver le dépôt des sources à partir desquelles cette image était fabriquée

  2. https://github.com/promet/docker-pa11y-ci testé rapidement, cela fonctionnait, mais je n’étais pas satisfait des points suivants :

    1. utilisation de Google chrome : je voulais si possible Chromium,

    2. utilisation de la version 1.* de Pa11y-ci : actuellement c’est la 2.* qui est maintenue,

    3. utilisation de la version Debian de l’image Node : une image basée sur alpine serait bien plus légère,

    4. le fichier docker-compose.yml du dépôt était plus pour build l’image que pour une utilisation où il suffit juste de cloner le dépôt.

J’ai donc forké https://github.com/promet/docker-pa11y-ci et mis en place les améliorations précédentes.

Difficultés rencontrées

L’erreur que j’ai faite a été de vouloir faire toutes les améliorations simultanément :

  • passage à Alpine Linux, donc la plupart des paquets n’ont pas exactement le même nom par rapport aux paquets Debian, du coup pour trouver les correspondances, cela a été assez manuel, paquet après paquets...

  • passage à la branche 2.* de Pa11y-ci qui du coup fait qu’on passe de la version 4.* de Pa11y à la 5.* qui elle s’appuie sur Puppeteer https://github.com/GoogleChrome/puppeteer qui amène beaucoup de changements,

  • passage à Chromium. Là j’avais des erreurs comme quoi « Chromium revision » n’était pas présent.

J’ai donc revu mon approche et décidé de procéder étape par étape en partant de l’image du fork qui elle buildée et était fonctionnelle :

  1. réorganisation à ma façon l’image d’origine, au passage upgrade sur Node 12 comme image de base. J’ai également décider de conserver l’image Debian Stretch afin d’avoir une image basée sur Debian et une basée sur Alpine au cas où la maintenance de l’image Alpine devienne trop coûteuse et permettre de comparer les tailles des images,

  2. passage à Pa11y-ci 2.*, et là cela ne fonctionnait plus à cause de l’utilisation de Puppeteer qui ajoutait de la sécurité (à raison) avec l’utilisation des sandbox en utilisateur root, pour résoudre le problème :

    1. création d’un autre utilisateur mais là message d’erreur indiquant que l’utilisateur n’avait pas accès à une sandbox et pas de solution qui fonctionnait,

    2. utilisation de l’option --no-sandbox pour permettre une utilisation en tant qu’utilisateur root, et c’est à ce moment là que je me suis rendu compte que le fichier de configuration config.json pour passer des options à Pa11y-ci qui peut en passer à Puppeteer n’était plus pris en compte. En effet l’entrée « chromeLaunchConfig » située au niveau 0 du fichier devait désormais être placée dans l’entrée « defaults »

  3. En parcourant la documentation de Puppeteer, j’ai pu voir la section dédiée à Docker https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-in-docker et voir l’astuce de la variable d’environnement PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true qui permet si l’on va télécharger Google Chrome ou Chromium via les paquets de la distribution, d’éviter qu’il ne soit téléchargé à nouveau via Npm ou Yarn lors de l’installation de Puppeteer. Et hop, une amélioration supplémentaire.

  4. Passage à Chromium et cette fois-ci avec l’option « executablePath » correctement prise en compte, cela a été simple de faire utiliser le Chromium téléchargé par le gestionnaire de paquet de la distribution.

  5. Une fois l’image Debian Stretch prête, création de l’image pour Alpine, et là cela a été simple, j’ai épuré les paquets nécessaires et pris ceux de la documentation Puppeteer dédiée à Alpine https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-on-alpine, ajout d’un lien symbolique pour avec le même executablePath par rapport à Debian Stretch et c’est ok.

  6. Branchement de build automatisé sur le Hub Docker pour que lors de push sur le dépôt Git cela rebuild les images.

Conclusion

Après avoir bataillé 2 jours, j’ai désormais 2 images Docker https://hub.docker.com/r/florenttorregrosa/pa11y-ci (Stretch 600 Mo et Alpine 150 Mo) permettant de faire des tests automatisés sur l’accessibilité.

Avantage, l’outil n’a aucun rapport avec Drupal (pour une fois :) ) et peut donc être utilisé sur n’importe quel site.

Un point d'amélioration est de permettre de se passer de l'option --no-sandbox afin d'avoir une exécution sécurisée. Le risque est je pense quasi nul si vous scannez des sites de confiance, d'autant que Puppeteer est exécuté dans un conteneur et non sur votre machine directement.

Voir la documentation de Pa11y et Pa11y-ci pour toutes les options possibles.

Ajouter un commentaire