Reference
YAML schema The full YAML schema for Maestro Deck flows, config block, steps, selectors, and built-in commands.
A Maestro flow is a YAML file with two parts separated by ---: a config block at the top, and a steps array below. The same format is used by mobile.dev's Maestro CLI, Maestro Studio, and Maestro Deck, flows are portable across all three.
appId : com.example.app # config block
tags : [ smoke , auth ]
---
- launchApp # steps
- tapOn : "Sign in"
- inputText : "qa@example.com"
- assertVisible : "Welcome"
The block above the first ---. All fields are optional except appId.
Field Type Description appIdstring Bundle ID (iOS) or package name (Android). Required. namestring Human-readable flow name. Defaults to the filename. tagsstring[] Free-form tags for filtering at run time. envmap Variables made available to steps as ${VAR_NAME}. onFlowStartstep[] Steps to execute before the first user step. onFlowCompletestep[] Steps to execute after the last user step, including on failure. jsEnginegraaljs | rhinoEngine used by evalScript. Defaults to graaljs.
appId : com.example.app
name : Checkout, happy path
tags : [ smoke , checkout ]
env :
USERNAME : qa@example.com
PASSWORD : hunter2
onFlowStart :
- runFlow : flows/_sign-in.yaml
onFlowComplete :
- clearKeychain
---
- tapOn : "Buy now"
Most commands accept a selector as a shorthand string (tapOn: "Sign in" matches by text) or as a structured object. The object form supports combining fields.
Field Description textVisible text. Supports regex when wrapped in /.../. idAccessibility identifier. Most stable, prefer this. classWidget class (Android) or control type (iOS). indexPick the Nth match, 0-indexed. enabledtrue / false.selectedtrue / false.checkedtrue / false.focusedtrue / false.width / heightConstrain by pixel size. point"50%,50%" or "100,200". Last-resort.
- tapOn :
id : "login-button"
enabled : true
Selectors with point are brittle across screen sizes. Use them only when no other field works (custom-drawn canvases, web views without IDs).
Command Description launchAppLaunch the app declared in appId. Accepts clearState: true to wipe app data first. stopAppStop the app. clearStateWipe app data without relaunching. clearKeychainiOS only. Clear all keychain entries for the bundle. killAppForce-kill the app process.
Command Description tapOnTap the matched element. Accepts a selector. doubleTapOnDouble-tap. longPressOnLong-press (default 1s). Pass duration: 2000 to override. inputTextType into the currently focused field. eraseTextDelete N characters from the focused field. Default 50. copyTextFromCopy a matched element's text into a flow variable. pasteTextPaste the clipboard into the focused field. swipefrom: and to: (selectors or start: "50%,80%" / end: "50%,20%").scrollScroll the screen up by one page. scrollUntilVisibleScroll until a selector matches. Accepts direction, speed, timeout. hideKeyboardDismiss the soft keyboard. pressKeyHardware keys: Back, Home, Enter, Power, volume up/down. backShortcut for pressKey: Back. Android only.
Command Description assertVisibleFail unless the selector matches a visible element. assertNotVisibleFail if the selector matches. assertTrueFail unless the JS expression is truthy: assertTrue: ${OUTPUT.foo == 'bar'}.
Command Description waitForAnimationToEndBlock until on-screen animations settle. Accepts timeout. extendedWaitUntilGeneralised wait, pass any assertion plus timeout.
Command Description runFlowInline another flow file. Accepts a path or a file: + env: map. runScriptExecute a JS file with access to flow variables. evalScriptInline JS expression: evalScript: ${output.token = '...'}. repeatLoop a block of steps. Accepts times: N or while: (an assertion). retryRetry a block on failure. Accepts maxRetries: N.
- repeat :
times : 3
commands :
- tapOn : "Next"
Command Description setLocationMock GPS: setLocation: {latitude: 48.85, longitude: 2.35}. setAirplaneModeenabled: true / false. Android only.toggleAirplaneModeFlip the current state. addMediaPush a media file (image, video) into the gallery. openLinkOpen a URL or deep link. takeScreenshotSave a screenshot to screenshots/<label>.png. startRecording / stopRecordingCapture a screen recording over a range of steps.
Three sources, evaluated in this order:
env: in the flow config.
--env KEY=value flags passed to maestro test.
Output of previous steps (copyTextFrom, evalScript, runScript).
Reference them in any string with ${VAR_NAME}:
env :
USERNAME : qa@example.com
---
- inputText : ${USERNAME}
- inputText : ${OUTPUT.token}
appId mismatch. A flow with the wrong appId will launch the wrong app or do nothing visible, Maestro doesn't always error loudly.
Selector ambiguity. When two elements match, Maestro picks the first by tree order, not the most visible. Add id or index to disambiguate.
assertVisible followed by tapOn. Redundant, tapOn already waits for visibility. See avoiding duplicate assertions .
Missing --- separator. A flow with only a config block and no --- is parsed as an empty steps array and exits immediately green.