| name | Maestro Mobile Testing |
| description | Black-box mobile UI testing with Maestro YAML flows - launchApp, tapOn, inputText, assertVisible, reusable runFlow subflows, environment parameters, JUnit reporting, and emulator-based CI pipelines. |
| version | 1.0.0 |
| author | thetestingacademy |
| license | MIT |
| tags | ["maestro","mobile","e2e","ios","android","yaml","flows","ui-testing","flutter","react-native"] |
| testingTypes | ["mobile","e2e"] |
| frameworks | ["appium"] |
| languages | ["typescript"] |
| domains | ["mobile"] |
| agents | ["claude-code","cursor","github-copilot","windsurf","codex","aider","continue","cline","zed","bolt","gemini-cli","amp"] |
Maestro Mobile Testing
This skill makes an AI agent write Maestro flows - declarative YAML files that drive iOS and Android apps black-box style with built-in waiting, no test harness compiled into the app, and no WebDriver session management. Trigger it when a repository contains a .maestro/ directory or *.yaml flows with appId: headers, or when the user wants fast, low-maintenance smoke tests for a native, React Native, or Flutter app without the weight of Appium.
Core Principles
- Maestro waits by default; do not teach it to sleep. Every
tapOn and assertVisible polls until the element appears or a timeout expires. Reach for extendedWaitUntil for slow screens; never add fixed delays as a first resort.
- One flow per user-visible behavior. A flow named
checkout-with-saved-card.yaml that does exactly that is debuggable. A 200-line regression.yaml is not. Compose bigger journeys from subflows with runFlow.
- Select by accessibility id first, visible text second.
tapOn: id: "submit-button" survives copy changes and localization; text selectors are acceptable for stable, single-language labels only.
- Start from a clean, deterministic state.
launchApp with clearState: true resets the app between flows; tests that inherit the previous flow's logged-in session fail in random orders.
- Parameterize with env, not copies. Credentials and hosts go in
env: blocks or -e KEY=value CLI arguments so the same flow runs against dev, staging, and CI builds.
- Treat flows as code. They live in the repo next to the app, run on every PR via emulator CI, and produce JUnit XML that the pipeline understands.
Setup
curl -fsSL "https://get.maestro.mobile.dev" | bash
export PATH="$PATH:$HOME/.maestro/bin"
maestro --version
maestro test .maestro/login.yaml
maestro .maestro/ --format junit --output maestro-report.xml
maestro studio