Run Maestro UI tests on real iOS devices — iPhone/iPad physical-device testing via an on-device XCTest driver and automatic USB port forwarding.
ℹ️ This is a maintained fork. The original devicelab-dev/maestro-ios-device (Apache-2.0) is frozen and only patches Maestro 2.0.9 – 2.1.0. This fork adds Maestro 2.5.1 support so it works with current Maestro installs — it's what powers physical-iOS support in Maestro Deck.
Patch sources: PR #2856 (real iOS device support) re-applied on the
cli-2.5.1Maestro tag — seepatches/for the reproducible diff. Originally built by DeviceLab.
- Patches your existing Maestro install with real-device support (swaps in patched 2.5.1 jars; your originals are backed up first).
- Builds and runs the XCTest driver on your iOS device.
- Sets up USB port forwarding so Maestro can talk to the device.
| Maestro version | Status |
|---|---|
| 2.5.1 | ✅ Supported (this fork) |
| 2.1.0 / 2.0.10 / 2.0.9 | ✅ Supported (upstream jars, retained) |
| Other 2.x | ❌ Not tested |
| 1.x | ❌ Not supported |
Patches are built against specific Maestro releases. Using an unsupported version will fail the
setupversion check.
- macOS (iOS device automation is Apple-toolchain-only — no Windows/Linux)
- Maestro 2.5.1 installed (
maestro --version) - Full Xcode (the on-device runner is built with
xcodebuild) - An Apple Developer account / Team ID (free works; its cert expires every 7 days)
- An iOS device on iOS 17+ with Developer Mode enabled, connected via USB and trusted
curl -fsSL https://raw.githubusercontent.com/BlueShork/maestro-ios-device/main/setup.sh | bashThis downloads the maestro-ios-device binary + the patched 2.5.1 jars + the XCTest
runner, backs up your current Maestro jars, and patches Maestro.
Verify:
maestro-ios-device --version# 1. Start the device bridge (keep it running):
maestro-ios-device --team-id YOUR_TEAM_ID --device DEVICE_UDID
# 2. In another terminal, run a flow:
maestro --driver-host-port 6001 --device DEVICE_UDID test flow.yamlFind your Team ID: security find-identity -v -p codesigning | grep Developer
(the 10-char code in parentheses), or Xcode → Settings → Accounts → Team ID.
Find your device UDID: xcrun xctrace list devices, or Finder → select the iPhone.
| Flag | Description |
|---|---|
--team-id |
Apple Developer Team ID (required) |
--device |
Device UDID (required) |
--driver-host-port |
Local port (default: auto from 6001) |
--version |
Show version |
--help |
Show help |
┌─────────────┐ ┌───────────────────┐ ┌─────────────┐
│ Maestro │────▶│ maestro-ios-device│────▶│ iOS Device │
│ (patched) │ │ (port forward) │ │ (XCTest) │
└─────────────┘ └───────────────────┘ └─────────────┘
:6001 :22087
maestro-ios-devicebuilds and installs the XCTest runner on the device.- The runner serves an HTTP driver on device port
22087. - Port forwarding maps
localhost:6001 → device:22087(over usbmux — no sudo). - Patched Maestro drives the device via
--driver-host-port 6001.
The --driver-host-port flag is registered hidden in the 2.5.1 patch, so it won't show
in maestro --help — that's expected; it is still accepted on maestro test.
Some commands are restricted by iOS itself:
| Command | Status | Notes |
|---|---|---|
clearState |
Not permitted on real devices; logs a warning and continues | |
setLocation |
Requires extra setup | |
addMedia |
❌ Unsupported | iOS restriction |
This fork is what gives Maestro Deck — a desktop app for driving Maestro on Android, iOS simulators, iOS physical devices, and Web — its one-click physical iPhone support. Maestro Deck auto-installs this bridge, builds the runner, and gives you a live screen + view-hierarchy inspector + tap/text + flow runs on a real device, right next to the simulator and Android experiences. 🚀
(The physical-device preview tops out at ~5 fps — Apple removed the OS-level iPhone screen-capture path on macOS 26 — while simulators stay buttery-smooth via the CoreSimulator framebuffer.)
cp ~/.maestro/backup/* "$(dirname "$(dirname "$(readlink -f "$(which maestro)")")")/lib/"(or just re-install Maestro 2.5.1 via Homebrew).
git clone --depth 1 --branch cli-2.5.1 https://github.com/mobile-dev-inc/Maestro.git
cd Maestro && git apply ../patches/maestro-2.5.1-physical-device.patch
JAVA_HOME=<jdk-21> ./gradlew :maestro-cli:installDist
# jars land in maestro-cli/build/install/maestro/lib/ (cli, client, ios-driver, ios)Maestro not patched— re-runsetup; confirmmaestro --versionis 2.5.1.Unsupported Maestro version— install Maestro 2.5.1 and re-runsetup.- Build fails / "certificate not trusted" — usually signing: check the Team ID, Developer Mode, and trust the developer cert on the device (Settings → General → VPN & Device Management).
- Stopped working after a Maestro upgrade — the upgrade overwrote the patched jars;
re-run
setup(and make sure you're back on 2.5.1).
Apache-2.0 (same as Maestro). This project is not affiliated with, endorsed by, or connected to mobile.dev, the official Maestro project, or DeviceLab. It patches your Maestro install to add functionality not yet in the official release. Use at your own risk.