Maestro
End-to-end UI testing for Apple apps with Maestro, paired with XcodeBuildMCP.
Use $maestro-apple-app-testing as the main workflow for focused Apple UI testing: simulator flows, inspection, screenshots, flaky-flow diagnosis, and journey-level regression of the affected flow(s).
| Use when | Building, debugging, authoring, or journey-level testing an Apple app with Maestro |
| Do not use for | Non-testing product implementation; pure unit/concurrency logic |
| Skill source | .agents/skills/maestro-apple-app-testing/SKILL.md |
Division of labor
| Concern | Tooling |
|---|---|
| Build, install, boot simulator, capture hierarchy | XcodeBuildMCP |
| Live hierarchy, screenshots, interaction while debugging | Maestro MCP (maestro mcp when configured) |
| Repeatable YAML execution / CI-like coverage | Maestro CLI (maestro test) |
| What to cover, stabilize, and report | $maestro-apple-app-testing |
Keep MCP and CLI pointed at the same simulator/device and app state.
Prerequisites (report blockers early)
Before authoring speculative flows:
command -v maestro
maestro --version
maestro list-devices
If Maestro or its MCP server is unavailable, stop and report the exact blocker.
Fast path
session_show_defaults(XcodeBuildMCP) — report project, scheme, configuration, simulatorId.- Resolve and reuse one exact simulator ID. Do not use
OS=latest/ unstable name-only selection. - Build and install/launch with XcodeBuildMCP: prefer MCP
build_run_sim; use the matching CLI only when active policy explicitly permits it. - Inspect the screen (Maestro MCP and/or
snapshot_ui/ hierarchy tools) before editing selectors. - Author or update flows under the consumer project’s agreed path (often
.maestro/). - Map the change to its existing flow(s). Run only the single edited or directly affected flow. Do not run tagged suites or every flow as a routine final check.
- On failure: preserve debug output, screenshots, hierarchy, video when useful; classify; reproduce once; fix; re-run the same focused flow.
- Run a complete suite only when the user explicitly requests it or a documented release/CI gate requires it.
Authoring rules (distilled from the skill)
- Prefer stable
testID/ accessibility selectors and explicit assertions. - Use automatic waiting / state assertions; do not use arbitrary sleeps when a wait can express the condition.
- Handle permissions and onboarding with conditionals or dedicated subflows.
- Inspect system-generated controls (for example SwiftUI tab buttons) before selecting: an identifier inside
.tabItemmay not propagate to the generated button — use the confirmed accessibility label when no identifier is exposed. - When authoring or repairing a flow, cover its relevant happy path, validation/errors, loading/empty, relaunch/persistence, navigation/back, permissions, keyboard/input, and accessibility-visible labels inside that focused flow — do not expand to unrelated flows.
- Never modify production data or use real credentials; use fixtures, test accounts, and env vars from the workspace.
- Never claim a test passed without running it.
Flaky-flow diagnosis
- Capture hierarchy + screenshot at the failing step.
- Classify failure: app behavior vs selector/flow vs fixture vs simulator/device vs build vs environment.
- Reproduce once before changing the flow.
- Fix the classified cause (selector, wait, app bug, env) — not random timeouts.
- Re-run the same smallest failing flow only. Do not escalate to a tagged or complete suite unless the user asks or release/CI policy requires it.
Do not use Maestro for
| Instead of Maestro | Use |
|---|---|
| Pure unit or concurrency logic | Swift Testing / XCTest via XcodeBuildMCP + $swift-testing-verification |
| Product implementation | Authoring skills ($swiftui-component-author, …) |
| Foundation skill maintenance | $codex-skill-maintainer + scripts |