Skip to content

fix(e2e): fail the packaged leg in seconds with the real cause, not a 900s hang - #441

Merged
Prekzursil merged 2 commits into
mainfrom
fix/v15-packaged-fuse
Aug 14, 2026
Merged

fix(e2e): fail the packaged leg in seconds with the real cause, not a 900s hang#441
Prekzursil merged 2 commits into
mainfrom
fix/v15-packaged-fuse

Conversation

@Prekzursil

Copy link
Copy Markdown
Owner

Root cause of a nightly that has been red since 2026-08-11

electron-builder.yml sets enableNodeCliInspectArguments: false (W66 hardening, commit d4a7e3f1, that same day).

Playwright drives an Electron main process over the Node inspector — its launcher passes --inspect=0 and waits for that inspector to come up. That fuse makes Electron ignore --inspect, so the inspector never appears and electron.launch waits out its full 900 s budget, reporting nothing but a timeout.

The shipped app is fine. The CI call log shows it starting normally:

[out] Checking for update
[out] Generated new staging user ID: …
[out] Update for version 1.5.0 is not available (latest version: 1.4.0, downgrade is disallowed)

wireAutoUpdater only fires on did-finish-load, so the renderer had already finished loading. Only Playwright's control channel is closed.

Why the fuse's own comment says nothing depends on --inspect

It says: "Measured before flipping: neither NODE_OPTIONS nor --inspect appears in ANY tracked .ts/.py/.json/.yml/.ps1/.mjs file, so nothing in this repo depends on either."

That measurement was honest and still wrong: --inspect is injected at runtime by playwright-core's Electron launcher, not written in any file here. A source grep structurally cannot see that dependency.

Two independent signals agree: the mechanism, and the exact date match between the fuse landing and the leg going red.

What this changes

Nothing about the fuse, and nothing about the app. The spec now checks the fuse first and throws in seconds with the cause and the options, instead of hanging for 15 minutes and saying only "timeout".

It throws rather than skips deliberately: the coverage is genuinely lost while the fuse is off, and a skip would turn a real gap into a green tick. The leg stays red — but red informatively.

The decision this surfaces (yours — it is the W66 trade-off)

  1. Flip the fuse true — restores packaged coverage, re-opens the Node-injection surface W66 closed.
  2. Build a test-only package with the fuse on, and assert separately that the release artifact has it off. Standard resolution; the tested bytes are no longer the shipped bytes.
  3. Cover the package without main-process assertions — drop app.isPackaged / asar-path checks and verify the artifact another way.

I have not picked one; the spec names all three in its failure message.

Verification

  • tsc --noEmit -p tsconfig.e2e.json clean.
  • Both-states control: the guard resolves electron-builder.yml and fires on the current state, and does not fire when the fuse is true.

… 900s hang

ROOT CAUSE of a nightly that has been red since 2026-08-11: electron-builder.yml sets 'enableNodeCliInspectArguments: false' (W66 hardening, commit d4a7e3f, that same day). Playwright drives an Electron MAIN process over the NODE inspector -- its launcher passes '--inspect=0' and waits for it -- and that fuse makes Electron IGNORE --inspect. The inspector never appears, so electron.launch waits out its full 900s budget and reports nothing but a timeout.

THE SHIPPED APP IS FINE. The CI call log shows it starting normally: 'DevTools listening on ws://...', then the renderer finishing load and the auto-updater reporting a result (wireAutoUpdater only fires on did-finish-load). Only Playwright's control channel is closed.

Why the fuse's own comment says nothing depends on --inspect: that was measured by grepping tracked sources, and --inspect is injected at RUNTIME by playwright-core's Electron launcher, not written in any file here. A source grep structurally cannot see it. Two signals agree: the mechanism, and the exact date match between the fuse landing and the leg going red.

This THROWS rather than skipping. The coverage is genuinely lost while the fuse is off, and a skip would turn a real gap into a green tick. The leg stays red -- but red in seconds, naming the cause and the three ways out (flip the fuse; build a test-only package and assert the release artifact separately; or cover the package without main-process assertions). That choice is the owner's W66 trade-off, not something to decide inside a spec file.

Verified: tsc -p tsconfig.e2e.json clean; the guard resolves electron-builder.yml and fires on the current state, and a both-states control confirms it does NOT fire when the fuse is true.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 01742e6dc9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread app/e2e/packaged.spec.ts
Comment on lines +91 to +95
const fuses = readFileSync(resolve(REPO_ROOT, 'electron-builder.yml'), 'utf8').replace(
/#[^\n]*/g,
'',
);
if (/enableNodeCliInspectArguments:\s*false/.test(fuses)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Inspect the fuse on the packaged executable

When the suggested test-only package is built with the inspector fuse enabled while the release configuration remains hardened, this guard still reads the root electron-builder.yml, sees false, and aborts without examining the artifact. Consequently option (b) in the new diagnostic cannot restore packaged coverage and the error can misreport the effective fuse state; derive the value from the selected executable or the configuration actually used to build it.

Useful? React with 👍 / 👎.

@Prekzursil
Prekzursil merged commit 6f98e8e into main Aug 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant