Maestro flows
Skill almasumdev/awesome-mobile-testing-agent-skills/.github/skills/e2e/maestro-flows
Expert guidance on writing, running, and parallelizing Maestro YAML flows for cross-platform mobile E2E testing. Use when adding Maestro coverage, wiring Maestro to CI, or moving off Detox/Appium for smoke flows.From its SKILL.md
npx -y skills add almasumdev/awesome-mobile-testing-agent-skills --skill maestro-flowsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.2 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Maestro Flows
Instructions
Maestro is a YAML-based black-box E2E runner that works on Android, iOS, and Flutter / React Native without a tool-specific binding. Its strengths: simple syntax, built-in retry, great CI ergonomics on Firebase Test Lab and Maestro Cloud. Its weakness: black-box only — no access to in-process state — so pair it with unit and integration tests for depth.
1. Project Layout
.maestro/
├── config.yaml # shared env, onFlowStart hooks
├── smoke/
│ ├── login.yaml
│ ├── checkout-happy.yaml
│ └── tabs-smoke.yaml
└── regression/
├── account-settings.yaml
└── search-results.yaml
Commit .maestro/ at the repo root. Tag flows by directory; CI runs one tier at a time.
2. A Minimal Flow
# .maestro/smoke/login.yaml
appId: com.example.app
tags:
- smoke
onFlowStart:
- runScript: ../scripts/seed_user.sh
---
- launchApp:
clearState: true
- assertVisible: "Sign in"
- tapOn:
id: "emailField"
- inputText: "${EMAIL}"
- tapOn:
id: "passwordField"
- inputText: "${PASSWORD}"
- tapOn: "Sign in"
- assertVisible:
id: "homeFeed"
timeout: 15000
Use IDs (testID / accessibilityIdentifier / Key), not visible text, for selectors that matter across locales.
3. Parameterizing Runs
Top-level env or CI environment variables feed ${VAR} substitution:
[email protected] \
PASSWORD=$E2E_PASSWORD \
maestro test .maestro/smoke/
Use runScript: to call a tiny shell or Node script that seeds users via the backend API and echoes credentials as output.EMAIL=....
4. Composition: runFlow
Factor shared preconditions into sub-flows:
# .maestro/_shared/login.yaml
- launchApp: { clearState: true }
- tapOn: { id: "emailField" }
- inputText: "${EMAIL}"
- tapOn: { id: "passwordField" }
- inputText: "${PASSWORD}"
- tapOn: "Sign in"
- runFlow: ../_shared/login.yaml
- tapOn: { id: "cartTab" }
- assertVisible: { id: "cartEmpty" }
5. Waits, Retries, Assertions
- Every
assertVisibleacceptstimeout:in ms — use it; the default (~5 s) is often too short after a navigation. extendedWaitUntil:for long async operations (network post-login).retry:on whole flows for transient device-farm noise; pair with a flake budget (seeflaky-test-reduction).
Avoid generic sleeps. If you find yourself adding - sleep: 3000, add an extendedWaitUntil on a visible element instead.
6. Platform Differences
Use platform: guards sparingly. Most flows run unmodified on Android and iOS. When platforms diverge:
- runFlow:
when:
platform: android
file: ../_shared/android_system_dialog.yaml
- runFlow:
when:
platform: ios
file: ../_shared/ios_permission_dialog.yaml
Keep divergent steps at system-dialog boundaries; the app UI itself should be shared.
7. CI Integration
GitHub Actions sketch:
- uses: mobile-dev-inc/action-maestro-cloud@latest
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
app-file: app/build/outputs/apk/release/app-release.apk
include-tags: smoke
For self-hosted runs on Firebase Test Lab:
gcloud firebase test android run \
--type instrumentation \
--app app-debug.apk \
--test app-debug-androidTest.apk \
--device model=redfin,version=33,orientation=portrait
For Android-only Maestro, you can also use the Maestro bundle: maestro test --device emulator-5554 .maestro/smoke/.
8. Parallelization
- Shard by flow file. Maestro Cloud shards automatically; on self-hosted, split directories across matrix jobs.
- Isolate user data. Each shard uses a different seeded account (
[email protected]). - Cap concurrent writes to shared backend resources; prefer per-user resources.
9. Failure Artifacts
Maestro Cloud and the CLI both produce a video + screenshots per step. Upload them unconditionally on failure:
- name: Upload Maestro artifacts
if: failure()
uses: actions/upload-artifact@v4
with: { name: maestro, path: ~/.maestro/tests/ }
10. What Maestro Is Not Good At
- In-process assertions (Redux state, coroutine job counts) — use component tests.
- Very complex branching logic — YAML becomes unreadable; split into sub-flows or move to code-based (XCUITest, Espresso, Detox).
- Anything needing real biometrics, push certificates, or deep OS integration — use the platform framework.
11. Checklist
- Flows live under
.maestro/smoke/and.maestro/regression/with clear tags. - Selectors are IDs, not visible text.
- Shared steps are factored into
_shared/*.yamland invoked withrunFlow. - Users and data are seeded per run via API, not reused across runs.
- No raw
sleep; waits are tied to visible elements or explicit conditions. - CI runs smoke on every PR and regression on merge / nightly with sharded parallelism.
- Videos and screenshots are uploaded on failure.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most test skills give in ~1.3k tokens
Counted across 964 of the 1,571 authors here whose files we hold, read 2026-08-07
- Close the browser when donein 55 of 964, across 12 files
- Wait for network idle statein 51 of 964, across 6 files
- Launch Chromium in headless modein 49 of 964, across 6 files
- Use descriptive selectors for elementsin 49 of 964, across 6 files
- Run provided scripts with help flag firstin 49 of 964, across 6 files
- Add appropriate explicit waitsin 48 of 964, across 5 files
- Use bundled scripts as black boxesin 46 of 964, across 3 files
- Do not read script source codein 46 of 964, across 3 files
- Use sync playwright for scriptsin 46 of 964, across 3 files
- Inspect dom before executing actionsin 46 of 964, across 3 files
- Run the full test suitein 37 of 964
- Write the failing test firstin 29 of 964, across 23 files
Said here and by no other author read
- commit the .maestro directory at the repo root
- use IDs for selectors
- factor shared preconditions into sub-flows
- use explicit timeouts on assertions
- use runScript to seed users
- shard by flow file
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.