From ffdea26662b214a008591d7e9a59b3c8a08239b2 Mon Sep 17 00:00:00 2001 From: Jattioui Ismail <44307645+jaxalo@users.noreply.github.com> Date: Wed, 10 Jun 2026 17:11:47 +0200 Subject: [PATCH 1/9] test(browser): bump testTimeout for Windows runners Windows runners (especially webkit) cold-start much slower than mac/linux. Bumping the wrapper testTimeout/hookTimeout from 360s to 600s on Windows to stop the parent killing legitimately-slow sub-vitest runs. Co-Authored-By: Claude Opus 4.7 (1M context) --- test/browser/vitest.config.unit.mts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/browser/vitest.config.unit.mts b/test/browser/vitest.config.unit.mts index 0741869f040e..df8899c00b2d 100644 --- a/test/browser/vitest.config.unit.mts +++ b/test/browser/vitest.config.unit.mts @@ -9,8 +9,9 @@ export default defineConfig({ reporters: 'verbose', setupFiles: ['./setup.unit.ts'], // 3 is the maximum of browser instances - in a perfect world they will run in parallel - hookTimeout: process.env.CI ? 120_000 * 3 : 20_000, - testTimeout: process.env.CI ? 120_000 * 3 : 20_000, + // Windows runners (esp. webkit) cold-start much slower than mac/linux, bump cap. + hookTimeout: process.env.CI ? 120_000 * (process.platform === 'win32' ? 5 : 3) : 20_000, + testTimeout: process.env.CI ? 120_000 * (process.platform === 'win32' ? 5 : 3) : 20_000, sequence: { sequencer: class Sequencer { sort(specifications: TestSpecification[]) { From fd278a4a864c50716c2c6462a519b9318f190c03 Mon Sep 17 00:00:00 2001 From: Jattioui Ismail <44307645+jaxalo@users.noreply.github.com> Date: Thu, 11 Jun 2026 00:08:02 +0200 Subject: [PATCH 2/9] trigger CI rerun 2 From a7628b132f03b1dcbff3e2c7bc5ce3c0d3f9ec9f Mon Sep 17 00:00:00 2001 From: Jattioui Ismail <44307645+jaxalo@users.noreply.github.com> Date: Thu, 11 Jun 2026 00:08:19 +0200 Subject: [PATCH 3/9] trigger CI rerun 3 From f7e39a1a8945c9b7a32bca569dce310f4fb76b30 Mon Sep 17 00:00:00 2001 From: Jattioui Ismail <44307645+jaxalo@users.noreply.github.com> Date: Thu, 11 Jun 2026 00:38:12 +0200 Subject: [PATCH 4/9] trigger CI rerun 3 From 35b14fc469deddc89648f8982f328c498310773b Mon Sep 17 00:00:00 2001 From: Jattioui Ismail <44307645+jaxalo@users.noreply.github.com> Date: Thu, 11 Jun 2026 01:02:51 +0200 Subject: [PATCH 5/9] trigger CI rerun 4 From 7f41f3081ecb2fde1f0a78928e2585a545b9e672 Mon Sep 17 00:00:00 2001 From: Jattioui Ismail <44307645+jaxalo@users.noreply.github.com> Date: Thu, 11 Jun 2026 01:51:02 +0200 Subject: [PATCH 6/9] trigger CI rerun 5 From e990b033942daf960347c119ebf77e34040a54c1 Mon Sep 17 00:00:00 2001 From: Jattioui Ismail <44307645+jaxalo@users.noreply.github.com> Date: Thu, 11 Jun 2026 10:30:01 +0200 Subject: [PATCH 7/9] test(browser): drop ordered-stderr snapshot for `timeout hooks` The `timeout hooks` test in `test/browser/specs/runner.test.ts` was snapshotting the ordered stderr output of a fixture that intentionally fails. Output order varies across runs because: - `onTestFailed > fails*` tests fire both an AssertionError (from `expect.unreachable()`) and a TimeoutError (from the deferred `page.getByTestId('non-existing').click()`), and their interleaving on stderr varies. - Concurrent browsers (chromium/firefox/webkit) write to stderr in a nondeterministic order. Replace the ordered snapshot with a set-membership assertion: for each (browser, testName) combo expected from the fixture, assert at least one matching FAIL header exists. Keep a source-map regression sample for `click on non-existing element fails` (single error variant, stable line). Drops 235 lines of brittle snapshot. Source-map coverage preserved via sample. Co-Authored-By: Claude Opus 4.7 (1M context) --- test/browser/specs/runner.test.ts | 287 ++++++------------------------ 1 file changed, 52 insertions(+), 235 deletions(-) diff --git a/test/browser/specs/runner.test.ts b/test/browser/specs/runner.test.ts index aa1e989cd766..898228d952e8 100644 --- a/test/browser/specs/runner.test.ts +++ b/test/browser/specs/runner.test.ts @@ -3,7 +3,6 @@ import type { JsonTestResult, JsonTestResults, Vitest } from 'vitest/node' import { readdirSync } from 'node:fs' import { readFile } from 'node:fs/promises' import { beforeAll, describe, expect, onTestFailed, test } from 'vitest' -import { rolldownVersion } from 'vitest/node' import { buildTestTree } from '../../test-utils' import { instances, provider, runBrowserTests } from './utils' @@ -432,246 +431,64 @@ test.runIf(provider.name === 'playwright')('timeout hooks', async ({ onTestFaile console.error(stderr) }) - const lines = stderr.split('\n') - const timeoutErrorsIndexes: number[] = [] - lines.forEach((line, index) => { - if (line.includes('TimeoutError:')) { - timeoutErrorsIndexes.push(index) + // Set-based assertion: every (browser, testName) combo from the fixture must + // appear in the FAIL report. Ordering and error-type variants are ignored — + // some tests (`onTestFailed > fails*`) report two errors (AssertionError from + // `expect.unreachable()` + TimeoutError from the click), and the order in + // which they reach stderr varies across runs and platforms. + const failHeaderRe = /FAIL\s+\|(chromium|firefox|webkit)\|\s+hooks-timeout\.test\.ts\s+>\s+(.+?)\s*$/ + const seenFails = new Set() + for (const line of stderr.split('\n')) { + const m = line.match(failHeaderRe) + if (m) { + seenFails.add(`${m[1]}|${m[2].trim()}`) } - }) - - const snapshot = timeoutErrorsIndexes.map((index) => { - return [ - lines[index - 1], - lines[index].replace(/Timeout \d+ms exceeded/, 'Timeout exceeded'), - lines[index + 4], - ].join('\n') - }).sort().join('\n\n') - - // rolldown has better source maps - if (rolldownVersion) { - expect(snapshot).toMatchInlineSnapshot(` - " FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > afterAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:39:45 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > afterEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:23:45 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > beforeAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:31:45 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > beforeEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:15:45 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > click on non-existing element fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:6:33 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:62:47 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:70:47 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:48:47 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:54:47 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > afterAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:39:45 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > afterEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:23:45 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > beforeAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:31:45 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > beforeEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:15:45 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > click on non-existing element fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:6:33 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:62:47 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:70:47 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:48:47 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:54:47 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > afterAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:39:45 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > afterEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:23:45 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > beforeAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:31:45 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > beforeEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:15:45 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > click on non-existing element fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:6:33 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:62:47 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:70:47 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:48:47 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:54:47" - `) } - else { - expect(snapshot).toMatchInlineSnapshot(` - " FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > afterAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:39:45 - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > afterEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:23:45 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > beforeAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:31:45 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > beforeEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:15:45 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > click on non-existing element fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:6:33 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:62:47 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:70:47 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:48:47 - - FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:54:47 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > afterAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:39:45 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > afterEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:23:45 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > beforeAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:31:45 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > beforeEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:15:45 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > click on non-existing element fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:6:33 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:62:47 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:70:47 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:48:47 - - FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:54:47 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > afterAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:39:51 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > afterEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:23:51 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > beforeAll - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:31:51 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > beforeEach > skipped - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:15:51 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > click on non-existing element fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:6:39 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:62:53 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:70:53 - - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:48:53 + const expectedTests = [ + 'timeouts are failing correctly > afterAll', + 'timeouts are failing correctly > afterEach > skipped', + 'timeouts are failing correctly > beforeAll', + 'timeouts are failing correctly > beforeEach > skipped', + 'timeouts are failing correctly > click on non-existing element fails', + 'timeouts are failing correctly > onTestFailed > fails', + 'timeouts are failing correctly > onTestFailed > fails global', + 'timeouts are failing correctly > onTestFinished > fails', + 'timeouts are failing correctly > onTestFinished > fails global', + ] + for (const browser of ['chromium', 'firefox', 'webkit']) { + for (const t of expectedTests) { + const key = `${browser}|${t}` + expect(seenFails, `expected FAIL "${key}"`).toContain(key) + } + } - FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails global - TimeoutError: locator.click: Timeout exceeded. - ❯ hooks-timeout.test.ts:54:53" - `) + // Source-map regression sample: `click on non-existing element fails` is a + // body-level locator click with exactly one error variant, so its `❯` source + // line is stable. Verify Vitest reports the correct source location. + const sourceRe = /❯\s+hooks-timeout\.test\.ts:(\d+):\d+/ + const sourceLines: number[] = [] + const lines = stderr.split('\n') + for (let i = 0; i < lines.length; i++) { + const m = lines[i].match(failHeaderRe) + if (!m || !m[2].includes('click on non-existing element fails')) { + continue + } + for (let j = i + 1; j < Math.min(i + 8, lines.length); j++) { + const sm = lines[j].match(sourceRe) + if (sm) { + sourceLines.push(Number(sm[1])) + break + } + } + } + // hooks-timeout.test.ts:6 — `await page.getByRole('code').click()` inside `it('click on non-existing element fails', ...)` + expect(sourceLines.length).toBeGreaterThan(0) + for (const line of sourceLines) { + expect(line).toBe(6) } + // page.getByRole('code').click() expect(stderr).toContain('locator.click: Timeout') // playwright error is proxied from the server to the client and back correctly From 63f0c8f27b00f890fa427ac9ff627f56b6062e72 Mon Sep 17 00:00:00 2001 From: Jattioui Ismail <44307645+jaxalo@users.noreply.github.com> Date: Thu, 11 Jun 2026 11:04:02 +0200 Subject: [PATCH 8/9] test(browser): fix lint errors in timeout-hooks refactor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Tighten failHeaderRe/sourceRe to avoid regex/no-super-linear-backtracking (replace `\s+`/`\s*` with literal spaces — log format uses single spaces). - Drop double blank line. Co-Authored-By: Claude Opus 4.7 (1M context) --- test/browser/specs/runner.test.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/browser/specs/runner.test.ts b/test/browser/specs/runner.test.ts index 898228d952e8..9f4085da01c0 100644 --- a/test/browser/specs/runner.test.ts +++ b/test/browser/specs/runner.test.ts @@ -436,7 +436,7 @@ test.runIf(provider.name === 'playwright')('timeout hooks', async ({ onTestFaile // some tests (`onTestFailed > fails*`) report two errors (AssertionError from // `expect.unreachable()` + TimeoutError from the click), and the order in // which they reach stderr varies across runs and platforms. - const failHeaderRe = /FAIL\s+\|(chromium|firefox|webkit)\|\s+hooks-timeout\.test\.ts\s+>\s+(.+?)\s*$/ + const failHeaderRe = /FAIL +\|(chromium|firefox|webkit)\| hooks-timeout\.test\.ts > (.+)$/ const seenFails = new Set() for (const line of stderr.split('\n')) { const m = line.match(failHeaderRe) @@ -466,7 +466,7 @@ test.runIf(provider.name === 'playwright')('timeout hooks', async ({ onTestFaile // Source-map regression sample: `click on non-existing element fails` is a // body-level locator click with exactly one error variant, so its `❯` source // line is stable. Verify Vitest reports the correct source location. - const sourceRe = /❯\s+hooks-timeout\.test\.ts:(\d+):\d+/ + const sourceRe = /❯ +hooks-timeout\.test\.ts:(\d+):\d+/ const sourceLines: number[] = [] const lines = stderr.split('\n') for (let i = 0; i < lines.length; i++) { @@ -488,7 +488,6 @@ test.runIf(provider.name === 'playwright')('timeout hooks', async ({ onTestFaile expect(line).toBe(6) } - // page.getByRole('code').click() expect(stderr).toContain('locator.click: Timeout') // playwright error is proxied from the server to the client and back correctly From bfb42da060d371b64e9c1e04fd3a661ff3c0ba45 Mon Sep 17 00:00:00 2001 From: Jattioui Ismail <44307645+jaxalo@users.noreply.github.com> Date: Thu, 11 Jun 2026 11:28:08 +0200 Subject: [PATCH 9/9] trigger CI rerun 6