<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kate Sai kishore</title>
    <description>The latest articles on DEV Community by Kate Sai kishore (@kate_saikishore_5d4d69ae).</description>
    <link>https://dev.to/kate_saikishore_5d4d69ae</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4239843%2Fe13e8d56-eaee-4b7e-8e37-6654a28c42da.jpg</url>
      <title>DEV Community: Kate Sai kishore</title>
      <link>https://dev.to/kate_saikishore_5d4d69ae</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kate_saikishore_5d4d69ae"/>
    <language>en</language>
    <item>
      <title>I built QAFind — a red Playwright build should mean a real bug</title>
      <dc:creator>Kate Sai kishore</dc:creator>
      <pubDate>Wed, 11 Nov 2026 20:53:17 +0000</pubDate>
      <link>https://dev.to/kate_saikishore_5d4d69ae/i-built-qafind-a-red-playwright-build-should-mean-a-real-bug-3hlm</link>
      <guid>https://dev.to/kate_saikishore_5d4d69ae/i-built-qafind-a-red-playwright-build-should-mean-a-real-bug-3hlm</guid>
      <description>&lt;p&gt;`If your team clicks &lt;strong&gt;Re-run failed jobs&lt;/strong&gt; more than once a week, your end-to-end suite has stopped telling you the truth. Red no longer means "you broke something". It means "something was slow, probably".&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;&lt;a href="https://github.com/katesaikishore/QAFind" rel="noopener noreferrer"&gt;QAFind&lt;/a&gt;&lt;/strong&gt; to fix that. It's an open-source (MIT) CLI that attaches to the Playwright suite you already run. You don't rewrite specs, adopt a new runner or sign up for anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does, in one sentence each
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;attach&lt;/code&gt;&lt;/strong&gt; wraps your existing &lt;code&gt;playwright.config.ts&lt;/code&gt;. Your config and specs are read, never written.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;verify-merge&lt;/code&gt;&lt;/strong&gt; runs the specs a PR touches, reruns failures once, and fails CI &lt;strong&gt;only on a regression that reproduces&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;flake&lt;/code&gt;&lt;/strong&gt; aggregates runs and tells you which tests flake, the probable cause, how confident it is, and who owns them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;attach --determinism&lt;/code&gt;&lt;/strong&gt; records and replays network traffic and freezes the browser clock, so fewer tests flake in the first place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signed evidence&lt;/strong&gt;: every verdict can be signed (HMAC or Ed25519) and exported as an in-toto attestation you can verify offline.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  60-second start
&lt;/h2&gt;

&lt;p&gt;From the root of any Playwright project:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npx qafind attach .&lt;br&gt;
npx playwright test --config .qafind/playwright.qafind.config.ts&lt;br&gt;
npx qafind flake .qafind/reports --markdown&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's it. The first command writes a wrapper config into &lt;code&gt;.qafind/&lt;/code&gt;. The second is your normal test run with one extra reporter. The third gives you a table like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;text&lt;br&gt;
| Test                          | Runs | Flakes | Cause            | Quarantine |&lt;br&gt;
| cart fixture returns totals   |  3   |   1    | network_fixture  | yes        |&lt;br&gt;
| login selector exists         |  3   |   1    | selector_drift   | yes        |&lt;br&gt;
| slow recommendations endpoint |  3   |   1    | timing           | yes        |&lt;br&gt;
| known checkout total mismatch |  3   |   3    | app_race         | no         |&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Notice the last row: it failed every time, so it's a real failure and it is &lt;strong&gt;never&lt;/strong&gt; suggested for quarantine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The merge gate
&lt;/h2&gt;

&lt;p&gt;Add one step to CI:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npx qafind verify-merge --run --base origin/main --head HEAD&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;First run&lt;/th&gt;
&lt;th&gt;Rerun&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;th&gt;Blocks merge?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;failed&lt;/td&gt;
&lt;td&gt;failed&lt;/td&gt;
&lt;td&gt;regression&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;yes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;failed&lt;/td&gt;
&lt;td&gt;passed&lt;/td&gt;
&lt;td&gt;flake&lt;/td&gt;
&lt;td&gt;no (but it's recorded)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;failed&lt;/td&gt;
&lt;td&gt;different failure&lt;/td&gt;
&lt;td&gt;unreproduced&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Flakes stop holding your PRs hostage. Real regressions still stop the merge. Add &lt;code&gt;--markdown&lt;/code&gt; for a PR comment, or &lt;code&gt;--intoto&lt;/code&gt; for a signed attestation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just use retries?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;retries: 2&lt;/code&gt; turns a flaky failure into a green exit code and throws away the information. Nobody counts how often a test needed a retry, and an intermittent bug your users will hit looks identical to a slow CI runner. QAFind keeps that information, counts it, and puts it in front of a human. Only the reproduced failures block.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it isn't
&lt;/h2&gt;

&lt;p&gt;I'd rather you trust it than be surprised by it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Playwright only&lt;/strong&gt;, for now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cause labels are suggestions&lt;/strong&gt;, based on error text plus an optional request log. On a synthetic benchmark (400 tests × 5 runs) they're 87.8% accurate on text alone and 90.3% with the request log. Check before you quarantine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebSockets and service workers&lt;/strong&gt; aren't recorded by the network replay yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a test generator.&lt;/strong&gt; It makes the tests you already have more trustworthy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Free for open source
&lt;/h2&gt;

&lt;p&gt;The CLI is MIT and fully local: no account needed for &lt;code&gt;attach&lt;/code&gt;, &lt;code&gt;flake&lt;/code&gt; or &lt;code&gt;verify-merge&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There's also an optional hosted GitHub App (&lt;a href="https://github.com/apps/qafind-ci" rel="noopener noreferrer"&gt;QAFind CI&lt;/a&gt;) that runs QA on pull requests and comments the report on the PR. &lt;strong&gt;Public repositories are free with no daily quota.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it and tell me where it's wrong
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npx qafind attach .&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;⭐ Repo: &lt;a href="https://github.com/katesaikishore/QAFind" rel="noopener noreferrer"&gt;github.com/katesaikishore/QAFind&lt;/a&gt;&lt;br&gt;
🌐 Site: &lt;a href="https://qafind.si" rel="noopener noreferrer"&gt;qafind.si&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you run it on a real suite, the most useful thing you can send me is a test it labelled wrong. Open an issue or drop it in the comments.&lt;/p&gt;

&lt;p&gt;What's the flakiest test in your suite right now, and what's its excuse?`&lt;/p&gt;

</description>
      <category>ai</category>
      <category>playwright</category>
      <category>testing</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Your Playwright suite is lying to you (and retries are how)</title>
      <dc:creator>Kate Sai kishore</dc:creator>
      <pubDate>Wed, 11 Nov 2026 20:49:12 +0000</pubDate>
      <link>https://dev.to/kate_saikishore_5d4d69ae/your-playwright-suite-is-lying-to-you-and-retries-are-how-508j</link>
      <guid>https://dev.to/kate_saikishore_5d4d69ae/your-playwright-suite-is-lying-to-you-and-retries-are-how-508j</guid>
      <description>&lt;p&gt;`&lt;br&gt;
Every team I've talked to about end-to-end tests has the same ritual.&lt;/p&gt;

&lt;p&gt;The PR goes red. Someone opens the CI log, sees &lt;code&gt;Timeout 30000ms exceeded&lt;/code&gt;, shrugs, and clicks &lt;strong&gt;Re-run failed jobs&lt;/strong&gt;. It goes green. Merge.&lt;/p&gt;

&lt;p&gt;Do that enough times and two things happen. First, people stop reading red builds at all. Second, the day a real regression shows up as a timeout, it gets the same shrug and the same re-run — and if it's intermittent, it merges.&lt;/p&gt;

&lt;p&gt;The suite isn't failing. It's &lt;em&gt;lying&lt;/em&gt;. A red check stops meaning "you broke something" and starts meaning "something, somewhere, was slow." I spent the last few months building tooling to make that verdict honest again, and this post is what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retries hide the thing you need to see
&lt;/h2&gt;

&lt;p&gt;Playwright's &lt;code&gt;retries: 2&lt;/code&gt; is the obvious fix, and it does make CI greener. But look at what it does to your signal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A test that fails, then passes on retry, is reported as &lt;strong&gt;flaky&lt;/strong&gt; in the HTML report — and &lt;strong&gt;passed&lt;/strong&gt; by the exit code. CI only reads the exit code.&lt;/li&gt;
&lt;li&gt;Nobody aggregates those flaky passes across runs. The test that has flaked on 30% of runs this month looks identical to the one that flaked once.&lt;/li&gt;
&lt;li&gt;A real race condition your users will hit 1 in 5 times looks &lt;em&gt;exactly&lt;/em&gt; like a flake. Retries launder it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So you have two bad options: retries off (every flake blocks a merge, people learn to ignore red) or retries on (every intermittent bug ships, people never see red). What I actually wanted was a third rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Block the merge only on a failure you can reproduce. Everything else gets reported, counted and owned — but doesn't block.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Rule 1: rerun once, block only what reproduces
&lt;/h2&gt;

&lt;p&gt;The core idea is boring on purpose. Run the specs a PR touches. If something fails, run those same specs again. Then:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;First run&lt;/th&gt;
&lt;th&gt;Rerun&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;th&gt;Blocks merge?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;failed&lt;/td&gt;
&lt;td&gt;failed&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;regression&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;failed&lt;/td&gt;
&lt;td&gt;passed&lt;/td&gt;
&lt;td&gt;flake&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;failed&lt;/td&gt;
&lt;td&gt;different failure&lt;/td&gt;
&lt;td&gt;unreproduced&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important part is that a flake isn't &lt;em&gt;forgotten&lt;/em&gt; — it's recorded with its error text and counted. It just doesn't get to hold your merge hostage.&lt;/p&gt;

&lt;p&gt;I wired this into an open-source CLI called &lt;a href="https://github.com/katesaikishore/QAFind" rel="noopener noreferrer"&gt;QAFind&lt;/a&gt; (MIT). In CI it's one command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npx qafind verify-merge --run --base origin/main --head HEAD&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--run&lt;/code&gt; picks the affected Playwright specs from the git diff, runs them with the JSON reporter, reruns the failures once, and exits &lt;code&gt;1&lt;/code&gt; &lt;strong&gt;only&lt;/strong&gt; if a regression reproduced. If you already produce Playwright JSON reports in your pipeline, you can hand it both reports instead (&lt;code&gt;--results first.json --rerun-results rerun.json&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;I tested it on a tiny demo suite where the &lt;em&gt;same assertion&lt;/em&gt; fails in two specs. In one it fails twice; in the other it fails then passes:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;text&lt;br&gt;
regression.spec.ts   failed → failed   1 reproduced regression   exit 1&lt;br&gt;
flake.spec.ts        failed → passed   1 flake, 0 regressions    exit 0&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Same error message. Different verdict. The only thing that changed the outcome was whether it reproduced — which is exactly the question a human asks before clicking re-run.&lt;/p&gt;

&lt;p&gt;I also ran it against a third-party open-source Playwright suite I don't own (a page-object example that drives a public demo shop). Its add-to-cart spec failed on both runs, so the verdict was "reproduced regression, merge blocked." No special setup for that repo — which brings me to the second rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rule 2: don't make me rewrite my specs
&lt;/h2&gt;

&lt;p&gt;Every testing tool I evaluated wanted me to adopt its runner, its DSL or its cloud. I have hundreds of specs. I'm not porting them.&lt;/p&gt;

&lt;p&gt;So the attach step wraps your config instead of replacing it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npx qafind attach .&lt;br&gt;
npx playwright test --config .qafind/playwright.qafind.config.ts&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;attach&lt;/code&gt; generates a wrapper config that imports your &lt;code&gt;playwright.config.ts&lt;/code&gt;, keeps your reporters, and appends one more reporter that writes a small JSON manifest per run. Your original config and specs are read, never written. In CI you change one flag.&lt;/p&gt;

&lt;p&gt;The fiddly part, if you ever try this yourself: Playwright resolves paths relative to the &lt;em&gt;config file that was loaded&lt;/em&gt;. Put the wrapper in a subfolder and suddenly &lt;code&gt;testDir&lt;/code&gt;, &lt;code&gt;outputDir&lt;/code&gt;, &lt;code&gt;globalSetup&lt;/code&gt;, &lt;code&gt;storageState&lt;/code&gt; and &lt;code&gt;webServer.cwd&lt;/code&gt; all point to the wrong place and Playwright cheerfully finds zero tests. The wrapper has to rebase every one of those. That one cost me a weekend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rule 3: when it flakes, say &lt;em&gt;why&lt;/em&gt; — and say how sure you are
&lt;/h2&gt;

&lt;p&gt;Once each run leaves a manifest, you can aggregate across runs:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npx qafind flake .qafind/reports --markdown&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;text&lt;br&gt;
| Test                          | Runs | Flakes | Cause            | Quarantine |&lt;br&gt;
| cart fixture returns totals   |  3   |   1    | network_fixture  | yes        |&lt;br&gt;
| login selector exists         |  3   |   1    | selector_drift   | yes        |&lt;br&gt;
| slow recommendations endpoint |  3   |   1    | timing           | yes        |&lt;br&gt;
| known checkout total mismatch |  3   |   3    | app_race         | no         |&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Look at the last row. It failed on &lt;strong&gt;every&lt;/strong&gt; run. That's not a flake — it's a stable failure, so it's never recommended for quarantine. A tool that auto-quarantines anything red is just a slower way to delete your tests.&lt;/p&gt;

&lt;p&gt;I want to be upfront about how the "Cause" column works, because this is where tools overclaim. It's deterministic matching on the recorded error text: &lt;code&gt;net::ERR_&lt;/code&gt; → network, a strict-mode locator violation → selector drift, a bare timeout → timing, an &lt;code&gt;expect&lt;/code&gt; mismatch → app race. If you run with &lt;code&gt;--determinism&lt;/code&gt;, it also records a per-test request ledger, which can &lt;em&gt;confirm&lt;/em&gt; a network cause (a transport failure was really recorded) or &lt;em&gt;contradict&lt;/em&gt; it (all requests succeeded, so it wasn't the network).&lt;/p&gt;

&lt;p&gt;On a seeded synthetic benchmark of 400 tests × 5 runs, that's 87.8% accurate on error text alone and 90.3% with the request ledger. Synthetic means I know the right answer by construction — it measures the classifier, not &lt;em&gt;your&lt;/em&gt; suite. It's a recommendation for a human, not proof of causality. Please verify before you quarantine anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: make the flakes go away instead of labelling them
&lt;/h2&gt;

&lt;p&gt;Labelling flakes is good. Not having them is better. The two biggest sources I see are the network and the clock, so &lt;code&gt;attach --determinism&lt;/code&gt; can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;record&lt;/strong&gt; every HTTP request/response per test, then &lt;strong&gt;replay&lt;/strong&gt; them byte-for-byte on later runs — and fail loudly on a missing fixture rather than silently hitting the network;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;freeze the browser clock&lt;/strong&gt; before navigation, so "3 minutes ago" and end-of-month date logic stop flipping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again with no spec changes: a generated tsconfig path alias points &lt;code&gt;@playwright/test&lt;/code&gt; at a shim that adds auto-use fixtures. Your &lt;code&gt;import { test } from '@playwright/test'&lt;/code&gt; keeps working. (Limits: WebSockets and service workers aren't recorded yet.)&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell my past self
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The exit code is the product.&lt;/strong&gt; Your HTML report can be beautiful; CI only reads one bit. Decide precisely what flips it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Passed on retry" is data, not success.&lt;/strong&gt; Keep it, count it, give it an owner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproduction is the cheapest honest test of a failure.&lt;/strong&gt; One rerun answers most "is this real?" questions before a human looks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never quarantine a test that fails every time.&lt;/strong&gt; That's a bug report.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Say how sure you are.&lt;/strong&gt; A cause label with no confidence attached will eventually be wrong in a way that costs someone a day.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;The CLI is MIT and runs entirely locally — no account needed for &lt;code&gt;attach&lt;/code&gt;, &lt;code&gt;flake&lt;/code&gt; or &lt;code&gt;verify-merge&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npx qafind attach .&lt;br&gt;
npx playwright test --config .qafind/playwright.qafind.config.ts&lt;br&gt;
npx qafind flake .qafind/reports --markdown&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/katesaikishore/QAFind" rel="noopener noreferrer"&gt;github.com/katesaikishore/QAFind&lt;/a&gt;. It's Playwright-only today. If you run it on your suite, I'd love to hear where the cause labels are wrong — real-suite misclassifications are the most useful bug reports I can get.&lt;/p&gt;

&lt;p&gt;How does your team handle flaky e2e tests today — retries, quarantine, or just vibes? Tell me in the comments.`&lt;/p&gt;

</description>
      <category>testing</category>
      <category>ai</category>
      <category>opensource</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
