# How OpenHuman's WDIO E2E Testing Framework Adapts to Linux vs. macOS

> Discover how OpenHuman's WDIO E2E testing framework handles Linux vs macOS differences using platform-specific drivers for seamless desktop app validation.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: testing
- Published: 2026-05-12

---

**OpenHuman uses WebdriverIO (WDIO) with platform-specific automation drivers—tauri-driver on Linux and Appium Mac2 on macOS—to test its Tauri-based desktop application, requiring different interaction models for WebView DOM access versus native UI automation.**

The **OpenHuman** E2E testing framework provides comprehensive coverage for a Tauri-powered desktop application using a single WDIO configuration that dynamically selects automation backends. According to the `tinyhumansai/openhuman` source code, the framework resides in `app/test/` and transparently handles the architectural differences between Linux's direct WebView access and macOS's native UI layer bridging.

## Platform-Specific Automation Architecture

The framework detects the host operating system at runtime and initializes the appropriate WebDriver implementation. This dual-backend approach accommodates fundamental differences in how each platform exposes the application's React-based WebView for automation.

### Linux: Tauri-Driver and Direct WebView Access

On **Linux**, the framework leverages **tauri-driver**, a W3C WebDriver server included with the Tauri toolchain. In [`app/test/wdio.conf.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/test/wdio.conf.ts), the configuration returns capabilities that point directly to the compiled binary:

```ts
if (process.platform === 'linux') {
  return [{ 'tauri:options': { application: getAppPath() } }];
}

```

The driver launches the executable located at `src-tauri/target/debug/OpenHuman` and exposes the WebView's DOM directly to WDIO commands. This enables standard Selenium-style interactions—`click()`, `sendKeys()`, and `executeScript()`—to function exactly as they would in a browser automation context.

### macOS: Appium Mac2 and Native UI Automation

On **macOS**, the framework switches to **Appium Mac2**, which utilizes Apple's XCUITest backend to drive the native macOS UI. The [`wdio.conf.ts`](https://github.com/tinyhumansai/openhuman/blob/main/wdio.conf.ts) constructs Appium-specific capabilities for the `.app` bundle:

```ts
return [
  {
    platformName: 'mac',
    'appium:automationName': 'Mac2',
    'appium:app': getAppPath(),
    'appium:showServerLogs': true,
  },
];

```

This backend represents UI elements as `XCUIElementType*` nodes rather than DOM nodes. Because XCUITest does not forward native click events into the embedded WebView, the framework requires W3C pointer actions for interaction, and `executeScript` calls are unsupported.

## Configuration and Capability Detection

The `getPlatformCapabilities()` function in [`app/test/wdio.conf.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/test/wdio.conf.ts) serves as the central decision point for driver selection. It inspects `process.platform` and returns the appropriate capability set, while also computing platform-specific port assignments:

```ts
const isLinuxDriver = process.platform === 'linux';
const driverPort = isLinuxDriver
  ? parseInt(process.env.TAURI_DRIVER_PORT || '4444', 10)
  : parseInt(process.env.APPIUM_PORT || '4723', 10);

```

Port **4444** serves the tauri-driver on Linux, while port **4723** connects to the Appium server on macOS.

## Runtime Platform Abstraction

To prevent test code from scattering platform-specific conditionals, the framework provides runtime helpers in [`app/test/e2e/helpers/platform.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/test/e2e/helpers/platform.ts). The `isTauriDriver()` function determines the active backend by inspecting browser capabilities:

```ts
export function isTauriDriver(): boolean {
  if (typeof browser === 'undefined') return process.platform === 'linux';
  const caps = browser.capabilities as Record<string, unknown>;
  const automation = String(
    caps['appium:automationName'] ?? caps['automationName'] ?? ''
  ).toLowerCase();
  if (automation === 'mac2' || automation.includes('mac2')) return false;
  const platform = String(caps.platformName ?? caps['appium:platformName'] ?? '').toLowerCase();
  if (platform === 'mac') return false;
  return true;
}

```

Additional helpers like `isMac2()` and `supportsExecuteScript()` allow test specifications to branch cleanly when encountering platform limitations.

## Handling UI Interaction Differences

The [`app/test/e2e/helpers/element-helpers.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/test/e2e/helpers/element-helpers.ts) file encapsulates the interaction model divergence. On Linux, `element.click()` propagates directly to the DOM. On macOS, the framework must translate clicks into W3C pointer actions to ensure the native UI forwards the event to the WebView:

```ts
export async function clickElement(selector: string) {
  const el = await $(selector);
  if (isTauriDriver()) {
    await el.click();               // DOM click works on Linux
  } else {
    // Appium Mac2 requires pointer actions
    await browser.performActions([
      {
        type: 'pointer',
        id: 'mouse',
        parameters: { pointerType: 'mouse' },
        actions: [
          { type: 'pointerMove', origin: el, x: 0, y: 0 }, 
          { type: 'pointerDown', button: 0 }, 
          { type: 'pointerUp', button: 0 }
        ],
      },
    ]);
  }
}

```

## CI Execution and Stability Considerations

The WDIO configuration adjusts connection timeouts based on platform behavior. Because tauri-driver can exhibit slower startup times on CI runners, [`app/test/wdio.conf.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/test/wdio.conf.ts) specifies elevated retry thresholds for Linux:

- **Linux**: `connectionRetryTimeout: 240000` (240 seconds) with `connectionRetryCount: 5`
- **macOS**: Standard Appium defaults for faster session establishment

This ensures reliable session creation across different CI environments without modifying test logic.

## Debugging Cross-Platform Failures

When assertions fail, the `afterTest` hook invokes `captureFailureArtifacts()` from [`app/test/e2e/helpers/artifacts.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/test/e2e/helpers/artifacts.ts) to record screenshots and page source. This artifact collection is crucial for debugging divergent UI states between Linux's direct WebView rendering and macOS's native UI layer composition.

Execution remains consistent across platforms via the same command interface:

```bash

# Build and run on either Linux or macOS

pnpm test:e2e:build
bash app/scripts/e2e-run-spec.sh app/test/e2e/specs/smoke.spec.ts smoke

```

## Summary

- **OpenHuman** uses **tauri-driver** on Linux for direct WebView DOM access and **Appium Mac2** on macOS for native UI automation.
- The `getPlatformCapabilities()` function in [`app/test/wdio.conf.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/test/wdio.conf.ts) selects the driver based on `process.platform`.
- Platform helpers in [`app/test/e2e/helpers/platform.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/test/e2e/helpers/platform.ts) abstract driver detection via `isTauriDriver()` and `supportsExecuteScript()`.
- Element interactions require W3C pointer actions on macOS (`performActions`) versus standard clicks on Linux.
- Linux CI runs use extended timeouts (240s) and increased retry counts (5) to accommodate tauri-driver startup latency.
- Screenshots and page sources are automatically captured via `captureFailureArtifacts()` to diagnose platform-specific failures.

## Frequently Asked Questions

### Why does OpenHuman use different automation drivers for Linux and macOS?

Tauri officially supports **tauri-driver** as a W3C WebDriver implementation for Linux, which provides direct access to the WebView's DOM. On macOS, Apple's security model and the structure of Tauri applications require native UI automation via **XCUITest** through Appium Mac2, as the WebView is not directly exposed to WebDriver commands in the same manner.

### Can I use the same test specification files on both Linux and macOS?

Yes. The framework maintains a single test suite in `app/test/e2e/specs/` that runs unchanged on both platforms. The [`platform.ts`](https://github.com/tinyhumansai/openhuman/blob/main/platform.ts) helpers automatically detect the active driver and execute the appropriate interaction method, allowing tests to remain agnostic of the underlying automation technology.

### Why does `browser.execute` fail on macOS but work on Linux?

The **tauri-driver** on Linux implements the W3C WebDriver specification fully, including script execution within the WebView context. **Appium Mac2** operates at the native macOS UI layer using XCUITest, which cannot inject JavaScript into the embedded WebView. Tests should check `supportsExecuteScript()` before attempting DOM-based script execution.

### How do I configure custom ports for parallel test execution?

Set environment variables before launching WDIO. For Linux, export `TAURI_DRIVER_PORT` (defaults to 4444). For macOS, export `APPIUM_PORT` (defaults to 4723). The [`wdio.conf.ts`](https://github.com/tinyhumansai/openhuman/blob/main/wdio.conf.ts) reads these variables via `process.env` when calculating the `driverPort` value.