|
| 1 | +--- |
| 2 | +name: interacting-with-android-device |
| 3 | +description: Instructions for capturing UI state, comparing with mocks, and interacting with an Android device using universal ADB commands. |
| 4 | +allowed-tools: |
| 5 | + - Bash(adb *) |
| 6 | + |
| 7 | + - Bash(./.claude/skills/interacting-with-android-device/scripts/adb-*) |
| 8 | + - Bash(sleep *) |
| 9 | + - Bash(./gradlew install*) |
| 10 | + - Read |
| 11 | + - Glob |
| 12 | +--- |
| 13 | + |
| 14 | +# Interacting with Android Device |
| 15 | + |
| 16 | +## Quick Start: Using Helper Scripts |
| 17 | + |
| 18 | +Helper scripts in the `.claude/skills/interacting-with-android-device/scripts/` directory automate repetitive UI testing tasks and reduce token overhead. |
| 19 | + |
| 20 | +**Available scripts:** |
| 21 | +- `adb-capture.sh [--xml] [--screenshot] [--all]` - Capture current device state. Default (no flags): both screenshot and XML hierarchy. |
| 22 | +- `adb-find-element.sh <text>` - Find element by text, return center coordinates (`X Y`). Dumps UI hierarchy, parses XML, calculates center from bounds. |
| 23 | +- `adb-tap-and-capture.sh <x> <y> [wait_seconds=2]` - Tap at coordinates, wait, capture and pull screenshot. |
| 24 | +- `adb-tap-element.sh <text> [wait_seconds=2]` - Find, tap, and capture in one command (recommended). Combines `adb-find-element.sh` + `adb-tap-and-capture.sh`. |
| 25 | +- `adb-navigate.sh <home|back|app-drawer> [wait_seconds=1]` - Navigation actions via keyevent or swipe, then capture screenshot. |
| 26 | + |
| 27 | +**Use these scripts instead of inlining commands** to save tokens and reduce mechanical steps. |
| 28 | + |
| 29 | +To use `adb-find-element.sh` for manual coordinate extraction: |
| 30 | +```bash |
| 31 | +COORDS=$(./.claude/skills/interacting-with-android-device/scripts/adb-find-element.sh "Check for update") |
| 32 | +X=$(echo $COORDS | awk '{print $1}') |
| 33 | +Y=$(echo $COORDS | awk '{print $2}') |
| 34 | +adb shell input tap $X $Y |
| 35 | +``` |
| 36 | + |
| 37 | +## 1. Capturing Current State |
| 38 | +To understand what is currently on the device: |
| 39 | +```bash |
| 40 | +# Capture both screenshot and UI hierarchy XML |
| 41 | +./.claude/skills/interacting-with-android-device/scripts/adb-capture.sh |
| 42 | + |
| 43 | +# Or capture only one |
| 44 | +./.claude/skills/interacting-with-android-device/scripts/adb-capture.sh --xml # UI hierarchy only |
| 45 | +./.claude/skills/interacting-with-android-device/scripts/adb-capture.sh --screenshot # Screenshot only |
| 46 | +``` |
| 47 | +* Read `view.xml` to find coordinates (`bounds`) and properties (like `text` or `resource-id`) of UI elements. |
| 48 | +* Use `screen.png` for visual verification against design mocks. |
| 49 | + |
| 50 | +## 2. Interacting with the Device |
| 51 | + |
| 52 | +### Using Scripts (Recommended) |
| 53 | +Use helper scripts to reduce token overhead and automate mechanical steps: |
| 54 | + |
| 55 | +* **Find and tap an element by text**: |
| 56 | + ```bash |
| 57 | + ./.claude/skills/interacting-with-android-device/scripts/adb-tap-element.sh "System" |
| 58 | + ``` |
| 59 | + This finds the element, taps it, captures screenshot—all in one command. |
| 60 | + |
| 61 | +* **Tap at specific coordinates**: |
| 62 | + ```bash |
| 63 | + ./.claude/skills/interacting-with-android-device/scripts/adb-tap-and-capture.sh 332 1367 2 |
| 64 | + ``` |
| 65 | + Parameters: `<x> <y> [wait_seconds]` |
| 66 | + |
| 67 | +* **Navigate (home, back, app-drawer)**: |
| 68 | + ```bash |
| 69 | + ./.claude/skills/interacting-with-android-device/scripts/adb-navigate.sh home |
| 70 | + ./.claude/skills/interacting-with-android-device/scripts/adb-navigate.sh back |
| 71 | + ./.claude/skills/interacting-with-android-device/scripts/adb-navigate.sh app-drawer |
| 72 | + ``` |
| 73 | + |
| 74 | +### Raw Commands (When Scripts Aren't Sufficient) |
| 75 | + |
| 76 | +* **Finding Coordinates**: From the dumped XML, find the `bounds` attribute of the element you want to interact with. The bounds are in `[left, top][right, bottom]` format. Use the center point for a tap: `x = (left + right) / 2`, `y = (top + bottom) / 2`. |
| 77 | +* **Inputting Text**: First tap the text field, then `adb shell input text "<your_text>"` (Note: handle spaces and special characters with quotes). |
| 78 | +* **Key Events** (if not using navigate script): |
| 79 | + * Back: `adb shell input keyevent 4` |
| 80 | + * Home: `adb shell input keyevent 3` |
| 81 | + * Enter: `adb shell input keyevent 66` |
| 82 | +* **Scrolling/Swiping**: Use `adb shell input swipe <x1> <y1> <x2> <y2> <duration_ms>` where: |
| 83 | + * `(x1, y1)` = starting point |
| 84 | + * `(x2, y2)` = ending point |
| 85 | + * `duration_ms` = duration in milliseconds (1000ms is typical; adjust for speed/distance) |
| 86 | + * **Note**: For expanding containers/drawers, use large distances (e.g., 2400→300 for a 2992px tall screen) |
| 87 | + |
| 88 | +## 3. Verification Workflow |
| 89 | +Follow these steps for a complete UI test: |
| 90 | +1. **Build and Install**: Ensure the latest version of the app is running: `./gradlew installDebug`. |
| 91 | +2. **Inspect**: Run `adb-capture.sh` to dump the UI hierarchy and take a screenshot. |
| 92 | +3. **Compare**: Check the current UI against any mock image files in the project. |
| 93 | +4. **Interact**: Perform an action (like a button click) using the calculated coordinates and `adb shell input tap`. |
| 94 | +5. **Wait**: Sleep for a second (`sleep 1`) to allow for animations or network transitions. |
| 95 | +6. **Verify**: Dump the UI hierarchy again to confirm the UI has updated as expected (e.g., a new screen is shown, or a success message appeared in the XML). |
| 96 | + |
| 97 | +## 4. Examples |
| 98 | + |
| 99 | +### Example: Navigate to Settings and Check for Updates |
| 100 | +**Using scripts:** |
| 101 | +```bash |
| 102 | +# Go to home screen |
| 103 | +./.claude/skills/interacting-with-android-device/scripts/adb-navigate.sh home |
| 104 | +
|
| 105 | +# Open app drawer |
| 106 | +./.claude/skills/interacting-with-android-device/scripts/adb-navigate.sh app-drawer |
| 107 | +
|
| 108 | +# Find and tap "Settings" app |
| 109 | +./.claude/skills/interacting-with-android-device/scripts/adb-tap-element.sh "Settings" 2 |
| 110 | +
|
| 111 | +# Find and tap "System" option |
| 112 | +./.claude/skills/interacting-with-android-device/scripts/adb-tap-element.sh "System" 2 |
| 113 | +
|
| 114 | +# Find and tap "Software updates" |
| 115 | +./.claude/skills/interacting-with-android-device/scripts/adb-tap-element.sh "Software updates" 2 |
| 116 | +
|
| 117 | +# Find and tap "Check for update" button |
| 118 | +./.claude/skills/interacting-with-android-device/scripts/adb-tap-element.sh "Check for update" 5 |
| 119 | +``` |
| 120 | + |
| 121 | +### Example: Swiping |
| 122 | +For swipe gestures not covered by the navigation script: |
| 123 | +```bash |
| 124 | +adb shell input swipe 672 2800 672 500 1000 && sleep 1 && adb shell screencap -p /sdcard/screen.png && adb pull /sdcard/screen.png . |
| 125 | +``` |
| 126 | + |
| 127 | +## 5. Best Practices |
| 128 | + |
| 129 | +### Coordinate Calculation |
| 130 | +* Always calculate coordinates from the `bounds` attribute in the XML dump, as layouts can vary across different screen sizes. |
| 131 | +* Parse bounds format `[left,top][right,bottom]` and compute center: `x = (left + right) / 2`, `y = (top + bottom) / 2` |
| 132 | +* Use shell tools to programmatically extract coordinates rather than estimating from screenshots |
| 133 | +* When multiple instances of an element exist (e.g., in prediction row and full list), verify you're using the correct one by checking the context |
| 134 | +
|
| 135 | +### Command Chaining and Efficiency |
| 136 | +* For custom operations not covered by scripts, combine tap + wait + capture: |
| 137 | + ```bash |
| 138 | + adb shell input tap X Y && sleep N && adb shell screencap -p /sdcard/screen.png && adb pull /sdcard/screen.png . |
| 139 | + ``` |
| 140 | +* Always include a sleep duration (typically 1-5 seconds) between tap and capture to allow animations and transitions to complete |
| 141 | +* Pull the screenshot immediately after capture to avoid losing transient UI states |
| 142 | +
|
| 143 | +### Navigation and State Evaluation |
| 144 | +* **Dump XML before interaction**: Always extract the UI hierarchy before tapping to find precise element locations |
| 145 | +* **Verify after each interaction**: Don't assume an action succeeded—capture a screenshot after every tap to confirm the correct element was activated and the UI changed as expected |
| 146 | +* **Check both visual and structural state**: Use screenshot for visual verification, XML dump for structural confirmation (element presence, text content, state changes) |
| 147 | +* **Identify navigation failures early**: If a tap opened the wrong screen, use back button (`adb shell input keyevent 4`) to recover immediately rather than continuing with an incorrect state |
| 148 | + |
| 149 | +### Interaction Patterns |
| 150 | +* **Scrolling before interaction**: When looking for an element, check if it's visible on screen first. If not, scroll using swipe gestures to reveal it |
| 151 | +* **Use consistent scroll direction**: For vertical scrolling in lists/settings, use downward swipes (higher Y → lower Y) to scroll down |
| 152 | +* **Handle app crashes gracefully**: Some apps may fail to launch. Don't retry the same action—use back button and try an alternative approach |
| 153 | +* **Sanitize Input**: When using `adb shell input text`, be mindful of special characters that might need escaping in a terminal shell |
| 154 | +* **Check Accessibility**: Use the `content-desc` and `text` properties in the XML hierarchy to ensure the UI is accessible for screen readers |
| 155 | + |
| 156 | +## 6. Troubleshooting |
| 157 | + |
| 158 | +### Device Not Connected |
| 159 | +If `adb devices` returns an empty list: |
| 160 | +* Check USB connection or emulator status |
| 161 | +* Enable USB debugging on the device (Settings > Developer Options > USB Debugging) |
| 162 | +* Accept the RSA key prompt on the device if asked |
| 163 | +* Restart the device or disconnect/reconnect the USB cable |
0 commit comments