Solutions for common issues when testing Tauri applications with WebdriverIO.
The service cannot find the tauri-driver executable.
Solution 1: Enable Auto-Installation
services: [
['@wdio/tauri-service', {
autoInstallTauriDriver: true, // Requires Rust/cargo
}]
]Solution 2: Manual Installation
# Install tauri-driver via cargo
cargo install tauri-driver
# Verify installation
which tauri-driver # macOS/Linux
where tauri-driver # WindowsSolution 3: Specify Path Manually
If installed in a non-standard location:
services: [
['@wdio/tauri-service', {
tauriDriverPath: '/custom/path/tauri-driver'
}]
]WebKitWebDriver is not installed on your Linux system.
Supported Distributions
Install for your distribution:
# Debian/Ubuntu
sudo apt-get install -y webkit2gtk-driver
# Fedora 40+
sudo dnf install -y webkit2gtk-driver
# Arch Linux
sudo pacman -S webkit2gtk-4.1
# Void Linux
sudo xbps-install -y webkit2gtk-develUnsupported Distributions
- Alpine Linux: Cannot build Tauri apps (musl incompatibility). Use Ubuntu, Debian, Fedora, or Arch instead.
- CentOS/RHEL: Stream 9 has glib too old (requires 2.70+), Stream 10 removed WebKitGTK. Use Fedora 40+ instead.
- openSUSE/SUSE: No official WebKitWebDriver package. Building from source is complex and not recommended.
The Edge WebDriver for Windows is not found.
Solution 1: Enable Auto-Download
services: [
['@wdio/tauri-service', {
autoDownloadEdgeDriver: true // Default: true
}]
]Solution 2: Manual Download
-
Check your WebView2 version:
- Build your app:
cargo build --release - Right-click the .exe → Properties → Details
- Note the "File version" (e.g., 143.0.3650.139)
- Build your app:
-
Download matching MSEdgeDriver from Microsoft Edge WebDriver
-
Add to PATH or specify in config:
services: [
['@wdio/tauri-service', {
autoDownloadEdgeDriver: false
}]
]See Edge WebDriver (Windows) for detailed setup.
The plugin required for testing is not detected.
Check 1: Plugin Registered in Rust
Edit src-tauri/src/main.rs:
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_wdio::init()) // This line required
.run(tauri::generate_context!())
.expect("error while running tauri application");
}Check 2: Frontend Import Present
Ensure the import is in your HTML or main JS file:
<script type="module">
import '@wdio/tauri-plugin';
</script>Check 3: withGlobalTauri Enabled
Edit src-tauri/tauri.conf.json:
{
"app": {
"withGlobalTauri": true
}
}Check 4: Permissions Configured
Edit src-tauri/capabilities/default.json:
{
"permissions": [
"core:default",
"core:window:default",
"wdio:default"
]
}Check 5: Rebuild Application
cd src-tauri
cargo clean
cargo build --releaseSee Plugin Setup for complete installation guide.
The frontend plugin didn't initialize.
Solution 1: Add Delay for Initialization
it('should have plugin', async () => {
// Wait for plugin to initialize
await browser.pause(500);
const hasPlugin = await browser.tauri.execute(() => {
return typeof window.wdioTauri !== 'undefined';
});
expect(hasPlugin).toBe(true);
});Solution 2: Check Import Timing
Make sure the plugin is imported before tests run:
- In
index.htmlfor standard Tauri apps - In your main framework entry point (main.ts, main.js)
- Not inside an iframe or separate context
Solution 3: Verify Plugin Loaded
it('should verify plugin is available', async () => {
const available = await browser.tauri.execute(() => {
return 'wdioTauri' in window;
});
expect(available).toBe(true);
});Commands aren't being mocked.
Check 1: Plugin is Available
const available = await browser.tauri.execute(() => {
return 'wdioTauri' in window;
});
if (!available) {
throw new Error('Plugin not available - cannot mock');
}Check 2: Mock Set Up Before Call
// ✅ Correct - mock first, then call
const mock = await browser.tauri.mock('my_command');
await mock.mockReturnValue('test');
await browser.tauri.execute(({ core }) => core.invoke('my_command'));
// ❌ Wrong - calling before mocking
await browser.tauri.execute(({ core }) => core.invoke('my_command'));
const mock = await browser.tauri.mock('my_command');Check 3: Use Correct Command Name
// Make sure command name matches exactly
const mock = await browser.tauri.mock('get_user'); // Must match your command name
await mock.mockReturnValue({ id: 1 });The Tauri app binary cannot be found.
Solution 1: Verify Binary Exists
# Windows
if exist "src-tauri\target\release\my-app.exe" echo "Found"
# Linux/macOS
ls -la src-tauri/target/release/my-appSolution 2: Build the Application
cd src-tauri
cargo build --releaseSolution 3: Use Correct Path
Update wdio.conf.ts:
services: [
['@wdio/tauri-service', {
appBinaryPath: './src-tauri/target/release/my-app.exe', // Windows
// or
appBinaryPath: './src-tauri/target/release/my-app', // Linux/macOS
}]
]Solution 4: Use Absolute Path
import path from 'path';
services: [
['@wdio/tauri-service', {
appBinaryPath: path.resolve('./src-tauri/target/release/my-app.exe')
}]
]Operations take too long or timeout unexpectedly.
Solution 1: Increase Command Timeout
services: [
['@wdio/tauri-service', {
commandTimeout: 60000 // 60 seconds instead of default 10s
}]
]Solution 2: Increase Start Timeout
services: [
['@wdio/tauri-service', {
startTimeout: 60000 // Allow more time for app to start
}]
]Solution 3: Wait for App to Be Ready
it('should wait for app', async () => {
// Give app time to fully initialize
await browser.pause(1000);
// Then run test
const element = await browser.$('button');
expect(element).toBeDefined();
});Solution 4: Check App Logs
Enable logging to see what's happening:
services: [
['@wdio/tauri-service', {
captureBackendLogs: true,
captureFrontendLogs: true,
logLevel: 'debug'
}]
]Multiple tests are conflicting on the same port.
Solution 1: Change tauri-driver Port
services: [
['@wdio/tauri-service', {
tauriDriverPort: 4445 // Instead of default 4444
}]
]Solution 2: Auto-Assign Ports for Multiremote
maxInstances: 3 // Each worker gets unique port (4444, 4445, 4446)Solution 3: Kill Process Using Port
# Linux/macOS
lsof -ti:4444 | xargs kill -9
# Windows (PowerShell)
Get-Process -Id (Get-NetTCPConnection -LocalPort 4444).OwningProcess | Stop-Process -ForceThe service cannot determine which driver provider to use.
Why this happens: On Windows and Linux, the service does not default to any driver provider automatically. It auto-detects the embedded provider only when either:
TAURI_WEBDRIVER_PORTenvironment variable is set, or- You are on macOS
Solution 1: Use embedded provider (recommended)
- Install
tauri-plugin-wdio-webdriverin your Tauri app:cd src-tauri && cargo add tauri-plugin-wdio-webdriver
- Register it in your Rust code and set
TAURI_WEBDRIVER_PORTor configuredriverProvider: 'embedded':Or signal via environment variable:services: [['@wdio/tauri-service', { driverProvider: 'embedded', }]]
TAURI_WEBDRIVER_PORT=4445 npx wdio run wdio.conf.ts
Solution 2: Use official tauri-driver
services: [['@wdio/tauri-service', {
driverProvider: 'official',
autoInstallTauriDriver: true,
}]]See Platform Support for per-platform details.
On macOS the embedded provider is auto-detected, but if the plugin is not installed the service will time out waiting for the WebDriver server.
Solution: Ensure tauri-plugin-wdio-webdriver is installed and registered:
#[cfg(debug_assertions)]
let builder = builder.plugin(tauri_plugin_wdio_webdriver::init());See Plugin Setup for the full setup guide.
Error: Window label "settings" not found. Available windows: main, dialog
Why this happens: The window label you specified doesn't exist in your Tauri application.
Solutions:
- Check available windows with
browser.tauri.listWindows() - Verify the window label matches exactly (case-sensitive)
- Ensure the window is created before your test runs
// Debug: List available windows
const windows = await browser.tauri.listWindows();
console.log('Available:', windows);Issue: Using { windowLabel: 'popup' } in execute call still uses the main window.
Why this happens: The sentinel is required to distinguish options from script arguments. Plain objects are treated as user arguments, not options.
Solutions:
- Verify the window exists:
const windows = await browser.tauri.listWindows(); - Use
browser.tauri.switchWindow(label)to change the session default - Check that @wdio/tauri-plugin is installed and registered in your Tauri app
- Use
withExecuteOptions()wrapper for per-call windowLabel:
import { withExecuteOptions } from '@wdio/tauri-service';
const result = await browser.tauri.execute(
(tauri) => tauri.core.invoke('get_data'),
withExecuteOptions({ windowLabel: 'popup' })
);// wdio.conf.ts
export const config = {
capabilities: [{
'wdio:tauriServiceOptions': {
driverProvider: 'embedded',
},
}],
};Get more detailed information about what the service is doing:
services: [
['@wdio/tauri-service', {
logLevel: 'debug', // Verbose logging
commandTimeout: 60000
}]
]npx wdio run wdio.conf.ts --logLevel debugit('should check service', async () => {
const service = browser.getService('@wdio/tauri-service');
console.log('Service:', service);
});Solution 1: Disable Unnecessary Log Capture
services: [
['@wdio/tauri-service', {
captureBackendLogs: false,
captureFrontendLogs: false, // Logs add overhead
}]
]Solution 2: Increase Log Level
services: [
['@wdio/tauri-service', {
backendLogLevel: 'warn', // Skip debug/info logs
frontendLogLevel: 'warn',
}]
]Solution 3: Run Tests Serially
// wdio.conf.ts
export const config = {
maxInstances: 1, // Run one test at a time
};Common Causes:
-
Missing WebDriver on CI
- Install webkit2gtk-driver on Linux CI
- Download MSEdgeDriver on Windows CI
-
Display Server Missing on Linux CI
- Use Xvfb for headless testing:
xvfb-run -a npm run test:e2e
- Use Xvfb for headless testing:
-
Different Binary on CI
- Ensure build happens before tests:
cargo build --release - Verify binary path matches CI environment
- Ensure build happens before tests:
-
Environment Variables
- Set
APP_BINARYor similar if using env-based paths:APP_BINARY="./src-tauri/target/release/my-app" npm run test:e2e
- Set
name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- uses: dtolnay/rust-toolchain@stable
- name: Install webkit2gtk-driver
run: sudo apt-get install -y webkit2gtk-driver
- name: Install dependencies
run: npm install
- name: Build Tauri app
run: npm run tauri build
- name: Run tests with Xvfb
run: xvfb-run -a npm run test:e2eIf you're still stuck:
- Check Configuration for all available options
- Review Usage Examples for correct patterns
- See Plugin Setup for plugin requirements
- Check Platform Support for platform-specific issues
- Enable debug logging to see detailed output
- Open a discussion in the GitHub Discussions or WDIO forum