Skip to content

test(desktop): main-frame e2e waits for the announced OS open, not a command, after a script navigation - #3937

Merged
h4yfans merged 1 commit into
feat/tauri-v2from
fix/3933-main-frame-linux
Nov 4, 2026
Merged

h4yfans merged 1 commit into
feat/tauri-v2from
fix/3933-main-frame-linux

Conversation

@h4yfans

@h4yfans h4yfans commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #3517
Closes #3933

Root cause

The test sent a command while a navigation it started was still loading, and on Linux Tauri refuses such a command.

  1. The first location.assign starts a navigation. WebKitGTK runs beforeunload and stops the page's loads (FrameLoader::continueLoadAfterNavigationPolicy: shouldClose(), then stopAllLoaders()). That aborts the ipc:// fetches in flight: about 10 of the app's own commands at that moment, every run.
  2. Tauri's IPC script then falls back to postMessage and keeps using it for that document (customProtocolIpcFailed is sticky, tauri-2.12.5/scripts/ipc-protocol.js).
  3. wry tags a postMessage command with webview.uri() (wry-0.57.1/src/webkitgtk/mod.rs, attach_ipc_handler). While a main-frame load is provisional, that URI is the URL being loaded, which here is the refused fixture URL. Tauri's ACL treats that as a remote page, and no capability names it: e2e_os_opens not allowed. Plugin not found. The ipc:// path reads the Origin header instead and is not affected.
  4. The spec polled e2e_os_opens right after each location.assign. When the first read landed in that window, the poll threw. /redirect hit it most because it has two round trips. The OS open is recorded in load-failed, which is also when the window closes.

The error text does not point to a startup or plugin-registration race. e2e_os_opens is an app command, and the app has no app ACL manifest. Tauri checks such a command against the ACL only when the request is not from a local origin (webview/mod.rs ~2075: plugin_command.is_some() || has_app_acl_manifest || !is_local). "Plugin not found" is the text resolve_access_message gives for any command with no ACL entry under the __app-acl__ key (ipc/authority.rs:408). In every failing container run, the same app had already answered vault_status and the earlier e2e_os_opens reads. In the instrumented runs, the identical call succeeded 3 s later in the same instance. #3924's linux-x64 failure (same spec, same text, rerun passed) is another occurrence of this flake.

The page sees no event when the refused load ends (window.navigation is undefined in WebKitGTK 2.50.4). So the app announces the event instead.

This is not reachable in production: app code never navigates the main frame by script (memry/no-location-navigation, external-link-guard.ts). The spec does this on purpose to exercise the guard's last line.

Change

  • src-tauri/src/e2e/reveal.rs (e2e feature only): record_os_open also emits e2e-os-open with the recorded entry.
  • main-frame.e2e.ts: watchOsOpens(page) listens for that event before the navigations. After a script navigation, the poll reads the page's list, which sends no command. Each test still checks the authoritative e2e_os_opens once the open arrived, when commands work again. Three polls changed: the stop/chain/redirect/popup loop, the memry-file PDF, and back/forward's /stop.
  • navigation_guard/linux.rs: the module doc said only that a resent command can run twice. It now also says the command is refused while the refused load is loading.

No timeouts were raised and no retries were added. Every wait is on the app's announced open.

Proof

All runs were in an ubuntu:22.04 arm64 container (WebKitGTK 2.50.4-0ubuntu0.22.04.1, xvfb, one worker), with wdio --spec e2e/specs/shell/main-frame.e2e.ts.

spec binary grep result
base CI build of feat/tauri-v2 cc23103 (run 41883239554, memry-tauri-e2e-linux-arm64) stop, chain 1/1 failed, then 3/10 failed (diagnostic copy)
base local e2e build of this branch stop, chain 4/10 failed, all e2e_os_opens not allowed. Plugin not found
this PR local e2e build of this branch stop, chain 10/10 passed
this PR local e2e build of this branch whole file 5/5 passed (9 passing each)

The diagnostic copy logged beforeunload, then 10 IPC custom protocol failed ... postMessage warnings at the first navigation, and the failure at the /redirect step. Three seconds later the same command succeeded.

CI proof, all on the build of this PR's head (run 41904873929, commit 6c629aa):

where spec result
container, memry-tauri-e2e-linux-arm64 of run 41904873929 this PR, whole file 10/10 runs passed (90/90 tests)
container, same binary base spec, stop, chain 6/10 passed: 3 failed with e2e_os_opens not allowed, and 1 app exited with code 101 at startup before any spec ran (see follow-ups)
Build e2e 1/2 (linux-x64), attempt 1 this PR main-frame 9/9, 0 failures
same job, re-run (attempt 2) this PR main-frame 9/9, 0 failures
same job, re-run (attempt 3) this PR main-frame 9/9, 0 failures

The other legs of the full-ci run (macOS, Windows x64/arm64) are green on attempt 1.

Local gate: pnpm lint, pnpm typecheck, pnpm format:check, git diff --check, cargo fmt --check, cargo clippy --workspace --all-targets -D warnings, cargo clippy -p memry-tauri --features e2e (only a pre-existing unused import in e2e/vault_writeback.rs, see follow-up), cargo test -p memry-tauri, check-line-ceilings, check-test-timing.

Follow-up (not in this PR)

  • cargo clippy -p memry-tauri --features e2e -- -D warnings fails on base: an unused E2eGate import in src-tauri/src/e2e/vault_writeback.rs. CI never lints the e2e feature, so nothing catches it.
  • In about 110 container launches, one e2e app exited with code 101 at startup, before main.log existed. The harness spawns the app with stdio: 'ignore' (harness/app-process.ts), so the panic text was lost. A 40-launch probe that kept stderr did not reproduce it. Capturing stderr there would make the next one diagnosable.

@h4yfans h4yfans added the full-ci Run the full CI matrix on a PR into feat/tauri-v2 label Nov 4, 2026
@github-actions github-actions Bot added the bug Something isn't working label Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

React Doctor found no new issues. 🎉

Reviewed by React Doctor for commit 6c629aa.

@h4yfans
h4yfans added this pull request to the merge queue Nov 4, 2026
Merged via the queue into feat/tauri-v2 with commit cb6fd64 Nov 4, 2026
114 checks passed
@h4yfans
h4yfans deleted the fix/3933-main-frame-linux branch November 4, 2026 22:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working full-ci Run the full CI matrix on a PR into feat/tauri-v2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

desktop-tauri e2e (Linux): main-frame 'stop, chain, redirect' test flakes with e2e_os_opens not allowed

1 participant