brainstorming
Structured design dialogue that validates ideas before implementation begins.
idb-claude-mobile-testing
Use when testing Claude Code Mobile app on iOS simulator with IDB CLI, when xc-mcp tools unavailable, or when needing testID-based UI automation - provides systematic workflow for finding elements by testID, tapping, typing, and verifying interactions using IDB accessibility tree
Full skill instructions
Systematic UI automation using IDB CLI for Claude Code Mobile app testing.
Core principle: Use IDB accessibility tree to find elements by testID (AXUniqueId), extract coordinates, then interact. No guessing coordinates. No MCP dependencies.
When to use: xc-mcp unavailable, expo-mcp local tools unavailable, need autonomous Gate 4A testing
# Verify IDB installed
which idb && which idb_companion
# Start idb_companion (if not running)
ps aux | grep idb_companion || idb_companion &
# Verify simulator booted
idb list-targets | grep Booted
# Verify IDB connected
idb list-apps --udid booted | head -5
Must show: IDB commands working, companion running, simulator booted
# Get complete accessibility tree (includes all AXUniqueId = testID)
idb ui describe-all --udid booted > /tmp/ui-tree.json
# Or save to project
idb ui describe-all --udid booted > logs/ui-tree.json
Returns: JSON array of ALL UI elements with:
AXUniqueId: The testID from React Nativeframe: {x, y, width, height} for tappingAXLabel: Visual label textenabled: Whether element is interactivetype: Button, TextArea, StaticText, etc.Use jq to parse (or Python/Node.js):
# Find send-button testID
cat logs/ui-tree.json | jq '.[] | select(.AXUniqueId == "send-button")'
# Extract just coordinates
cat logs/ui-tree.json | jq '.[] | select(.AXUniqueId == "send-button") | .frame'
# Returns: {"x":350, "y":798, "width":36, "height":36}
Or find in output directly:
idb ui describe-all --udid booted | grep -A 3 '"AXUniqueId":"send-button"'
Tap at CENTER of element:
center_x = frame.x + (frame.width / 2)
center_y = frame.y + (frame.height / 2)
Example:
# Tap send button (calculated center coordinates)
idb ui tap --udid booted 368 816
Verify with screenshot:
xcrun simctl io booted screenshot logs/after-tap.png
# 1. Get UI tree
idb ui describe-all --udid booted > logs/ui-tree.json
# 2. Find message-input coordinates
INPUT_COORDS=$(cat logs/ui-tree.json | jq -r '.[] | select(.AXUniqueId == "message-input") | "\(.frame.x + .frame.width/2) \(.frame.y + .frame.height/2)"')
# 3. Tap input field (split coordinates)
IDB_X=$(echo $INPUT_COORDS | cut -d' ' -f1)
IDB_Y=$(echo $INPUT_COORDS | cut -d' ' -f2)
idb ui tap --udid booted $IDB_X $IDB_Y
# 4. Type text
idb ui text --udid booted "Hello Claude"
# 5. Screenshot to verify
xcrun simctl io booted screenshot logs/message-typed.png
# 1. Find send-button (same process)
SEND_COORDS=$(cat logs/ui-tree.json | jq -r '.[] | select(.AXUniqueId == "send-button") | "\(.frame.x + .frame.width/2) \(.frame.y + .frame.height/2)"')
# 2. Tap send button
idb ui tap --udid booted $(echo $SEND_COORDS | cut -d' ' -f1) $(echo $SEND_COORDS | cut -d' ' -f2)
# 3. Screenshot result
xcrun simctl io booted screenshot logs/message-sent.png
# 1. Get fresh UI tree (in case elements moved)
idb ui describe-all --udid booted > logs/ui-tree-2.json
# 2. Find settings-button
SETTINGS_COORDS=$(cat logs/ui-tree-2.json | jq -r '.[] | select(.AXUniqueId == "settings-button") | "\(.frame.x + .frame.width/2) \(.frame.y + .frame.height/2)"')
# 3. Tap settings
idb ui tap --udid booted $(echo $SETTINGS_COORDS | cut -d' ' -f1) $(echo $SETTINGS_COORDS | cut -d' ' -f2)
# 4. Wait for navigation animation
sleep 1
# 5. Screenshot Settings screen
xcrun simctl io booted screenshot logs/settings-screen.png
For complex testing, use Python:
#!/usr/bin/env python3
import json
import subprocess
import sys
def get_ui_tree(udid="booted"):
"""Get UI accessibility tree"""
result = subprocess.run(
["idb", "ui", "describe-all", "--udid", udid],
capture_output=True, text=True
)
return json.loads(result.stdout)
def find_element_by_testid(tree, testid):
"""Find element by AXUniqueId (testID)"""
for element in tree:
if element.get("AXUniqueId") == testid:
return element
return None
def get_tap_coordinates(element):
"""Calculate center coordinates for tapping"""
frame = element["frame"]
x = frame["x"] + frame["width"] / 2
y = frame["y"] + frame["height"] / 2
return int(x), int(y)
def tap_element(testid, udid="booted"):
"""Find element by testID and tap it"""
tree = get_ui_tree(udid)
element = find_element_by_testid(tree, testid)
if not element:
print(f"Element with testID '{testid}' not found")
return False
if not element.get("enabled", False):
print(f"Element '{testid}' found but not enabled")
return False
x, y = get_tap_coordinates(element)
print(f"Tapping '{testid}' at ({x}, {y})")
subprocess.run(["idb", "ui", "tap", "--udid", udid, str(x), str(y)])
return True
def type_text(text, udid="booted"):
"""Type text into focused field"""
subprocess.run(["idb", "ui", "text", "--udid", udid, text])
# Usage examples
if __name__ == "__main__":
# Tap message input
tap_element("message-input")
# Type message
type_text("Hello Claude")
# Tap send button
tap_element("send-button")
Save as: scripts/idb-test-helper.py
Use:
python scripts/idb-test-helper.py
All interactive elements have testIDs (from codebase review):
ChatScreen:
chat-header - Header containerconnection-status - Connection indicatorsettings-button - Settings gear iconmessage-list - Messages FlatListmessage-bubble-{id} - Individual messagemessage-input - Text input fieldsend-button - Send buttonslash-command-menu - Command menuslash-command-{name} - Individual commandSettingsScreen:
settings-header - Headerback-button - Back navigationserver-url-input - Server URL fieldproject-path-input - Project path fieldauto-scroll-toggle - Auto-scroll switchhaptic-toggle - Haptic feedback switchview-sessions-button - View sessions buttonOther Screens:
filebrowser-header, file-search-input, file-list, file-item-{path}codeviewer-header, code-contentsessions-header, sessions-list, session-item-{id}| Mistake | Reality |
|---|---|
| "Try xc-mcp first" | WRONG if unavailable. Check IDB directly. |
| "Guess coordinates" | WRONG. Always get UI tree first. |
| "Tap without verifying enabled" | WRONG. Check enabled: true in tree. |
| "Use old UI tree" | WRONG. Elements move. Get fresh tree before each tap. |
| "Tap corner of element" | WRONG. Tap CENTER for reliability. |
Complete Gate 4A workflow:
# 1. Screenshot initial state
xcrun simctl io booted screenshot logs/01-initial.png
# 2. Tap message input
idb ui describe-all --udid booted > logs/ui.json
TAP_X=$(cat logs/ui.json | jq '.[] | select(.AXUniqueId == "message-input") | .frame.x + .frame.width/2')
TAP_Y=$(cat logs/ui.json | jq '.[] | select(.AXUniqueId == "message-input") | .frame.y + .frame.height/2')
idb ui tap --udid booted $TAP_X $TAP_Y
# 3. Type message
idb ui text --udid booted "test message"
xcrun simctl io booted screenshot logs/02-typed.png
# 4. Tap send
# (same process with send-button testID)
# 5. Navigate to Settings
# (same process with settings-button testID)
# 6. Verify all 5 screens
# (repeat for each screen's navigation buttons)
Once skill is created and tested:
Structured design dialogue that validates ideas before implementation begins.
Comprehensive design intelligence for web and mobile UI/UX across 10 technology stacks.
Comprehensive implementation plans for multi-step tasks, breaking down specs into bite-sized, testable steps.
Introduction to the obra skills system with mandatory skill invocation rules and best practices.
Execute a written implementation plan with critical review and task checkpoints.
Delegate independent tasks to specialized agents working concurrently with isolated context.
Isolated git worktrees with smart directory selection and safety verification.
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
Plan searchable and shareable content that drives traffic, builds authority, and generates leads.
README-first repository scanner that extracts commands and classifies reproduction candidates without executing them.
Brainstorm and prioritize marketing strategies tailored to your SaaS stage, budget, and goals.
Plan and optimize your website's page hierarchy, navigation, URL structure, and internal linking.
The world's fastest calendar for remote work
Capture, organize, and utilize your knowledge effortlessly.
Instant Summaries of Audio & Video Interviews with AnySummary
Transform PDFs into engaging mind maps.
Chat with any PDF instantly
Create an optimal daily plan using your voice
A productivity platform to centralize organizational knowledge and workflows with contextual AI assistance.
AskYourPDF Pricing Plans: Tailored to Your Needs