How to Write Conditional Logic in Maestro YAML: Complete Guide with Examples
Maestro lets you conditionally execute commands directly inside a flow file by adding a when: (or legacy if:) block to any supported command, parsing conditions into a YamlCondition data class that evaluates platform, visibility, or JavaScript expressions before running the command.
Conditional logic in Maestro YAML allows your mobile test flows to adapt dynamically to UI state, device platform, or environment variables without external scripting. According to the mobile-dev-inc/Maestro source code, the orchestration engine supports declarative conditions through the when: block defined in maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlCondition.kt.
Understanding the when: Block Structure
In YamlCondition.kt (lines 6‑14), Maestro defines the data class that captures all supported conditional fields. When the YAML parser processes a flow, YamlFluentCommand converts these definitions into concrete MaestroCommand objects. For each command carrying a conditional block, the parser invokes YamlCondition.toCondition() (lines 1005‑1013 in YamlFluentCommand.kt) to build a runtime Condition instance used by the executor.
This architecture allows the engine to evaluate conditions eagerly before executing the command. As noted in the project's CHANGELOG.md (line 99), this eager evaluation improves performance by checking script conditions ahead of visibility checks.
Supported Condition Types
Platform Filtering
Execute commands only on specific operating systems using the platform field. Valid values are ANDROID or IOS.
Visibility Checks
Use visible to run a command only when an element matching the selector is displayed. Conversely, use notVisible to execute only when an element is hidden from view.
JavaScript Expressions
The true field accepts arbitrary JavaScript expressions that must evaluate to true for the command to execute. This enables complex logic using environment variables or computed values via Maestro's built-in functions.
Debug Labels
Add an optional label field to any condition for clearer debugging and test reporting output.
Practical Code Examples
Run a script only when a button is visible:
- runScript:
when:
visible: "Continue"
file: scripts/doStuff.js
label: "Run when Continue button appears"
Launch the app only on Android devices:
- launchApp:
when:
platform: ANDROID
appId: com.example.myapp
Execute a flow step only when a JavaScript condition is true:
- assertTrue:
when:
true: "${env('ENABLE_ASSERT') === 'true'}"
condition: "someVariable > 0"
label: "Guarded assertion"
Conditional repeat loop using while syntax:
- repeat:
while:
notVisible: "Loading"
times: 10
commands:
- tapOn: "Refresh"
Run a sub-flow with multiple conditions:
- runFlow:
when:
platform: iOS
true: "${env('RUN_SUBFLOW') == '1'}"
file: subflows/login.yaml
Commands Supporting Conditional Logic
The when: block (and legacy if: syntax) functions across multiple command types in the orchestration layer. The parser handles conditional conversion for:
runScript– Execute JavaScript files conditionallyrunFlow– Include sub-flows based on runtime staterepeat– Loop usingwhileconditions (evaluated vianotVisibleor other checks)assertTrue– Guard assertions with preconditionsassertVisible– Conditional visibility assertionslaunchApp– Platform-specific app launches
Summary
- Add conditional logic in Maestro YAML using the
when:block on supported commands, or the legacyif:syntax - Conditions support platform filtering (
ANDROID/IOS), visibility checks (visible/notVisible), and JavaScript boolean expressions (true) - The parser converts YAML conditions to runtime
Conditionobjects viaYamlCondition.toCondition()inYamlFluentCommand.kt - Evaluation happens eagerly before command execution to optimize performance, skipping the command entirely when the condition is
false - Use optional
labelfields to improve debugging and test reporting clarity
Frequently Asked Questions
Can I combine multiple conditions in a single when: block?
Yes. You can specify multiple checks such as platform: iOS and true: "${env('FLAG') == '1'}" within the same when: block, and Maestro requires all conditions to evaluate to true before executing the command. This allows you to gate flows by both device type and environment configuration simultaneously.
What is the difference between when: and if: in Maestro YAML?
There is no functional difference. Maestro supports both when: and the legacy if: syntax for backward compatibility. Both keywords trigger the same condition parsing logic in YamlFluentCommand.kt, converting your YAML into a Condition instance that the runtime evaluates before command execution.
What JavaScript context is available in the true condition?
The true field executes JavaScript expressions with access to Maestro's built-in functions such as env() for reading environment variables. The expression must return a boolean value, and the evaluation occurs eagerly—before the associated command runs—according to the implementation in YamlCondition.toCondition().
Can I use conditional logic with repeat loops?
Yes. The repeat command accepts a while: block that uses the same condition structure as when:. You can specify notVisible, visible, platform, or true conditions to control loop execution. The engine evaluates the condition before each iteration, continuing the loop only while the condition remains satisfied.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →