|
| 1 | +#!/bin/bash |
| 2 | +# run-tests-ci-android.sh - CI-only script for running Android E2E tests. |
| 3 | +# |
| 4 | +# Designed to run inside reactivecircus/android-emulator-runner's `script` context |
| 5 | +# where the emulator is already booted. Builds the app, installs it, and runs |
| 6 | +# maestro tests. |
| 7 | +# |
| 8 | +# The emulator serial is passed via EMULATOR_SERIAL (defaults to emulator-5554). |
| 9 | + |
| 10 | +set -euo pipefail |
| 11 | + |
| 12 | +SERIAL="${EMULATOR_SERIAL:-emulator-5554}" |
| 13 | + |
| 14 | +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" |
| 15 | +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" |
| 16 | +MAESTRO_ROOT="$REPO_ROOT/.maestro" |
| 17 | +SCREENSHOT_ROOT="$MAESTRO_ROOT" |
| 18 | +BUNDLE_ID="swmansion.enriched.example" |
| 19 | + |
| 20 | +DEFAULT_MAESTRO_RUNNER="$HOME/.maestro-runner/bin/maestro-runner" |
| 21 | +if [ -n "${MAESTRO_RUNNER:-}" ]; then |
| 22 | + MAESTRO_BIN="$MAESTRO_RUNNER" |
| 23 | +elif [ -x "$DEFAULT_MAESTRO_RUNNER" ]; then |
| 24 | + MAESTRO_BIN="$DEFAULT_MAESTRO_RUNNER" |
| 25 | +elif command -v maestro-runner >/dev/null 2>&1; then |
| 26 | + MAESTRO_BIN="$(command -v maestro-runner)" |
| 27 | +else |
| 28 | + echo "Error: maestro-runner not found." >&2 |
| 29 | + exit 1 |
| 30 | +fi |
| 31 | + |
| 32 | +echo "=== Using maestro-runner: $MAESTRO_BIN ===" |
| 33 | +"$MAESTRO_BIN" --version || true |
| 34 | + |
| 35 | +echo "=== Waiting for emulator to be ready ===" |
| 36 | +adb -s "$SERIAL" wait-for-device |
| 37 | +until adb -s "$SERIAL" shell getprop sys.boot_completed 2>/dev/null | grep -q "^1$"; do |
| 38 | + sleep 2 |
| 39 | +done |
| 40 | + |
| 41 | +adb -s "$SERIAL" shell pm disable-user --user 0 com.google.android.inputmethod.latin 2>/dev/null || true |
| 42 | +adb -s "$SERIAL" shell settings put secure spell_checker_enabled 0 |
| 43 | + |
| 44 | +echo "=== Building and installing app ===" |
| 45 | +yarn example android --device "$SERIAL" |
| 46 | + |
| 47 | +set_font_scale() { |
| 48 | + case "$1" in |
| 49 | + default) adb -s "$SERIAL" shell settings put system font_scale 1.0 ;; |
| 50 | + large) adb -s "$SERIAL" shell settings put system font_scale 1.5 ;; |
| 51 | + esac |
| 52 | +} |
| 53 | + |
| 54 | +trap 'set_font_scale default' EXIT |
| 55 | +set_font_scale default |
| 56 | + |
| 57 | +FLOWS=".maestro/enrichedInput/flows .maestro/enrichedText/flows" |
| 58 | +ASSETS_DIR="$MAESTRO_ROOT/assets" |
| 59 | +[ -d "$ASSETS_DIR" ] && FLOWS="$ASSETS_DIR $FLOWS" |
| 60 | + |
| 61 | +EXTRA="--env SCREENSHOT_ROOT=$SCREENSHOT_ROOT --exclude-tags ios-only" |
| 62 | +DRIVER_ARGS="--driver devicelab" |
| 63 | + |
| 64 | +run_maestro() { |
| 65 | + local tmp rc attempt max_attempts=3 |
| 66 | + for attempt in $(seq 1 "$max_attempts"); do |
| 67 | + tmp=$(mktemp) |
| 68 | + local cmd |
| 69 | + # shellcheck disable=SC2086 |
| 70 | + cmd=$(printf '%q ' "$MAESTRO_BIN" --platform android --device "$SERIAL" $DRIVER_ARGS $EXTRA "$@" test $FLOWS) |
| 71 | + script -qec "$cmd" /dev/null 2>&1 | tee "$tmp" |
| 72 | + rc=${PIPESTATUS[0]} |
| 73 | + |
| 74 | + if [ "$rc" -eq 0 ]; then |
| 75 | + rm -f "$tmp" |
| 76 | + return 0 |
| 77 | + fi |
| 78 | + |
| 79 | + if sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\r//g' "$tmp" | grep -Eqi "did not match any [Ff]lows|no flows matched"; then |
| 80 | + echo "warn: no flows matched the tag filter — treating as success" >&2 |
| 81 | + rm -f "$tmp" |
| 82 | + return 0 |
| 83 | + fi |
| 84 | + |
| 85 | + if [ "$attempt" -lt "$max_attempts" ] && sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\r//g' "$tmp" | grep -Eqi 'failed to create driver|driver crashed on startup|DeviceLab driver crashed'; then |
| 86 | + echo "warn: driver crashed on startup (attempt $attempt/$max_attempts), retrying in 10s..." >&2 |
| 87 | + local sock="/tmp/devicelab-driver-${SERIAL}.sock" |
| 88 | + adb -s "$SERIAL" forward --remove "localfilesystem:$sock" 2>/dev/null || true |
| 89 | + adb -s "$SERIAL" shell am force-stop dev.devicelab.driver.android.test 2>/dev/null || true |
| 90 | + sleep 10 |
| 91 | + rm -f "$tmp" |
| 92 | + continue |
| 93 | + fi |
| 94 | + |
| 95 | + rm -f "$tmp" |
| 96 | + return "$rc" |
| 97 | + done |
| 98 | +} |
| 99 | + |
| 100 | +set +e |
| 101 | + |
| 102 | +echo "=== Running maestro tests ===" |
| 103 | +run_maestro --exclude-tags accessibility |
| 104 | +EXIT_REGULAR=$? |
| 105 | + |
| 106 | +echo "=== Running maestro accessibility tests ===" |
| 107 | +set_font_scale large |
| 108 | +run_maestro --include-tags accessibility |
| 109 | +EXIT_A11Y=$? |
| 110 | + |
| 111 | +set -e |
| 112 | + |
| 113 | +exit $(( EXIT_REGULAR != 0 || EXIT_A11Y != 0 )) |
0 commit comments