How to Test Maestro YAML Configurations Locally: CLI and Validation Guide
You can test Maestro YAML configurations locally using the maestro test CLI command against an emulator, simulator, or browser, or validate syntax without a device using the Studio server's dry-run endpoint.
Maestro is an open-source mobile UI testing framework by mobile-dev-inc that lets you write test flows in human-readable YAML. Whether you are iterating on a single flow or running a full regression suite against a local device, the CLI provides multiple ways to test Maestro YAML configurations locally without requiring cloud infrastructure.
Installing the Maestro CLI
Before testing flows locally, install the Maestro command-line tool. The installation script downloads the latest binary and adds it to your path.
curl -fsSL "https://get.maestro.mobile.dev" | bash
Verify the installation by checking the version:
maestro --version
Running Flows Against Local Devices
The primary way to test Maestro YAML configurations locally is through the maestro test command, implemented in TestCommand.kt. This entry point orchestrates the entire execution pipeline: parsing your YAML, planning the run, connecting to the device, and reporting results.
Single Flow Execution
To run a single YAML file on a connected emulator, simulator, or browser:
maestro test path/to/your/flow.yaml
Under the hood, TestCommand invokes TestRunner.runSingle, which parses the file using MaestroFlowParser and executes each MaestroCommand against the device session created by MaestroSessionManager.
Batch Execution with Folders
You can test multiple flows by pointing the CLI at a directory or using glob patterns:
# Run all YAML files in a directory
maestro test path/to/flows/
# Run with specific output format
maestro test path/to/flow.yaml --format HTML_DETAILED --output report.html
When targeting a folder, WorkspaceExecutionPlanner.plan (defined in WorkspaceExecutionPlanner.kt) resolves the file set, handles sub-flows, and applies tag filters to build an ExecutionPlan before execution begins.
Capturing Debug Output
For troubleshooting failed tests, use the --debug-output flag to preserve device logs and screenshots:
maestro test path/to/flow.yaml --debug-output ./debug
The TestDebugReporter.kt file manages this directory, cleaning old files and organizing artifacts by test run.
Validating YAML Syntax Without a Device
You do not need a running emulator to validate that your YAML is syntactically correct. Maestro's Studio server provides a dry-run mode that parses the flow without executing commands.
Using the Studio Server API
The dry-run logic lives in DeviceService.kt. While the CLI does not expose a dedicated dry-run flag, you can validate YAML by starting the Studio server and hitting the run-command endpoint:
curl -X POST http://localhost:3000/api/run-command \
-H "Content-Type: application/json" \
-d '{"yaml":"- launchApp","dryRun":true}'
The server uses MaestroFlowParser to convert the YAML string into a list of MaestroCommand objects and returns the parsed structure, allowing you to catch syntax errors early without device interaction.
Advanced Local Testing Options
The maestro test command supports several options for complex local testing scenarios, all parsed in TestCommand.kt:
--config <file>: Supply a workspace-levelconfig.yamlto set default values likeappIdor environment variables.--include-tags <list>/--exclude-tags <list>: Filter which flows to run based on custom tags defined in your YAML metadata.--shard-split N: Distribute flows across N connected devices, splitting the suite evenly.--shard-all N: Run the complete flow suite on each of N connected devices simultaneously.--continuous: Keep the session alive and automatically re-run flows when file changes are detected, enabling rapid iteration.--headless: For web flows, launch the browser without a visible window.--screen-size WxH: Specify dimensions for headless browser testing (e.g.,1920x1080).
Example with tags and sharding:
maestro test flows/ --include-tags smoke --shard-split 2
Understanding the Internal Execution Flow
Testing locally involves four distinct phases implemented across the Maestro codebase.
1. Parsing with MaestroFlowParser
First, your YAML is converted into executable commands. In MaestroFlowParser.kt, the parseCommand method handles this transformation:
// maestro-orchestra/src/main/kotlin/maestro/orchestra/yaml/MaestroFlowParser.kt
val commands = MaestroFlowParser.parseCommand(Paths.get(""), "", yamlString)
This produces a list of MaestroCommand objects that represent actions like launchApp, tapOn, or assertVisible.
2. Planning with WorkspaceExecutionPlanner
For multi-flow runs, WorkspaceExecutionPlanner.kt builds an execution plan that respects your directory structure and tag filters:
val executionPlan = WorkspaceExecutionPlanner.plan(
input = setOf(Paths.get("flow1.yaml"), Paths.get("subfolder")),
includeTags = listOf("smoke"),
excludeTags = emptyList(),
config = Paths.get("config.yaml")
)
3. Execution with TestRunner
Finally, TestRunner.kt handles the actual device interaction. For single flows, runSingle manages the session, executes commands, and handles reporting:
TestRunner.runSingle(
maestro = maestro,
device = device,
flowFile = File("login_flow.yaml"),
env = mapOf("USERNAME" to "test"),
resultView = AnsiResultView(),
debugOutputPath = debugPath,
analyze = false,
apiKey = null,
testOutputDir = null,
deviceId = null
)
For suites, runMultiple iterates through the ExecutionPlan, executing each flow in sequence or parallel depending on sharding configuration.
Summary
- Install the Maestro CLI using the official install script to get the
maestro testcommand. - Run single flows with
maestro test <file.yaml>or batch test directories to validate complete suites locally. - Debug failures using
--debug-outputto capture screenshots and logs, or generate HTML reports with--format HTML_DETAILED. - Validate syntax without a device by using the Studio server's dry-run endpoint at
/api/run-command. - Optimize execution with sharding (
--shard-split,--shard-all), tag filtering, and continuous mode for rapid local iteration. - Key source files:
TestCommand.kt(CLI entry),MaestroFlowParser.kt(YAML parsing),WorkspaceExecutionPlanner.kt(execution planning), andTestRunner.kt(device execution).
Frequently Asked Questions
Can I test Maestro YAML without connecting a device?
Yes. Start the Maestro Studio server and POST to the run-command endpoint with "dryRun": true in the JSON body. This uses MaestroFlowParser to validate syntax without executing commands against a device, as implemented in DeviceService.kt.
How do I run only specific tests from my local workspace?
Use the --include-tags and --exclude-tags flags with the maestro test command. Tags are defined in your YAML file metadata, and WorkspaceExecutionPlanner filters the execution plan accordingly before TestRunner begins execution.
What is the difference between --shard-split and --shard-all?
--shard-split N divides your flow suite across N connected devices, giving each device a subset of flows to complete the suite faster. --shard-all N runs the entire suite on each of N devices simultaneously, useful for testing across different device configurations or OS versions.
Where does Maestro store debug logs and screenshots when testing locally?
When you provide the --debug-output <path> flag, TestDebugReporter.kt creates a directory at the specified path containing subdirectories for each flow run with screenshots, device logs, and hierarchy dumps to help diagnose failures.
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 →