#!/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"
|
stop_current_aligner
|
if "$@" >"$log" 2>&1; then
|
stop_current_aligner
|
echo "PASS $name"
|
else
|
local code="$?"
|
echo "FAIL $name (log: $log)" >&2
|
tail -c 6000 "$log" >&2 || true
|
best_effort_stop_current_aligner || 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 space-lane-split-view "$SCRIPT_DIR/round1-space-lane-split-view-fixture-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 vertical-keyboard-app-focus "$SCRIPT_DIR/round1-vertical-keyboard-app-focus-fixture-qa.sh"
|
run_step window-activation "$SCRIPT_DIR/round1-window-activation-fixture-qa.sh"
|
run_step multi-page-identity "$SCRIPT_DIR/round1-multi-page-identity-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 horizontal-waterfall "$SCRIPT_DIR/round1-horizontal-waterfall-fixture-qa.sh"
|
run_step theme-toggle "$SCRIPT_DIR/round1-theme-toggle-fixture-qa.sh"
|
run_step space-lane-dark-hover "$SCRIPT_DIR/round1-space-lane-dark-hover-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 <<EOF
|
Round01 main UI QA passed
|
Log directory: $LOG_DIR
|
Covered: trigger, overlay uniqueness, keyboard navigation, candidate filtering,
|
screenshots/fallbacks, minimized-window restore/activation, mouse activation,
|
multi-page precise activation/close targeting, App column alignment,
|
Split View Space Lane rendering, theme toggle, Space Lane dark hover readability,
|
and final no-residual check.
|
EOF
|