#!/usr/bin/env bash # test_platforms.sh # # Builds the app, runs it in each platform emulator, drives a full # interaction sequence via the QEMU monitor, and compares screenshots # against stored baselines. # # Usage: # ./tests/test_platforms.sh # compare against baselines # ./tests/test_platforms.sh --update # overwrite baselines with current output # # Requirements: pebble SDK on PATH, python3 set -euo pipefail REPO="$(cd "$(dirname "$0")/.." && pwd)" TESTS="$REPO/tests" BASELINES="$TESTS/baselines" SHOTS="$TESTS/screenshots" PLATFORMS=(basalt chalk diorite emery flint gabbro) # `pebble install` starts the emulator, waits for boot, installs, then exits. # 120 s covers even a first-ever cold start. INSTALL_TIMEOUT=120 # Seconds to wait after install for the app to fully render before testing. RENDER_WAIT=4 UPDATE_FLAG="" if [[ "${1:-}" == "--update" ]]; then UPDATE_FLAG="--update" fi # ── Helpers ─────────────────────────────────────────────────────────────────── log() { echo " $*"; } pass() { echo " ✓ $*"; } fail() { echo " ✗ $*"; FAILURES+=("$*"); } kill_emulators() { pebble kill --force 2>/dev/null || true sleep 1 } # ── Build ───────────────────────────────────────────────────────────────────── echo "" echo "═══════════════════════════════════════════" echo " Golf Score — platform test suite" echo "═══════════════════════════════════════════" echo "" echo "Building..." cd "$REPO" pebble build 2>&1 | tail -3 echo "" mkdir -p "$SHOTS" "$BASELINES" FAILURES=() # ── Per-platform loop ───────────────────────────────────────────────────────── for PLATFORM in "${PLATFORMS[@]}"; do echo "── $PLATFORM ─────────────────────────────────" INSTALL_LOG="$SHOTS/${PLATFORM}_install.log" kill_emulators # Install — runs foreground (no --logs, no --vnc). # pebble install starts the emulator, waits for boot, installs, then exits. # The QEMU monitor port is written to /tmp/pb-emulator.json during startup. log "Installing (timeout ${INSTALL_TIMEOUT}s)..." if timeout "$INSTALL_TIMEOUT" \ pebble install --emulator "$PLATFORM" "$REPO/build/golf_score.pbw" \ > "$INSTALL_LOG" 2>&1; then pass "Installed" else EXIT=$? MSG="install failed (exit $EXIT)" [[ $EXIT -eq 124 ]] && MSG="install timed out after ${INSTALL_TIMEOUT}s" fail "$PLATFORM: $MSG — see $INSTALL_LOG" kill_emulators continue fi log "Waiting ${RENDER_WAIT}s for initial render..." sleep "$RENDER_WAIT" # Run the full interaction + screenshot sequence log "Running UI test sequence..." UI_EXIT=0 python3 "$TESTS/run_ui_test.py" \ "$PLATFORM" "$SHOTS" "$BASELINES" $UPDATE_FLAG || UI_EXIT=$? if [[ $UI_EXIT -eq 0 ]]; then if [[ -n "$UPDATE_FLAG" ]]; then pass "Baselines updated" else pass "All steps passed" fi elif [[ $UI_EXIT -eq 2 ]]; then fail "$PLATFORM: UI test setup error (monitor connection?)" else fail "$PLATFORM: one or more UI steps failed" fi kill_emulators echo "" done # ── Summary ─────────────────────────────────────────────────────────────────── echo "═══════════════════════════════════════════" if [[ ${#FAILURES[@]} -eq 0 ]]; then echo " All platforms passed" echo "═══════════════════════════════════════════" exit 0 else echo " ${#FAILURES[@]} failure(s):" for F in "${FAILURES[@]}"; do echo " ✗ $F"; done echo "═══════════════════════════════════════════" exit 1 fi