Quick Start
# Run a single flow
maestro-runner flow.yaml
# Run top-level flows in a directory (does NOT recurse into subdirectories)
maestro-runner flows/
# Run multiple files
maestro-runner login.yaml checkout.yaml settings.yaml
The test subcommand is optional -- maestro-runner flow.yaml and maestro-runner test flow.yaml are identical.
Directory Scanning Behavior
When a directory is passed, only top-level .yaml/.yml files are collected. Subdirectories are ignored by default. Files named config.yaml or config.yml are always excluded (treated as workspace config).
To include subdirectory flows, create a config.yaml in the directory:
# config.yaml - include flows from subdirectories
flows:
- "auth/*" # Top-level files in auth/
- "checkout/*" # Top-level files in checkout/
- "**" # All .yaml/.yml files recursively
- "**/smoke*.yaml" # Recursive, matching a filename pattern
# With config.yaml in flows/ directory, subdirectory flows are included
maestro-runner flows/
# Or reference individual files/subdirectories directly
maestro-runner flows/auth/login.yaml flows/checkout/cart.yaml
Commands
test (default)
Run Maestro flows on a device. This is the default command -- you can omit it.
maestro-runner [global-flags] [test] [test-flags] <flow-file-or-folder>...
At least one flow file or folder path is required.
Global Flags
Available on all commands. These can appear before or after the test keyword.
| Flag | Alias | Type | Default | Env Var | Description |
|---|---|---|---|---|---|
--platform |
-p |
string | (auto-detect) | MAESTRO_PLATFORM |
Platform: ios, android, web |
--device |
--udid |
string | (auto-detect) | MAESTRO_DEVICE |
Device ID (comma-separated for multiple) |
--driver |
-d |
string | uiautomator2 |
MAESTRO_DRIVER |
Driver: uiautomator2, appium |
--appium-url |
string | http://127.0.0.1:4723 |
APPIUM_URL |
Appium server URL (for appium driver) | |
--caps |
string | APPIUM_CAPS |
Path to Appium capabilities JSON file | ||
--verbose |
bool | false |
MAESTRO_VERBOSE |
Enable verbose logging | |
--app-file |
string | MAESTRO_APP_FILE |
App binary (.apk/.app/.ipa) to install before testing | ||
--no-ansi |
bool | false |
Disable ANSI colors | ||
--team-id |
string | MAESTRO_TEAM_ID, DEVELOPMENT_TEAM |
Apple Development Team ID for WDA code signing | ||
--start-emulator |
string | MAESTRO_START_EMULATOR |
Start Android emulator by AVD name (e.g., Pixel_7_API_33) |
||
--start-simulator |
string | MAESTRO_START_SIMULATOR |
Start iOS simulator by name or UDID (e.g., iPhone 15 Pro) |
||
--auto-start-emulator |
bool | false |
MAESTRO_AUTO_START_EMULATOR |
Auto-start an emulator/simulator if no devices found | |
--shutdown-after |
bool | true |
MAESTRO_SHUTDOWN_AFTER |
Shutdown devices started by maestro-runner after tests | |
--boot-timeout |
int | 180 |
Device boot timeout in seconds |
Test Flags
These flags apply only to the test command (or the default action).
| Flag | Alias | Type | Default | Env Var | Description |
|---|---|---|---|---|---|
--config |
string | Path to workspace config.yaml |
|||
--env |
-e |
string (repeatable) | Environment variables (KEY=VALUE), can be specified multiple times |
||
--include-tags |
string (repeatable) | Only include flows with these tags | |||
--exclude-tags |
string (repeatable) | Exclude flows with these tags | |||
--output |
string | ./reports |
Output directory for reports | ||
--flatten |
bool | false |
Don't create timestamp subfolder (requires --output) |
||
--parallel |
int | Run tests in parallel on N devices | |||
--wait-for-idle-timeout |
int | 5000 |
MAESTRO_WAIT_FOR_IDLE_TIMEOUT |
Wait for device idle in ms (0 = disabled) |
Environment Variables
All flags with an Env Var column can be set via environment variable instead of the CLI flag. CLI flags take precedence over environment variables.
Additionally:
NO_COLOR-- disables ANSI color output (standard convention)MAESTRO_RUNNER_HOME-- overrides the home directory for drivers and cache. Resolution order: (1) this env var, (2) parent of binary's directory if binary is in abin/subdirectory, (3) current working directory
Tag Filtering
Flows define tags in their YAML config:
tags:
- smoke
- login
Filter which flows run:
# Only run flows tagged "smoke"
maestro-runner flows/ --include-tags smoke
# Run all flows except those tagged "flaky"
maestro-runner flows/ --exclude-tags flaky
# Multiple tags (repeat the flag)
maestro-runner flows/ --include-tags smoke --include-tags regression
# Combine include and exclude
maestro-runner flows/ --include-tags smoke --exclude-tags slow
Logic:
--include-tags: Flow must have at least one matching tag to be included.--exclude-tags: Flow is excluded if it has any matching tag.- If both are specified, exclude takes precedence.
- If neither is specified, all flows run.
Output & Reports
Reports are generated automatically after every run.
# Default: ./reports/<timestamp>/
maestro-runner flows/
# Custom directory: ./my-reports/<timestamp>/
maestro-runner flows/ --output ./my-reports
# Flat (no timestamp subfolder): ./my-reports/
maestro-runner flows/ --output ./my-reports --flatten
Generated files in the output directory:
report.html-- visual HTML reportreport.json-- machine-readable JSON reportmaestro-runner.log-- detailed execution log
Driver Selection
UIAutomator2 (default, Android)
Direct communication with the UIAutomator2 server on the device. No external dependencies.
maestro-runner flows/
maestro-runner --driver uiautomator2 flows/
WDA (iOS, auto-selected)
When --platform ios is set and the default driver is used, maestro-runner automatically selects the WDA (WebDriverAgent) driver.
maestro-runner --platform ios flows/
Appium (both platforms, cloud providers)
Connects to an external Appium server. Required for cloud providers (BrowserStack, SauceLabs, LambdaTest).
# Local Appium server
maestro-runner --driver appium flows/
# With capabilities file
maestro-runner --driver appium --caps caps.json flows/
# Cloud provider
maestro-runner --driver appium \
--appium-url "https://your-cloud-provider/wd/hub" \
--caps cloud-caps.json \
flows/
Capabilities file (caps.json): Standard Appium JSON capabilities. CLI flags (--platform, --device, --app-file) override values in the caps file.
App Installation
Install an app before testing with --app-file. This ensures you always test the right build.
# Android
maestro-runner --app-file app.apk flows/
# iOS simulator
maestro-runner --platform ios --app-file App.app flows/
# iOS real device
maestro-runner --platform ios --team-id ABCDE12345 --app-file App.ipa flows/
If --app-file is not set, maestro-runner runs against whatever is already installed on the device.
Emulator & Simulator Management
maestro-runner can start and manage Android emulators and iOS simulators.
Android Emulator
# Start a specific AVD before running tests
maestro-runner --start-emulator Pixel_7_API_33 flows/
# Auto-start if no devices found
maestro-runner --auto-start-emulator flows/
# Keep emulator running after tests
maestro-runner --start-emulator Pixel_7_API_33 --shutdown-after=false flows/
iOS Real Device
# Run on a connected real device (team ID required for code signing)
maestro-runner --platform ios --team-id ABCDE12345 flows/
# Specify a device by UDID
maestro-runner --platform ios --team-id ABCDE12345 --device 00001234-ABCDEF012345 flows/
iOS Simulator
# Start a named simulator
maestro-runner --platform ios --start-simulator "iPhone 15 Pro" flows/
# Auto-start if no simulators are booted
maestro-runner --platform ios --auto-start-emulator flows/
Parallel Execution with Auto-Start
# Start 3 emulators and run tests in parallel
maestro-runner --platform android --parallel 3 --auto-start-emulator flows/
# Start 2 iOS simulators in parallel
maestro-runner --platform ios --parallel 2 --auto-start-emulator flows/
Each parallel emulator requires a unique AVD (Android locks the AVD directory at boot, preventing the same AVD from running twice).
Devices started by maestro-runner are automatically shut down after tests unless --shutdown-after=false is set. Cleanup also runs on SIGINT (Ctrl+C) and SIGTERM.
Parallel Execution
Run tests across multiple devices simultaneously.
# Auto-detect devices
maestro-runner --parallel 2 flows/
# Specific devices
maestro-runner --device emulator-5554,emulator-5556 flows/
# Auto-start emulators to reach target count
maestro-runner --parallel 3 --auto-start-emulator flows/
During parallel execution, brief status updates are shown to avoid interleaved output. Detailed results are displayed after all tests complete.
Note: Parallel execution is not yet supported with the Appium driver.
Workspace Config
A config.yaml file can set shared configuration for all flows:
maestro-runner --config config.yaml flows/
The config file can define:
appId-- default app ID for all flowsenv-- environment variables (CLI-eflags take precedence)waitForIdleTimeout-- idle timeout override
Version Information
maestro-runner --version
Exit Codes
| Code | Meaning |
|---|---|
0 |
All flows passed |
1 |
One or more flows failed, or a runtime error occurred |
Key Differences from Maestro CLI
| Feature | Maestro CLI | maestro-runner |
|---|---|---|
| Binary name | maestro |
maestro-runner |
| Test command | maestro test (required) |
maestro-runner flows/ or maestro-runner test flows/ |
| Default driver | Maestro's own driver | uiautomator2 (direct) or wda (iOS) |
| Appium support | No | --driver appium with --caps |
| Cloud providers | No | Via --driver appium --appium-url |
| Device start (Android) | maestro start-device |
--start-emulator <avd> |
| Device start (iOS) | maestro start-device |
--start-simulator <name> |
| Auto device start | No | --auto-start-emulator |
| Parallel execution | No | --parallel N |
| WDA management | Built-in | maestro-runner wda update |
| Reports | HTML/JUnit | HTML + JSON + log |
| Environment vars | maestro test -e KEY=VAL |
Same: -e KEY=VAL |
| Tag filtering | --include-tags, --exclude-tags |
Same |