Desktop Apps
How WebdriverIO automates a desktop app depends on how the app is built. Native macOS apps are automated through Appium with the Mac2 driver ('appium:automationName': 'Mac2'), which requires Xcode. Apps built with a web-based framework are driven through their embedded browser engine by a dedicated WebdriverIO service. The Electron service uses Chromium via an auto-installed Chromedriver and can also call Electron main-process APIs. The Tauri service and the Dioxus service drive the operating system webview: WebView2 on Windows, WKWebView on macOS and WebKitGTK on Linux. These three services run the same suite on Windows, macOS and Linux. Native Windows apps have no recommended driver today: Appium's Windows Driver is built on Microsoft's WinAppDriver, which is no longer maintained. There is no documented support for automating arbitrary native Linux apps.
| App type | macOS | Windows | Linux | How |
|---|---|---|---|---|
| Native app | Yes | Not recommended | Not documented | Appium Mac2 driver |
| Electron | Yes | Yes | Yes | @wdio/electron-service (Chromedriver) |
| Tauri | Yes | Yes | Yes | @wdio/tauri-service (embedded plugin, tauri-driver or CrabNebula) |
| Dioxus | Yes | Yes | Yes | @wdio/dioxus-service (embedded driver; external driver on Windows only) |
Quick start
npm create wdio@latest ./ scaffolds all of these. Choose "Desktop Testing - of Electron, Tauri, Dioxus, or macOS Applications" and then your framework. Every setup below also needs @wdio/cli @wdio/local-runner @wdio/mocha-framework @wdio/spec-reporter tsx and a tsconfig.json with "types": ["node", "@wdio/globals/types", "@wdio/mocha-framework"].
Electron (macOS, Windows, Linux)
npm install --save-dev @wdio/electron-service
/// <reference types="@wdio/electron-service" />
export const config: WebdriverIO.Config = {
runner: 'local',
specs: ['./test/specs/**/*.ts'],
capabilities: [{
browserName: 'electron',
'wdio:electronServiceOptions': {
// only needed if auto-detection of Electron Forge / electron-builder output fails
// appBinaryPath: './dist-electron/linux-unpacked/myApp',
appArgs: []
}
}],
services: ['electron'],
framework: 'mocha',
reporters: ['spec'],
mochaOpts: {
ui: 'bdd',
timeout: 60000
}
}
import { browser } from '@wdio/globals'
describe('Electron Testing', () => {
it('should print application title', async () => {
console.log('Hello', await browser.getTitle(), 'application!')
})
})
Use browser.electron.execute((electron, ...args) => { ... }) to run code in the main process, and browser.electron.mock() to mock Electron APIs.
Native macOS app (Appium Mac2)
npm install --save-dev @wdio/appium-service appium appium-mac2-driver
export const config: WebdriverIO.Config = {
runner: 'local',
port: 4723,
specs: ['./test/specs/**/*.ts'],
capabilities: [{
platformName: 'Mac',
'appium:automationName': 'Mac2',
'appium:bundleId': 'com.apple.calculator'
}],
services: ['appium'],
framework: 'mocha',
reporters: ['spec'],
mochaOpts: {
ui: 'bdd',
timeout: 60000
}
}
import { expect, $ } from '@wdio/globals'
describe('MacOS Testing', () => {
it('should calculate the meaning of life', async function () {
await $('//XCUIElementTypeButton[@label="seven"]').click()
await $('//XCUIElementTypeButton[@label="multiply"]').click()
await $('//XCUIElementTypeButton[@label="six"]').click()
await $('//XCUIElementTypeButton[@title="="]').click()
await expect($('//XCUIElementTypeStaticText[@label="main display"]')).toHaveText('42')
})
})
appium:bundleId selects the app to launch at session start.
Tauri and Dioxus
Both need a Rust-side addition to your app, so follow their quick starts:
- Tauri: add the
tauri-plugin-wdio-webdrivercrate (the embedded provider), then useservices: [['tauri', { appBinaryPath: './src-tauri/target/release/my-tauri-app', driverProvider: 'embedded' }]]. See the Tauri Quick Start. - Dioxus: add the
wdio-dioxus-bridgecrate and create a debug build (cargo build). Then useservices: [['dioxus', { driverProvider: 'embedded' }]]withbrowserName: 'dioxus'and'dioxus:options': { application: './target/debug/my-app' }. See the Dioxus Quick Start.
Choose your path
- macOS: native macOS apps with Appium and the Mac2 driver.
- Windows: current state of native Windows app automation.
- Electron: setup, then configuration (including binary paths per OS), accessing Electron APIs, API reference and mocking, window management, deeplinks, standalone mode and debugging.
- Tauri: platform support, configuration, plugin setup, CrabNebula, Edge WebDriver on Windows, usage examples and the API reference.
- Dioxus: platform support, configuration, bridge setup, browser mode (frontend-only tests in Chrome with mocked commands), usage examples and the API reference.
- Multiremote: the Electron, Tauri and Dioxus services support multiremote sessions, e.g. two app instances in one test.
Linux
On Linux, WebdriverIO drives Electron, Tauri and Dioxus apps. Things to know:
- Headless CI: these apps need a display server. The testrunner can wrap workers in Xvfb (
autoXvfb, on by default, with optionalxvfbAutoInstall). Alternatively, runxvfb-run -a npx wdio run wdio.conf.ts. See Headless & Xvfb. - Tauri with the
officialprovider needs WebKitWebDriver (webkit2gtk-driverpackage). Theembeddedprovider needs no external driver. - Dioxus supports only the
embeddedprovider on Linux, and building Dioxus apps requires the WebKitGTK development libraries. - Electron on Ubuntu 24.04+ and other AppArmor-enabled distributions: set the service option
apparmorAutoInstallif Electron fails to start.
Troubleshooting
- Electron: Common Issues, e.g. "DevToolsActivePort file doesn't exist" in CI.
- Tauri: Troubleshooting, including Edge WebDriver and WebView2 version mismatches.
- Dioxus: Troubleshooting.
- macOS: see the Appium Mac2 Driver project for driver-specific setup such as Xcode.
Next steps
- Configuration reference for every
wdio.conf.tsoption. - Appium Service options for the Mac2 setup.
- Other platforms: Web Browsers, Mobile Apps, Extensions & Editors.