| name | agent-device-mobile-automation |
| description | Control iOS, Android, TV, and desktop devices for AI-driven mobile app testing and verification |
| triggers | ["test my mobile app with an AI agent","automate iOS simulator for testing","inspect Android app UI programmatically","verify mobile app changes on real devices","capture screenshots and logs from mobile app","debug mobile app with AI assistance","create mobile e2e tests with agent-device","profile React Native app performance"] |
agent-device Mobile Automation
Skill by ara.so — AI Agent Skills collection.
agent-device is a CLI tool designed for AI agents to control and verify mobile apps on iOS, Android, TV, web, and desktop platforms. It provides token-efficient snapshots, semantic element references, and evidence capture for AI-driven testing workflows.
What agent-device Does
- Inspect app UI through structured accessibility snapshots with interactive refs (
@e1, @e2, etc.)
- Interact with apps: open, tap, type, scroll, gestures, wait, assert, handle alerts
- Capture evidence: screenshots, videos, logs, traces, network traffic, performance samples
- Replay workflows by recording
.ad scripts for CI and repeatable e2e checks
- Cross-platform support for iOS Simulator, Android Emulator, physical devices, tvOS, macOS, Linux
Installation
Global CLI Installation
npm install -g agent-device@latest
Verify Installation
agent-device doctor
agent-device --version
agent-device help workflow
Prerequisites by Platform
- All platforms: Node.js 22+
- iOS/tvOS/macOS: Xcode with command-line tools, macOS Accessibility permissions
- Android: Android SDK, ADB configured
- Web: Node.js 24+
- Linux desktop: AT-SPI accessibility support
Check setup:
agent-device doctor --platform ios
agent-device doctor --platform android
Key Commands Reference
Discovery & Session Management
agent-device apps --platform ios
agent-device apps --platform android
agent-device open "AppName" --platform ios
agent-device open com.example.app --platform android
agent-device close
Inspection
agent-device snapshot
agent-device snapshot -i
agent-device snapshot --components
agent-device snapshot --selectors
Snapshot Output Example:
@e1 [heading] "Settings"
@e2 [button] "Sign In"
@e3 [text-field] "Email"
@e4 [button] "Submit"
Interaction Commands
agent-device tap @e2
agent-device tap 'button[label="Sign In"]'
agent-device fill @e3 "user@example.com"
agent-device type "Hello World"
agent-device scroll down
agent-device scroll up --amount 0.5
agent-device swipe left
agent-device swipe right --from @e5
agent-device wait @e6 --timeout 5000
agent-device wait 2000
agent-device assert @e7 --exists
agent-device assert @e8 --text "Welcome"
agent-device alert accept
agent-device alert dismiss
Evidence Capture
agent-device screenshot ./artifacts/screen.png
agent-device video start
agent-device video stop ./artifacts/recording.mp4
agent-device logs ./artifacts/app.log
agent-device network start
agent-device network stop ./artifacts/network.har
agent-device profile start
agent-device profile stop ./artifacts/perf.json
agent-device react-profile start
agent-device react-profile stop ./artifacts/react-profile.json
Replay & Recording
agent-device record start ./scripts/login-flow.ad
agent-device open MyApp --platform ios
agent-device tap @e1
agent-device fill @e2 "test@example.com"
agent-device record stop
agent-device replay ./scripts/login-flow.ad
agent-device export maestro ./scripts/login-flow.ad --output ./maestro/login.yaml
Configuration
Session Options
agent-device open MyApp --platform ios --device "iPhone 15 Pro"
agent-device open MyApp --platform ios --args "--env=staging"
agent-device open com.company.myapp --platform android
Global Flags
agent-device snapshot -i --verbose
agent-device snapshot --format json
agent-device wait @e1 --timeout 10000
Environment Variables
export AGENT_DEVICE_PLATFORM=ios
export AGENT_DEVICE_DEVICE="iPhone 15 Pro"
export AGENT_DEVICE_ARTIFACTS=./test-artifacts
Real Code Examples
Example 1: Login Flow Verification
#!/bin/bash
agent-device open "MyApp" --platform ios
agent-device screenshot ./artifacts/01-launch.png
agent-device snapshot -i
agent-device fill @e1 "$TEST_EMAIL"
agent-device fill @e2 "$TEST_PASSWORD"
agent-device screenshot ./artifacts/02-filled.png
agent-device tap @e3
agent-device wait 'heading[label="Welcome"]' --timeout 5000
agent-device snapshot -i
agent-device screenshot ./artifacts/03-logged-in.png
agent-device close
Example 2: Android E2E Test with Evidence
#!/bin/bash
agent-device open com.example.shop --platform android
agent-device video start
agent-device network start
agent-device logs start ./artifacts/app.log
agent-device snapshot -i
agent-device tap 'button[text="Shop"]'
agent-device wait 2000
agent-device snapshot -i
agent-device tap '@e5'
agent-device wait 'button[text="Add to Cart"]'
agent-device tap 'button[text="Add to Cart"]'
agent-device screenshot ./artifacts/added-to-cart.png
agent-device tap 'button[content-desc="Cart"]'
agent-device wait 2000
agent-device snapshot -i
agent-device tap 'button[text="Checkout"]'
agent-device wait 3000
agent-device video stop ./artifacts/checkout-flow.mp4
agent-device network stop ./artifacts/network.har
agent-device close
Example 3: React Native Component Inspection
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
async function inspectReactNativeApp() {
await execAsync('agent-device open MyRNApp --platform ios');
const { stdout } = await execAsync('agent-device snapshot --components --format json');
const snapshot = JSON.parse(stdout);
const loginButton = snapshot.components.find(
(c: any) => c.type === 'Button' && c.props?.title === 'Log In'
);
if (loginButton) {
console.log('Found login button:', loginButton.ref);
await execAsync(`agent-device tap ${loginButton.ref}`);
}
await execAsync('agent-device screenshot ./artifacts/after-tap.png');
await execAsync('agent-device close');
}
Example 4: Replay Script (.ad format)
Create login-test.ad:
# Login flow replay script
open MyApp --platform ios
wait 2000
snapshot -i
fill @e1 "test@example.com"
fill @e2 "password123"
screenshot ./artifacts/login-filled.png
tap @e3
wait heading[label="Dashboard"] --timeout 5000
assert heading[label="Dashboard"] --exists
screenshot ./artifacts/dashboard.png
close
Execute:
agent-device replay ./login-test.ad
Example 5: Performance Profiling
#!/bin/bash
agent-device open MyApp --platform ios
agent-device profile start
agent-device tap @e1
agent-device wait 1000
agent-device scroll down
agent-device wait 1000
agent-device tap @e5
agent-device wait 2000
agent-device profile stop ./artifacts/navigation-perf.json
agent-device react-profile start
agent-device tap 'button[label="Load Data"]'
agent-device wait 3000
agent-device react-profile stop ./artifacts/react-render.json
agent-device close
Common Patterns
Pattern 1: Conditional Flow Based on Snapshot
SNAPSHOT=$(agent-device snapshot -i)
if echo "$SNAPSHOT" | grep -q "Sign In"; then
echo "User not logged in, performing login..."
agent-device tap 'button[label="Sign In"]'
agent-device fill @e1 "$USER_EMAIL"
agent-device fill @e2 "$USER_PASSWORD"
agent-device tap 'button[label="Submit"]'
agent-device wait 3000
else
echo "User already logged in"
fi
Pattern 2: Retry with Evidence
retry_with_screenshot() {
local max_attempts=3
local attempt=1
while [ $attempt -le $max_attempts ]; do
echo "Attempt $attempt..."
if agent-device tap "$1" 2>/dev/null; then
echo "Success"
return 0
fi
agent-device screenshot "./artifacts/retry-$attempt.png"
agent-device snapshot -i > "./artifacts/snapshot-$attempt.txt"
attempt=$((attempt + 1))
sleep 2
done
return 1
}
retry_with_screenshot '@e5'
Pattern 3: Multi-Platform Test
#!/bin/bash
test_on_platform() {
local platform=$1
echo "Testing on $platform..."
agent-device open MyApp --platform "$platform"
agent-device snapshot -i
agent-device tap @e1
agent-device wait 2000
agent-device screenshot "./artifacts/${platform}-result.png"
agent-device close
}
test_on_platform ios
test_on_platform android
Pattern 4: Selector-Based Interaction (More Reliable Than Refs)
agent-device tap 'button[label="Continue"]'
agent-device fill 'text-field[label="Username"]' "myuser"
agent-device tap '[testID="submit-button"]'
agent-device assert '[testID="success-message"]' --exists
agent-device tap 'button[text="Sign Up"]'
agent-device tap 'button[label="Submit"][enabled="true"]'
Troubleshooting
Issue: "No devices found"
xcrun simctl list devices
adb devices
xcrun simctl boot "iPhone 15 Pro"
agent-device apps --platform ios
Issue: "Element not found"
agent-device tap @e1
agent-device wait 2000
agent-device snapshot -i
agent-device tap 'button[label="Next"]'
agent-device wait @e5 --timeout 10000
Issue: "Session timeout"
export AGENT_DEVICE_TIMEOUT=30000
agent-device wait @e1 --timeout 30000
Issue: Accessibility data missing
Issue: Commands not being recorded
agent-device record start ./test.ad
ls -lh ./test.ad
Debugging Tips
agent-device snapshot -i --verbose
agent-device logs ./debug.log
agent-device screenshot ./debug-$(date +%s).png
agent-device snapshot --format json | jq '.elements[] | select(.role=="button")'
CI/CD Integration
GitHub Actions Example
name: Mobile QA
on: [pull_request]
jobs:
test-ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '22'
- name: Install agent-device
run: npm install -g agent-device@latest
- name: Run iOS tests
run: |
agent-device doctor --platform ios
./scripts/test-ios.sh
- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v3
with:
name: test-artifacts
path: ./artifacts/
EAS Workflow (Expo)
build:
name: Agent QA
steps:
- run:
name: Install agent-device
command: npm install -g agent-device@latest
- run:
name: Run tests
command: |
agent-device open MyExpoApp --platform ios
agent-device replay ./e2e/smoke-test.ad
Additional Resources
Best Practices for AI Agents
- Always run
agent-device snapshot -i after screen changes to get fresh element refs
- Prefer selectors over refs for stable automation:
'button[label="Submit"]' vs @e5
- Use testID in React Native for reliable element targeting
- Capture evidence before assertions to help debug failures
- Use
--verbose flag when troubleshooting unclear behavior
- Start recordings at workflow beginning to capture full context
- Check
agent-device doctor before starting automation on new environments
- Use
agent-device apps to verify app is installed and discoverable
- Set reasonable timeouts (default 5s may be too short for slow screens)
- Close sessions explicitly with
agent-device close to free resources