diff --git a/test-apps/android-test-app/alarm-test-lib.sh b/test-apps/android-test-app/alarm-test-lib.sh index ae590c3..7f59ccf 100644 --- a/test-apps/android-test-app/alarm-test-lib.sh +++ b/test-apps/android-test-app/alarm-test-lib.sh @@ -12,6 +12,12 @@ # # Configuration can be overridden before sourcing: # APP_ID="custom.package" source "${SCRIPT_DIR}/alarm-test-lib.sh" +# +# STRICT MODE NOTE: +# This library does NOT set strict mode itself (set -euo pipefail) because +# it's a library file. Scripts that source this library SHOULD set strict mode: +# set -euo pipefail +# IFS=$'\n\t' # --- Config Defaults (can be overridden before sourcing) --- @@ -27,6 +33,13 @@ : "${SCREENSHOT_ROOT:=screenshots}" : "${ENABLE_SCREENSHOTS:=1}" +# Run folder configuration (P1) +: "${RUN_ID:=$(date '+%Y%m%d_%H%M%S' 2>/dev/null || echo 'unknown')}" +: "${RUN_DIR:=runs/${RUN_ID}}" + +# Release gating configuration (P4) +: "${RELEASE_GATE_PHASE3:=0}" + # Derived config (for backward compatibility with Phase 1) PACKAGE="${APP_ID}" ACTIVITY="${APP_ID}/.MainActivity" @@ -38,7 +51,11 @@ YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color -# --- UI/Log Helpers --- +# ======================================== +# PUBLIC API - UI/Log Helpers +# ======================================== +# These are the primary functions that all scripts should use. +# Deprecated functions (print_*, wait_for_*) are kept for backward compatibility. section() { echo @@ -84,8 +101,54 @@ ui_prompt() { echo } -# Phase 1 compatibility aliases (print_* functions) +# ======================================== +# PUBLIC API - Command Execution Helpers +# ======================================== + +run_cmd() { + # Execute a command and capture output + # Usage: run_cmd "description" command [args...] + # Returns: exit code of command + local desc="$1" + shift + local cmd=("$@") + + info "Running: $desc" + if "${cmd[@]}"; then + ok "$desc completed" + return 0 + else + local exit_code=$? + error "$desc failed (exit code: $exit_code)" + return $exit_code + fi +} + +require_cmd() { + # Execute a command and exit on failure + # Usage: require_cmd "description" command [args...] + # Exits script if command fails + local desc="$1" + shift + local cmd=("$@") + + info "Required: $desc" + if ! "${cmd[@]}"; then + local exit_code=$? + error "$desc failed (exit code: $exit_code)" + exit $exit_code + fi + ok "$desc completed" +} + +# ======================================== +# DEPRECATED - Phase 1 Compatibility Aliases +# ======================================== +# These functions are kept for backward compatibility but should not be used +# in new code. Use the public API functions above instead. + print_header() { + # DEPRECATED: Use section() instead echo "" echo -e "${BLUE}========================================${NC}" echo -e "${BLUE}$1${NC}" @@ -94,36 +157,44 @@ print_header() { } print_step() { + # DEPRECATED: Use substep() instead echo -e "${GREEN}→ Step $1:${NC} $2" } print_wait() { + # DEPRECATED: Use info() or warn() instead echo -e "${YELLOW}⏳ $1${NC}" } print_success() { + # DEPRECATED: Use ok() instead echo -e "${GREEN}✅ $1${NC}" } print_error() { + # DEPRECATED: Use error() instead echo -e "${RED}❌ $1${NC}" } print_info() { + # DEPRECATED: Use info() instead echo -e "${BLUE}ℹ️ $1${NC}" } print_warn() { + # DEPRECATED: Use warn() instead echo -e "${YELLOW}⚠️ $1${NC}" } wait_for_user() { + # DEPRECATED: Use pause() instead echo "" read -p "Press Enter when ready to continue..." echo "" } wait_for_ui_action() { + # DEPRECATED: Use ui_prompt() instead ui_prompt "$1" } @@ -611,3 +682,257 @@ should_run_test() { return 1 } +# ======================================== +# PUBLIC API - Run Folder & Evidence Helpers (P1) +# ======================================== + +ensure_run_dir() { + # Create run directory structure if it doesn't exist + # Creates: RUN_DIR/logs, RUN_DIR/alarms, RUN_DIR/screens, RUN_DIR/notes + # Returns: 0 on success, 1 on failure + local base_dir + if [ -n "$SCRIPT_DIR" ] && [ -d "$SCRIPT_DIR" ]; then + base_dir="${SCRIPT_DIR}/${RUN_DIR}" + elif [ -n "${BASH_SOURCE[0]}" ]; then + local lib_dir + lib_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd 2>/dev/null)" || lib_dir="" + if [ -n "$lib_dir" ]; then + base_dir="${lib_dir}/${RUN_DIR}" + else + base_dir="${RUN_DIR}" + fi + else + base_dir="${RUN_DIR}" + fi + + mkdir -p "${base_dir}/logs" "${base_dir}/alarms" "${base_dir}/screens" "${base_dir}/notes" 2>/dev/null || { + error "Failed to create run directory: ${base_dir}" + return 1 + } + + # Export for use by capture functions + export RUN_DIR_ABS="${base_dir}" + return 0 +} + +get_run_dir() { + # Get absolute path to current run directory + # Returns: absolute path, or empty string if not initialized + echo "${RUN_DIR_ABS:-}" +} + +capture_alarms() { + # Capture AlarmManager dump to run folder + # Usage: capture_alarms "