Maestro Deck
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"

Config block

The block above the first ---. All fields are optional except appId.

FieldTypeDescription
appIdstringBundle ID (iOS) or package name (Android). Required.
namestringHuman-readable flow name. Defaults to the filename.
tagsstring[]Free-form tags for filtering at run time.
envmapVariables 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"

Selectors

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.

FieldDescription
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).

Commands reference

Lifecycle

CommandDescription
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.

Interaction

CommandDescription
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.

Assertions

CommandDescription
assertVisibleFail unless the selector matches a visible element.
assertNotVisibleFail if the selector matches.
assertTrueFail unless the JS expression is truthy: assertTrue: ${OUTPUT.foo == 'bar'}.

Waits

CommandDescription
waitForAnimationToEndBlock until on-screen animations settle. Accepts timeout.
extendedWaitUntilGeneralised wait, pass any assertion plus timeout.

Flow control

CommandDescription
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"

Device control

CommandDescription
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.

Variables

Three sources, evaluated in this order:

  1. env: in the flow config.
  2. --env KEY=value flags passed to maestro test.
  3. 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}

Common pitfalls

  • 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.
Share:LinkedInX / Twitter

On this page