| name | mobile-e2e |
| description | Mobile E2E testing with Maestro for React Native / Expo. Three workflows: analyze code → generate user flow docs → generate/run Maestro YAML tests with diagnostic reports. Triggers on: E2E testing, Maestro, testIDs, test coverage, release checks, smoke tests for React Native apps.
|
| argument-hint | <workflow> [target] |
Mobile E2E Testing Skill
End-to-end testing for React Native / Expo mobile apps using Maestro. Three workflows that form a pipeline: analyze code → generate flow docs → generate Maestro YAML → execute & report.
Workflows
Determine which workflow(s) the user needs:
| User Request | Workflow | Command |
|---|
| "analyze flows", "generate test plan", "document user flows", "find missing testIDs" | 1. Flow Analysis | /mobile-e2e analyze [screen/feature] |
| "generate maestro tests", "create yaml tests", "write e2e" | 2. YAML Generation | /mobile-e2e generate [flow-doc.md] |
| "run e2e", "execute tests", "e2e report" | 3. Execute & Report | /mobile-e2e run [environment] |
| "full pipeline", "e2e from scratch" | All three | /mobile-e2e pipeline [feature] |
When to Read Reference Files
Each reference file serves a specific purpose — only read what you need:
| Reference | Read When |
|---|
references/maestro-templates.md | Generating YAML files (Workflow 2). Config, utility flows, individual/master flow templates, common interaction patterns, runner script, timeouts |
references/maestro-gotchas.md | Generating YAML (Workflow 2) or debugging failures (Workflow 3). Platform limitations and pitfalls: BottomSheet/Portal dual-render, scroll, keyboard, SegmentedControl, StepHeader, pressKey Escape, assertNotVisible, clearInput |
references/testid-conventions.md | Analyzing testIDs or recommending new ones (Workflow 1). Naming rules, patterns by feature type, compound component patterns |
references/flow-doc-template.md | Writing markdown test plan docs (Workflow 1). Output template for test plans and individual flow docs |
references/troubleshooting.md | Debugging test failures (Workflow 3). Environment/config issues, session management, timing, permissions. For Maestro command gotchas see maestro-gotchas.md instead |
Workflow 1: Flow Analysis → Markdown Docs
Goal: Analyze the app's codebase and produce detailed user flow documents that describe what to test.
Steps
-
Discover app structure
- Read
app.json / app.config.ts to get appId
- Find navigation structure: search for
createStackNavigator, createDrawerNavigator, createBottomTabNavigator, Screen name=
- Find all screen components (search for
Screen, export default, screen-level components)
-
Inventory testIDs
- Search for
testID props across all .tsx files
- Build a map of
screen → [testIDs]
- Flag screens with zero or few testIDs as gaps
- Read
references/testid-conventions.md for naming rules when recommending new testIDs
-
Map user flows
- For each screen/feature, trace the user journey:
- Entry point (how the user gets there)
- Interactive elements (buttons, inputs, toggles, lists)
- State changes (loading, empty, error, success)
- Exit points (back navigation, drawer, tabs)
- Classify flows by priority: P0 (critical path), P1 (important), P2 (nice-to-have)
-
Generate markdown doc
- Read
references/flow-doc-template.md for the output template
- Output goes to
docs/e2e/<feature-name>-test-plan.md
- Include: flow descriptions, step-by-step actions, testIDs used, pass criteria, gaps/blockers
Output Structure
docs/e2e/
├── <feature>-test-plan.md # Per-feature test plans
├── staging-test-plan.md # Full staging test plan (all features)
├── production-test-plan.md # Production-safe subset (read-only)
├── E2E_TESTING_GUIDE.md # Developer guide for writing new tests
└── RELEASE_CHECKLIST.md # Pre-release procedures
Scoping
If the user specifies a feature (e.g., "analyze the login flow"), only analyze that feature's screens and produce a single flow doc. Don't analyze the entire app unless asked.
Workflow 2: YAML Generation → Maestro Tests
Goal: Convert flow documentation into executable Maestro YAML files.
Read references/maestro-templates.md for structural templates, then references/maestro-gotchas.md for platform limitations and pitfalls.
Steps
-
Read the flow doc — parse the markdown test plan to extract steps, testIDs, and assertions
-
Setup project structure (if .maestro/ doesn't exist)
.maestro/
├── config.yaml # Global config (appId, timeouts, env vars)
├── utils/ # Reusable sub-flows
│ ├── launch-app.yaml # Fresh launch (clearState + clearKeychain)
│ ├── resume-app.yaml # Resume existing session
│ ├── login.yaml # Basic login (no OTP)
│ └── login-with-otp.yaml # Full login + OTP
├── flows/ # Feature-level test flows
│ ├── smoke.yaml
│ ├── auth/
│ └── <feature>/
└── release-checks/ # Pre-release suites
├── staging/
│ ├── run-all.yaml # Master flow (single session)
│ └── NN-flow-name.yaml
└── production/
├── run-all.yaml
└── NN-flow-name.yaml
-
Generate files using the templates from references/maestro-templates.md:
- config.yaml, utility flows, test flows, run-all.yaml master flows
scripts/e2e-run.sh — runner script that loads .env credentials
-
Platform considerations:
- iOS: Use
clearKeychain: true, handle Expo Dev Client launcher, swipe RIGHT for drawer
- Android: Use
clearState: true (keychain not an issue), handle back button with pressKey: back
Key Conventions
- Use
extendedWaitUntil for dynamic content, assertVisible only after screen is confirmed loaded
- Use
optional: true for permission-gated or state-dependent elements
- Never hardcode credentials — use
${ENV_VAR} syntax loaded from .env
- Production flows are READ-ONLY (no sends, no edits, no deletes)
- Flows run sequentially sharing one session —
run-all.yaml ensures this
- Handle multi-language alerts with
optional: true for each language variant
- Read
references/maestro-gotchas.md for all platform limitations (BottomSheet, scroll, keyboard, SegmentedControl, StepHeader, pressKey Escape, assertNotVisible, clearInput)
Workflow 3: Execute & Report
Goal: Run Maestro tests and produce a diagnostic report.
Read references/troubleshooting.md when analyzing failures — it contains 25 solved problems from real projects.
Steps
-
Pre-flight checks
maestro --version
xcrun simctl list devices booted
adb devices
lsof -i :8081 -i :8082 | grep LISTEN
xcrun simctl listapps booted | grep <appId>
-
Execute tests
- Single flow:
maestro test .maestro/flows/<flow>.yaml
- Release suite:
./scripts/e2e-run.sh <staging|production>
- With JUnit output:
maestro test --format junit --output report.xml <flow>
- With env overrides:
maestro test -e EMAIL=x -e PASSWORD=y <flow>
-
Capture results — parse Maestro output for PASSED/FAILED per flow, collect timing
-
Generate report — output to docs/e2e/reports/YYYY-MM-DD-<env>.md
Report Format
# E2E Test Report — <Environment>
**Date:** YYYY-MM-DD HH:MM
**Device:** <simulator/emulator name + OS version>
**App Version:** <from app.json>
**Total:** X flows | Passed: Y | Failed: Z
## Results
| # | Flow | Status | Duration | Notes |
|---|------|--------|----------|-------|
| 01 | App Launch | PASS | 12s | |
| 02 | Login Flow | PASS | 8s | |
| 03 | Feature X | FAIL | 30s | Timeout on element-id |
## Failures
### 03 — Feature X (FAILED)
**Error:** <exact Maestro error>
**Root Cause Analysis:**
- [ ] **Missing testID**: Check if testID exists in component
- [ ] **Loading timeout**: Screen takes too long to load
- [ ] **Auth session lost**: Previous flow broke the session
- [ ] **Navigation issue**: Screen didn't navigate correctly
**Recommended Fix:** <specific recommendation>
## TestID Coverage Gaps
| Screen | Missing testIDs | Impact |
|--------|----------------|--------|
| ScreenName | No testIDs found | Cannot test this screen |
## Recommendations
- <actionable next steps>
Failure Classification
| Category | Description | Fix Owner |
|---|
| Missing testID | Element has no testID prop | App Developer |
| Wrong testID | testID doesn't match YAML | Test Author |
| Timeout | Element loads too slowly | App Developer / Infra |
| Navigation | Wrong screen displayed | App Developer |
| Auth | Session expired or login failed | Backend / Config |
| Portal/BottomSheet | gorhom BottomSheet content invisible to Maestro (neither testID nor text work) | App Developer (implement native Modal dual-render with useNativeModal prop) |
| Animation | Element hidden during animation | Test Author (add wait) |
| Permission | Feature gated by user role | Config (test account perms) |
| Flaky | Intermittent failures | Test Author (add waits/retries) |
| Not Implemented | Feature not yet built | App Developer |