Skip to main content

Maestro

Maestro is a declarative, YAML-based end-to-end testing tool for mobile and web apps. The @archibald/maestro integration package wires it into Archibald projects as the native E2E counterpart to Cypress, with a thin runner wrapper and host-aware install verification.

For broader usage guidance — selector strategy, flow authoring, environment variables — see End-to-end testing → Maestro.

Repository Integration

There are two ways to install the Maestro integration into an Archibald project.

Option A: Archibald CLI command

archibald add maestro

This:

  • Installs @archibald/maestro as a dev dependency (pinned to the project's Archibald version).
  • Scaffolds a maestro/ directory at the project root with a starter config.yaml and flows/smoke.yaml.
  • Adds a maestro script in package.json that invokes archibald maestro.

Option B: Manual installation

npm install --save-dev @archibald/maestro

Create a maestro/ directory at the project root:

# maestro/config.yaml
appId: <your.bundle.id>
flows:
- flows/
# maestro/flows/smoke.yaml
appId: <your.bundle.id>
---
- launchApp
- assertVisible: 'Welcome'

Add a script to package.json:

{
"scripts": {
"maestro": "archibald maestro"
}
}

The Maestro CLI

Maestro itself is a JVM-based CLI distributed outside of npm. This package does not install it; it detects whether the binary is present on PATH (with a fallback to ~/.maestro/bin/maestro) and prints platform-specific install instructions if it is missing.

HostInstall
macOSbrew tap mobile-dev-inc/tap && brew install maestro
Linux / WSLcurl -fsSL "https://get.maestro.mobile.dev" | bash then add ~/.maestro/bin to your $PATH
Windowsinstall via WSL using the Linux instructions, or follow the manual setup

Tested against Maestro 2.5.x. Avoid versions <= 2.1 — they do not reliably trigger React Native New Architecture Pressable components on iOS.

Public API

import {
assertMaestroInstalled,
verifyMaestroInstall,
MaestroNotInstalledError,
runMaestro,
getInstallInstructions,
formatInstallInstructions,
detectHostPlatform
} from '@archibald/maestro';

Install verification

const status = verifyMaestroInstall();
// { installed: true, binaryPath: '/opt/homebrew/bin/maestro', version: '2.5.1' }
// or { installed: false, reason: 'not_found' }

assertMaestroInstalled(); // throws MaestroNotInstalledError with platform-specific install instructions when missing

assertMaestroInstalled() is what the archibald maestro CLI calls before spawning a flow.

Runner wrapper

const { exitCode } = await runMaestro({
flows: 'maestro/flows', // file or directory
flowEnv: { USERNAME: process.env.USERNAME ?? '' }, // forwarded as -e KEY=value
extraArgs: ['--app-id', 'com.example.preview'] // anything else passed to `maestro test`
});

The wrapper spawns the resolved binary with test, inherits stdio, and resolves with the maestro exit code.

Host detection

const platform = detectHostPlatform(); // 'darwin' | 'linux' | 'wsl' | 'win32' | 'unknown'
const instruction = getInstallInstructions(platform);
console.log(formatInstallInstructions(instruction));

Useful for embedding install hints in your own tooling.

Project Setup

Once the CLI is installed on your host and archibald add maestro has scaffolded the project, the typical workflow is:

# 1. Build + install the app on a simulator/emulator
pnpm ios # or: pnpm android

# 2. Run the flows
pnpm maestro # equivalent to: archibald maestro

Maestro drives an installed binary on a simulator/emulator — it does not connect to Metro. Always rebuild and reinstall after changing source files that affect flow targets.

CI

Maestro Cloud is the recommended path for CI: upload flows + your app binary and Maestro runs them on managed devices. The package does not ship Maestro Cloud helpers — invoke maestro cloud directly from your pipeline once you have a MAESTRO_CLOUD_API_KEY set. See the Maestro Cloud docs for the latest reference.

Further documentation