Skip to content

Commit 9f49301

Browse files
committed
Add Android test emulator skill
1 parent 7b60367 commit 9f49301

2 files changed

Lines changed: 130 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
name: android-test-emulator
3+
description: Launch or create the local Android emulator required before running Android connected/instrumented tests in this repository. Use this whenever running Android tests is required and no suitable device is already connected.
4+
---
5+
6+
# Android Test Emulator
7+
8+
Use this skill before running Android connected tests such as `connectedAndroidTest` or `connectedDebugAndroidTest`.
9+
10+
The required AVD name is `Unstyled_Tests`. If it does not exist, create it with:
11+
12+
- API level: `23`
13+
- System image: `system-images;android-23;default;x86_64`
14+
- Disk size: `2048M`
15+
16+
## Workflow
17+
18+
1. Check connected devices:
19+
20+
```bash
21+
adb devices
22+
```
23+
24+
2. If a device is already connected and booted, use it.
25+
26+
3. Otherwise launch/create the project emulator:
27+
28+
```bash
29+
bash .agents/skills/android-test-emulator/scripts/launch_unstyled_tests_emulator.sh
30+
```
31+
32+
4. Wait until boot is complete before running Android tests. The script waits for:
33+
34+
```bash
35+
adb shell getprop sys.boot_completed
36+
```
37+
38+
5. After the emulator is ready, run the requested Android test task.
39+
40+
## Notes
41+
42+
- Do not run Android tests until the emulator appears in `adb devices` as `device` and `sys.boot_completed` is `1`.
43+
- If `emulator` is not on `PATH`, use `$ANDROID_HOME/emulator/emulator`, `$ANDROID_SDK_ROOT/emulator/emulator`, or `$HOME/Library/Android/sdk/emulator/emulator`.
44+
- The script uses the same runtime options expected for test execution: `-no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none`.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
AVD_NAME="Unstyled_Tests"
5+
API_LEVEL="23"
6+
ARCH="x86_64"
7+
DISK_SIZE="2048M"
8+
SYSTEM_IMAGE="system-images;android-${API_LEVEL};default;${ARCH}"
9+
10+
if [ -n "${ANDROID_HOME:-}" ]; then
11+
SDK_ROOT="$ANDROID_HOME"
12+
elif [ -n "${ANDROID_SDK_ROOT:-}" ]; then
13+
SDK_ROOT="$ANDROID_SDK_ROOT"
14+
else
15+
SDK_ROOT="$HOME/Library/Android/sdk"
16+
fi
17+
18+
export ANDROID_HOME="$SDK_ROOT"
19+
export ANDROID_SDK_ROOT="$SDK_ROOT"
20+
21+
SDKMANAGER="$SDK_ROOT/cmdline-tools/latest/bin/sdkmanager"
22+
AVDMANAGER="$SDK_ROOT/cmdline-tools/latest/bin/avdmanager"
23+
EMULATOR="$SDK_ROOT/emulator/emulator"
24+
ADB="$SDK_ROOT/platform-tools/adb"
25+
26+
for tool in "$SDKMANAGER" "$AVDMANAGER" "$EMULATOR" "$ADB"; do
27+
if [ ! -x "$tool" ]; then
28+
echo "Required Android SDK tool not found or not executable: $tool" >&2
29+
exit 1
30+
fi
31+
done
32+
33+
if ! "$EMULATOR" -list-avds | grep -Fxq "$AVD_NAME"; then
34+
"$SDKMANAGER" "platform-tools" "emulator" "platforms;android-${API_LEVEL}" "$SYSTEM_IMAGE"
35+
printf "no\n" | "$AVDMANAGER" create avd \
36+
--force \
37+
--name "$AVD_NAME" \
38+
--package "$SYSTEM_IMAGE" \
39+
--device "pixel"
40+
41+
CONFIG="$HOME/.android/avd/${AVD_NAME}.avd/config.ini"
42+
if [ -f "$CONFIG" ]; then
43+
if grep -q '^disk.dataPartition.size=' "$CONFIG"; then
44+
sed -i.bak "s/^disk.dataPartition.size=.*/disk.dataPartition.size=${DISK_SIZE}/" "$CONFIG"
45+
else
46+
printf "\ndisk.dataPartition.size=%s\n" "$DISK_SIZE" >> "$CONFIG"
47+
fi
48+
fi
49+
fi
50+
51+
if "$ADB" devices | awk 'NR > 1 && $2 == "device" { found = 1 } END { exit found ? 0 : 1 }'; then
52+
boot_completed="$("$ADB" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r' || true)"
53+
if [ "$boot_completed" = "1" ]; then
54+
echo "Android device already connected and booted."
55+
"$ADB" devices
56+
exit 0
57+
fi
58+
fi
59+
60+
"$EMULATOR" \
61+
-avd "$AVD_NAME" \
62+
-no-snapshot-save \
63+
-no-window \
64+
-gpu swiftshader_indirect \
65+
-noaudio \
66+
-no-boot-anim \
67+
-camera-back none >/tmp/unstyled-tests-emulator.log 2>&1 &
68+
69+
"$ADB" wait-for-device
70+
71+
for _ in $(seq 1 180); do
72+
boot_completed="$("$ADB" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r' || true)"
73+
if [ "$boot_completed" = "1" ]; then
74+
"$ADB" shell settings put global window_animation_scale 0 >/dev/null 2>&1 || true
75+
"$ADB" shell settings put global transition_animation_scale 0 >/dev/null 2>&1 || true
76+
"$ADB" shell settings put global animator_duration_scale 0 >/dev/null 2>&1 || true
77+
echo "Android emulator $AVD_NAME is booted."
78+
"$ADB" devices
79+
exit 0
80+
fi
81+
sleep 1
82+
done
83+
84+
echo "Timed out waiting for Android emulator $AVD_NAME to boot." >&2
85+
echo "Emulator log: /tmp/unstyled-tests-emulator.log" >&2
86+
exit 1

0 commit comments

Comments
 (0)