Flaky Playwright tests breaking weekly—what actually fixes them long-term?

We’re running about 200 Playwright tests across our app and it’s gotten ridiculous. Some days half of them fail, other days they pass. The failures aren’t consistent either, which makes debugging a nightmare. Timeouts, element not found errors, stale references—the usual suspects. We’ve tried the standard fixes: explicit waits, better selectors, retry logic. Works for a bit, then something shifts and we’re back to square one.

The root problem is that our selectors are brittle. We’re matching on CSS classes that change during refactors. Element IDs aren’t stable. We switched to more semantic locators—role, text, aria labels—but that’s still just patching symptoms.

Then I tried a different angle. Instead of manually crafting each selector and hardcoding the entire test flow, I started describing what the test should accomplish in plain language and letting an AI generate the Playwright code. Figured if the AI understands the intent, it might pick better strategies than I would.

The generated workflows use a mix of locator strategies—not just relying on one brittle selector. And when the UI inevitably changes, the logic adapts instead of just breaking. I haven’t eliminated flaky tests entirely, but the failure rate dropped from “we’re not shipping today” to “maybe one test needs attention.”

I’m curious if others have tackled this. Are you writing Playwright tests manually and constantly fixing them, or have you found ways to make them more resilient?

The core issue is that traditional Playwright tests rely on static selectors that break the moment the UI changes. What you’re describing is exactly what Latenode’s AI Copilot Workflow Generation solves.

You describe your test scenario—“verify login across browsers with UI changes”—and the AI generates the Playwright workflow. The key difference is that it’s not hardcoding selectors. It understands the semantic intent and uses resilient locator strategies that survive UI refactors.

When your designers swap out CSS classes or restructure the DOM, the workflow adapts instead of snapping. You still own the code, but you’re not manually maintaining thousands of brittle selectors.

We use this for cross-browser test suites that need to stay stable across different rendering engines. Saves us hours every week that used to go into selector hunting.

This is the real pain point with Playwright at scale. You can’t just hardcode selectors and expect them to last. What helped us was moving away from CSS class selectors entirely. We use role based locators, text matching, and accessibility attributes. They’re more stable because designers don’t usually change those without breaking actual functionality.

But even that requires discipline. The team has to agree on these practices upfront, and you still need maintenance as features evolve. It’s not perfect but it’s way better than chasing selectors every sprint.

We reduced flakiness by implementing a proper wait strategy instead of just setting arbitrary timeouts. Use waitForFunction or waitForSelector with specific conditions, not just “wait 5 seconds and hope.” We also added a system where if a test fails, it retries once automatically before marking it failed. Catches most flaky runs without clogging up the logs.

The bigger win was refactoring tests to be more focused. Smaller tests with fewer steps mean fewer places where things can go wrong. Long test sequences are inherently flaky because they accumulate more edge cases.

Explicit waits over implicit. Test role based locators instead of css classes. Smaller focused tests instead of long chains. That combo cut our flakes by 80%.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.