5.9 KiB
E2E Testing Guide
Overview
Desktop E2E tests use WebDriverIO (WDIO) to drive the Tauri app via two automation backends:
| Platform | Driver | Port | App format | Selectors |
|---|---|---|---|---|
| Linux (CI default) | tauri-driver |
4444 | Debug binary | CSS / DOM |
| macOS (local dev) | Appium Mac2 | 4723 | .app bundle |
XPath / accessibility |
Linux is the default CI path (ubuntu-22.04). macOS E2E is available for local development and as an optional CI workflow.
Quick start
Linux (CI default)
# Install tauri-driver (one-time)
cargo install tauri-driver
# Build the E2E app
pnpm workspace openhuman-app test:e2e:build
# Run all flows
pnpm workspace openhuman-app test:e2e:all:flows
# Run a single spec
bash app/scripts/e2e-run-spec.sh test/e2e/specs/smoke.spec.ts smoke
On headless Linux (CI), tests run under Xvfb for a virtual display.
macOS (local dev)
# Install Appium + Mac2 driver (one-time, needs Node 24+)
npm install -g appium
appium driver install mac2
# Build the .app bundle
pnpm workspace openhuman-app test:e2e:build
# Run all flows
pnpm workspace openhuman-app test:e2e:all:flows
Docker on macOS (Linux E2E locally)
Run the same Linux-based E2E stack from macOS using Docker:
# Build + run all E2E flows
docker compose -f e2e/docker-compose.yml run --rm e2e
# Build the app first (if needed)
docker compose -f e2e/docker-compose.yml run --rm e2e \
pnpm workspace openhuman-app test:e2e:build
# Run a single spec
docker compose -f e2e/docker-compose.yml run --rm e2e \
bash app/scripts/e2e-run-spec.sh test/e2e/specs/smoke.spec.ts smoke
Requires Docker Desktop or Colima. The repo is bind-mounted so builds persist between runs.
Architecture
Platform detection
app/test/e2e/helpers/platform.ts exports:
isTauriDriver()—trueon Linux (tauri-driver session)isMac2()—trueon macOS (Appium Mac2 session)supportsExecuteScript()—truewhenbrowser.execute()works (tauri-driver only)
Element helpers
app/test/e2e/helpers/element-helpers.ts provides a unified API:
| Helper | Mac2 (macOS) | tauri-driver (Linux) |
|---|---|---|
waitForText(text) |
XPath over @label/@value/@title | XPath over DOM text content |
waitForButton(text) |
XCUIElementTypeButton XPath | button / [role="button"] XPath |
clickText(text) |
W3C pointer actions | Standard el.click() |
clickNativeButton(text) |
W3C pointer actions on XCUIElementTypeButton | Standard el.click() on button |
clickToggle() |
XCUIElementTypeSwitch / XCUIElementTypeCheckBox | [role="switch"] / input[type="checkbox"] |
waitForWindowVisible() |
XCUIElementTypeWindow | Window handle check |
waitForWebView() |
XCUIElementTypeWebView | document.readyState check |
hasAppChrome() |
XCUIElementTypeMenuBar | Window handle check |
dumpAccessibilityTree() |
Accessibility XML | HTML page source |
Deep link helpers
app/test/e2e/helpers/deep-link-helpers.ts handles auth deep links:
- tauri-driver:
browser.execute(window.__simulateDeepLink(url))(primary),xdg-open(fallback) - Appium Mac2:
macos: deepLinkextension command (primary),open -a ...(fallback)
Writing cross-platform specs
- Use helpers from
element-helpers.ts— never use rawXCUIElementType*selectors in specs - Use
clickNativeButton(text)instead of inline button-clicking code - Use
hasAppChrome()instead of checking forXCUIElementTypeMenuBar - Use
waitForWebView()instead of checking forXCUIElementTypeWebView - For macOS-only tests, use
process.platformguards or separate spec files
Environment variables
| Variable | Default | Description |
|---|---|---|
TAURI_DRIVER_PORT |
4444 |
tauri-driver WebDriver port |
APPIUM_PORT |
4723 |
Appium server port |
E2E_MOCK_PORT |
18473 |
Mock backend server port |
OPENHUMAN_WORKSPACE |
(temp dir) | App workspace directory |
OPENHUMAN_SERVICE_MOCK |
0 |
Enable service mock mode |
OPENHUMAN_E2E_AUTH_BYPASS |
unset | Enable JWT bypass auth |
DEBUG_E2E_DEEPLINK |
(verbose) | Set to 0 to silence deep link logs |
E2E_FORCE_CARGO_CLEAN |
unset | Force cargo clean before E2E build |
CI workflows
Default (every push/PR)
The e2e-linux job runs on ubuntu-22.04:
- Installs system deps (webkit2gtk, Xvfb, dbus)
- Installs
tauri-drivervia cargo - Builds the app with mock server URL baked in
- Runs all E2E flows under Xvfb
Optional macOS E2E
The e2e-macos job runs only via manual dispatch (workflow_dispatch with run_macos_e2e: true):
- Installs Appium + Mac2 driver
- Builds the
.appbundle - Runs all E2E flows
Troubleshooting
Linux: "WebView not ready" timeout
Ensure DISPLAY is set and Xvfb is running:
export DISPLAY=:99
Xvfb :99 -screen 0 1280x1024x24 &
Also ensure dbus is started (required by webkit2gtk):
eval $(dbus-launch --sh-syntax)
Linux: tauri-driver not found
cargo install tauri-driver
macOS: Deep links not working in tauri dev
Deep links require a .app bundle. Use pnpm tauri build --debug --bundles app instead.
Docker: Build is slow on first run
The first Docker build compiles Rust + tauri-driver from source. Subsequent runs use cached layers. Cargo registry and git sources are cached via Docker volumes.
Agent-observable artifact flow
For a canonical, inspectable run that drops screenshots, page-source dumps, and mock request logs on disk:
bash app/scripts/e2e-agent-review.sh
Artifacts land in app/test/e2e/artifacts/<timestamp>-agent-review/. Full details + helper API: AGENT-OBSERVABILITY.md. Any failing test triggers wdio.conf.ts's afterTest hook, which writes failure-*.png + failure-*.source.xml into the same run dir.