| | |
| | | local expected_last_mouse="$3" |
| | | local app_count="${4:-$FIXTURE_APP_COUNT}" |
| | | local windows_per_app="${5:-$FIXTURE_WINDOWS_PER_APP}" |
| | | local quick_switch_expectation="${6:-visible}" |
| | | |
| | | rm -f "$report" |
| | | "$APP/Contents/MacOS/Aligner" \ |
| | |
| | | --round01-fixture-windows-per-app="$windows_per_app" \ |
| | | --round01-debug-overlay-width="$OVERLAY_WIDTH" \ |
| | | --round01-disable-screenshot-refresh \ |
| | | --round01-debug-window-activation \ |
| | | --round01-debug-mouse-sequence="$sequence" \ |
| | | --round01-quick-switch-report="$report" & |
| | | |
| | | APP_PID=$! |
| | | |
| | | wait_for_report "$report" "$expected_last_mouse" |
| | | swift "$SCRIPT_DIR/window-logic-qa.swift" --expect-quick-switch >&2 |
| | | if [ "$quick_switch_expectation" = "hidden" ]; then |
| | | swift "$SCRIPT_DIR/window-logic-qa.swift" --expect-no-quick-switch >&2 |
| | | else |
| | | swift "$SCRIPT_DIR/window-logic-qa.swift" --expect-quick-switch >&2 |
| | | fi |
| | | |
| | | kill "$APP_PID" 2>/dev/null || true |
| | | wait "$APP_PID" 2>/dev/null || true |
| | |
| | | segments = root.get("spaceLaneSegments", []) |
| | | |
| | | require(report.get("snapshotLoaded") is True, "snapshotLoaded must be true") |
| | | require(root.get("activeSpaceFocusID") == 1, "Space Lane focus must set activeSpaceFocusID") |
| | | require(root.get("spaceLaneFocusedSpaceID") == 1, "click-space must persist focused Space") |
| | | require(root.get("lastSpaceLaneClickSpaceID") == 1, "last clicked Space must be recorded") |
| | | require(root.get("activeSpaceFocusID") == 1, "Space Lane hover must set activeSpaceFocusID") |
| | | require(root.get("spaceLaneHoveredSpaceID") == 1, "hover-space must expose hovered Space") |
| | | require(root.get("spaceLaneFocusedSpaceID") is None, "hover-space must not persist clicked Space focus") |
| | | require(root.get("lastSpaceLaneClickSpaceID") is None, "hover-space must not record a Space click") |
| | | require(root.get("lastSpaceFocusedAppGroupIndex") == 0, "first related App column must be appGroupIndex 0") |
| | | require(root.get("spaceFocusAppGroupIndexes") == list(range(fixture_app_count)), "all fixture apps must be marked related to focused Space") |
| | | require(root.get("waterfallScrollOffset") == 0, "first related App column should remain visible at offset zero") |
| | | |
| | | focused_segments = [segment for segment in segments if segment.get("isFocused") is True] |
| | | require(len(focused_segments) == 1, "exactly one Space Lane segment must be focused") |
| | | require(focused_segments[0].get("label") == "A1", "focused Space should be A1") |
| | | require(focused_segments[0].get("label") == "01", "focused Space should be 01") |
| | | require("focused" in focused_segments[0].get("visualStates", []), "focused Space segment must expose focused visual state") |
| | | |
| | | require(len(items) == fixture_app_count, "App Shelf fixture item count must match app count") |
| | |
| | | columns = root.get("waterfallColumns", []) |
| | | last_index = fixture_app_count - 1 |
| | | |
| | | require(root.get("activeSpaceFocusID") == 1, "Space focus must persist after clicking App Shelf item") |
| | | require(report.get("quickSwitchVisible") is False, "remote App click must close Quick Switch after committing its first window") |
| | | require(root.get("activeSpaceFocusID") == 1, "Space hover preview should still be reflected in the pre-commit report") |
| | | require(root.get("lastClickedAppGroupIndex") == last_index, "remote App click must be recorded") |
| | | require(root.get("lastAppShelfClickChangedSelection") is True, "App Shelf click must move keyboard selection to the remote App column") |
| | | require(root.get("selectedAppGroupIndex") == last_index, "remote App click must focus the remote App column") |
| | | require(root.get("lastCommittedWindowID") is None, "App Shelf click must not commit a window") |
| | | expected_window_id = columns[last_index].get("cards", [])[0].get("windowID") |
| | | require(root.get("lastCommittedWindowID") == expected_window_id, "App Shelf click must commit the first remote window") |
| | | require(report.get("lastCommittedWindowID") == expected_window_id, "session must surface the remote App commit") |
| | | require(report.get("lastActivationWindowID") == expected_window_id, "activation window must be the first remote window") |
| | | require(report.get("lastActivationResult") == "activated", "debug activation must activate the first remote window") |
| | | require(report.get("lastCommitSource") == "mouse", "remote App commit source must be mouse") |
| | | require(root.get("waterfallScrollOffset", 0) > 0, "remote App click must scroll Waterfall horizontally") |
| | | require(items[last_index].get("spaceFocusDirection") == "visible", "remote App must become visible after click") |
| | | require(columns[last_index].get("spaceFocusDirection") == "visible", "remote Waterfall column must become visible after click") |
| | |
| | | print(json.dumps({ |
| | | "activeSpaceFocusID": root.get("activeSpaceFocusID"), |
| | | "lastClickedAppGroupIndex": root.get("lastClickedAppGroupIndex"), |
| | | "lastCommittedWindowID": root.get("lastCommittedWindowID"), |
| | | "lastActivationResult": report.get("lastActivationResult"), |
| | | "waterfallScrollOffset": root.get("waterfallScrollOffset"), |
| | | "remoteDirectionAfterClick": items[last_index].get("spaceFocusDirection") |
| | | }, indent=2, ensure_ascii=False)) |
| | | PY |
| | | } |
| | | |
| | | assert_space_click_report() { |
| | | /usr/bin/python3 - "$1" <<'PY' |
| | | import json |
| | | import sys |
| | | |
| | | path = sys.argv[1] |
| | | |
| | | with open(path, "r", encoding="utf-8") as file: |
| | | report = json.load(file) |
| | | |
| | | def require(condition, message): |
| | | if not condition: |
| | | print(message, file=sys.stderr) |
| | | print(json.dumps(report, indent=2, ensure_ascii=False), file=sys.stderr) |
| | | sys.exit(1) |
| | | |
| | | root = report.get("rootView", {}) |
| | | columns = sorted(root.get("waterfallColumns", []), key=lambda column: column.get("appGroupIndex", 0)) |
| | | target_space_id = 1 |
| | | first_space_card = None |
| | | for column in columns: |
| | | cards = sorted(column.get("cards", []), key=lambda card: card.get("windowIndex", 0)) |
| | | first_space_card = next((card for card in cards if card.get("primarySpaceID") == target_space_id), None) |
| | | if first_space_card is not None: |
| | | break |
| | | |
| | | require(first_space_card is not None, "fixture must include at least one window in Space A1") |
| | | expected_window_id = first_space_card.get("windowID") |
| | | |
| | | require(report.get("snapshotLoaded") is True, "snapshotLoaded must be true") |
| | | require(report.get("quickSwitchVisible") is False, "click-space must close Quick Switch after committing a window in that Space") |
| | | require(root.get("lastSpaceLaneClickSpaceID") == target_space_id, "click-space must record the clicked Space") |
| | | require(root.get("spaceLaneFocusedSpaceID") is None, "click-space must not reuse persistent focus as its behavior") |
| | | require(root.get("lastCommittedWindowID") == expected_window_id, "click-space must commit the first window in the clicked Space") |
| | | require(report.get("lastCommittedWindowID") == expected_window_id, "session must surface the Space click commit") |
| | | require(report.get("lastActivationWindowID") == expected_window_id, "activation window must match the first window in clicked Space") |
| | | require(report.get("lastActivationResult") == "activated", "debug activation must activate the clicked Space window") |
| | | require(report.get("lastCommitSource") == "mouse", "click-space commit source must be mouse") |
| | | |
| | | print(json.dumps({ |
| | | "clickedSpaceID": root.get("lastSpaceLaneClickSpaceID"), |
| | | "lastCommittedWindowID": root.get("lastCommittedWindowID"), |
| | | "lastActivationResult": report.get("lastActivationResult") |
| | | }, indent=2, ensure_ascii=False)) |
| | | PY |
| | | } |
| | |
| | | "$SCRIPT_DIR/package-app.sh" >&2 |
| | | |
| | | FOCUS_REPORT="$REPORT_DIR/round01-three-zone-linkage-focus-report.json" |
| | | SPACE_CLICK_REPORT="$REPORT_DIR/round01-three-zone-linkage-space-click-report.json" |
| | | REMOTE_REPORT="$REPORT_DIR/round01-three-zone-linkage-remote-report.json" |
| | | SCROLL_REPORT="$REPORT_DIR/round01-three-zone-linkage-scroll-report.json" |
| | | |
| | | run_report "$FOCUS_REPORT" "click-space:1" "click-space:1" |
| | | run_report "$FOCUS_REPORT" "hover-space:1" "hover-space:1" |
| | | assert_focus_report "$FOCUS_REPORT" |
| | | |
| | | run_report "$REMOTE_REPORT" "click-space:1,click-app:$REMOTE_APP_INDEX" "click-app:$REMOTE_APP_INDEX" |
| | | run_report "$SPACE_CLICK_REPORT" "click-space:1" "click-space:1" "$FIXTURE_APP_COUNT" "$FIXTURE_WINDOWS_PER_APP" hidden |
| | | assert_space_click_report "$SPACE_CLICK_REPORT" |
| | | |
| | | run_report "$REMOTE_REPORT" "hover-space:1,click-app:$REMOTE_APP_INDEX" "click-app:$REMOTE_APP_INDEX" "$FIXTURE_APP_COUNT" "$FIXTURE_WINDOWS_PER_APP" hidden |
| | | assert_remote_click_report "$REMOTE_REPORT" |
| | | |
| | | run_report "$SCROLL_REPORT" "scroll-app-shelf:99999" "scroll-app-shelf:99999" 60 1 |