From 1db76534188ce140bfc699c3ee68fd8fb04f86bf Mon Sep 17 00:00:00 2001 From: gololdf1sh Date: Fri, 8 May 2026 17:07:28 +0300 Subject: [PATCH] fix(playwright): reset cleanup state at start of _afterSuite to prevent worker crashes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a test fails and its screenshot also fails (timeout, closed page, etc.), `saveScreenshot()` sets `hasCleanupError = true` and pushes to `testFailures[]`. These flags are reset per-test in `_beforeTest()` (line 567-568), but NOT at the start of `_afterSuite()`. So when the last test in a suite has a screenshot failure, the stale error state carries over into `_afterSuite`. At the end of `_afterSuite` (line 841-844), the method checks `if (this.hasCleanupError && this.testFailures.length > 0)` and throws — even if the suite's own cleanup completed successfully. This throw is fatal in a `run-workers` context: it kills the worker thread and silently drops all remaining test files assigned to that worker. Observed impact: in a 4-worker parallel run (133 scenarios), Worker 01 crashed at minute 1 due to this bug. Its remaining ~21 tests were never executed and never reported — a silent 16% test loss with no indication in the CI summary. The fix resets `hasCleanupError` and `testFailures` at the top of `_afterSuite` so the guard clause only evaluates errors from the suite teardown itself, not leftover test-level errors. Co-Authored-By: Claude Opus 4.6 --- lib/helper/Playwright.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/helper/Playwright.js b/lib/helper/Playwright.js index 3fdd6f822..d119ec606 100644 --- a/lib/helper/Playwright.js +++ b/lib/helper/Playwright.js @@ -755,6 +755,11 @@ class Playwright extends Helper { } async _afterSuite() { + // Reset leftover test-level cleanup state (e.g. screenshot failures) + // so only errors from this suite teardown are evaluated below. + this.hasCleanupError = false + this.testFailures = [] + // Stop browser after suite completes // For restart strategies: stop after each suite // For session mode (restart:false): stop after the last suite