Une agence spécialisée dans les sites vitrines pour cabinets de conseil livre en moyenne quatre à cinq projets WordPress par mois. La recette manuelle au clavier, page par page, ne passait plus à cette cadence : certains pièges au clavier passaient entre les mailles du filet, découverts seulement après mise en ligne, parfois par un client qui s’en plaignait directement.
Nous avons construit avec cette agence un test automatisé, exécuté avec Playwright à chaque déploiement en préproduction, capable de détecter la majorité des pièges au clavier avant qu’un humain n’ait besoin d’intervenir. Voici la démarche, étape par étape.
Étape 1 : définir ce qu’est un piège à clavier pour un script
Un piège à clavier se produit lorsqu’un utilisateur, en appuyant répétitivement sur Tab, se retrouve bloqué sur un même élément ou dans une boucle fermée dont il ne peut sortir sans utiliser la souris. Pour un script, cela se traduit par un test simple : simuler un grand nombre de pressions sur Tab et vérifier que l’élément actif finit toujours par changer, sauf dans les cas où une boucle est volontaire, comme à l’intérieur d’une fenêtre modale ouverte.
Étape 2 : installer Playwright et préparer le test
npm init playwright@latest
npx playwright install
Nous avons créé un fichier de test dédié, capable de parcourir une liste d’URL fournie en paramètre, correspondant aux gabarits principaux du site à recetter : accueil, page de contenu, fiche produit, formulaire de contact.
Étape 3 : simuler la navigation clavier

import { test, expect } from '@playwright/test';
const pages = ['/', '/a-propos/', '/contact/', '/services/'];
for (const url of pages) {
test(`pas de piège clavier sur ${url}`, async ({ page }) => {
await page.goto(url);
const focusedElements = new Set();
let repetitions = 0;
for (let i = 0; i < 60; i++) {
await page.keyboard.press('Tab');
const handle = await page.evaluateHandle(() => document.activeElement);
const outerHTML = await handle.evaluate((el) => el?.outerHTML?.slice(0, 80));
if (focusedElements.has(outerHTML)) {
repetitions++;
}
focusedElements.add(outerHTML);
}
expect(repetitions).toBeLessThan(45);
});
}
Le test appuie soixante fois sur Tab et enregistre l’élément actif à chaque étape. Si un même élément revient de façon anormalement répétée, cela indique probablement une boucle fermée. Le seuil de quarante-cinq répétitions tolérées permet d’absorber les cas légitimes de petites boucles courtes, comme un menu à trois éléments parcouru plusieurs fois si la page contient peu de contenu focusable.
Étape 4 : gérer le cas des modales ouvertes intentionnellement
Une fenêtre modale correctement construite doit justement piéger le focus à l’intérieur d’elle-même tant qu’elle reste ouverte : c’est un comportement voulu, pas un bug. Notre test exclut ce cas en vérifiant d’abord qu’aucun élément avec role="dialog" n’est présent et visible dans la page avant de lancer la boucle de détection, et en ajoutant un test spécifique et séparé pour les modales, qui vérifie au contraire que le focus reste bien confiné tant qu’elles sont ouvertes.
const dialogOpen = await page.locator('[role="dialog"]:visible').count();
if (dialogOpen > 0) {
test.skip();
}
Étape 5 : intégrer le test au pipeline de déploiement
Ce test a été ajouté au pipeline d’intégration continue de l’agence, exécuté automatiquement dès qu’une branche est poussée vers l’environnement de préproduction. Un rapport HTML généré par Playwright est joint au résultat du déploiement, consultable directement par l’équipe de recette avant la mise en ligne définitive.
- Quarante pages types passées au crible à chaque déploiement
- Trois pièges réels détectés lors des deux premiers mois d’utilisation
- Un temps d’exécution total inférieur à deux minutes pour l’ensemble des gabarits
Un test automatisé de ce genre ne remplace jamais un vrai parcours clavier humain, mais il attrape les régressions grossières avant qu’un client ne les découvre en production, ce qui change complètement la nature de la conversation avec lui.
Notre verdict
Ce test ne détecte pas tous les pièges possibles : il repère surtout les boucles évidentes et répétées, pas les subtilités de focus perdu après fermeture d’un composant, par exemple. Il constitue néanmoins un filet de sécurité précieux, particulièrement utile pour une agence qui produit des sites au rythme soutenu et qui ne peut pas se permettre une recette manuelle exhaustive à chaque mise à jour mineure. Nous recommandons de le compléter, une fois par trimestre, par un vrai passage clavier humain sur les pages les plus critiques du site.