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/maestroas a dev dependency (pinned to the project's Archibald version). - Scaffolds a
maestro/directory at the project root with a starterconfig.yamlandflows/smoke.yaml. - Adds a
maestroscript inpackage.jsonthat invokesarchibald 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.
| Host | Install |
|---|---|
| macOS | brew tap mobile-dev-inc/tap && brew install maestro |
| Linux / WSL | curl -fsSL "https://get.maestro.mobile.dev" | bash then add ~/.maestro/bin to your $PATH |
| Windows | install 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.