| | |
| | | continue |
| | | ids = [int(value) for value in re.findall(r"\d+", match.group(1))] |
| | | |
| | | if not ids: |
| | | print("No attributed Finder tab/page windowIDs found in this QA run", file=sys.stderr) |
| | | sys.exit(3) |
| | | |
| | | print(",".join(str(value) for value in sorted(set(ids)))) |
| | | PY |
| | | } |
| | |
| | | sys.exit(4) |
| | | |
| | | snapshot_windows = {window.get("id"): window for window in snapshot.get("windows", [])} |
| | | finder_attributed = [ |
| | | finder_candidates = [ |
| | | window for window_id, window in snapshot_windows.items() |
| | | if window_id in attributed_ids |
| | | and window.get("app", {}).get("bundleIdentifier") == "com.apple.finder" |
| | | if window.get("app", {}).get("bundleIdentifier") == "com.apple.finder" |
| | | and window.get("identifierSource") == "cgWindow" |
| | | and window.get("spaceIDs") |
| | | and window.get("title") |
| | | ] |
| | | require(finder_attributed, "snapshot must contain at least one attributed Finder CG-only tab/page") |
| | | require(finder_candidates, "snapshot must contain at least one Finder CG-only tab/page") |
| | | |
| | | root = report.get("rootView", {}) |
| | | cards = [] |
| | |
| | | if column.get("bundleIdentifier") != "com.apple.finder": |
| | | continue |
| | | for card in column.get("cards", []): |
| | | if card.get("windowID") not in attributed_ids: |
| | | window = snapshot_windows.get(card.get("windowID"), {}) |
| | | if window.get("app", {}).get("bundleIdentifier") != "com.apple.finder": |
| | | continue |
| | | if window.get("identifierSource") != "cgWindow": |
| | | continue |
| | | visible = card.get("visibleFrame") or {} |
| | | if visible.get("width", 0) <= 1 or visible.get("height", 0) <= 1: |
| | |
| | | continue |
| | | cards.append((column, card, title)) |
| | | |
| | | require(cards, "Quick Switch report must expose at least one visible attributed Finder tab/page card") |
| | | require(cards, "Quick Switch report must expose at least one visible Finder CG tab/page card") |
| | | |
| | | title_counts = {} |
| | | for _, _, title in cards: |
| | | title_counts[title] = title_counts.get(title, 0) + 1 |
| | | |
| | | cards.sort(key=lambda item: ( |
| | | 0 if not (snapshot_windows.get(item[1].get("windowID"), {}).get("spaceIDs") or []) else 1, |
| | | 0 if title_counts[item[2]] == 1 else 1, |
| | | item[1].get("globalIndex", 10**9), |
| | | item[1].get("windowID", 10**9), |
| | |
| | | "appGroupIndex": column["appGroupIndex"], |
| | | "windowIndex": card["windowIndex"], |
| | | "primarySpaceID": card.get("primarySpaceID"), |
| | | "hasAttributedSpace": window_id in attributed_ids, |
| | | "snapshotSpaceIDs": snapshot_windows.get(window_id, {}).get("spaceIDs") or [], |
| | | "title": title, |
| | | "titleLength": len(title), |
| | | "titleHash": card.get("titleHash") or snapshot_windows.get(window_id, {}).get("titleHash"), |
| | |
| | | PY |
| | | } |
| | | |
| | | assert_no_finder_activation_failure_log() { |
| | | local log_file="$1" |
| | | local target="$2" |
| | | /usr/bin/python3 - "$log_file" "$target" <<'PY' |
| | | import json |
| | | import sys |
| | | |
| | | log_path, target_path = sys.argv[1:3] |
| | | with open(target_path, "r", encoding="utf-8") as file: |
| | | target = json.load(file) |
| | | |
| | | window_id = str(target.get("windowID")) |
| | | bad_lines = [] |
| | | for line in open(log_path, "r", encoding="utf-8", errors="replace"): |
| | | if f"windowID={window_id}" not in line: |
| | | continue |
| | | if "event=windowActivation.finderTab.noSelectableHost" in line: |
| | | bad_lines.append(line.strip()) |
| | | elif "event=windowActivation.finderTab.hostMissing" in line: |
| | | bad_lines.append(line.strip()) |
| | | elif "event=windowActivation.activate.finderTabResult" in line and "activated=false" in line: |
| | | bad_lines.append(line.strip()) |
| | | elif "event=quickSwitch.activation.commit.result" in line and "result=activationFailed" in line: |
| | | bad_lines.append(line.strip()) |
| | | |
| | | if bad_lines: |
| | | print("Finder activation log contains failure markers for clicked target", file=sys.stderr) |
| | | print(json.dumps({ |
| | | "targetWindowID": target.get("windowID"), |
| | | "hasAttributedSpace": target.get("hasAttributedSpace"), |
| | | "snapshotSpaceIDs": target.get("snapshotSpaceIDs"), |
| | | "lines": bad_lines[-8:], |
| | | }, indent=2, ensure_ascii=False), file=sys.stderr) |
| | | sys.exit(7) |
| | | PY |
| | | } |
| | | |
| | | mkdir -p "$REPORT_DIR" |
| | | stop_current_aligner |
| | | "$SCRIPT_DIR/package-app.sh" >&2 |
| | |
| | | |
| | | assert_click_report "$CLICK_REPORT" "$TARGET_JSON" |
| | | assert_focused_finder_title "$TARGET_JSON" "$FOCUSED_JSON" |
| | | assert_no_finder_activation_failure_log "$CLICK_DEV_LOG" "$TARGET_JSON" |
| | | done |
| | | |
| | | stop_current_aligner |
| | |
| | | Round01 Finder tabs live QA passed |
| | | Log directory: $REPORT_DIR |
| | | Covered: |
| | | - Finder CG-only tab/page records inherit a high-confidence fullscreen Space. |
| | | - Finder CG-only tab/page records are clicked even when Space attribution is unavailable. |
| | | - Quick Switch clicks target exact Finder tab/page windowIDs. |
| | | - Finder focused window title matches each clicked card after activation. |
| | | - Finder activation logs contain no hostMissing/noSelectableHost/activationFailed for clicked targets. |
| | | - Multiple Finder tab/page targets are exercised in one run to catch intermittent host mismatch. |
| | | EOF |