Skip to content

Commit 3fa937d

Browse files
committed
Replace instrumentation test with adb-based UI automation
Pure adb approach avoids jcenter dependency issue (barista library). Uses uiautomator dump + input tap/text commands to drive the app. Captures UI dumps at each stage plus logcat and screenshots.
1 parent afe883e commit 3fa937d

1 file changed

Lines changed: 188 additions & 37 deletions

File tree

.github/workflows/test.yml

Lines changed: 188 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,13 @@ jobs:
5252
- name: Build debug APK
5353
run: ./gradlew assembleDebug
5454

55-
- name: Build androidTest APK
56-
run: ./gradlew assembleDebugAndroidTest
57-
5855
- name: Enable KVM
5956
run: |
6057
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
6158
sudo udevadm control --reload-rules
6259
sudo udevadm trigger --name-match=kvm
6360
64-
- name: Start Android emulator
61+
- name: Start Android emulator and run test
6562
uses: reactivecircus/android-emulator-runner@v2
6663
with:
6764
api-level: 30
@@ -71,69 +68,223 @@ jobs:
7168
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim
7269
disable-animations: true
7370
script: |
71+
set -e
72+
7473
echo "=== Emulator booted ==="
7574
adb shell getprop ro.build.version.sdk
7675
adb shell getprop ro.product.cpu.abi
7776
78-
echo "=== Installing APKs ==="
77+
echo "=== Installing APK ==="
7978
adb install -r app/build/outputs/apk/debug/app-debug.apk
80-
adb install -r app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk
8179
8280
echo "=== Granting permissions ==="
8381
adb shell pm grant com.scisammy.ubuntuandroid android.permission.READ_EXTERNAL_STORAGE || true
8482
adb shell pm grant com.scisammy.ubuntuandroid android.permission.WRITE_EXTERNAL_STORAGE || true
8583
84+
echo "=== Pre-check: native libs ==="
85+
adb shell "find /data/app/ -name 'lib_proot*' 2>/dev/null" || echo "no proot lib found"
86+
adb shell "find /data/app/ -name 'lib_busybox*' 2>/dev/null" || echo "no busybox lib found"
87+
8688
echo "=== Clearing logcat ==="
8789
adb logcat -c
8890
89-
echo "=== Running instrumentation tests ==="
90-
adb shell am instrument -w -e class tech.ula.ui.UbuntuLaunchTest com.scisammy.ubuntuandroid.test/androidx.test.runner.AndroidJUnitRunner 2>&1 || true
91+
echo "=== Launching app ==="
92+
adb shell am start -n com.scisammy.ubuntuandroid/.MainActivity
93+
sleep 5
9194
92-
echo "=== Capturing logcat ==="
93-
adb logcat -d -s "tech.ula:*" "busybox:*" "ULA:*" "System.out:*" "System.err:*" > /tmp/logcat.txt 2>&1 || true
95+
echo "=== UI dump after launch ==="
96+
adb shell uiautomator dump /sdcard/ui_launch.xml 2>/dev/null || true
97+
adb pull /sdcard/ui_launch.xml /tmp/ui_launch.xml 2>/dev/null || true
98+
cat /tmp/ui_launch.xml 2>/dev/null || echo "no ui dump"
9499
95-
echo "=== Checking if server is running ==="
96-
adb shell "netstat -tlnp 2>/dev/null | grep 2022" || echo "Port 2022 not listening"
97-
adb shell "ps -ef 2>/dev/null | grep dropbear" || echo "No dropbear process"
98-
adb shell "ps -ef 2>/dev/null | grep proot" || echo "No proot process"
100+
echo "=== Check logcat for errors ==="
101+
adb logcat -d | grep -i "error\|exception\|crash\|fatal\|missing" | tail -30 || echo "no errors found"
99102
100-
echo "=== Listing support dir ==="
101-
adb shell "ls -la /data/data/com.scisammy.ubuntuandroid/files/support/ 2>/dev/null" || echo "Support dir not found"
102-
adb shell "ls -la /data/data/com.scisammy.ubuntuandroid/files/ 2>/dev/null" || echo "Files dir not found"
103+
echo "=== Wait for app list to load (20s) ==="
104+
sleep 20
103105
104-
echo "=== Dumping UI hierarchy ==="
105-
adb shell uiautomator dump /sdcard/ui_dump.xml 2>/dev/null || true
106-
adb pull /sdcard/ui_dump.xml /tmp/ui_dump.xml 2>/dev/null || true
106+
echo "=== UI dump after wait ==="
107+
adb shell uiautomator dump /sdcard/ui_loaded.xml 2>/dev/null || true
108+
adb pull /sdcard/ui_loaded.xml /tmp/ui_loaded.xml 2>/dev/null || true
109+
cat /tmp/ui_loaded.xml 2>/dev/null || echo "no ui dump"
107110
108-
echo "=== Taking screenshot ==="
109-
adb shell screencap -p /sdcard/screenshot.png 2>/dev/null || true
110-
adb pull /sdcard/screenshot.png /tmp/screenshot.png 2>/dev/null || true
111+
echo "=== Look for Ubuntu in the list ==="
112+
adb shell uiautomator dump /sdcard/ui_full.xml 2>/dev/null || true
113+
adb pull /sdcard/ui_full.xml /tmp/ui_full.xml 2>/dev/null || true
114+
grep -i "ubuntu" /tmp/ui_full.xml 2>/dev/null || echo "Ubuntu not found in UI"
111115
112-
echo "=== Checking filesystem dirs ==="
113-
adb shell "ls /data/data/com.scisammy.ubuntuandroid/files/ 2>/dev/null" || echo "No files dir"
116+
echo "=== Try clicking Ubuntu (first app item) ==="
117+
# Get bounds of first list item and click center
118+
BOUNDS=$(adb shell uiautomator dump /dev/tty 2>/dev/null | grep -oP 'resource-id="com.scisammy.ubuntuandroid:id/apps_name"[^>]*bounds="\[\d+,\d+\]\[\d+,\d+\]"' | head -1 | grep -oP 'bounds="\[\d+,\d+\]\[\d+,\d+\]"')
119+
echo "Ubuntu bounds: $BOUNDS"
120+
if [ -n "$BOUNDS" ]; then
121+
# Parse bounds
122+
X1=$(echo "$BOUNDS" | grep -oP '\[(\d+),' | head -1 | tr -dc '0-9')
123+
Y1=$(echo "$BOUNDS" | grep -oP ',(\d+)\]' | head -1 | tr -dc '0-9')
124+
X2=$(echo "$BOUNDS" | grep -oP '\[(\d+),' | tail -1 | tr -dc '0-9')
125+
Y2=$(echo "$BOUNDS" | grep -oP ',(\d+)\]' | tail -1 | tr -dc '0-9')
126+
CX=$(( (X1 + X2) / 2 ))
127+
CY=$(( (Y1 + Y2) / 2 ))
128+
echo "Clicking at ($CX, $CY)"
129+
adb shell input tap $CX $CY
130+
else
131+
echo "Could not find Ubuntu, trying tap at common position"
132+
adb shell input tap 540 400
133+
fi
134+
sleep 3
114135
115-
echo "=== DONE ==="
136+
echo "=== UI dump after clicking Ubuntu ==="
137+
adb shell uiautomator dump /sdcard/ui_after_click.xml 2>/dev/null || true
138+
adb pull /sdcard/ui_after_click.xml /tmp/ui_after_click.xml 2>/dev/null || true
139+
cat /tmp/ui_after_click.xml 2>/dev/null || echo "no ui dump"
116140
117-
- name: Upload logcat
118-
if: always()
119-
uses: actions/upload-artifact@v4
120-
with:
121-
name: logcat
122-
path: /tmp/logcat.txt
123-
if-no-files-found: ignore
141+
echo "=== Check for credentials dialog ==="
142+
adb shell "dumpsys activity top | grep -i 'ACTIVITY\|DIALOG\|EditText\|username\|password'" || true
143+
144+
echo "=== Type username ==="
145+
adb shell input tap 540 300
146+
sleep 1
147+
adb shell input text "user"
148+
adb shell input keyevent 61 # TAB
149+
sleep 1
150+
adb shell input text "pass"
151+
adb shell input keyevent 61 # TAB
152+
adb shell input text "vncpass"
153+
sleep 1
154+
155+
echo "=== Click OK button (positive button in dialog) ==="
156+
# Dialog positive button is typically at bottom-right
157+
adb shell uiautomator dump /sdcard/ui_dialog.xml 2>/dev/null || true
158+
adb pull /sdcard/ui_dialog.xml /tmp/ui_dialog.xml 2>/dev/null || true
159+
# Find the OK button
160+
OK_BOUNDS=$(cat /tmp/ui_dialog.xml 2>/dev/null | grep -oP 'text="OK"[^>]*bounds="\[\d+,\d+\]\[\d+,\d+\]"' | grep -oP 'bounds="\[\d+,\d+\]\[\d+,\d+\]"')
161+
if [ -n "$OK_BOUNDS" ]; then
162+
X1=$(echo "$OK_BOUNDS" | grep -oP '\[(\d+),' | head -1 | tr -dc '0-9')
163+
Y1=$(echo "$OK_BOUNDS" | grep -oP ',(\d+)\]' | head -1 | tr -dc '0-9')
164+
X2=$(echo "$OK_BOUNDS" | grep -oP '\[(\d+),' | tail -1 | tr -dc '0-9')
165+
Y2=$(echo "$OK_BOUNDS" | grep -oP ',(\d+)\]' | tail -1 | tr -dc '0-9')
166+
CX=$(( (X1 + X2) / 2 ))
167+
CY=$(( (Y1 + Y2) / 2 ))
168+
echo "Clicking OK at ($CX, $CY)"
169+
adb shell input tap $CX $CY
170+
else
171+
echo "OK button not found, pressing enter"
172+
adb shell input keyevent 66 # ENTER
173+
fi
174+
sleep 3
175+
176+
echo "=== UI dump after credentials ==="
177+
adb shell uiautomator dump /sdcard/ui_after_creds.xml 2>/dev/null || true
178+
adb pull /sdcard/ui_after_creds.xml /tmp/ui_after_creds.xml 2>/dev/null || true
179+
cat /tmp/ui_after_creds.xml 2>/dev/null || echo "no ui dump"
180+
181+
echo "=== Check for SSH radio button ==="
182+
adb shell uiautomator dump /sdcard/ui_conn.xml 2>/dev/null || true
183+
adb pull /sdcard/ui_conn.xml /tmp/ui_conn.xml 2>/dev/null || true
184+
SSH_BOUNDS=$(cat /tmp/ui_conn.xml 2>/dev/null | grep -oP 'text="SSH"[^>]*bounds="\[\d+,\d+\]\[\d+,\d+\]"' | grep -oP 'bounds="\[\d+,\d+\]\[\d+,\d+\]"')
185+
if [ -n "$SSH_BOUNDS" ]; then
186+
X1=$(echo "$SSH_BOUNDS" | grep -oP '\[(\d+),' | head -1 | tr -dc '0-9')
187+
Y1=$(echo "$SSH_BOUNDS" | grep -oP ',(\d+)\]' | head -1 | tr -dc '0-9')
188+
X2=$(echo "$SSH_BOUNDS" | grep -oP '\[(\d+),' | tail -1 | tr -dc '0-9')
189+
Y2=$(echo "$SSH_BOUNDS" | grep -oP ',(\d+)\]' | tail -1 | tr -dc '0-9')
190+
CX=$(( (X1 + X2) / 2 ))
191+
CY=$(( (Y1 + Y2) / 2 ))
192+
echo "Clicking SSH at ($CX, $CY)"
193+
adb shell input tap $CX $CY
194+
fi
195+
sleep 1
196+
197+
echo "=== Click OK for connection type ==="
198+
adb shell uiautomator dump /sdcard/ui_conn2.xml 2>/dev/null || true
199+
adb pull /sdcard/ui_conn2.xml /tmp/ui_conn2.xml 2>/dev/null || true
200+
OK_BOUNDS2=$(cat /tmp/ui_conn2.xml 2>/dev/null | grep -oP 'text="OK"[^>]*bounds="\[\d+,\d+\]\[\d+,\d+\]"' | grep -oP 'bounds="\[\d+,\d+\]\[\d+,\d+\]"')
201+
if [ -n "$OK_BOUNDS2" ]; then
202+
X1=$(echo "$OK_BOUNDS2" | grep -oP '\[(\d+),' | head -1 | tr -dc '0-9')
203+
Y1=$(echo "$OK_BOUNDS2" | grep -oP ',(\d+)\]' | head -1 | tr -dc '0-9')
204+
X2=$(echo "$OK_BOUNDS2" | grep -oP '\[(\d+),' | tail -1 | tr -dc '0-9')
205+
Y2=$(echo "$OK_BOUNDS2" | grep -oP ',(\d+)\]' | tail -1 | tr -dc '0-9')
206+
CX=$(( (X1 + X2) / 2 ))
207+
CY=$(( (Y1 + Y2) / 2 ))
208+
echo "Clicking OK at ($CX, $CY)"
209+
adb shell input tap $CX $CY
210+
else
211+
adb shell input keyevent 66
212+
fi
213+
214+
echo "=== Waiting for server to start (120s) ==="
215+
sleep 10
216+
217+
echo "=== Progress check (10s) ==="
218+
adb shell uiautomator dump /sdcard/ui_progress1.xml 2>/dev/null || true
219+
adb pull /sdcard/ui_progress1.xml /tmp/ui_progress1.xml 2>/dev/null || true
220+
cat /tmp/ui_progress1.xml 2>/dev/null | grep -oP 'text="[^"]*"' | head -20 || true
221+
222+
sleep 20
223+
224+
echo "=== Progress check (30s) ==="
225+
adb shell uiautomator dump /sdcard/ui_progress2.xml 2>/dev/null || true
226+
adb pull /sdcard/ui_progress2.xml /tmp/ui_progress2.xml 2>/dev/null || true
227+
cat /tmp/ui_progress2.xml 2>/dev/null | grep -oP 'text="[^"]*"' | head -20 || true
228+
229+
sleep 30
230+
231+
echo "=== Progress check (60s) ==="
232+
adb shell uiautomator dump /sdcard/ui_progress3.xml 2>/dev/null || true
233+
adb pull /sdcard/ui_progress3.xml /tmp/ui_progress3.xml 2>/dev/null || true
234+
cat /tmp/ui_progress3.xml 2>/dev/null | grep -oP 'text="[^"]*"' | head -20 || true
235+
236+
sleep 30
237+
238+
echo "=== Progress check (90s) ==="
239+
adb shell uiautomator dump /sdcard/ui_progress4.xml 2>/dev/null || true
240+
adb pull /sdcard/ui_progress4.xml /tmp/ui_progress4.xml 2>/dev/null || true
241+
cat /tmp/ui_progress4.xml 2>/dev/null | grep -oP 'text="[^"]*"' | head -20 || true
242+
243+
sleep 30
244+
245+
echo "=== Final diagnostics (120s+) ==="
246+
adb shell uiautomator dump /sdcard/ui_final.xml 2>/dev/null || true
247+
adb pull /sdcard/ui_final.xml /tmp/ui_final.xml 2>/dev/null || true
248+
249+
echo "=== Final UI state ==="
250+
cat /tmp/ui_final.xml 2>/dev/null | grep -oP 'text="[^"]*"' | head -30 || true
251+
252+
echo "=== Support directory ==="
253+
adb shell "ls -la /data/data/com.scisammy.ubuntuandroid/files/support/ 2>/dev/null" || echo "support dir not found"
254+
255+
echo "=== Files directory ==="
256+
adb shell "ls -la /data/data/com.scisammy.ubuntuandroid/files/ 2>/dev/null" || echo "files dir not found"
257+
258+
echo "=== Check port 2022 ==="
259+
adb shell "netstat -tlnp 2>/dev/null | grep 2022" || echo "port 2022 not listening"
260+
261+
echo "=== Check proot/dropbear processes ==="
262+
adb shell "ps -ef 2>/dev/null | grep -E 'proot|dropbear|busybox'" || echo "no relevant processes"
263+
264+
echo "=== Logcat errors ==="
265+
adb logcat -d | grep -iE "error|exception|fail|missing|crash" | grep -v "chromium\|DEBUG\|sentry" | tail -50 || echo "no errors"
266+
267+
echo "=== Logcat ula tags ==="
268+
adb logcat -d -s "Ula:*" "ULA:*" "tech.ula:*" "LocalServerManager:*" "BusyboxExecutor:*" | tail -50 || true
269+
270+
echo "=== Screenshot ==="
271+
adb shell screencap -p /sdcard/screenshot_final.png 2>/dev/null || true
272+
adb pull /sdcard/screenshot_final.png /tmp/screenshot_final.png 2>/dev/null || true
273+
274+
echo "=== DONE ==="
124275
125-
- name: Upload UI dump
276+
- name: Upload UI dumps
126277
if: always()
127278
uses: actions/upload-artifact@v4
128279
with:
129-
name: ui-dump
130-
path: /tmp/ui_dump.xml
280+
name: ui-dumps
281+
path: /tmp/ui_*.xml
131282
if-no-files-found: ignore
132283

133284
- name: Upload screenshot
134285
if: always()
135286
uses: actions/upload-artifact@v4
136287
with:
137288
name: screenshot
138-
path: /tmp/screenshot.png
289+
path: /tmp/screenshot_final.png
139290
if-no-files-found: ignore

0 commit comments

Comments
 (0)