| | |
| | | RUN_ID="$(date +%Y%m%d_%H%M%S)" |
| | | REPORT_DIR="$BUILD_REPORT_ROOT/round01-finder-tabs-live-$RUN_ID" |
| | | DEV_LOG="$HOME/Library/Logs/Aligner/aligner-dev.log" |
| | | REPORT_WAIT="${ALIGNER_ROUND1_FINDER_TABS_REPORT_WAIT:-7.0}" |
| | | REPORT_WAIT="${ALIGNER_ROUND1_FINDER_TABS_REPORT_WAIT:-35.0}" |
| | | |
| | | fail() { |
| | | echo "Round01 Finder tabs live QA failed: $*" >&2 |
| | |
| | | --round0-skip-permissions \ |
| | | --round01-open-quick-switch \ |
| | | --round01-disable-screenshot-refresh \ |
| | | --round01-quick-switch-auto-hide-after=0.8 \ |
| | | --round01-quick-switch-quit-after=1.3 \ |
| | | --round01-quick-switch-report="$report" >"$app_log" 2>&1 |
| | | wait_for_report "$report" "loaded" |
| | | --round01-quick-switch-auto-hide-after=20.0 \ |
| | | --round01-quick-switch-quit-after=21.0 \ |
| | | --round01-quick-switch-report="$report" >"$app_log" 2>&1 & |
| | | local app_pid="$!" |
| | | if ! wait_for_report "$report" "loaded"; then |
| | | kill "$app_pid" 2>/dev/null || true |
| | | wait "$app_pid" 2>/dev/null || true |
| | | return 1 |
| | | fi |
| | | kill "$app_pid" 2>/dev/null || true |
| | | wait "$app_pid" 2>/dev/null || true |
| | | } |
| | | |
| | | run_click() { |
| | | local app_group_index="$1" |
| | | local window_index="$2" |
| | | local report="$3" |
| | | local app_log="$4" |
| | | local window_id="$1" |
| | | local report="$2" |
| | | local app_log="$3" |
| | | stop_current_aligner |
| | | rm -f "$report" |
| | | ALIGNER_DIAGNOSTICS_INCLUDE_SENSITIVE=1 \ |
| | |
| | | --round0-skip-permissions \ |
| | | --round01-open-quick-switch \ |
| | | --round01-disable-screenshot-refresh \ |
| | | --round01-debug-mouse-sequence="click-card:$app_group_index:$window_index" \ |
| | | --round01-quick-switch-quit-after=1.8 \ |
| | | --round01-quick-switch-report="$report" >"$app_log" 2>&1 |
| | | wait_for_report "$report" "activated" |
| | | --round01-debug-mouse-sequence="click-card-id:$window_id" \ |
| | | --round01-quick-switch-quit-after=34.0 \ |
| | | --round01-quick-switch-report="$report" >"$app_log" 2>&1 & |
| | | local app_pid="$!" |
| | | if ! wait_for_report "$report" "activated"; then |
| | | kill "$app_pid" 2>/dev/null || true |
| | | wait "$app_pid" 2>/dev/null || true |
| | | return 1 |
| | | fi |
| | | wait "$app_pid" 2>/dev/null || true |
| | | } |
| | | |
| | | focused_finder_window_report() { |
| | |
| | | PY |
| | | } |
| | | |
| | | select_target() { |
| | | select_targets() { |
| | | local snapshot="$1" |
| | | local report="$2" |
| | | local attributed_ids_csv="$3" |
| | | local output="$4" |
| | | /usr/bin/python3 - "$snapshot" "$report" "$attributed_ids_csv" "$output" <<'PY' |
| | | import json |
| | | import os |
| | | import sys |
| | | |
| | | snapshot_path, report_path, ids_csv, output_path = sys.argv[1:5] |
| | | attributed_ids = {int(value) for value in ids_csv.split(",") if value} |
| | | max_targets = max(1, int(os.environ.get("ALIGNER_ROUND1_FINDER_TABS_MAX_TARGETS", "4"))) |
| | | with open(snapshot_path, "r", encoding="utf-8") as file: |
| | | snapshot = json.load(file) |
| | | with open(report_path, "r", encoding="utf-8") as file: |
| | |
| | | item[1].get("globalIndex", 10**9), |
| | | item[1].get("windowID", 10**9), |
| | | )) |
| | | column, card, title = cards[0] |
| | | target = { |
| | | "windowID": card["windowID"], |
| | | "appGroupIndex": column["appGroupIndex"], |
| | | "windowIndex": card["windowIndex"], |
| | | "primarySpaceID": card.get("primarySpaceID"), |
| | | "title": title, |
| | | "titleLength": len(title), |
| | | "titleHash": card.get("titleHash") or snapshot_windows.get(card.get("windowID"), {}).get("titleHash"), |
| | | "visibleFrame": card.get("visibleFrame"), |
| | | } |
| | | targets = [] |
| | | seen_window_ids = set() |
| | | for column, card, title in cards: |
| | | window_id = card["windowID"] |
| | | if window_id in seen_window_ids: |
| | | continue |
| | | seen_window_ids.add(window_id) |
| | | targets.append({ |
| | | "windowID": window_id, |
| | | "appGroupIndex": column["appGroupIndex"], |
| | | "windowIndex": card["windowIndex"], |
| | | "primarySpaceID": card.get("primarySpaceID"), |
| | | "title": title, |
| | | "titleLength": len(title), |
| | | "titleHash": card.get("titleHash") or snapshot_windows.get(window_id, {}).get("titleHash"), |
| | | "visibleFrame": card.get("visibleFrame"), |
| | | }) |
| | | if len(targets) >= max_targets: |
| | | break |
| | | |
| | | require(targets, "Quick Switch report must expose at least one selectable Finder tab/page target") |
| | | |
| | | with open(output_path, "w", encoding="utf-8") as file: |
| | | json.dump(target, file, indent=2, ensure_ascii=False) |
| | | json.dump(targets, file, indent=2, ensure_ascii=False) |
| | | |
| | | print(f"TARGET_COUNT={len(targets)}") |
| | | PY |
| | | } |
| | | |
| | | target_at_index() { |
| | | local targets="$1" |
| | | local index="$2" |
| | | local output="$3" |
| | | /usr/bin/python3 - "$targets" "$index" "$output" <<'PY' |
| | | import json |
| | | import sys |
| | | |
| | | targets_path, index_text, output_path = sys.argv[1:4] |
| | | index = int(index_text) |
| | | with open(targets_path, "r", encoding="utf-8") as file: |
| | | targets = json.load(file) |
| | | if index < 0 or index >= len(targets): |
| | | print(f"target index {index} is out of range", file=sys.stderr) |
| | | sys.exit(4) |
| | | target = targets[index] |
| | | with open(output_path, "w", encoding="utf-8") as file: |
| | | json.dump(target, file, indent=2, ensure_ascii=False) |
| | | print(f"TARGET_WINDOW_ID={target['windowID']}") |
| | | print(f"APP_GROUP_INDEX={target['appGroupIndex']}") |
| | | print(f"WINDOW_INDEX={target['windowIndex']}") |
| | | print(f"TARGET_SPACE_ID={target['primarySpaceID']}") |
| | | print(f"TARGET_SPACE_ID={target.get('primarySpaceID')}") |
| | | PY |
| | | } |
| | | |
| | |
| | | SNAPSHOT_DEV_LOG="$REPORT_DIR/snapshot-dev.log" |
| | | INITIAL_REPORT="$REPORT_DIR/initial-report.json" |
| | | INITIAL_APP_LOG="$REPORT_DIR/initial-app.log" |
| | | CLICK_REPORT="$REPORT_DIR/click-report.json" |
| | | CLICK_APP_LOG="$REPORT_DIR/click-app.log" |
| | | CLICK_DEV_LOG="$REPORT_DIR/click-dev.log" |
| | | TARGET_JSON="$REPORT_DIR/target.json" |
| | | FOCUSED_JSON="$REPORT_DIR/focused-finder.json" |
| | | TARGETS_JSON="$REPORT_DIR/targets.json" |
| | | |
| | | SNAPSHOT_LOG_OFFSET="$(dev_log_size)" |
| | | run_snapshot_dump "$SNAPSHOT_JSON" "$SNAPSHOT_STDERR" |
| | |
| | | ATTRIBUTED_IDS="$(extract_attributed_ids "$SNAPSHOT_DEV_LOG")" |
| | | |
| | | run_report "$INITIAL_REPORT" "$INITIAL_APP_LOG" |
| | | eval "$(select_target "$SNAPSHOT_JSON" "$INITIAL_REPORT" "$ATTRIBUTED_IDS" "$TARGET_JSON")" |
| | | eval "$(select_targets "$SNAPSHOT_JSON" "$INITIAL_REPORT" "$ATTRIBUTED_IDS" "$TARGETS_JSON")" |
| | | |
| | | CLICK_LOG_OFFSET="$(dev_log_size)" |
| | | run_click "$APP_GROUP_INDEX" "$WINDOW_INDEX" "$CLICK_REPORT" "$CLICK_APP_LOG" |
| | | sleep 0.8 |
| | | extract_dev_log_since "$CLICK_LOG_OFFSET" "$CLICK_DEV_LOG" |
| | | focused_finder_window_report "$FOCUSED_JSON" |
| | | for ((target_index = 0; target_index < TARGET_COUNT; target_index++)); do |
| | | TARGET_JSON="$REPORT_DIR/target-$target_index.json" |
| | | CLICK_REPORT="$REPORT_DIR/click-report-$target_index.json" |
| | | CLICK_APP_LOG="$REPORT_DIR/click-app-$target_index.log" |
| | | CLICK_DEV_LOG="$REPORT_DIR/click-dev-$target_index.log" |
| | | FOCUSED_JSON="$REPORT_DIR/focused-finder-$target_index.json" |
| | | |
| | | assert_click_report "$CLICK_REPORT" "$TARGET_JSON" |
| | | assert_focused_finder_title "$TARGET_JSON" "$FOCUSED_JSON" |
| | | eval "$(target_at_index "$TARGETS_JSON" "$target_index" "$TARGET_JSON")" |
| | | CLICK_LOG_OFFSET="$(dev_log_size)" |
| | | run_click "$TARGET_WINDOW_ID" "$CLICK_REPORT" "$CLICK_APP_LOG" |
| | | sleep 0.8 |
| | | extract_dev_log_since "$CLICK_LOG_OFFSET" "$CLICK_DEV_LOG" |
| | | focused_finder_window_report "$FOCUSED_JSON" |
| | | |
| | | assert_click_report "$CLICK_REPORT" "$TARGET_JSON" |
| | | assert_focused_finder_title "$TARGET_JSON" "$FOCUSED_JSON" |
| | | done |
| | | |
| | | stop_current_aligner |
| | | |
| | |
| | | Log directory: $REPORT_DIR |
| | | Covered: |
| | | - Finder CG-only tab/page records inherit a high-confidence fullscreen Space. |
| | | - Quick Switch click targets the exact Finder tab/page windowID. |
| | | - Finder focused window title matches the clicked card after activation. |
| | | - Quick Switch clicks target exact Finder tab/page windowIDs. |
| | | - Finder focused window title matches each clicked card after activation. |
| | | - Multiple Finder tab/page targets are exercised in one run to catch intermittent host mismatch. |
| | | EOF |