QA visuelle avec Playwright CLI
Règle d'or : pas de verdict sans sortie de commande fraîche. Pas de « ça devrait aller ».
Configuration minimale
- Playwright en tant que devDependency du projet ;
playwright.config.tsavec viewport explicite de 375px (pasdevices['Pixel 7']qui donne 412px) et les projetsdesktop-chromeetmobile-chrome. - Scripts de capture dans
scripts/shot.mjs(ne pas utiliser MCP pour cela : le CLI est plus rapide et reproductible). - Pour axe :
@axe-core/playwright. - Servir le build de production (
npm run build && npm run start) pour mesurer les performances réelles ; utiliser le dev uniquement pour le débogage.
Contrôles par page et par locale
- Console et réseau :
page.on('console'),page.on('pageerror'),page.on('requestfailed')et réponses ≥400. Échec = rouge. - Débordement : sur chaque viewport, vérifier que
document.documentElement.scrollWidth <= clientWidth + 1; si débordement, lister les éléments responsables (getBoundingClientRect().right > innerWidth). - Accessibilité : axe sans violation
critical/serious; un seulh1;img[alt]complet ; focus visible sur tout élément interactif (vérifier:focus-visibleavec un vrai clavier, pas à l'œil) ; ordre de tabulation logique. - Réduction de mouvement :
page.emulateMedia({ reducedMotion: 'reduce' }); pas de ping, d'autoplay ni d'animation de plus de 200ms. - Liens : extraire tous les
href, valider les internes (200) et marquer les externes comme informatifs ; 0href="#"sans gestionnaire. - SEO :
title,meta description, canonical, OG,hreflangpar locale, JSON-LD parseable,sitemap.xmletrobots.txt200. - Performances : mesurer LCP/CLS avec PerformanceObserver après chargement ; objectif LCP < 2.5s et CLS < 0.1 sur desktop ; mesurer le jank de scroll en comptant les trames longues (>50ms) avec rAF pendant 5s de défilement automatisé.
- Canvas/scroll : comme le canvas peut être noir en headless, vérifier par DOM : éléments avec opacité/transform attendues, textes des beats présents et visibles dans les plages correctes, et état exposé dans
windows'il existe.
Boucle
- Après chaque exécution : rapport avec tableau gate/commande/résultat/statut et liste des bloquants avec preuve (selector, log ou capture).
- Si un gate échoue : corriger (tests/scripts propres) ou proposer le correctif concret dans
src/avec preuve ; répéter le cycle complet. - Enregistrer les captures datées dans
docs/qa/(desktop + mobile par locale principale) et baseline pour comparer les régressions. - Ne pas déclarer PRÊT avec un gate rouge ou non exécuté.
Limites honnêtes
- Impossible de valider une séquence d'images sur iOS réel depuis headless : le mentionner dans le rapport.
- Lighthouse via
npx lighthouseest optionnel mais recommandé sur le build de production ; si impossible à exécuter, le dire plutôt que d'estimer.