agentleFS
JuanMarchettoJuanMarchetto/agent-skills/skills/maestro-mobile-testing/SKILL.md

maestro-mobile-testing

Skill5 starsChanged 8 months agoMITView on GitHub

Maestro mobile E2E testing patterns for React Native/Expo apps: YAML test flows, testID selectors, adaptive auth state, optimistic update verification, GraalJS scripting, cross-platform stability, CI/CD integration, Maestro Cloud, and MCP server integration. Use when: write Maestro test, flaky mobile test, test my app, automate mobile testing, mobile E2E, debug test failure, Maestro setup.

  • Pipes a download into a shell
  • Installs packages

2 other projects use a version of this, 2 of them edited.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. About 0 are common, 5 are distinctive, and 8 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Cause: No simulator/emulator running, or Maestro can't detect it.

    line 194
  2. Very specific:

    Verify with maestro devices (should list at least one device)

    line 199
  3. Very specific:

    Run maestro hierarchy to see all elements on screen — check if your element exists

    line 210
  4. Very specific:

    Use maestro studio to interactively explore the element tree

    line 211
  5. Very specific:

    Add extendedWaitUntil before the interaction (the element may need time to render)

    line 212
  6. Very specific:

    Check if a native alert or permission dialog is blocking — add tapOn: text: "OK" optional: true before your step

    line 213
  7. Very specific:

    Verify the testID is actually set in your React Native component (testID="my-button")

    line 214
  8. Distinctive:

    Symptoms: Test passes sometimes, fails other times.

    line 218
  9. Distinctive:

    Race conditions: Add auth pre-flight pattern (Pattern 2) — don't interact before auth resolves

    line 221
  10. Very specific:

    Animations: Use extendedWaitUntil instead of fixed sleep calls

    line 222
  11. Distinctive:

    Network dependency: Start a mock API server instead of relying on real backends

    line 223
  12. Distinctive:

    iOS cold boot crash: Add the post-launch swipe (see gotchas.md)

    line 224
  13. Very specific:

    Optional elements: Don't use optional: true unless the action is genuinely optional

    line 225

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Maestro Mobile E2E Testing

Overview

Maestro is a declarative YAML-based mobile E2E testing framework. It provides automatic waiting, built-in retry logic, and fast execution without boilerplate. It's more stable than Detox or Appium for React Native apps.

Key Features

  • Declarative YAML — no imperative test code, just steps
  • Automatic waiting — no manual sleep() or flaky waits
  • Built-in retry — reduces test flakiness
  • Fast execution — runs quickly without setup overhead
  • Maestro Studio — interactive test builder (maestro studio)
  • Sub-flows — reusable YAML sequences for DRY tests
  • JavaScript scripting — GraalJS runtime for HTTP calls and data manipulation
  • Maestro Cloud — real device testing in CI without local simulators

Quick Start

Install

curl -Ls "https://get.maestro.mobile.dev" | bash
brew install openjdk@17
export JAVA_HOME=/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home

Minimal test

appId: com.myapp
---
- launchApp
- tapOn:
    id: "my-button"
- assertVisible: "Expected Text"

Run

maestro test .maestro/smoke-test.yaml
maestro test --debug .maestro/smoke-test.yaml  # step through
maestro studio                                  # interactive builder

Pattern Index

#PatternReference
1Selector Strategy: testID vs Textcore-patterns.md
2Auth Pre-Flight Patterncore-patterns.md
3Adaptive Tests (Both Auth States)core-patterns.md
4Testing Optimistic Updatescore-patterns.md
5Dismissing Native Alertscore-patterns.md
6Sub-Flows for Reusabilitycore-patterns.md
7Deep Links (Expo)core-patterns.md
8Platform-Specific Logiccore-patterns.md
9Environment Variablescore-patterns.md
10Selector State Propertiescore-patterns.md
11Relative Position Selectorscore-patterns.md
-OTP/Magic-Link Auth Testingauth-testing.md
-CI/CD & Maestro Cloudci-cd.md
-Critical Gotchas & Platform Differencesgotchas.md
-MCP Server Integrationmcp-integration.md

Test File Template

# {Feature} {Action} Test
#
# Tests: {what this validates}
# Prerequisites:
# - Simulator/emulator running with app installed
# - Backend or mock server running (if API-dependent)

appId: com.myapp
env:
  TEST_EMAIL: maestro-{feature}@example.com
  EMAIL_SERVICE_URL: http://localhost:8025
---
# ==========================================
# STEP 1: LAUNCH + AUTH PRE-FLIGHT
# ==========================================

- launchApp

- swipe:
    direction: DOWN
    duration: 100

- extendedWaitUntil:
    visible:
      id: "auth-loaded"
    timeout: 15000

- takeScreenshot: 01-initial-state

# ==========================================
# STEP 2: {ACTION}
# ==========================================

- tapOn:
    id: "target-element"

# ==========================================
# STEP 3: VERIFY
# ==========================================

- extendedWaitUntil:
    visible:
      id: "expected-result"
    timeout: 5000

- takeScreenshot: 02-final-state

Example Output

Running a Maestro test produces output like this:

$ maestro test .maestro/smoke-test.yaml

 ║
 ║  > Flow: .maestro/smoke-test.yaml
 ║
 ║    ✅  Launch app "com.myapp"
 ║    ✅  Swipe from center to bottom
 ║    ✅  Wait until "auth-loaded" is visible (timeout: 15s)
 ║    ✅  Take screenshot "01-initial-state"
 ║    ✅  Tap on "tab-home"
 ║    ✅  Wait until "dashboard-header" is visible (timeout: 5s)
 ║    ✅  Tap on "action-button"
 ║    ✅  Wait until "undo-button" is visible (timeout: 3s)
 ║    ✅  Take screenshot "02-final-state"
 ║
 ║    Duration: 8.2s
 ║    Status: ✅ PASSED

Screenshots are saved to ~/.maestro/tests/{timestamp}/.

Folder Structure

.maestro/
├── README.md                    # Quick reference + testID inventory
├── config.yaml                  # Shared configuration
├── flows/                       # Reusable sub-flows
│   ├── auth-and-return.yaml
│   ├── complete-action.yaml
│   └── verify-result.yaml
├── scripts/                     # GraalJS helpers
│   ├── fetch-otp.js
│   └── split-otp.js
├── smoke-test.yaml              # Guest navigation
├── auth-signin.yaml             # OTP sign-in flow
├── feature-screenshots.yaml     # Screenshot capture flows
└── feature-action.yaml          # Feature-specific tests

scripts/
├── mock-api-server.ts           # Lightweight mock for E2E
└── run-e2e.sh                   # Orchestration script

Naming Conventions

TypePatternExample
Main test{feature}-{action}.yamlcheckout-purchase.yaml
Sub-flow{action}-{context}.yamlauth-and-return-to-dashboard.yaml
Script{verb}-{noun}.jsfetch-otp.js

Troubleshooting

Device Not Found

Error: No devices found

Cause: No simulator/emulator running, or Maestro can't detect it.

Fix:

  • iOS: Open Xcode > Window > Devices and Simulators > boot a simulator, or run xcrun simctl boot "iPhone 16"
  • Android: Start emulator with emulator -avd <name> or open Android Studio > Device Manager
  • Verify with maestro devices (should list at least one device)

Element Not Found

Error: Element not found: id "my-button"

Cause: The element hasn't rendered yet, the testID is wrong, or a native alert is blocking it.

Fix:

  1. Run maestro hierarchy to see all elements on screen — check if your element exists
  2. Use maestro studio to interactively explore the element tree
  3. Add extendedWaitUntil before the interaction (the element may need time to render)
  4. Check if a native alert or permission dialog is blocking — add tapOn: text: "OK" optional: true before your step
  5. Verify the testID is actually set in your React Native component (testID="my-button")

Flaky Tests

Symptoms: Test passes sometimes, fails other times.

Common causes and fixes:

  • Race conditions: Add auth pre-flight pattern (Pattern 2) — don't interact before auth resolves
  • Animations: Use extendedWaitUntil instead of fixed sleep calls
  • Network dependency: Start a mock API server instead of relying on real backends
  • iOS cold boot crash: Add the post-launch swipe (see gotchas.md)
  • Optional elements: Don't use optional: true unless the action is genuinely optional

Checklist for New Tests

[ ] Unique test email (maestro-{feature}@example.com)
[ ] Selector strategy chosen (testID for i18n, text for single-language)
[ ] Auth pre-flight pattern used (auth-loaded)
[ ] Post-launch swipe added (iOS crash prevention)
[ ] Both auth states handled (adaptive flows)
[ ] Native alerts dismissed after mutations
[ ] Short timeouts for optimistic updates (3-5s)
[ ] Sub-flows created for reusable sequences
[ ] Descriptive screenshots at key points
[ ] Header comment with prerequisites
[ ] Mock API server started if backend-dependent
[ ] Tags added for CI filtering (ci, smoke, wip)

Debugging

maestro test --debug .maestro/test.yaml   # Step through interactively
maestro record .maestro/test.yaml          # Record as video
maestro studio                             # Interactive UI builder
maestro hierarchy                          # View element tree

Resources

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.