diff --git a/android/app/src/androidTest/java/org/whoneedhelp/mobile/CrossClientStagingInstrumentedTest.java b/android/app/src/androidTest/java/org/whoneedhelp/mobile/CrossClientStagingInstrumentedTest.java index 48e436f..f31f122 100644 --- a/android/app/src/androidTest/java/org/whoneedhelp/mobile/CrossClientStagingInstrumentedTest.java +++ b/android/app/src/androidTest/java/org/whoneedhelp/mobile/CrossClientStagingInstrumentedTest.java @@ -45,10 +45,7 @@ public final class CrossClientStagingInstrumentedTest { String browserReply = requiredArgument("browser_reply"); try (ActivityScenario scenario = launch(loginPath)) { - waitForElementText( - "remember-login-button", - "Keep me logged in on this device" - ); + waitForElement("remember-login-button"); click("remember-login-button"); waitForElementText( "main-content", diff --git a/scripts/android-browser-staging-e2e.sh b/scripts/android-browser-staging-e2e.sh index b98ac05..05f9d79 100755 --- a/scripts/android-browser-staging-e2e.sh +++ b/scripts/android-browser-staging-e2e.sh @@ -14,6 +14,7 @@ tools_image="who-need-help:android-e2e-tools-$run_id" browser_image="who-need-help-e2e-tests:android-$run_id" android_image="who-need-help-android:cross-client-$run_id" container="who-need-help-android-cross-client-$run_id" +avd_volume="who-need-help-android-avd-cross-client-$run_id" package=org.whoneedhelp.mobile.staging service_class=org.whoneedhelp.mobile.TrackingService fixture_password="$(openssl rand -hex 24)" @@ -234,6 +235,7 @@ cleanup() { fi docker rm -f "$container" >/dev/null 2>&1 || true + docker volume rm -f "$avd_volume" >/dev/null 2>&1 || true docker image rm "$android_image" "$browser_image" "$tools_image" >/dev/null 2>&1 || true { @@ -243,6 +245,12 @@ cleanup() { else printf 'true\n' fi + printf 'volume_absent=' + if docker volume inspect "$avd_volume" >/dev/null 2>&1; then + printf 'false\n' + else + printf 'true\n' + fi printf 'fixture_prefix_absent=' if [[ -f "$output_dir/database-cleanup.diff" ]] && [[ ! -s "$output_dir/database-cleanup.diff" ]]; then @@ -277,12 +285,41 @@ docker build \ --tag "$android_image" \ android >"$output_dir/android-image-build.log" +docker volume create "$avd_volume" >"$output_dir/avd-volume.txt" + docker run -d \ --name "$container" \ --device /dev/kvm \ + --mount \ + "type=volume,source=$avd_volume,target=/home/gradle/.android/avd/who_need_help_test.avd" \ "$android_image" >"$output_dir/container-id.txt" -adb wait-for-device +if [[ "$(docker inspect --format '{{.State.Running}}' "$container")" != true ]]; then + docker logs "$container" >"$output_dir/emulator.log" 2>&1 || true + echo "Android cross-client emulator exited before ADB became available; inspect $output_dir/emulator.log." >&2 + exit 1 +fi + +adb_ready=0 +for _attempt in $(seq 1 90); do + if [[ "$(docker inspect --format '{{.State.Running}}' "$container")" != true ]]; then + break + fi + + if [[ "$(adb get-state 2>/dev/null || true)" == device ]]; then + adb_ready=1 + break + fi + + sleep 2 +done + +if [[ "$adb_ready" -ne 1 ]]; then + docker logs "$container" >"$output_dir/emulator.log" 2>&1 || true + echo "Android cross-client emulator did not expose a ready ADB device." >&2 + exit 1 +fi + booted= for _attempt in $(seq 1 90); do booted=$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r') @@ -343,6 +380,12 @@ start_android_phase exchangeMessageAndTrackingWithBrowser tracking_started=0 for _attempt in $(seq 1 45); do + if ! kill -0 "$android_runner_pid" 2>/dev/null; then + wait_android_phase + echo "Android instrumentation exited before foreground tracking started." >&2 + exit 1 + fi + adb shell dumpsys notification --noredact >"$output_dir/notifications-current.txt" adb shell dumpsys activity services "$package" >"$output_dir/services-current.txt" if grep -Fq "Sharing live location" "$output_dir/notifications-current.txt" && diff --git a/scripts/android-staging-smoke.sh b/scripts/android-staging-smoke.sh index 5c5c013..bcdc0cb 100755 --- a/scripts/android-staging-smoke.sh +++ b/scripts/android-staging-smoke.sh @@ -9,6 +9,7 @@ TEST_APK="$ROOT/android/dist-staging/who-need-help-staging-androidTest.apk" run_id=$(date -u +%Y%m%d%H%M%S)-$$ image="who-need-help-android:staging-smoke-$run_id" container="who-need-help-android-staging-smoke-$run_id" +avd_volume="who-need-help-android-avd-staging-smoke-$run_id" output="$ROOT/output/android-staging-smoke/$run_id" package=org.whoneedhelp.mobile.staging activity=org.whoneedhelp.mobile.MainActivity @@ -77,6 +78,7 @@ cleanup() { fi docker rm -f "$container" >/dev/null 2>&1 || true + docker volume rm -f "$avd_volume" >/dev/null 2>&1 || true docker image rm "$image" >/dev/null 2>&1 || true { @@ -87,6 +89,13 @@ cleanup() { printf 'true\n' fi + printf 'volume_absent=' + if docker volume inspect "$avd_volume" >/dev/null 2>&1; then + printf 'false\n' + else + printf 'true\n' + fi + printf 'image_absent=' if docker image inspect "$image" >/dev/null 2>&1; then printf 'false\n' @@ -113,11 +122,21 @@ docker build \ --tag "$image" \ "$ROOT/android" >"$output/image-build.txt" +docker volume create "$avd_volume" >"$output/avd-volume.txt" + docker run -d \ --name "$container" \ --device /dev/kvm \ + --mount \ + "type=volume,source=$avd_volume,target=/home/gradle/.android/avd/who_need_help_test.avd" \ "$image" >"$output/container-id.txt" +if [ "$(docker inspect --format '{{.State.Running}}' "$container")" != "true" ]; then + docker logs "$container" >"$output/emulator.log" 2>&1 || true + echo "Android staging emulator exited before ADB became available; inspect $output/emulator.log." >&2 + exit 1 +fi + docker exec "$container" adb wait-for-device booted=