Playwright Firefox boots the engine: the pref its build lags, and the error that hid it - #103
Merged
Conversation
… error that hid it Two bugs wearing one symptom. THE BOOT FAILURE: Playwright 1.57.0's Firefox build (144) ships WebAssembly JS Promise Integration DISABLED where release Firefox has it on — which is why the owner's phone runs the app while headless Firefox died at device setup. Everything else the device store needs was measured present under Gecko: module SharedWorkers, OPFS (createWritable; no sync access handles, which the store never asks for), Web Locks, non-extractable CryptoKeys through IndexedDB. The harness now launches Firefox with javascript.options.wasm_js_promise_integration=true — restoring a release default the automation build lags, not granting the page anything a real user's browser lacks — and e2e-deps probes with the same pref so the recipe cannot certify a browser the suite would refuse. THE OPACITY: the banner was honest all along (the engine's own needs-JSPI refusal reached it); the bare 'Error' was Juggler rendering a console.error(errorObject) to an out-of-process observer as the word Error and nothing else — a logging idiom that is lossless under CDP and total loss under Juggler. Boot logging now leads with the string. And the refusal got sharper: the worker probes WebAssembly.Suspending at bringUpEngine — in the SharedWorker, the realm that instantiates, since JSPI availability is per-global — and refuses with a PlatformError (code no-jspi) whose sentence names the missing capability instead of whichever import happened to suspend first. THE GATE: firefox-smoke — the suite's first non-Chromium scenario. It reads the five platform facts out of the page (so a pref that silently stops applying cannot become a green lie), runs the T0 anchor path, and survives a reload. The runner grew per-scenario engine selection with lazy launch; Firefox is ordered last so earlier failures never pay for a second browser. Deliberately not a second matrix: the visor ceremonies are engine-independent. The CI browser cache key gains a -ff suffix: the cache saves only on a miss, so the grown browser set under the old key would have hit forever with a chromium-only archive and re-downloaded Firefox every run. Gates: e2e 24/24 (firefox-smoke 3 acts), invariants 9/9, devstore matrix ALL PASS, deno checks clean.
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.
Two bugs wearing one symptom (the solo page dying opaquely under headless Playwright Firefox):
WebAssembly.Suspendingundefined by default; function withjavascript.options.wasm_js_promise_integration=true), and everything else the device store needs was measured present under Gecko: module SharedWorkers, OPFS viacreateWritable, Web Locks, non-extractable CryptoKeys through IndexedDB. The harness sets the pref — restoring a release default the automation build lags, not granting the page anything real users lack — ande2e-depsprobes with the same pref so it can't certify a browser the suite would refuse.Errorwas Juggler renderingconsole.error(errorObject)as the word "Error" — lossless under CDP, total loss under Juggler. Boot logging now leads with the string, and the worker refuses early with aPlatformError(no-jspi) whose sentence names the missing capability ("this browser cannot run the engine: it has no WebAssembly JS Promise Integration…") instead of whichever import happened to suspend first. Probed in the SharedWorker, the realm that instantiates — JSPI availability is per-global.firefox-smoke, the suite's first non-Chromium scenario — reads the five platform facts out of the page (a silently-lapsed pref cannot become a green lie), runs the T0 anchor path, survives a reload. Runner grows per-scenario engine selection with lazy launch, ordered last so earlier failures never pay for a second browser.-ff— the cache saves only on a miss, so the grown browser set under the old key would have re-downloaded Firefox ~90MB on every run forever.Gates: e2e 24/24, invariants 9/9, devstore matrix ALL PASS.