AI context file for the WebdriverIO Desktop & Mobile Testing monorepo.
This is a monorepo providing WebdriverIO services for automated testing of native desktop and mobile applications.
Supported Frameworks:
- Electron -
@wdio/electron-service(v10.x) - Tauri -
@wdio/tauri-service(v1.x)
Planned: Dioxus, React Native, Flutter, Capacitor, Neutralino. See ROADMAP.md for details.
| Category | Technology |
|---|---|
| Language | TypeScript 5.9+ (strict mode, ESM) |
| Runtime | Node.js 18 LTS or 20 LTS |
| Package Manager | pnpm 10.27.0+ |
| Monorepo | Turborepo 2.5+ with pnpm workspaces |
| Testing | Vitest 3.2+ (unit/integration), WebdriverIO 9.0+ (E2E) |
| Linting | Biome 2.2.5 + ESLint 9.37+ |
| Build | TypeScript compiler (dual ESM/CJS) |
packages/
├── electron-service/ # Electron WDIO service
├── tauri-service/ # Tauri WDIO service
├── tauri-plugin/ # Tauri v2 plugin (Rust + JS)
├── electron-cdp-bridge/ # Chrome DevTools Protocol bridge
├── native-utils/ # Cross-platform utilities
├── native-types/ # TypeScript type definitions
├── native-spy/ # Spy utilities for mocking
└── bundler/ # Build tool for packages
fixtures/
├── e2e-apps/ # E2E test applications
└── package-tests/ # Package integration test fixtures
e2e/ # End-to-end test suites
agent-os/ # Agent OS standards and specs
WDIO runs launcher and worker services in separate processes. Every service package splits into two classes:
src/
├── index.ts # Package entry point (default=worker, named launcher=launcher)
├── launcher.ts # Launcher service (main process)
├── service.ts # Worker service (worker process)
├── types.ts # TypeScript type definitions
└── constants/ # Constants and configuration
Launcher (launcher.ts) — runs in main process, no browser access:
- Hooks:
onPrepare,onWorkerStart,onWorkerEnd,onComplete - Responsibilities: binary detection, port allocation, driver spawning, capability mutation
- Throw
SevereServiceError(fromwebdriverio) for fatal failures that should stop the runner
Worker (service.ts) — runs in worker process, receives browser via before hook:
- Hooks:
before,beforeTest,beforeCommand,after,afterSession - Responsibilities: API injection onto
browser, mock lifecycle, window focus, log capture
Use createLogger from @wdio/native-utils for all logging:
import { createLogger } from '@wdio/native-utils';
const log = createLogger('service-name', 'module-name');Mocks span two process boundaries — an inner mock in the app context and an outer mock in the test process. The inner mock (created via @wdio/native-spy) intercepts real API calls inside the app. The outer mock (vitest-compatible) is used for test assertions. Call data syncs one-way from inner to outer via update(), serialized as JSON across CDP/WebDriver boundaries. See agent-os/standards/global/mock-architecture.md for details.
- Strict mode enabled
- Prefer
undefinedovernull - ESM modules everywhere (dual CJS build for compatibility)
- Avoid
any- use proper types - No barrel files (
index.tswith only re-exports) except at package roots
- 2 spaces indentation
- Single quotes for strings
- Trailing commas in objects/arrays
- Max line length: 120 characters
- Arrow functions for callbacks
- No comments unless explicitly requested
- JSDoc for public APIs only when necessary
test/
├── *.spec.ts # Unit tests
└── integration/
└── *.spec.ts # Integration tests
- 80%+ test coverage required
- Unit tests for logic, integration tests for process management
- E2E tests in
e2e/directory
pnpm test # All tests
pnpm --filter @wdio/tauri-service test # Specific package
pnpm test:integration # Integration tests onlypnpm build # Build all packages
pnpm lint # Lint all packages
pnpm typecheck # Type check all packages
pnpm test # Run all testsThis codebase uses a Result<T, E> type for operations that can fail:
type Result<T, E = Error> =
| { ok: true; value: T }
| { ok: false; error: E }
// Usage
if (result.ok) {
console.log(result.value); // Success case
} else {
console.error(result.error); // Error case
}Important: Do not use .success or .data properties. Use .ok to check and .value/.error to access.
- Windows requires
.cmdfiles for shell scripts - Use
get-portfor dynamic port allocation to avoid conflicts - Driver processes need graceful shutdown (SIGTERM, then SIGKILL after timeout)
- File paths must handle both Unix and Windows separators
| File | Purpose |
|---|---|
| README.md | Project overview and quick start |
| CONTRIBUTING.md | Contribution guidelines |
| ROADMAP.md | Framework support roadmap |
| docs/setup.md | Detailed setup instructions |
| docs/package-structure.md | Package conventions |
| docs/architecture.md | Service architecture |
| docs/e2e-testing.md | E2E testing guide |
This project uses Agent OS v3 for AI-assisted development standards. Standards are in agent-os/standards/ and can be injected using /inject-standards.
Available commands:
/discover-standards- Extract patterns from codebase/inject-standards- Inject standards into context/shape-spec- Enhanced spec shaping/plan-product- Product planning
- Create
packages/<framework>-service/ - Follow the service architecture pattern (launcher.ts, service.ts, types.ts)
- Add to
pnpm-workspace.yaml - Update
turbo.jsonwith build dependencies - Create E2E test app in
fixtures/e2e-apps/<framework>/
- Tests are in
test/integration/ - Mock drivers are in
test/fixtures/ - Use
fileParallelism: falsein vitest config for port isolation - Check port conflicts if tests hang
- E2E tests require built apps in
fixtures/e2e-apps/ - Check
e2e/wdio.*.conf.tsfor configuration - Protocol handlers may need setup (see
docs/e2e-testing.md)