Ariver
2026-06-04 ecba8206e4c8cac76dd3e6f8844204abfda03dfd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/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 <<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,
App column alignment, and final no-residual check.
EOF