# How to Write Conditional Logic in Maestro YAML: Complete Guide with Examples

> Master Maestro YAML conditional logic. Learn to conditionally execute commands using when or if blocks with platform, visibility, or JS expressions. Boost your automation.

- Repository: [Maestro/Maestro](https://github.com/mobile-dev-inc/Maestro)
- Tags: how-to-guide
- Published: 2026-03-20

---

**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`](https://github.com/mobile-dev-inc/Maestro/blob/main/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlCondition.kt).

## Understanding the `when:` Block Structure

In [`YamlCondition.kt`](https://github.com/mobile-dev-inc/Maestro/blob/main/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`](https://github.com/mobile-dev-inc/Maestro/blob/main/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`](https://github.com/mobile-dev-inc/Maestro/blob/main/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:

```yaml
- runScript:
    when:
      visible: "Continue"
    file: scripts/doStuff.js
    label: "Run when Continue button appears"

```

Launch the app only on Android devices:

```yaml
- launchApp:
    when:
      platform: ANDROID
    appId: com.example.myapp

```

Execute a flow step only when a JavaScript condition is true:

```yaml
- assertTrue:
    when:
      true: "${env('ENABLE_ASSERT') === 'true'}"
    condition: "someVariable > 0"
    label: "Guarded assertion"

```

Conditional repeat loop using `while` syntax:

```yaml
- repeat:
    while:
      notVisible: "Loading"
    times: 10
    commands:
      - tapOn: "Refresh"

```

Run a sub-flow with multiple conditions:

```yaml
- 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 conditionally
- `runFlow` – Include sub-flows based on runtime state
- `repeat` – Loop using `while` conditions (evaluated via `notVisible` or other checks)
- `assertTrue` – Guard assertions with preconditions
- `assertVisible` – Conditional visibility assertions
- `launchApp` – Platform-specific app launches

## Summary

- Add conditional logic in Maestro YAML using the `when:` block on supported commands, or the legacy `if:` syntax
- Conditions support platform filtering (`ANDROID`/`IOS`), visibility checks (`visible`/`notVisible`), and JavaScript boolean expressions (`true`)
- The parser converts YAML conditions to runtime `Condition` objects via `YamlCondition.toCondition()` in [`YamlFluentCommand.kt`](https://github.com/mobile-dev-inc/Maestro/blob/main/YamlFluentCommand.kt)
- Evaluation happens eagerly before command execution to optimize performance, skipping the command entirely when the condition is `false`
- Use optional `label` fields 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`](https://github.com/mobile-dev-inc/Maestro/blob/main/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.