# Technical Documentation: mobile-dev-inc/Maestro

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/mobile-dev-inc/Maestro)

### Overview (README.md)

> [!TIP]
> Great things happen when testers connect — [Join the Maestro Community](https://maestrodev.typeform.com/to/FelIEe8A)


<p align="center">
  <a href="https://www.maestro.dev">
    <img width="1200" alt="Maestro logo" src="https://github.com/mobile-dev-inc/Maestro/blob/main/assets/banne_logo.png" />
  </a>
</p>


**Maestro** is an open-source framework that makes UI and end-to-end testing for Android, iOS, and web apps simple and fast.

Hand-write your first YAML flow with the CLI in under 5 minutes, build flows visually in Maestro Studio, or add **Maestro MCP** to your coding agent for agentic UI testing.

Flows run on any emulator, simulator, browser, or physical Android device. Physical iOS devices are not yet supported.

<p align="center">
  <img src="assets/twitch2-small.gif" alt="A Maestro flow in plain YAML running on the Twitch Android app in an emulator" width="760" />
</p>

&nbsp;

## Table of Contents

- [Why Maestro?](#why-maestro)
- [Getting Started](#getting-started)
- [Maestro MCP – Agentic UI Testing](#maestro-mcp--agentic-ui-testing)
- [Maestro Studio – Test IDE](#maestro-studio--test-ide)
- [Maestro Cloud – Parallel Execution & Scalability](#maestro-cloud--parallel-execution--scalability)
- [Resources & Community](#resources--community)
- [Contributing](#contributing)

&nbsp;

## Why Maestro?

Maestro is built on learnings from its predecessors (Appium, Espresso, UIAutomator, XCTest, Selenium, Playwright), plus 3 decisions made early: drive the app through the platform's accessibility layer, install as a single binary with no drivers or SDK, and keep every test a flat list of YAML commands.

- **Human-readable YAML flows** – express interactions as commands like `launchApp`, `tapOn`, and `assertVisible`.
- **Built for coding agents** – the Maestro MCP server ships inside the Maestro CLI (`maestro mcp`, nothing else to install). Claude Code, Cursor, Codex, Grok Build, or any MCP client can control your app on a live device: inspect the screen, tap, scroll, assert, and check its own work while it builds. Ask for a flow when you want a repeatable test — that's agentic UI testing.
- **Framework agnostic** – React Native, Flutter, native iOS and Android, Ionic, and hybrid apps all use the same commands. Meta uses Maestro to test React Native itself, and Expo supports Maestro as its preferred E2E testing platform.
- **Cross-platform coverage** – one flow syntax for Android, iOS, and web, on emulators, simulators, browsers, and physical Android devices.
- **Resilience & smart waiting** – built-in flakiness tolerance and automatic waiting handle dynamic UIs without manual `sleep()` calls.
- **Fast iteration & simple install** – one install line, no drivers, no SDK, no dependencies; flows are interpreted, so there's no compilation step. First test in 5 minutes.

**Simple Example:**
```
# flow_contacts_android.yaml

appId: com.android.contacts
---
- launchApp
- tapOn: "Create new contact"
- tapOn: "First Name"
- inputText: "John"
- tapOn: "Last Name"
- inputText: "Snow"
- tapOn: "Save"
```

&nbsp;

## Getting Started

Maestro requires Java 17 or higher to be installed on your system. You can verify your Java version by running:

```
java -version
```

Installing the CLI:

Run the following command to install Maestro on macOS, Linux or Windows (WSL):

```
curl -fsSL "https://get.maestro.mobile.dev" | bash
```

The links below will guide you through the next steps.

- [Installing Maestro](https://docs.maestro.dev/maestro-cli/how-to-install-maestro-cli) (includes regular Windows installation)
- [Add Maestro MCP to your coding agent](https://docs.maestro.dev/get-started/maestro-mcp)
- [Run your first test with the Maestro CLI](https://docs.maestro.dev/maestro-cli/run-your-first-test-with-the-maestro-cli) (or just ask your agent to do it for you)

&nbsp;

## Maestro MCP – Agentic UI Testing

<img src="assets/maestro-mcp-demo.gif" alt="A coding agent checking its work on an Android emulator through Maestro MCP, with every command shown live in the Maestro Viewer" />

Maestro MCP ships inside the Maestro CLI and works with Claude Code, Cursor, Codex, Gemini CLI, Copilot, Grok Build, or any MCP client. It gives your agent a live device (an emulator, simulator, or physical Android device), and Maestro Viewer embeds that device inside your coding agent, showing every MCP command as it runs.

With Maestro MCP, your agent can control the app directly: inspect the screen, tap, scroll, and assert. While it builds or changes a feature, it checks its own work on the device.

Your agent can also write tests. Ask for an end-to-end flow and it writes plain YAML, runs it until it passes, and the flow stays in your repo as a deterministic test for CI.

Setup for each coding agent is in the [Maestro MCP docs](https://docs.maestro.dev/get-started/maestro-mcp).

&nbsp;

## Maestro Studio – Test IDE

**Maestro Studio Desktop** is a lightweight IDE that lets you design and execute tests visually — no terminal needed. It is also free, even though Studio is not an open-source project. So you won't find the Maestro Studio code here.

- **Simple setup** – just download the native app for macOS, Windows, or Linux.
- **Visual flow builder & inspector** – record interactions, inspect elements, and build flows visually.

[Download Maestro Studio](https://maestro.dev/?utm_source=github-readme#maestro-studio)

&nbsp;

## [Maestro Cloud](https://maestro.dev/cloud?utm_source=github-readme) – Parallel Execution & Scalability

When your test suite grows, run hundreds of tests in parallel on dedicated infrastructure, cutting execution times by up to 90%. Includes built-in notifications, deterministic environments, and complete debugging tools.

Pricing for Maestro Cloud is completely transparent and can be found on the [pricing page](https://maestro.dev/pricing?utm_source=github-readme).

👉 [Start your free 7-day trial](https://maestro.dev/cloud?utm_source=github-readme)

&nbsp;

## Resources & Community

- 💬 [Join the Slack Community](https://slack.maestro.dev)
- 📘 [Documentation](https://docs.maestro.dev)
- 📰 [Blog](https://maestro.dev/blog?utm_source=github-readme)
- 🐦 [Follow us on X](https://twitter.com/maestro__dev)
- ⏯️ [Check out our YouTube channel](https://www.youtube.com/@mobile-dev)

&nbsp;

## Contributing

Maestro is open-source under the Apache 2.0 license — contributions are welcome!

- Check [good first issues](https://github.com/mobile-dev-inc/maestro/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
- Read the [Contribution Guide](https://github.com/mobile-dev-inc/Maestro/blob/main/CONTRIBUTING.md)
- Found a bug or want a feature? See [how to open a good issue](https://github.com/mobile-dev-inc/Maestro/blob/main/docs/issues.md)
- Fork, create a branch, and open a Pull Request.

If you find Maestro useful, ⭐ star the repository to support the project.



```
  Built with ❤️ by Maestro.dev
```

---

### Issues (`docs/issues.md`)

# Issues

How to open a good issue, whether you use the form on GitHub or file it some other way, such
as `gh issue create` or an agent. The forms in
[`.github/ISSUE_TEMPLATE/`](../.github/ISSUE_TEMPLATE/) ask for the same things; this page is
for when you're not using them.

Before you open one:

- **Search the [existing issues](https://github.com/mobile-dev-inc/maestro/issues)** — yours
  may already be there. A comment with your details on an existing issue helps more than a
  duplicate.
- **Maestro Studio** (the desktop app) has its own
  [issue tracker](https://github.com/mobile-dev-inc/maestro-studio/issues/new/choose).
- **Questions and discussion** belong in the [Slack community](https://slack.maestro.dev).

Issues here are public permanently. The rules on
[sensitive information](pull-requests.md#sensitive-information-public-repo) apply to issues
too, including to the logs, screenshots, and flows you attach.

## Bug reports

Use these headings, in this order (`### Steps to reproduce` and so on), which is how an issue
filed through the form reads.

- **Steps to reproduce** — a minimal, reproducible example, step by step. Include the device
  you saw it on (physical Android device, iOS simulator, …) and its OS version (e.g. Android 14
  with Play Services, iOS 18). Include the flow file: without it, a bug is much harder to
  reproduce, and issues that can't be reproduced are much more likely to be closed.
- **Actual results** — what happens.
- **Expected results** — what you expected to happen.
- **About app** — the app you're testing: open source (link it) or closed source (share a
  binary or a small sample that reproduces it); native or cross-platform; the framework it's
  built with and its version (e.g. SwiftUI, Compose 1.6, React Native, Flutter 3.22); its
  minimum and target SDK or iOS version, if relevant.
- **About environment** — the machine running Maestro: OS and version, processor architecture
  (x86_64, arm64), Java version (`java -version`), and Xcode version for iOS.
- **Logs** — the full output of the command you ran, as text in a code block, not a
  screenshot. `maestro bugreport` produces a zip you can attach.
- **Maestro version** — from `maestro --version`.
- **How did you install Maestro?** — install script, Homebrew, built from source (give the
  commit), or other.
- **Anything else?** — links, related issues, anything else that gives context.

## Feature requests

- **Use case** — the problem that led you to want this, and the alternatives you've considered.
  Describe the problem, not only the solution you have in mind.
- **Proposal** — what the feature should look like from the user's side, e.g. the YAML you'd
  like to write.
- **Anything else?** — links, related issues, anything else that gives context.

---

### Pull Requests (`docs/pull-requests.md`)

# Pull requests

How to write a PR. We squash-merge, so the PR title becomes the commit subject on `main`.
Reasoning reference: Google's [Writing good CL descriptions](https://google.github.io/eng-practices/review/developer/cl-descriptions.html).

## Body

Three sections, each as short as complete.

- **Why** — the value: what someone using or maintaining Maestro gets from this that they
  didn't have before, and the issues it resolves (`Fixes #123`). 1–4 sentences.
- **Approach** — how you solved it. Call out important changes in behaviour. If there are code
  changes you'd like the reviewer to look at closely, point them out.
- **Verification** — what you actually did to confirm it: tests you added or ran, a screenshot
  or recording for anything visible, a benchmark. Only for changes to CI is "CI passed" enough.
  If the change affects what Maestro does on a device or in a browser, a Maestro flow under
  `e2e/` that shows it working helps — see [`e2e/README.md`](../e2e/README.md).

Describe a bug by its effect — what a user sees or can't do — not by the defect in the code.
The defect is detail the Approach can cover: the code could change and the bug still stand, and
the reader is a person deciding whether this matters. "A flow with an empty `appId` fails with
an error that doesn't say which flow or field", not "Missing null check in the config parser".

## Ready or draft

Opening a PR asks a human to review it. Open it as ready when it is. Open it as a draft
(`gh pr create --draft`) when there's a reason not to ask yet — you want to see CI pass first,
or it's still missing something — and mark it ready when that's resolved.

## Sensitive information (public repo)

Everything pushed or posted here is public permanently: commits, branch names, code and
comments, test fixtures and flows, PR and issue text, review comments, and the logs and
screenshots you attach. For everyone:

- No secrets, tokens, credentials, or sensitive `.env` contents.
- Redact other people's personal details (names, emails, device identifiers) from logs and
  screenshots unless they've agreed to share them.

You're welcome to say who you work for and what your team uses Maestro for, and to share apps
or other information that helps, such as a reproduction or something already public.

## Staff contributors only

If you know which customer, org, account, or deployment a change is for — from a tracker,
Slack, or Maestro Cloud — that's staff context, and it must not reach this repo anywhere listed
above. External contributors don't have it; staff do. Reduce it to what the change does and why
it matters:

- Never name them — say "a customer", "a large deployment".
- Don't include what identifies them either: their app's package or bundle ID, their URLs or
  domains, flows copied from their suite, screenshots or view hierarchies of their app, Maestro
  Cloud org, project, upload, or run IDs, dashboard links.
- Reproduce the bug against the demo app (`e2e/demo_app/`) or a minimal sample, not their app,
  and name the screen and flow after the behaviour, not the customer.
- Reference internal trackers by ID, never by content ("fixes MA-1234", not what it says or who
  filed it).
- Describe the bug by its effect, not who reported it. No quoted Slack/ticket text. No
  attributed metrics.

No automated check catches a customer name in prose — this is on the author and reviewer.

## No tool attribution

No `Co-authored-by:` for an AI tool, no "Generated with…", no session links — in the title,
body, or commits.

---

--- METRICS ---
- Files Extracted: 3
- Estimated Token Budget: ~3346 tokens
- Canonical Reference: https://codewiki.google/github.com/mobile-dev-inc/Maestro
