| | |
| | | # shellcheck source=build-output-paths.sh |
| | | source "$SCRIPT_DIR/build-output-paths.sh" |
| | | APP="$BUILD_CURRENT_APP" |
| | | DOMAIN="com.ar.Aligner" |
| | | THEME_KEY="com.ar.Aligner.preferences.appearance.theme" |
| | | LAYOUT_REPORT="$BUILD_REPORT_ROOT/round01-horizontal-waterfall-layout-report.json" |
| | | KEYBOARD_REPORT="$BUILD_REPORT_ROOT/round01-horizontal-waterfall-keyboard-report.json" |
| | | APP_ENTER_REPORT="$BUILD_REPORT_ROOT/round01-horizontal-waterfall-app-enter-report.json" |
| | |
| | | WINDOW_SHORTCUT_TARGET_WINDOW_INDEX="${ALIGNER_ROUND1_HORIZONTAL_WATERFALL_WINDOW_SHORTCUT_TARGET_WINDOW_INDEX:-5}" |
| | | ARROW_WRAP_KEY_SEQUENCE="${ALIGNER_ROUND1_HORIZONTAL_WATERFALL_ARROW_WRAP_KEY_SEQUENCE:-app:1,down,up,left,down,enter}" |
| | | REPORT_WAIT="${ALIGNER_ROUND1_HORIZONTAL_WATERFALL_REPORT_WAIT:-6.0}" |
| | | OLD_THEME_SET=0 |
| | | OLD_THEME="" |
| | | |
| | | fail() { |
| | | echo "Round01.1 horizontal Waterfall fixture QA failed: $*" >&2 |
| | |
| | | done |
| | | |
| | | fail "current Aligner app did not exit before QA" |
| | | } |
| | | |
| | | preserve_user_theme() { |
| | | if OLD_THEME="$(/usr/bin/defaults read "$DOMAIN" "$THEME_KEY" 2>/dev/null)"; then |
| | | OLD_THEME_SET=1 |
| | | else |
| | | OLD_THEME_SET=0 |
| | | OLD_THEME="" |
| | | fi |
| | | } |
| | | |
| | | restore_user_theme() { |
| | | if [ "$OLD_THEME_SET" -eq 1 ]; then |
| | | /usr/bin/defaults write "$DOMAIN" "$THEME_KEY" -string "$OLD_THEME" |
| | | else |
| | | /usr/bin/defaults delete "$DOMAIN" "$THEME_KEY" >/dev/null 2>&1 || true |
| | | fi |
| | | } |
| | | |
| | | wait_for_loaded_report() { |
| | |
| | | if physical_symbols: |
| | | require(root.get("lastAppShelfIndexKeySymbol") == physical_symbols[-1], "last physical App index symbol must be reported") |
| | | require(target_app_index < len(columns), "target App index must exist") |
| | | target_card = columns[target_app_index].get("cards", [])[0] |
| | | current_target_cards = columns[target_app_index].get("cards", []) |
| | | committed_window_id = root.get("lastCommittedWindowID") |
| | | suppressed_window_ids = set(report.get("suppressedActivationWindowIDs", [])) |
| | | require(root.get("hoverTargetKind") == "app", "App index focus must leave hover target on the App icon") |
| | | require(root.get("keyboardFocusedAppGroupIndex") == target_app_index, "keyboard App focus must target requested App") |
| | | require(root.get("keyboardFocusedWindowID") is None, "App icon focus must not keep stale window keyboard focus") |
| | | require(root.get("selectedAppGroupIndex") == target_app_index, "App icon focus must select the target App") |
| | | require(root.get("selectedWindowIndex") == 0, "App icon focus must select the first window") |
| | | require(root.get("horizontalAppDefaultWindowID") == target_card.get("windowID"), "App default window ID must match the first window") |
| | | require(root.get("lastCommittedAppGroupIndex") == target_app_index, "Enter on App icon must commit the target App") |
| | | require(root.get("lastCommittedWindowIndex") == 0, "Enter on App icon must commit the first window") |
| | | require(root.get("lastCommittedWindowID") == target_card.get("windowID"), "Enter on App icon must commit the first window ID") |
| | | require(committed_window_id in suppressed_window_ids, "Enter on App icon may remove committed first window only when suppression records it") |
| | | require(root.get("lastCommitSource") == "keyboard", "App Enter commit must be keyboard sourced") |
| | | require(target_card.get("isHorizontalAppDefault") is True, "target first card must report app default state") |
| | | require("appDefault" in target_card.get("visualStates", []), "target first card must expose appDefault visual state") |
| | | require("selected" in target_card.get("visualStates", []), "target first card must expose selected visual state") |
| | | require(committed_window_id not in [card.get("windowID") for card in current_target_cards], "suppressed committed App Enter target must not remain in current cards") |
| | | |
| | | print(json.dumps({ |
| | | "commands": root.get("keyboardCommandsApplied"), |
| | |
| | | require(target_app_index < len(columns), "target App index must exist") |
| | | target_column = columns[target_app_index] |
| | | cards = target_column.get("cards", []) |
| | | require(target_window_index < len(cards), "target window index must exist") |
| | | target_card = cards[target_window_index] |
| | | require(target_card.get("windowShortcutCode") == expected_code, "target card must expose the expected two-character shortcut code") |
| | | require(target_card.get("primarySpaceLabel") != target_card.get("windowShortcutCode"), "shortcut code must replace the old Space label in the UI meta slot") |
| | | committed_window_id = root.get("lastCommittedWindowID") |
| | | suppressed_window_ids = set(report.get("suppressedActivationWindowIDs", [])) |
| | | pre_commit = root.get("lastWindowShortcutPreCommitFilterSnapshot", {}) |
| | | require(pre_commit.get("phase") == "targetPreCommit", "two-key shortcut must record a pre-commit filter snapshot") |
| | | require(pre_commit.get("targetCode") == expected_code, "pre-commit snapshot must record target shortcut code") |
| | | require(pre_commit.get("targetWindowID") == committed_window_id, "pre-commit target must match committed window ID") |
| | | require(pre_commit.get("matchedWindowIDs") == [committed_window_id], "pre-commit snapshot must match exactly the committed window") |
| | | require(root.get("lastCommittedAppGroupIndex") == target_app_index, "two-key shortcut must commit target App") |
| | | require(root.get("lastCommittedWindowIndex") == target_window_index, "two-key shortcut must commit target window") |
| | | require(root.get("lastCommittedWindowID") == target_card.get("windowID"), "two-key shortcut must commit target window ID") |
| | | require(committed_window_id in suppressed_window_ids, "two-key shortcut may remove committed target only when suppression records it") |
| | | require(root.get("lastCommitSource") == "keyboard", "two-key shortcut commit must be keyboard sourced") |
| | | require(root.get("selectedAppGroupIndex") == target_app_index, "two-key shortcut must select target App") |
| | | require(root.get("selectedWindowIndex") == target_window_index, "two-key shortcut must select target window") |
| | | require(root.get("selectedWindowID") == target_card.get("windowID"), "two-key shortcut selection ID must match target window") |
| | | require(committed_window_id not in [card.get("windowID") for column in columns for card in column.get("cards", [])], "suppressed two-key target must not remain in current cards") |
| | | |
| | | for column in columns: |
| | | for card in column.get("cards", []): |
| | |
| | | require(root.get("waterfallViewMode") == "horizontalMasonry", "arrow wrap run must use horizontalMasonry") |
| | | require(root.get("keyboardCommandsApplied") == key_sequence, "arrow wrap keyboard commands must be applied") |
| | | require(len(columns) == fixture_app_count, "fixture App count must match") |
| | | target_card = columns[target_app_index].get("cards", [])[0] |
| | | committed_window_id = root.get("lastCommittedWindowID") |
| | | suppressed_window_ids = set(report.get("suppressedActivationWindowIDs", [])) |
| | | require(root.get("lastCommittedAppGroupIndex") == target_app_index, "left arrow from first App icon must wrap to the last App") |
| | | require(root.get("lastCommittedWindowIndex") == 0, "down arrow from App icon must land on the first window") |
| | | require(root.get("lastCommittedWindowID") == target_card.get("windowID"), "Enter after arrow focus must commit the focused first window") |
| | | require(root.get("selectedAppGroupIndex") == target_app_index, "selected App must match wrapped App") |
| | | require(root.get("selectedWindowIndex") == 0, "selected window must be the wrapped App first window") |
| | | require(committed_window_id in suppressed_window_ids, "arrow focus Enter may remove committed target only when suppression records it") |
| | | require(root.get("lastCommitSource") == "keyboard", "arrow focus Enter commit must be keyboard sourced") |
| | | require(committed_window_id not in [card.get("windowID") for column in columns for card in column.get("cards", [])], "suppressed arrow target must not remain in current cards") |
| | | |
| | | print(json.dumps({ |
| | | "commands": root.get("keyboardCommandsApplied"), |
| | |
| | | wait "$APP_PID" 2>/dev/null || true |
| | | fi |
| | | stop_current_aligner |
| | | restore_user_theme |
| | | } |
| | | trap cleanup EXIT |
| | | preserve_user_theme |
| | | /usr/bin/defaults write "$DOMAIN" "$THEME_KEY" -string "light" |
| | | |
| | | run_fixture "$LAYOUT_REPORT" --round01-debug-mouse-sequence="hover-app:$HOVER_APP_INDEX" |
| | | wait_for_loaded_report "$LAYOUT_REPORT" |
| | |
| | | |
| | | trap - EXIT |
| | | stop_current_aligner |
| | | restore_user_theme |
| | | echo "Round01.1 horizontal Waterfall fixture QA passed" |