js: upstream the browser page driver (#59's browser half) - #71
Merged
Conversation
Three consumers carry near-identical copies of the browser leg's machinery: a static server over the repository root, an import map for this package's bare specifiers, a Playwright engine launch with the Gecko JSPI pref, heartbeat-based stall detection, the Chrome-binary ladder, an in-page worker pool, and a shard worker compiling cores and running the case loop. The skeleton moves upstream: - ./browser-driver (node-only): runPageHarness — the webcrypto primitive, generalized with a routes hook (reverse proxies, health checks) and a package self-mount at /__component-test so pages and workers reach the harness core without per-repo path math — buildHarnessPage, componentTestImportMap, and findChrome. - js/viewer/page-runner.mjs (browser-safe): the in-page pool loop — per-suite worker pools, suite-order restoration, heartbeats, one results payload per suite. - js/viewer/browser-worker.mjs (browser-safe): the generic shard worker; module workers cannot see import maps, so every module reference arrives as a URL, and the consumer's import object comes from its own module's suiteImports(env). - resolveTestsExport moves to the harness (it is pure logic the browser worker needs; three consumers kept inline copies because it shipped node-only) — node-runner re-exports it. What stays per-consumer: the SUT imports module, env/config, proxy routes, pool sizing, and the results frame. Unit tests cover the page builder, the self-mount map, and the Chrome ladder's env override; the in-page halves are syntax-checked here and integration-gated by the consumers' browser legs.
This was referenced Aug 7, 2026
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.
The remaining half of #59. The thrice-copied browser-leg machinery (webcrypto
scripts/browser-page-driver.mjs+ worker pool, websocketrun-browser.mjs, webrtcrun-browser.mjs) moves upstream as three pieces:./browser-driver(node-only):runPageHarness— the webcrypto primitive generalized with arouteshook (webrtc's mailbox reverse-proxy shape) and a package self-mount (/__component-test) so pages and workers reach the harness core without each repo'simport.meta.resolvepath math;buildHarnessPage(import map + embedded config + page-runner bootstrap);componentTestImportMap;findChrome(the CHROME_PATH → system → Playwright-cache ladder). The caller passes its ownplaywright-core, as before.js/viewer/page-runner.mjs(browser-safe): the in-page per-suite worker-pool loop with suite-order restoration and heartbeats.js/viewer/browser-worker.mjs(browser-safe): the generic shard worker — cores by URL (module workers cannot see import maps), the consumer's import object via its ownsuiteImports(env)module, optionalContextoverride, fresh instance per case.resolveTestsExportrelocates to the harness (browser-safe; the worker needs it, and three consumers kept inline copies while it was node-only)../node-runnerre-exports it, so js: upstream the node suite-runner loop (#59's node half) #70 adopters are unaffected.Per-consumer residue, deliberately: SUT imports module, env/config, proxy routes, pool sizing, results frame.
Verification: unit tests for the page builder / self-mount map / Chrome-ladder env override (in
verify-imports), syntax checks on the in-page halves,verify-nodegoldens + viewer selftest for the harness relocation. The integration gate is the first consumer: polymorph-tls#32 (jco-browser targets), which follows immediately and is the seam test this design was deferred for.