Files
daily-notification-plugin/test-apps/android-test-app/test-phase3.sh
Matthew Raymer f6df9e13fb feat: add operator console and wire test scripts with event emission
- Add TestEventsPlugin for receiving ADB broadcast intents
- Create operator console UI (console/index.html, console.css, console.js)
- Add test plan structure (plan.json) with phases, tests, and steps
- Wire all test scripts (phase1, phase2, phase3) with step context and events
- Add event emission helpers to alarm-test-lib.sh (step_start, step_pass, etc.)
- Update test-phase1.sh with comprehensive prerequisite verification
- Register TestEventsPlugin in capacitor.plugins.json
- Add console documentation (CONSOLE-USAGE.md, CONSOLE-REMAINING-WORK.md)
- Add test implementation alignment tracking (TEST-IMPLEMENTATION-ALIGNMENT.md)

This enables real-time test progress tracking via structured events
from shell scripts to the operator console UI.
2025-12-29 09:37:12 +00:00

726 lines
25 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
# ========================================
# Phase 3 Testing Script Boot Recovery
# ========================================
# Source shared library
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/alarm-test-lib.sh"
# Initialize run directory (P1)
ensure_run_dir || {
error "Failed to initialize run directory"
exit 1
}
# Phase 3 specific configuration
# Log tags / patterns (matched to actual ReactivationManager logs)
BOOT_SCENARIO_VALUE="BOOT"
NONE_SCENARIO_VALUE="NONE"
# Release gating config (P4.1)
# 0 = advisory mode (default): failures become warnings, continue
# 1 = release-blocking mode: failures exit with nonzero
: "${RELEASE_GATE_PHASE3:=0}"
# Allow selecting specific tests on the command line (e.g. ./test-phase3.sh 1 3)
SELECTED_TESTS=()
# Phase 3 specific: override extract_scenario_from_logs to handle boot recovery
extract_scenario_from_logs() {
local logs="$1"
local scen
# Looks for "Detected scenario: BOOT" or "Starting boot recovery" format
if echo "$logs" | grep -qi "Starting boot recovery\|boot recovery"; then
echo "$BOOT_SCENARIO_VALUE"
else
# Use shared library function as fallback
scen="$(grep -oE "${SCENARIO_KEY}[A-Z_]+" <<<"$logs" | tail -n1 | sed "s/${SCENARIO_KEY}//" || true)"
echo "$scen"
fi
}
# ------------------------------------------------------------------------------
# TEST 1 Boot with Future Alarms
# ------------------------------------------------------------------------------
test1_boot_future_alarms() {
section "TEST 1: Boot with Future Alarms"
# Set test context
set_test_context "phase3" "phase3_test1" ""
info "Purpose: Verify alarms are recreated on boot when schedules have future run times."
info "Expected time: 2-3 minutes (includes 30-60s reboot)"
info "Automatable: Partial (requires manual reboot confirmation)"
info "If you see: 'Boot recovery not detected' → Check boot receiver registration and BOOT_COMPLETED permission"
echo ""
pause
# Capture initial state
set_test_context "phase3" "phase3_test1" "p3_t1_s1"
step_start "p3_t1_s1" "Launch app & check plugin status"
capture_alarms "phase3_test1_initial"
capture_logcat "phase3_test1_initial" "DNP" 50
substep "Step 1: Launch app & check plugin status"
launch_app
ui_prompt "1) In the app UI, verify plugin status:
⚙️ Plugin Settings: ✅ Configured
🔌 Native Fetcher: ✅ Configured
If either shows ❌ or 'Not configured', click 'Configure Plugin', wait until both are ✅, then press Enter."
ui_prompt "2) Now schedule at least one future notification (e.g., click 'Test Notification' to schedule for a few minutes in the future)."
step_pass "p3_t1_s1" "Plugin configured and notification scheduled"
# Capture before reboot state
capture_alarms "phase3_test1_before_reboot"
substep "Step 2: Verify alarms are scheduled"
set_test_context "phase3" "phase3_test1" "p3_t1_s2"
step_start "p3_t1_s2" "Verify alarms scheduled"
show_alarms
local before_count system_before
before_count="$(get_plugin_alarm_count)"
system_before="$(get_system_alarm_count)"
info "Plugin alarms before reboot: $before_count (expected: 1)"
info "System/other alarms: $system_before (for context)"
if [[ "$before_count" -eq 0 ]]; then
warn "No plugin alarms found before reboot; TEST 1 may not be meaningful."
step_warn "p3_t1_s2" "No alarms found"
elif [[ "$before_count" -eq 1 ]]; then
ok "Single plugin alarm confirmed (one per day)"
step_pass "p3_t1_s2" "Alarms verified"
else
warn "Found $before_count plugin alarms (expected: 1)"
step_warn "p3_t1_s2" "Unexpected alarm count"
fi
pause
substep "Step 3: Reboot emulator"
set_test_context "phase3" "phase3_test1" "p3_t1_s3"
step_start "p3_t1_s3" "Reboot emulator"
warn "The emulator will reboot now. This will take 30-60 seconds."
pause
reboot_emulator
step_pass "p3_t1_s3" "Emulator rebooted"
substep "Step 4: Collect boot recovery logs"
set_test_context "phase3" "phase3_test1" "p3_t1_s4"
step_start "p3_t1_s4" "Collect boot recovery logs"
info "Collecting recovery logs from boot..."
sleep 2 # Give recovery a moment to complete
# Capture after reboot state
capture_alarms "phase3_test1_after_reboot"
capture_logcat "phase3_test1_after_reboot" "DNP-REACTIVATION" 250
capture_screenshot "phase3_test1_after_reboot"
local logs
logs="$(get_recovery_logs)"
echo "$logs"
local missed rescheduled verified errors scenario
missed="$(extract_field_from_logs "$logs" "missed")"
rescheduled="$(extract_field_from_logs "$logs" "rescheduled")"
verified="$(extract_field_from_logs "$logs" "verified")"
errors="$(extract_field_from_logs "$logs" "errors")"
scenario="$(extract_scenario_from_logs "$logs")"
echo
info "Parsed recovery summary:"
echo " scenario = ${scenario:-<none>}"
echo " missed = ${missed}"
echo " rescheduled= ${rescheduled}"
echo " verified = ${verified}"
echo " errors = ${errors}"
echo
# Determine verdict
local test1_passed=false
local test1_message=""
if [[ "$errors" -gt 0 ]]; then
error "Recovery reported errors>0 (errors=$errors)"
test1_message="Recovery reported errors (errors=$errors)"
fi
if [[ "$scenario" == "$BOOT_SCENARIO_VALUE" && "$rescheduled" -gt 0 ]]; then
ok "TEST 1 PASSED: Boot recovery detected and alarms rescheduled (scenario=$scenario, rescheduled=$rescheduled)."
test1_passed=true
test1_message="Boot recovery detected and alarms rescheduled (scenario=$scenario, rescheduled=$rescheduled)"
elif echo "$logs" | grep -qi "Starting boot recovery\|boot recovery"; then
if [[ "$rescheduled" -gt 0 ]]; then
ok "TEST 1 PASSED: Boot recovery ran and alarms rescheduled (rescheduled=$rescheduled)."
test1_passed=true
test1_message="Boot recovery ran and alarms rescheduled (rescheduled=$rescheduled)"
else
test1_message="Boot recovery ran but rescheduled=0. Check implementation or logs."
fi
else
test1_message="Boot recovery not clearly detected. Review logs and boot receiver implementation (scenario=${scenario:-<none>}, rescheduled=$rescheduled)"
fi
substep "Step 5: Verify alarms were recreated"
show_alarms
local after_count system_after
after_count="$(get_plugin_alarm_count)"
system_after="$(get_system_alarm_count)"
info "Plugin alarms after boot: $after_count (expected: 1)"
info "System/other alarms: $system_after (for context)"
if [[ "$after_count" -eq 0 && "$test1_passed" == "true" ]]; then
warn "Alarms were not recreated despite recovery success. Check alarm scheduling logic."
test1_message="Boot recovery succeeded but alarms not recreated (rescheduled=$rescheduled, after_count=$after_count)"
test1_passed=false
step_fail "p3_t1_s4" "Alarms not recreated"
elif [[ "$after_count" -gt 0 && "$test1_passed" == "true" ]]; then
ok "Alarms successfully recreated after boot (after_count=$after_count)"
step_pass "p3_t1_s4" "Boot recovery successful"
else
step_fail "p3_t1_s4" "Boot recovery failed"
fi
# Emit verdict
set_test_context "phase3" "phase3_test1" "p3_t1_s5"
if [[ "$test1_passed" == "true" ]]; then
verdict_pass "phase3_test1_boot_future_alarms" "$test1_message"
else
verdict_fail "phase3_test1_boot_future_alarms" "$test1_message"
fi
evidence_block "phase3_test1_boot_future_alarms"
}
# ------------------------------------------------------------------------------
# TEST 2 Boot with Past Alarms
# ------------------------------------------------------------------------------
test2_boot_past_alarms() {
section "TEST 2: Boot with Past Alarms"
# Set test context
set_test_context "phase3" "phase3_test2" ""
info "Purpose: Verify missed alarms are detected and next occurrence is scheduled on boot."
info "Expected time: 5-6 minutes (includes 3min wait + 30-60s reboot)"
info "Automatable: Partial (requires manual time advancement or wait)"
info "If you see: 'No missed alarms detected' → Verify alarm time actually passed before reboot"
info "Automation hint: Use 'adb shell date' to check current time, advance if needed"
echo ""
pause
# Capture initial state
set_test_context "phase3" "phase3_test2" "p3_t2_s1"
step_start "p3_t2_s1" "Schedule notification for past time"
capture_alarms "phase3_test2_initial"
capture_logcat "phase3_test2_initial" "DNP" 50
substep "Step 1: Launch app & ensure plugin configured"
launch_app
ui_prompt "1) In the app UI, verify plugin status:
⚙️ Plugin Settings: ✅ Configured
🔌 Native Fetcher: ✅ Configured
If needed, click 'Configure Plugin', then press Enter."
ui_prompt "2) Click 'Test Notification' to schedule a notification for 2 minutes in the future.
After scheduling, we'll wait for the alarm time to pass, then reboot."
step_pass "p3_t2_s1" "Notification scheduled"
# Capture before wait state
capture_alarms "phase3_test2_before_wait"
substep "Step 2: Wait for alarm time to pass"
set_test_context "phase3" "phase3_test2" "p3_t2_s2"
step_start "p3_t2_s2" "Wait for alarm time to pass"
info "Waiting 3 minutes for scheduled alarm time to pass..."
warn "You can manually advance system time if needed (requires root/emulator)"
sleep 180 # Wait 3 minutes
step_pass "p3_t2_s2" "Alarm time passed"
# Capture after wait state
capture_alarms "phase3_test2_after_wait"
substep "Step 3: Verify alarm time has passed"
set_test_context "phase3" "phase3_test2" "p3_t2_s3"
step_start "p3_t2_s3" "Reboot emulator"
info "Alarm time should now be in the past"
show_alarms
pause
substep "Step 4: Reboot emulator"
warn "The emulator will reboot now. This will take 30-60 seconds."
pause
reboot_emulator
step_pass "p3_t2_s3" "Emulator rebooted"
substep "Step 5: Collect boot recovery logs"
set_test_context "phase3" "phase3_test2" "p3_t2_s4"
step_start "p3_t2_s4" "Collect boot recovery logs"
info "Collecting recovery logs from boot..."
sleep 2
# Capture after reboot state
capture_alarms "phase3_test2_after_reboot"
capture_logcat "phase3_test2_after_reboot" "DNP-REACTIVATION" 250
capture_screenshot "phase3_test2_after_reboot"
local logs
logs="$(get_recovery_logs)"
echo "$logs"
local missed rescheduled verified errors scenario
# For TEST 2, we need the FIRST entry (which has missed count) not the last
# Boot recovery runs twice (LOCKED_BOOT_COMPLETED and BOOT_COMPLETED)
# First run marks missed alarms, second run only reschedules (missed=0)
missed="$(echo "$logs" | grep -E "missed=" | sed -E "s/.*missed=([0-9]+).*/\1/" | head -n1 || echo "0")"
rescheduled="$(extract_field_from_logs "$logs" "rescheduled")"
verified="$(extract_field_from_logs "$logs" "verified")"
errors="$(extract_field_from_logs "$logs" "errors")"
scenario="$(extract_scenario_from_logs "$logs")"
echo
info "Parsed recovery summary:"
echo " scenario = ${scenario:-<none>}"
echo " missed = ${missed}"
echo " rescheduled= ${rescheduled}"
echo " verified = ${verified}"
echo " errors = ${errors}"
echo
# Determine verdict
local test2_passed=false
local test2_message=""
if [[ "$errors" -gt 0 ]]; then
error "Recovery reported errors>0 (errors=$errors)"
test2_message="Recovery reported errors (errors=$errors)"
fi
if [[ "$missed" -ge 1 && "$rescheduled" -ge 1 ]]; then
ok "TEST 2 PASSED: Past alarms detected and next occurrence scheduled (missed=$missed, rescheduled=$rescheduled)."
test2_passed=true
test2_message="Past alarms detected and next occurrence scheduled (missed=$missed, rescheduled=$rescheduled)"
elif [[ "$missed" -ge 1 ]]; then
test2_message="Past alarms detected (missed=$missed) but rescheduled=$rescheduled. Check reschedule logic."
else
test2_message="No missed alarms detected. Verify alarm time actually passed before reboot (missed=$missed, rescheduled=$rescheduled)"
fi
if [[ "$test2_passed" == "true" ]]; then
step_pass "p3_t2_s4" "Past alarms detected and rescheduled"
else
step_fail "p3_t2_s4" "Past alarms not detected"
fi
# Emit verdict
set_test_context "phase3" "phase3_test2" "p3_t2_s5"
if [[ "$test2_passed" == "true" ]]; then
verdict_pass "phase3_test2_boot_past_alarms" "$test2_message"
else
verdict_fail "phase3_test2_boot_past_alarms" "$test2_message"
fi
evidence_block "phase3_test2_boot_past_alarms"
}
# ------------------------------------------------------------------------------
# TEST 3 Boot with No Schedules
# ------------------------------------------------------------------------------
test3_boot_no_schedules() {
section "TEST 3: Boot with No Schedules"
# Set test context
set_test_context "phase3" "phase3_test3" ""
info "Purpose: Verify boot recovery handles empty database gracefully."
info "Expected time: 2-3 minutes (includes 30-60s reboot)"
info "Automatable: Yes"
info "If you see: 'rescheduled>0 on first launch' → Check that boot recovery isn't misfiring"
echo ""
pause
# Capture initial state (before uninstall)
set_test_context "phase3" "phase3_test3" "p3_t3_s1"
step_start "p3_t3_s1" "Fresh install"
capture_alarms "phase3_test3_initial"
substep "Step 1: Uninstall app to clear DB/state"
set +e
$ADB_BIN uninstall "$APP_ID" >/dev/null 2>&1
set -e
ok "App uninstalled (state cleared)"
substep "Step 2: Reinstall app"
if $ADB_BIN install -r "$APK_PATH"; then
ok "App installed"
step_pass "p3_t3_s1" "Fresh install complete"
else
error "Reinstall failed"
step_fail "p3_t3_s1" "Reinstall failed"
exit 1
fi
info "Clearing logcat..."
clear_logs
ok "Logs cleared"
pause
substep "Step 3: Reboot emulator WITHOUT scheduling anything"
set_test_context "phase3" "phase3_test3" "p3_t3_s2"
step_start "p3_t3_s2" "Reboot without schedules"
warn "Do NOT schedule any notifications. The app should have no schedules in the database."
warn "The emulator will reboot now. This will take 30-60 seconds."
pause
reboot_emulator
step_pass "p3_t3_s2" "Emulator rebooted"
substep "Step 4: Collect boot recovery logs"
set_test_context "phase3" "phase3_test3" "p3_t3_s3"
step_start "p3_t3_s3" "Verify no recovery ran"
info "Collecting recovery logs from boot..."
sleep 2
# Capture after reboot state
capture_alarms "phase3_test3_after_reboot"
capture_logcat "phase3_test3_after_reboot" "DNP-REACTIVATION" 250
capture_screenshot "phase3_test3_after_reboot"
local logs
logs="$(get_recovery_logs)"
echo "$logs"
local scenario rescheduled missed
scenario="$(extract_scenario_from_logs "$logs")"
rescheduled="$(extract_field_from_logs "$logs" "rescheduled")"
missed="$(extract_field_from_logs "$logs" "missed")"
echo
info "Parsed recovery summary:"
echo " scenario = ${scenario:-<none>}"
echo " rescheduled= ${rescheduled}"
echo " missed = ${missed}"
echo
# Determine verdict
local test3_passed=false
local test3_message=""
if [[ -z "$logs" ]]; then
ok "TEST 3 PASSED: No recovery logs when there are no schedules (safe behavior)."
test3_passed=true
test3_message="No recovery logs when there are no schedules (safe behavior)"
elif echo "$logs" | grep -qiE "No schedules found|No schedules present"; then
ok "TEST 3 PASSED: Explicit 'No schedules found' message logged with no rescheduling."
test3_passed=true
test3_message="Explicit 'No schedules found' message logged with no rescheduling"
elif [[ "$scenario" == "$NONE_SCENARIO_VALUE" && "$rescheduled" -eq 0 ]]; then
ok "TEST 3 PASSED: NONE scenario detected with no rescheduling."
test3_passed=true
test3_message="NONE scenario detected with no rescheduling (scenario=$scenario, rescheduled=$rescheduled)"
elif [[ "$rescheduled" -gt 0 ]]; then
test3_message="rescheduled>0 on first launch / empty DB. Check that boot recovery isn't misfiring (rescheduled=$rescheduled)"
else
test3_passed=true # Not a failure, just needs review
test3_message="Logs present but no rescheduling; review scenario handling to ensure it's explicit about NONE / NO_SCHEDULES (scenario=${scenario:-<none>}, rescheduled=$rescheduled)"
fi
if [[ "$test3_passed" == "true" ]]; then
step_pass "p3_t3_s3" "No recovery ran (correct)"
else
step_fail "p3_t3_s3" "Recovery ran when it shouldn't"
fi
# Emit verdict
set_test_context "phase3" "phase3_test3" "p3_t3_s4"
if [[ "$test3_passed" == "true" ]]; then
verdict_pass "phase3_test3_boot_no_schedules" "$test3_message"
else
verdict_fail "phase3_test3_boot_no_schedules" "$test3_message"
fi
evidence_block "phase3_test3_boot_no_schedules"
}
# ------------------------------------------------------------------------------
# TEST 4 Silent Boot Recovery (App Never Opened)
# ------------------------------------------------------------------------------
test4_silent_boot_recovery() {
section "TEST 4: Silent Boot Recovery (App Never Opened)"
# Set test context
set_test_context "phase3" "phase3_test4" ""
info "Purpose: Verify boot recovery occurs even when the app is never opened after reboot."
info "Expected time: 2-3 minutes (includes 30-60s reboot)"
info "Automatable: Partial (requires manual verification that app was not opened)"
info "If you see: 'Boot recovery not detected' → Verify boot receiver is registered and has BOOT_COMPLETED permission"
echo ""
pause
# Capture initial state
set_test_context "phase3" "phase3_test4" "p3_t4_s1"
step_start "p3_t4_s1" "Schedule notification"
capture_alarms "phase3_test4_initial"
capture_logcat "phase3_test4_initial" "DNP" 50
substep "Step 1: Launch app & ensure plugin configured"
launch_app
ui_prompt "1) In the app UI, verify plugin status:
⚙️ Plugin Settings: ✅ Configured
🔌 Native Fetcher: ✅ Configured
If needed, click 'Configure Plugin', then press Enter."
ui_prompt "2) Click 'Test Notification' to schedule a notification for a few minutes in the future."
step_pass "p3_t4_s1" "Notification scheduled"
# Capture before reboot state
capture_alarms "phase3_test4_before_reboot"
substep "Step 2: Verify alarms are scheduled"
set_test_context "phase3" "phase3_test4" "p3_t4_s2"
step_start "p3_t4_s2" "Reboot without opening app"
show_alarms
local before_count system_before
before_count="$(get_plugin_alarm_count)"
system_before="$(get_system_alarm_count)"
info "Plugin alarms before reboot: $before_count (expected: 1)"
info "System/other alarms: $system_before (for context)"
if [[ "$before_count" -eq 0 ]]; then
warn "No plugin alarms found; TEST 4 may not be meaningful."
step_warn "p3_t4_s2" "No alarms found"
elif [[ "$before_count" -eq 1 ]]; then
ok "Single plugin alarm confirmed (one per day)"
step_pass "p3_t4_s2" "Alarms verified"
else
warn "Found $before_count plugin alarms (expected: 1)"
step_warn "p3_t4_s2" "Unexpected alarm count"
fi
pause
substep "Step 3: Reboot emulator (DO NOT open app after reboot)"
warn "IMPORTANT: After reboot, DO NOT open the app. Boot recovery should run silently."
warn "The emulator will reboot now. This will take 30-60 seconds."
pause
reboot_emulator
step_pass "p3_t4_s2" "Emulator rebooted (app not opened)"
substep "Step 4: Collect boot recovery logs (without opening app)"
set_test_context "phase3" "phase3_test4" "p3_t4_s3"
step_start "p3_t4_s3" "Collect boot recovery logs"
info "Collecting recovery logs from boot (app was NOT opened)..."
sleep 2
# Capture after reboot state (without opening app)
capture_alarms "phase3_test4_after_reboot"
capture_logcat "phase3_test4_after_reboot" "DNP-REACTIVATION" 250
capture_screenshot "phase3_test4_after_reboot"
local logs
logs="$(get_recovery_logs)"
echo "$logs"
local missed rescheduled verified errors scenario
missed="$(extract_field_from_logs "$logs" "missed")"
rescheduled="$(extract_field_from_logs "$logs" "rescheduled")"
verified="$(extract_field_from_logs "$logs" "verified")"
errors="$(extract_field_from_logs "$logs" "errors")"
scenario="$(extract_scenario_from_logs "$logs")"
echo
info "Parsed recovery summary:"
echo " scenario = ${scenario:-<none>}"
echo " missed = ${missed}"
echo " rescheduled= ${rescheduled}"
echo " verified = ${verified}"
echo " errors = ${errors}"
echo
substep "Step 5: Verify alarms were recreated (without opening app)"
show_alarms
local after_count system_after
after_count="$(get_plugin_alarm_count)"
system_after="$(get_system_alarm_count)"
info "Plugin alarms after boot (app never opened): $after_count (expected: 1)"
info "System/other alarms: $system_after (for context)"
# Determine verdict
local test4_passed=false
local test4_message=""
if [[ "$errors" -gt 0 ]]; then
error "Recovery reported errors>0 (errors=$errors)"
test4_message="Recovery reported errors (errors=$errors)"
fi
if [[ "$after_count" -gt 0 && "$rescheduled" -gt 0 ]]; then
ok "TEST 4 PASSED: Boot recovery occurred silently and alarms were recreated (rescheduled=$rescheduled) without app launch."
test4_passed=true
test4_message="Boot recovery occurred silently and alarms were recreated (rescheduled=$rescheduled, after_count=$after_count) without app launch"
elif [[ "$rescheduled" -gt 0 ]]; then
ok "TEST 4 PASSED: Boot recovery occurred silently (rescheduled=$rescheduled), but alarm count check unclear."
test4_passed=true
test4_message="Boot recovery occurred silently (rescheduled=$rescheduled), but alarm count unclear (after_count=$after_count)"
elif echo "$logs" | grep -qi "Starting boot recovery\|boot recovery"; then
test4_message="Boot recovery ran but alarms may not have been recreated. Check logs and implementation (rescheduled=$rescheduled, after_count=$after_count)"
else
test4_message="Boot recovery not detected. Verify boot receiver is registered and has BOOT_COMPLETED permission (scenario=${scenario:-<none>}, rescheduled=$rescheduled)"
fi
if [[ "$test4_passed" == "true" ]]; then
step_pass "p3_t4_s3" "Silent boot recovery successful"
else
step_fail "p3_t4_s3" "Silent boot recovery failed"
fi
# Emit verdict
set_test_context "phase3" "phase3_test4" "p3_t4_s4"
if [[ "$test4_passed" == "true" ]]; then
verdict_pass "phase3_test4_silent_boot_recovery" "$test4_message"
else
verdict_fail "phase3_test4_silent_boot_recovery" "$test4_message"
fi
evidence_block "phase3_test4_silent_boot_recovery"
}
# ------------------------------------------------------------------------------
# Main
# ------------------------------------------------------------------------------
main() {
# Parse CLI args for --gate-phase3 flag
local gate_phase3=0
local test_args=()
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
echo "Usage: $0 [--gate-phase3] [TEST_IDS...]"
echo
echo "If no TEST_IDS are given, all tests (1, 2, 3, 4) will run."
echo
echo "Options:"
echo " --gate-phase3 Enable release gating (failures exit with non-zero)"
echo " Equivalent to: RELEASE_GATE_PHASE3=1 $0"
echo
echo "Environment:"
echo " RELEASE_GATE_PHASE3=0|1 Release gating mode (default: 0)"
echo " 0 = advisory (warn and continue)"
echo " 1 = release-blocking (fail and exit)"
echo
echo "Examples:"
echo " $0 # run all tests (advisory mode)"
echo " $0 1 # run only TEST 1 (advisory mode)"
echo " $0 --gate-phase3 # run all tests (release-blocking mode)"
echo " $0 --gate-phase3 2 3 # run TEST 2 and 3 (release-blocking mode)"
echo " RELEASE_GATE_PHASE3=1 $0 # same as --gate-phase3"
return 0
;;
--gate-phase3)
gate_phase3=1
shift
;;
*)
test_args+=("$1")
shift
;;
esac
done
# Set RELEASE_GATE_PHASE3 if flag was provided
if [[ "$gate_phase3" -eq 1 ]]; then
RELEASE_GATE_PHASE3=1
fi
SELECTED_TESTS=("${test_args[@]}")
section "Phase 3 Testing Script Boot Recovery"
info "Mode: ${RELEASE_GATE_PHASE3:-0} (0=advisory, 1=release-blocking)"
info "Run ID: ${RUN_ID}"
info "Evidence directory: $(get_run_dir)"
echo ""
info "This script will guide you through Phase 3 tests."
info "You'll be prompted when UI interaction is needed."
echo ""
warn "⚠️ WARNING: This script will reboot the emulator multiple times."
info " Each reboot takes 30-60 seconds."
echo ""
pause
require_adb_device
build_app
install_app
if should_run_test "1" SELECTED_TESTS; then
test1_boot_future_alarms
pause
fi
if should_run_test "2" SELECTED_TESTS; then
test2_boot_past_alarms
pause
fi
if should_run_test "3" SELECTED_TESTS; then
test3_boot_no_schedules
pause
fi
if should_run_test "4" SELECTED_TESTS; then
test4_silent_boot_recovery
fi
section "Testing Complete"
info "Test Results Summary:"
echo ""
echo "All test verdicts are shown above with evidence locations."
echo "Review evidence in: $(get_run_dir)"
echo ""
echo "Release gating mode: ${RELEASE_GATE_PHASE3:-0}"
echo " - 0 (advisory): Failures become warnings, script continues"
echo " - 1 (release-blocking): Failures cause script to exit with non-zero"
echo ""
ok "Phase 3 testing script complete!"
echo ""
echo "Next steps:"
echo " - Review evidence in: $(get_run_dir)"
echo " - Verify all test verdicts above"
echo " - Update documentation with test results"
echo ""
}
main "$@"