| Name | Last commit date | |
|---|---|---|
| .. | ||
| specs | 6 months ago | |
| package.json | 6 months ago | |
| README.md | 6 months ago | |
| wdio.conf.js | 6 months ago | |
E2E tests
End-to-end tests for the Writer desktop app, driven via WebdriverIO and the
Choochmeque/tauri-webdriver
plugin (the only viable WebDriver path for Tauri v2 on macOS as of April 2026 —
official tauri-driver does not support macOS, see
tauri-apps/tauri#7068).
This setup is experimental. The plugin is early-stage; expect rough edges.
One-time setup
Install the WebDriver intermediary CLI globally:
cargo install tauri-webdriver --locked
Install JS deps from the repo root:
vp install
Running
From apps/desktop/e2e/:
pnpm run test:e2e
This builds the app with --features e2e (which embeds the WebDriver server)
and then runs the smoke spec. The first build is slow; incremental rebuilds
are fast.
The e2e build uses an isolated bundle identifier (
com.writer-computer.e2e) so it does NOT collide withtauri-plugin-single-instancefrom a Writer dev or release instance running in another worktree. You can leave your normal Writer running.
What gets tested
specs/smoke.spec.js contains two specs:
-
mounts the React app— waits for the React top-level wrapper (<div class="animate-fade-in">, present in both the welcome and editor branches) to mount. Validates that the WKWebView loads and React renders. -
creates a file and writes hello world via the Tauri IPC bridge— creates a fresh temp directory on the host, then drives the real Rust IPC commands (create_file,write_file) from inside the WKWebView viawindow.__TAURI_INTERNALS__.invoke, and asserts the bytes hit disk. Validates JS → IPC bridge → Rust command handler → filesystem end-to-end. The temp dir is removed on teardown so no host state leaks between runs.
The point is infrastructure validation, not feature coverage. Both specs are independent of any restored workspace because the e2e build uses an isolated bundle identifier (see below).
How it works
pnpm run build:appproducesWriter.appwith thee2eCargo feature, which includestauri-plugin-webdriver(an embedded HTTP WebDriver server).wdio.conf.js(onPrepare) spawns thetauri-webdriverintermediary CLI on port 4444.- WebdriverIO connects to 4444; the intermediary launches
Writer.appand proxies WebDriver commands to the embedded server. - The spec runs; afterwards
onCompletekills the intermediary and the app quits.
Build flavors
vp run desktop#devandvp buildare unchanged — no WebDriver server.- The e2e build invokes
cargo tauri build --features e2e --bundles app --config '{"identifier":"com.writer-computer.e2e","bundle":{"createUpdaterArtifacts":false}}'. The overrides:--bundles appskips DMG creation.createUpdaterArtifacts: falseskips updater artifact signing (which would otherwise demandTAURI_SIGNING_PRIVATE_KEY).identifier: "com.writer-computer.e2e"gives the e2e build its owntauri-plugin-single-instancenamespace and its own app data dir (~/Library/Application Support/com.writer-computer.e2e/). Without this, a Writer dev/release instance running in another worktree would intercept the launch and the WebDriver plugin would never start.
- Never enable
--features e2efor releases shipped to users — it opens an HTTP server on localhost:4445.
Troubleshooting
ENOENT: tauri-webdriver— runcargo install tauri-webdriver --locked.- Port 4444/4445 in use — a previous run did not clean up.
pkill -f tauri-webdriverand retry. - App binary not found — run
pnpm run build:appfirst (or usepnpm run test:e2ewhich chains them). - Test hangs at
waitForDisplayed— the WKWebView likely did not load. Sanity-check thatvp run desktop#devstill launches the app normally.