From c07d3391984674de34562b50b40f55ef9cae830d Mon Sep 17 00:00:00 2001 From: Edward Irby Date: Wed, 23 Sep 2026 08:42:36 -0700 Subject: [PATCH] =?UTF-8?q?fix(controller):=20warm=20the=20WebView=20brows?= =?UTF-8?q?er=20in=20beforeAll=20=E2=80=94=20the=20transport-seam=20flake?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `constructs and accepts the injected transport` spec timed out at 20s on a cold CI runner: the first Bun.WebView in a process pays cold headless-Chrome startup, and the test-level 20s budget was too small to absorb it. Warm the chrome backend with one throwaway view in beforeAll (60s hook budget) so the specs run against a warm browser. Applied to both WebView harnesses (controller.spec.ts and transport-seam.spec.ts); controller.spec's harness notes document the warm-up. --- src/controller/tests/controller.spec.ts | 11 ++++++++++- src/controller/tests/transport-seam.spec.ts | 9 ++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/controller/tests/controller.spec.ts b/src/controller/tests/controller.spec.ts index 68d46967c..35e224024 100644 --- a/src/controller/tests/controller.spec.ts +++ b/src/controller/tests/controller.spec.ts @@ -27,6 +27,9 @@ * ERR_INVALID_STATE on concurrent same-slot ops); the specs await sequentially. * - Ephemeral storage is the default; each test gets a fresh view disposed via * `await using`. Chrome is spawned once per Bun process; each view is a tab. + * - `beforeAll` warms the backend with one throwaway view (60s hook budget): + * the first view in a process pays cold Chrome startup, which can exceed a + * test's 20s budget on a cold CI runner — pay it once, outside any test. */ import { afterAll, beforeAll, describe, expect, test } from 'bun:test' import { type FixtureServer, startServer } from './fixtures/serve.ts' @@ -63,7 +66,13 @@ const getFixture = (): FixtureServer => { beforeAll(async () => { fixture = startServer(0) -}) + // Warm the chrome backend: the first WebView in a process pays cold browser + // startup, which can exceed a test's 20s budget on a cold CI runner. Pay it + // here, outside any test budget, so every spec runs against a warm browser. + const view = new Bun.WebView({ backend: { type: 'chrome', url: false } }) + await view.navigate(`http://localhost:${fixture.port}/health`) + view.close() +}, 60_000) afterAll(async () => { if (fixture) { diff --git a/src/controller/tests/transport-seam.spec.ts b/src/controller/tests/transport-seam.spec.ts index c14f9fbe0..c34208c0a 100644 --- a/src/controller/tests/transport-seam.spec.ts +++ b/src/controller/tests/transport-seam.spec.ts @@ -54,7 +54,14 @@ const waitFor = async (read: () => Promise, timeoutMs = 8000): beforeAll(async () => { server = await startTransportServer(0) port = server.port -}) + // Warm the chrome backend: the first WebView in a process pays cold browser + // startup, which can exceed a test's 20s budget on a cold CI runner (the + // flaky `constructs and accepts` timeout). Pay it here, outside any test + // budget, so every spec runs against a warm browser. + const view = new Bun.WebView({ backend: { type: 'chrome', url: false } }) + await view.navigate(`http://localhost:${port}/health`) + view.close() +}, 60_000) afterAll(async () => { if (server) {