Drive the iOS Simulator with axe
axe talks to a booted simulator through HID and the accessibility APIs. Install: brew install cameroncooke/axe/axe. Every command needs --udid <UDID>; get it from axe list-simulators or xcrun simctl list devices booted.
Core loop
- Read the screen:
axe describe-ui --udid $UDIDreturns the real element tree (labels, identifiers, frames). Read coordinates from it; never guess pixels from a screenshot. - Act: prefer selectors over coordinates because they survive layout changes.
axe tap --label "Sign In" --udid $UDID(also--id,--value,--element-type Button)axe tap -x 200 -y 400 --udid $UDIDwhen no accessibility label existsaxe type "hello@example.com" --udid $UDIDafter focusing a text fieldaxe swipefrom one point to another to scroll (seeaxe swipe --helpfor the flags)axe button,axe gesture(presets),axe key,axe key-combofor hardware buttons and keyboards
- Observe:
axe describe-uiagain, plusaxe screenshot --udid $UDID(writes a PNG; seeaxe screenshot --helpfor the output option). - Repeat until the flow is verified.
Use --wait-timeout on tap when a screen is still animating. axe <subcommand> --help is the source of truth for flags.
Batch a sequence
axe batch runs ordered steps in one HID session, which is faster and more reliable than many separate calls. See axe batch --help for the step syntax.
Recording
axe record-video --udid $UDID records the display to MP4 (see --help for output and stopping). Useful as evidence for a bug report or PR.
Tips
- Add
accessibilityIdentifiervalues to the views you automate; it makes--idselectors stable. - If
describe-uireturns nothing, confirm the simulator is booted and the app is in the foreground. - The
ios-simulatorMCP server in this plugin exposes similar tap, swipe, type and screenshot tools when a shell is not available.


