- playwright
- flaky
- locators
- ci
- debug
Pourquoi vos tests Playwright deviennent flaky (et comment les arrêter)
waitForTimeout, locators fragiles, animations, API lentes, données instables, parallélisation — les 6 causes les plus fréquentes et comment Doctests les détecte automatiquement.
Tu lances la CI : vert. Tu relances sans rien changer : rouge. Tu relances encore : vert. Toute l’équipe connaît ce test « connu pour être flaky » — et personne ne le corrige parce que « on n’a pas le temps ».
Ce n’est pas de la malchance. C’est structurel. Presque toujours, la flakiness vient d’un petit nombre de patterns répétés. Les identifier, c’est déjà la moitié du chemin pour les arrêter.
Voici les 6 causes que je vois le plus souvent en audit — et comment les détecter automatiquement avant qu’elles ne bloquent ta prochaine MEP.
1. waitForTimeout — le flaky factory
await page.waitForTimeout(3000);
await expect(page.locator('.success')).toBeVisible();
Tu supposes que 3 secondes suffisent. Parfois oui. Parfois l’API met 3,5 s. Parfois 800 ms suffisent et tu perds du temps. Parfois la CI est chargée et 3 s ne suffisent pas.
Playwright auto-retry les assertions — pas les waitForTimeout. C’est la cause #1 de tests structurellement flaky.
Fix : remplace par une assertion sur l’état UI :
await expect(page.getByRole('alert')).toBeVisible({ timeout: 10_000 });
Doctests remonte ce pattern en scan statique (waitForTimeout dans les specs) — souvent classé RACE dans les rapports d’audit.
2. Mauvais locators — CSS, nth-child, texte instable
await page.locator('div > span:nth-child(3)').click();
await page.locator('.btn-primary').click();
Ces sélecteurs cassent à chaque refacto CSS, à chaque traduction, à chaque A/B test. Playwright retry — parfois le DOM est « presque » bon, parfois non. Flaky garanti à moyen terme.
Fix :
getByRole('button', { name: /confirmer/i })getByTestId('checkout-submit')- Page Object Model pour centraliser les changements
En audit, Doctests flaggue les locators CSS fragiles, les xpath non justifiés et les bypass POM (locator inline dans 40 specs au lieu d’un page object).
3. Animations et transitions non attendues
Un bouton devient cliquable après une animation de 400 ms. Ton test clique à 200 ms. Parfois ça passe (animation skip en CI headless), parfois non.
Autres cas :
- overlay / modal qui fade-in
- skeleton loader qui masque le vrai contenu
- scroll virtuel qui déplace l’élément cible
Fix :
await expect(locator).toBeVisible()avant interactionawait expect(locator).toBeEnabled()si pertinent- désactiver les animations en env test seulement si tu contrôles le front (feature flag), pas en contournement aveugle
Le scan Doctests détecte les interactions sans assertion préalable sur l’élément (click direct après navigation sans wait explicite sur l’état).
4. API lentes ou non mockées
Ton test remplit un formulaire, clique « Valider », assert le succès — mais l’API met 8 s un jour sur deux (charge, cold start, rate limit).
Sans mock réseau ou timeout explicite sur l’assertion finale, tu joues à la roulette.
Fix :
page.route()pour stabiliser les réponses en E2Eexpect(..., { timeout: 15_000 })sur l’état post-API- tag
@slowpour isoler ces specs du smoke PR
Doctests analyse les patterns de wait implicite et les specs sans fixtures de données ni isolation réseau documentée.
5. Données instables — le même user, le même panier
test('ajoute un produit', async ({ page }) => {
await login(page, 'test@example.com');
// ...
});
Deux workers parallèles, même compte, même panier, même commande #42 — collision. Le test A échoue parce que le test B a vidé le stock.
Autres pièges :
- date du jour hardcodée (
2024-01-15) - IDs auto-incrémentés supposés fixes
- état partagé entre tests (pas de cleanup)
Fix :
- factory par test (
createUser(),createOrder()) - fixtures Playwright avec scope
test - base de test reset ou transactions rollback
Le scan remonte l’absence de factories, les emails hardcodés répétés et les specs sans isolation (test.describe.configure({ mode: 'serial' }) utilisé comme pansement).
6. Parallélisation — quand fullyParallel: true expose la dette
Playwright parallelise par défaut. C’est une feature — sauf si ta suite suppose un ordre implicite ou un état global.
Signaux :
test.describe.serialpartout (tu masques le problème)- fichiers qui passent seuls en local, flaky en CI (4 workers)
storageStatepartagé et écrasé entre tests
Fix :
- isolation données + auth par worker
- tags pour séparer smoke (parallel safe) vs regression (serial si unavoidable)
workers: 1temporaire le temps de corriger — pas comme solution permanente
Sur l’Audit Flakiness approfondi, Doctests ingère tes runs CI et calcule le flake rate par test — souvent corrélé aux specs qui échouent uniquement en parallèle.
Comment Doctests détecte ces problèmes automatiquement
Je ne devine pas ces patterns à la main sur 200 specs. Doctests, mon moteur interne, scanne le repo et produit un rapport actionnable.
Scan gratuit (2 min)
Sur /services/devis : tu colles l’URL GitHub → score 0–100, dimensions (locators, waits, structure POM, CI), signaux d’anti-patterns. Aperçu immédiat sans engagement.
Audit Flash 490 € (48 h)
Scan code-only approfondi sur ton repo :
- 20+ règles statiques (waitForTimeout, locators CSS, bypass POM, fixtures manquantes…)
- Score de maturité + top findings priorisés
- PDF 8–12 pages + plan de remédiation
- Exemple de livrable : /services/exemple-audit-flash
Aucune modification de ton code — diagnostic only.
Audit Flakiness approfondi
Ingestion de tes derniers runs CI (JUnit, report JSON) :
- flake rate par test sur 30 jours
- corrélation flake × anti-patterns dans le spec / POM
- priorisation :
impact = flake_rate × fréquence × sévérité patterns
Tu sais quels 5 tests corriger en premier — pas « toute la suite est flaky ».
Ce que le scan remonte concrètement
| Problème | Signal Doctests |
|---|---|
waitForTimeout | Règle RACE — comptage + extrait de code |
| Locators CSS fragiles | Règle LOCATOR — fichier + ligne |
| Bypass POM | Interaction inline hors page objects |
| Données partagées | Emails / IDs dupliqués, pas de factory |
| CI opaque | Pas de config retry / artefacts / shards documentés |
| Flaky runtime | Corrélation CI (audit approfondi) |
Ce n’est pas un linter générique. Ce sont des règles calibrées Playwright + TypeScript, enrichies par ce que je vois sur les missions réelles.
Par où commencer cette semaine
- Lance le scan gratuit — tu verras si
waitForTimeoutet locators CSS dominent - Note le top 3 findings — ce sont tes quick wins
- Si la CI est rouge plusieurs fois par semaine → Audit Flash pour un plan PDF priorisé
- Si tu as 100+ specs et des runs CI → audit approfondi pour la liste flaky corrélée
Tu n’as pas besoin de réécrire 200 tests. Tu as besoin de tuer les 20 % qui causent 80 % du bruit.
Conclusion
Les tests Playwright ne deviennent pas flaky « tout seuls ». Ils héritent de waits arbitraires, locators fragiles, données partagées et API non maîtrisées — amplifiés par la parallélisation.
Doctests existe pour rendre ces causes visibles en minutes, pas en semaines de debug. Scan, score, top findings, plan — puis tu choisis si tu corriges en interne ou si on enchaîne sur un Sprint de stabilisation.
Le bloc en bas de page te montre comment réserver un Audit Flash ou lancer un diagnostic sur ton repo.