fix: SW-wait timeout + automatic dev-server warm-up (0.1.2)#3
Merged
Conversation
page.waitForFunction's signature is (pageFunction, arg, options). The timeout was passed in the second (arg) slot, so Playwright ignored it and fell back to its 30s default. That cap is too low for Firefox/WebKit to claim the service worker in headless CI, where they routinely need longer than 30s — the wait timed out and no tests ran. Move the timeout into the options slot so config.timeout actually applies. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…is set A cold Vite dev server compiles the module graph and runs optimizeDeps on first load, forcing a reload that races service-worker registration. Chromium tolerates it; Firefox/WebKit time out claiming the worker — worst in parallel/matrix runs where each job hits its own cold server. In a sequential run the first engine warms the shared server for the rest; this makes that warm-up explicit and automatic so every engine starts hot. Before running the configured browsers (only when waitForServiceWorker is set), drive one throwaway Chromium page load through the same readiness gates, falling back to a configured engine if Chromium isn't installed. It's internal to waitForServiceWorker with no separate option, and best-effort: a warm-up that can't complete logs a warning and the run continues. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A single job (npx twd-runner run launches engines in parallel inside one runner) is portable across any CI — GitLab, CircleCI, Jenkins — and needs no CI-specific orchestration. Frame that as the default and note the GitHub Actions matrix only as an optional per-engine-isolation extra. Also drop the matrix-centric wording from the warm-up note. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bump to 0.1.2 for the SW-wait timeout fix + automatic warm-up. README: note that `npm install` does not fetch browser binaries (npx playwright install does), that all engines should be installed since the warm-up uses Chromium even for Firefox/WebKit-only runs, and that the composite action installs browsers in CI so the manual step isn't needed there. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes cross-browser flakiness where Firefox/WebKit time out claiming the service worker in headless CI while Chromium passes — surfaced when running a larger suite (it reproduced reliably with ~120 SW-mocked tests). Two root causes, both fixed here.
1.
config.timeoutwas ignored for the SW wait (af1f1b5)page.waitForFunction(fn, { timeout })passed the options object in Playwright'sargslot (signature iswaitForFunction(pageFunction, arg, options)), so the timeout was silently dropped and the wait fell back to Playwright's 30s default. That cap is too low for Firefox/WebKit to claim the SW in headless CI, so the wait timed out and no tests ran. Moved the timeout into the options slot.Proven with a standalone Playwright repro:
2. Cold dev server races SW registration (
03d8b1a)A cold Vite dev server compiles the module graph and runs
optimizeDepson first load, forcing a full-page reload that races SW registration. Chromium shrugs it off; Firefox/WebKit lose the race. In a sequential run the first engine accidentally warms the shared server for the rest — which is why serial passed but parallel/cold runs failed.Now, when
waitForServiceWorkeris set, the runner does one throwaway Chromium page load first (same readiness gates) so every engine starts against a warm server. It's:waitForServiceWorker.3. Docs (
974e566,d95e401)npx twd-runner runruns engines in parallel inside one runner) as the portable, CI-agnostic pattern; the GitHub matrix is noted only as an optional per-engine-isolation extra.npm installdoes not fetch browser binaries (npx playwright installdoes), that all engines should be installed since the warm-up uses Chromium, and that the composite action installs browsers in CI.Testing
vitest: 42 passing (addedwarmUpcoverage + corrected the timeout-signature assertion).Changes
src/runBrowser.js—waitForReadyhelper, timeout fix,warmUp()src/index.js— warm-up pass before the run whenwaitForServiceWorkeris setsrc/config.js— unchanged (warm-up is internal, no new key)tests/— warmUp + timeout-signature coverageREADME.md,package.json,package-lock.json— docs + 0.1.2🤖 Generated with Claude Code