Maestro Usage
Quick reference for writing Maestro E2E flows. For the full command API, see resources/api-reference.md. For testing patterns and pitfalls, see resources/best-practices.md.
Flow File Structure
Every Maestro flow is a YAML file with an optional header section separated from commands by ---:
appId: com.example.app
name: "My Test Flow"
env:
USERNAME: "test@example.com"
PASSWORD: "password123"
tags:
- smoke
- regression
---
- launchApp:
clearState: true
- tapOn: "Login"
- inputText: "test@example.com"
Header Fields
| Field |
Required |
Description |
appId |
Yes |
Bundle ID (iOS) or package name (Android) |
name |
No |
Custom display name for the flow |
env |
No |
Environment variables accessible via ${VAR_NAME} |
tags |
No |
Tags for filtering (maestro test --include-tags smoke) |
jsEngine |
No |
rhino (default) or graaljs |
onFlowStart |
No |
Commands to run before the flow starts |
onFlowComplete |
No |
Commands to run after the flow ends (pass or fail) |
Command Quick Reference
Interaction
| Command |
Simple Form |
Purpose |
tapOn |
- tapOn: "Text" |
Tap an element |
doubleTapOn |
- doubleTapOn: "Text" |
Double-tap |
longPressOn |
- longPressOn: "Text" |
Long press |
inputText |
- inputText: "hello" |
Type text into focused field |
eraseText |
- eraseText: 5 |
Erase N characters (or all) |
pressKey |
- pressKey: Enter |
Press a key (Enter, home, back, etc.) |
swipe |
- swipe: { direction: LEFT } |
Swipe gesture |
scroll |
- scroll |
Simple scroll down |
scrollUntilVisible |
see API ref |
Scroll until element appears |
hideKeyboard |
- hideKeyboard |
Dismiss keyboard |
Navigation & App Lifecycle
| Command |
Simple Form |
Purpose |
launchApp |
- launchApp |
Launch app (with optional clearState, permissions) |
stopApp |
- stopApp |
Stop current app |
killApp |
- killApp |
Force kill (Android: process death) |
openLink |
- openLink: "https://..." |
Open URL or deep link |
back |
- back |
Press back (Android only) |
clearState |
- clearState |
Clear app data |
Assertions
| Command |
Simple Form |
Purpose |
assertVisible |
- assertVisible: "Text" |
Assert element is visible |
assertNotVisible |
- assertNotVisible: "Text" |
Assert element is not visible |
assertTrue |
- assertTrue: "1 + 1 === 2" |
Assert JS expression is truthy |
Waiting
| Command |
Purpose |
extendedWaitUntil |
Wait for element to appear/disappear with timeout |
waitForAnimationToEnd |
Wait until animations settle |
Flow Control
| Command |
Purpose |
runFlow |
Run a subflow from a file or inline, optionally conditional |
runScript |
Execute a JavaScript file |
repeat |
Repeat commands N times or while a condition is true |
retry |
Retry commands up to N times (max 3) on failure |
Clipboard & Text
| Command |
Purpose |
copyTextFrom |
Copy text from a UI element into maestro.copiedText |
setClipboard |
Set arbitrary text to clipboard |
pasteText |
Paste clipboard into focused field |
Device & Media
| Command |
Purpose |
setLocation |
Spoof GPS coordinates |
setOrientation |
Set portrait/landscape |
addMedia |
Add images/videos to device gallery |
toggleAirplaneMode |
Toggle airplane mode |
travel |
Simulate movement between GPS points |
Recording & Screenshots
| Command |
Purpose |
takeScreenshot |
Capture screenshot to file |
startRecording |
Begin video recording |
stopRecording |
End video recording |
AI-Powered (Experimental)
| Command |
Purpose |
assertWithAI |
AI-based visual assertion |
assertNoDefectsWithAI |
AI-based defect detection |
extractTextWithAI |
AI-based text extraction from screen |
Selectors
Selectors identify which UI element a command targets. Combine them for precision.
Core
text: Visible text or accessibility label (regex). - tapOn: "Login" is shorthand for text: "Login".
id: Accessibility identifier / resource ID (regex).
index: 0-based index when multiple elements match.
point: Screen coordinates ("50%, 50%" or "100, 250").
css: CSS selector (web only).
Relational
above / below / leftOf / rightOf: Position relative to an anchor element.
containsChild: Parent with a direct child matching criteria.
childOf: Element that is a direct child of a parent.
containsDescendants: Parent with specific descendants at any depth.
State
enabled: true / false — interactive state.
checked: true / false — checkbox/switch state.
focused: true / false — has keyboard focus.
selected: true / false — selected tab/segment.
Traits
traits: text: Any element containing text.
traits: long-text: Element with 200+ characters.
traits: square: Element with ~1:1 aspect ratio.
Common Arguments
Every command supports these optional fields:
label: Custom display name for the step in output.
optional: If true, flow continues even if the command fails (logged as warning).
Conditions (when)
runFlow and runScript support conditional execution:
- runFlow:
when:
visible: "Some Element" # element is visible
# notVisible: "Other" # element is NOT visible
# platform: iOS # platform check (Android|iOS|Web)
# true: ${MY_VAR == 'yes'} # JavaScript expression
commands:
- tapOn: "Some Element"
Multiple conditions are ANDed together.
Environment Variables
Access env vars with ${VAR_NAME} syntax anywhere in YAML values:
env:
USERNAME: "default_user"
---
- inputText: ${USERNAME}
Override at runtime: maestro test -e USERNAME=other_user flow.yaml
JavaScript Integration
Use runScript to execute JS files. Access env vars directly. Use output object to pass data back to the flow:
// scripts/setup.js
var name = "User_" + Date.now();
output.generatedName = name;
- runScript: scripts/setup.js
- inputText: ${output.generatedName}
HTTP Requests in JS
var response = http.get("https://api.example.com/data");
var data = json(response.body);
output.userId = data.id;
Methods: http.get(), http.post(), http.put(), http.delete(), http.request().
CLI Commands
| Command |
Purpose |
maestro test flow.yaml |
Run a single flow |
maestro test dir/ |
Run all flows in a directory |
maestro test --format junit dir/ |
Generate JUnit report |
maestro test --format html dir/ |
Generate HTML report |
maestro test -e KEY=VAL flow.yaml |
Pass env vars at runtime |
maestro test --include-tags smoke dir/ |
Run only flows with tag |
maestro studio |
Launch interactive browser IDE |
maestro cloud |
Run tests in Maestro Cloud |
Additional Resources
- Full command API with all options: resources/api-reference.md
- JavaScript & HTTP reference: resources/javascript-reference.md
- CLI commands & flags: resources/cli-reference.md
- Best practices and patterns: resources/best-practices.md
- Maestro MCP tool reference: resources/mcp-reference.md
- Annotated examples: examples/ (utilities, test flows, advanced patterns, project structure)
- Official docs: https://maestro.mobile.dev