The Backstory
iOS real device support has been one of Maestro's most requested features since January 2023.
Almost three years of developers asking for the same thing. Issue after issue. Comment after comment.
We looked at the codebase. Surprisingly, a lot of groundwork was already there. Infrastructure PRs had been merged. The foundation existed.
It just needed someone to finish the last mile.
Why Us?
At DeviceLab, we run tests on real devices every day. It's literally what we do.
When our customers started asking for Maestro support on physical iOS devices, we had the context—and the motivation—to build it.
So we did.
We submitted PR #2856 to give it back to the community.
But here's the thing: The Maestro team has indicated official iOS real device support won't land until next year. No committed timeline. Our PR won't help anyone until it's merged—or until they build their own solution.
We didn't want teams to wait that long.
That's why we packaged a ready-to-use tool.
What It Looks Like
Your existing Maestro flows. Real iPhones. No changes.
appId: com.example.app
---
- launchApp
- tapOn: "Login"
- inputText: "user@example.com"
- tapOn: "Submit"
- assertVisible: "Welcome"
Same YAML. Same commands. Just real devices.
Tested on: iOS 26.x and iOS 18.x, including parallel execution on multiple devices.
Under the Hood
Getting Maestro to talk to real iOS devices required four pieces:
1. Device Detection
Maestro's iOS driver was built for simulators. We taught it to recognize physical devices with Developer Mode enabled.
2. XCTest Runner
The XCTest driver needed to be built and deployed to actual hardware—not just the simulator. This requires code signing with a valid Apple Developer certificate.
3. Port Forwarding
Simulators run on localhost. Real devices don't.
We bridge that gap:
localhost:6001 → device:22087
4. Session Management
Real devices have constraints simulators don't. We handle them gracefully—like clearState working via app reinstall instead of simctl commands.
The Architecture
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
│ Maestro │────▶│ maestro-ios-device│────▶│ iOS Device │
│ (patched) │ │ (port forward) │ │ (XCTest) │
└─────────────┘ └──────────────────┘ └─────────────┘
:6001 :22087
-
maestro-ios-devicebuilds and installs the XCTest runner on your device - The runner starts an HTTP server on the device
- Port forwarding connects your local Maestro to the device
- Your tests run exactly as they would on a simulator
Bonus: Parallel Testing
While we were in there, we unlocked something else.
Running tests on multiple devices simultaneously? Wasn't possible before. Hardcoded port limitation.
Now it is:
# Terminal 1
maestro-ios-device --team-id ABC123 --device DEVICE_1 --driver-host-port 6001
# Terminal 2
maestro-ios-device --team-id ABC123 --device DEVICE_2 --driver-host-port 6002
Parallel testing on real iOS devices. Finally.
The Honest Limitations
We're not claiming this is perfect. Some iOS platform restrictions apply:
| Command | Status | Notes |
|---|---|---|
clearState |
✅ Works | Via app reinstall (requires --app-file) |
setLocation |
⚠️ Limited | Requires additional setup |
addMedia |
❌ Not supported | iOS restriction |
These are Apple's limitations, not ours.
Try It
Install:
curl -fsSL https://raw.githubusercontent.com/devicelab-dev/maestro-ios-device/main/setup.sh | bash
Start the device bridge:
maestro-ios-device --team-id YOUR_TEAM_ID --device DEVICE_UDID
Run your tests (in another terminal):
maestro --driver-host-port 6001 --device DEVICE_UDID --app-file /path/to/app.ipa test flow.yaml
Full docs: github.com/devicelab-dev/maestro-ios-device
Compatibility
| Maestro Version | Status |
|---|---|
| 2.0.10 | ✅ Supported |
| 2.0.9 | ✅ Supported |
| Other versions | ❌ Not tested |
⚠️ Disclaimer
This is an unofficial community tool. Not supported by mobile.dev or the Maestro team. Use at your own risk.
When Maestro releases official iOS device support, we recommend switching to the official version.
Links
Built by DeviceLab—stop renting devices you already own.
Top comments (0)