Skip to content

fix(e2e): explicit Cargo feature + stage fixtures into Tauri $TEMP scope#29

Merged
shyhunter merged 1 commit into
mainfrom
fix/e2e-feature-flag-and-fixture-staging
Apr 29, 2026
Merged

fix(e2e): explicit Cargo feature + stage fixtures into Tauri $TEMP scope#29
shyhunter merged 1 commit into
mainfrom
fix/e2e-feature-flag-and-fixture-staging

Conversation

@shyhunter
Copy link
Copy Markdown
Owner

Summary

Two adjacent fixes that together unblock npm run test:e2e on macOS, addressing the long-standing E2E breakage flagged in yesterday's security-hardening session.

1. Cargo debug_assertions predicate → explicit e2e feature

The previous [target.'cfg(debug_assertions)'.dependencies] form was incorrect: Cargo evaluates [target.<cfg>.dependencies] against target spec triples and target features, not against rustc's debug_assertions flag. This produced an unexpected-cfg warning and made plugin inclusion non-deterministic.

Replaced with an opt-in e2e Cargo feature. tauri-plugin-webdriver-automation now compiles in only when built with --features e2e; release builds are unaffected.

2. Stage e2e fixtures into Tauri's $TEMP capability scope

Tauri's fs capability scope (src-tauri/capabilities/default.json) only permits reads from $DOCUMENT / $DOWNLOAD / $DESKTOP / $TEMP. Real fixtures live in ~/papercut/test-fixtures/, which is outside every allowed scope. Every PDF/Image E2E test was failing with Timed out waiting for step 1 because:

handleFileSelected(path)
  → getFileSizeBytes(path)        ← Tauri fs scope check fails
  → catch sets corruptFileError   ← step never advances

src/e2e/helpers/driver.ts already documented the intended fix ("CI can place [fixtures] inside /tmp (within Tauri's $TEMP fs scope)"), but the staging wiring was missing.

Now: at the top of wdio.conf.ts we copy real fixtures into ${os.tmpdir()}/papercut-e2e/real/, and generate-e2e-fixtures.mjs writes generated error-path fixtures (large-sparse.*, corrupt.*) into ${os.tmpdir()}/papercut-e2e/error/. The driver helper picks both up via E2E_*_DIR env vars set by the same code (CI overrides still win via ??=).

Result

  • Before: 100% of PDF tests failed at Timed out waiting for step 1.
  • After: Success-case PDF compression tests (PDF-Q-WEB / SCREEN / PRINT) all pass in ~21s.
  • A separate upstream issue (lock poisoned: PoisonError in tauri-plugin-webdriver-automation 0.1.3 across test transitions) blocks the remaining tests. Tracked upstream — out of scope for this PR.

New build command

npm run e2e:build
# alias for: tauri build --debug --features e2e --bundles app

The previous command (npm run tauri -- build --debug --bundles app) no longer compiles the plugin in. The --bundles app flag is still required because the default DMG bundling step deletes the .app that wdio expects.

Files changed

  • src-tauri/Cargo.toml[features] + optional = true dep
  • src-tauri/src/lib.rs#[cfg(feature = "e2e")]
  • src/e2e/wdio.conf.ts — top-of-file fixture staging
  • src/e2e/fixtures/generate-e2e-fixtures.mjs — write to $TMPDIR/papercut-e2e/error/
  • package.json — new e2e:build script

Security notes (R015)

  • No secrets touched. No Tauri capability scope expanded — fix uses only the existing $TEMP allowlist already in default.json.
  • The e2e Cargo feature is opt-in; never set in any production/release build path. Renderer→Rust trust boundary (P014) unchanged.
  • Risk to flag: if a future CI/release workflow accidentally adds --features e2e to a packaged build, it would expose the WebDriver automation port (4444) to whoever runs the resulting .app. Suggest a follow-up note in .claude/project_rules_decisions.md under P013 reinforcing that e2e must remain off in any release-path build.

Test plan

  • cargo check --manifest-path src-tauri/Cargo.toml — clean (no e2e feature)
  • cargo check --manifest-path src-tauri/Cargo.toml --features e2e — clean (with e2e feature)
  • npm run test — 503/503 passing
  • npx tsc --noEmit (main) — clean
  • npm run e2e:build then npm run test:e2e:pdf — PDF-Q-WEB/SCREEN/PRINT pass; further tests blocked by the upstream PoisonError noted above
  • npm audit --omit=dev — 0 advisories (per P015)

🤖 Generated with Claude Code

Two adjacent fixes that together unblock `npm run test:e2e` on macOS:

1. Replace `[target.'cfg(debug_assertions)'.dependencies]` (which Cargo
   evaluates against target spec triples, not rustc's debug_assertions
   flag, producing an unexpected-cfg warning and non-deterministic plugin
   inclusion) with an opt-in `e2e` Cargo feature. The
   tauri-plugin-webdriver-automation plugin now compiles in only when
   built with --features e2e. Release builds are unaffected.

2. Stage e2e fixtures into ${os.tmpdir()}/papercut-e2e/{real,error,output}/
   so they fall inside Tauri's $TEMP fs capability scope. Without this,
   every test fails at handleFileSelected → getFileSizeBytes → scope
   denied → corrupt-file branch, and the step bar never advances past 0.
   Real fixtures are mirrored at the top of wdio.conf.ts; generated
   error-path fixtures (large-sparse, corrupt) go to the same staging
   area via generate-e2e-fixtures.mjs.

After this change, the success-case PDF compression tests
(PDF-Q-WEB / SCREEN / PRINT) all pass. A separate upstream issue in
tauri-plugin-webdriver-automation 0.1.3 (lock poisoned: PoisonError on
cross-test transitions) prevents the rest of the suite from completing
and is tracked upstream.

New build command: `npm run e2e:build` (alias for
`tauri build --debug --features e2e --bundles app`).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@shyhunter
Copy link
Copy Markdown
Owner Author

Upstream issue filed: danielraffel/tauri-webdriver#4

@shyhunter shyhunter merged commit 203e483 into main Apr 29, 2026
14 of 16 checks passed
@shyhunter shyhunter deleted the fix/e2e-feature-flag-and-fixture-staging branch April 29, 2026 08:05
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