đŸ’„Blog # 25: From Red to Green: Taming Unreliable Tests with Playwright’s Retry Magic

Published on May 20, 2025
 Hey folks 👋 If you’ve ever shouted "But it worked yesterday!" at your test suite — welcome to the club.

In today’s post, I’m sharing my real-world experience dealing with flaky tests in Playwright and how I used retry logic to keep my sanity intact (well, mostly!).

đŸ§Ș The Problem: Tests That Fail Randomly (A Tester’s Nightmare)

Picture this: I wrote a test that checked for a simple piece of text on a page. It ran smoothly on my machine—until suddenly, it didn’t. đŸ˜€

Sometimes it failed due to timeouts. Sometimes due to delayed elements. Sometimes the page just didn’t load fast enough.

That’s when I learned the infamous name for this phenomenon: Flaky Tests.
😈

🔁 Enter Retries – Playwright’s Built-In Magic

Playwright offers a super handy way to automatically rerun failed tests. You can set this up in the config file or directly via CLI.
🔧 Retry via playwright.config.js

// playwright.config.js
export default {
  retries: 2, // Retry failed tests up to 2 times
  use: { headless: true }
};
Boom! No more random failures (or at least, fewer).
💡 You can even set retries differently for CI vs local runs:


export default {
  retries: process.env.CI ? 2 : 0,
};

đŸ§« A Real-World Example: Dynamic Content Loading

Let’s simulate a flaky scenario using this awesome site:

🔗 https://the-internet.herokuapp.com/dynamic_loading/1

Here’s a Playwright test that sometimes fails due to slow loading:


const { test, expect } = require('@playwright/test');

test('flaky test with dynamic loading', async ({ page }) => {
  await page.goto('https://the-internet.herokuapp.com/dynamic_loading/1');
  await page.click('button'); // Start loading content
  await expect(page.locator('#finish')).toHaveText('Hello World!');
});
If “Hello World!” doesn’t load fast enough, the test may fail. But with retries: 2, Playwright gives it a couple of extra chances.

🔍 CLI Retry for Quick Debugging

Don’t want to touch your config file? No problem. You can use the CLI:

npx playwright test --retries=3
This saved me during debugging sessions when I wanted fast feedback without committing config changes.

🧠 Pro Tip: Retry Only What’s Needed

You don’t always want to retry every test. Sometimes only one test is flaky.
test.describe.configure({ retries: 1 });
test('
occasionally flaky API test', async ({ page }) => {
  // this one can use a retry
});
Use this selectively—especially when the flakiness is temporary and known.

⛔ Mistakes I Made (So You Don’t Have To)

While exploring retries, I ran into a few bumps that taught me some important lessons:
  • Retrying too many times hides real problems
Setting retries: 5 felt like a quick fix, but it only delayed debugging. I learned that 1–2 retries are usually enough to identify true flaky behaviour.
  • Retries don’t replace root cause analysis
Just because a test passes after a retry doesn’t mean it’s fine. I now use tools like Playwright’s trace viewer and smarter wait strategies to get to the bottom of issues.
  • Be careful with data-changing tests
Retrying tests that perform actions like form submissions or database updates can lead to duplicates or inconsistent data. Now, I avoid retries for such non-idempotent operations.

📝 My Retry Cheat Sheet

Scenario                           How
Retry all tests                   retries: 2 in playwright.config.js
Retry a test group           test.describe.configure({ retries: 1 })
CLI retries                           npx playwright test --retries=3
Custom retry logic           for-loop with try/catch and delays

🚀 Final Thoughts

Retries are a great tool—but not a permanent fix. They helped me gain control over flaky tests while I worked on better test design and smarter waiting strategies.
Remember:
  • Retry the right tests
  • Use retry info (test.info().retry) to debug
  • And most importantly—fix the root cause when you can!

Well, that’s a wrap on retries! I hope this post helps you feel a little more in control when your tests act up. If you’ve got retry tips or horror stories of your own, I’d love to hear them—let’s learn together!

Until next time, happy testing and fewer flakes! ✹