#!/bin/bash # Round01 main UI automated QA entrypoint. It runs the focused Quick Switch # UI checks serially because several steps rebuild/package the same app. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" OUTPUT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # shellcheck source=build-output-paths.sh source "$SCRIPT_DIR/build-output-paths.sh" SOURCE_ROOT="$OUTPUT_ROOT/C1.source" BUILD_ROOT="$OUTPUT_ROOT/C2.builds" APP="$BUILD_CURRENT_APP" LOCK_DIR="$BUILD_LOCK_ROOT/round1-main-ui-qa.lock" RUN_ID="$(date +%Y%m%d_%H%M%S)" LOG_DIR="${ALIGNER_ROUND1_MAIN_UI_QA_LOG_DIR:-/tmp/aligner-round01-main-ui-qa-$RUN_ID}" LOCK_HELD=0 fail() { echo "Round01 main UI QA failed: $*" >&2 exit 1 } acquire_lock() { mkdir -p "$BUILD_ROOT" if ! mkdir "$LOCK_DIR" 2>/dev/null; then fail "another round1-main-ui-qa.sh appears to be running; run packaging QA scripts serially" fi LOCK_HELD=1 } release_lock() { if [ "$LOCK_HELD" -eq 1 ]; then rmdir "$LOCK_DIR" 2>/dev/null || true LOCK_HELD=0 fi } aligner_pids_for_current_app() { ps -axo pid=,args= | while read -r pid command; do if [[ "$command" == "$APP/Contents/MacOS/Aligner"* ]] \ || [[ "$command" == "/Applications/Aligner.app/Contents/MacOS/Aligner"* ]] \ || [[ "$command" == "$HOME/Applications/Aligner.app/Contents/MacOS/Aligner"* ]]; then echo "$pid" fi done } best_effort_stop_current_aligner() { for pid in $(aligner_pids_for_current_app); do kill "$pid" 2>/dev/null || true done for _ in {1..30}; do [ -z "$(aligner_pids_for_current_app)" ] && return sleep 0.1 done return 1 } stop_current_aligner() { best_effort_stop_current_aligner && return fail "current Aligner app did not exit before QA" } assert_no_current_aligner() { local pids pids="$(aligner_pids_for_current_app)" if [ -n "$pids" ]; then fail "Aligner test process remained after QA: $pids" fi } run_step() { local name="$1" shift local log="$LOG_DIR/$name.log" echo "==> $name" if "$@" >"$log" 2>&1; then echo "PASS $name" else local code="$?" echo "FAIL $name (log: $log)" >&2 tail -c 6000 "$log" >&2 || true exit "$code" fi } cleanup() { best_effort_stop_current_aligner || true release_lock } mkdir -p "$LOG_DIR" acquire_lock trap cleanup EXIT stop_current_aligner run_step swift-test swift test --package-path "$SOURCE_ROOT" run_step trigger-session "$SCRIPT_DIR/round1-trigger-session-qa.sh" run_step session-snapshot "$SCRIPT_DIR/round1-session-snapshot-qa.sh" run_step candidate-filter "$SCRIPT_DIR/round1-candidate-filter-fixture-qa.sh" run_step screenshot-session "$SCRIPT_DIR/round1-screenshot-session-qa.sh" run_step keyboard-navigation "$SCRIPT_DIR/round1-keyboard-navigation-fixture-qa.sh" run_step window-activation "$SCRIPT_DIR/round1-window-activation-fixture-qa.sh" run_step mouse-interaction "$SCRIPT_DIR/round1-mouse-interaction-fixture-qa.sh" run_step app-column-alignment "$SCRIPT_DIR/round1-app-column-alignment-fixture-qa.sh" run_step no-quick-switch-residual swift "$SCRIPT_DIR/window-logic-qa.swift" --expect-no-quick-switch assert_no_current_aligner release_lock trap - EXIT cat <