| | |
| | | def near(lhs, rhs, tolerance=0.01): |
| | | return abs((lhs or 0) - (rhs or 0)) <= tolerance |
| | | |
| | | def is_blue(color, min_alpha=0.30): |
| | | return ( |
| | | isinstance(color, dict) |
| | | and color.get("blue", 0) >= 0.85 |
| | | and color.get("green", 0) >= 0.35 |
| | | and color.get("red", 1) <= 0.18 |
| | | and color.get("alpha", 0) >= min_alpha |
| | | ) |
| | | |
| | | require(report.get("snapshotLoaded") is True, "snapshotLoaded must be true") |
| | | require(report.get("displayCount", 0) >= 1, "displayCount must be >= 1") |
| | | require(report.get("spaceCount", 0) >= 1, "spaceCount must be >= 1") |
| | |
| | | require(all(isinstance(segment.get("appNames"), list) for segment in lane_segments), "Space Lane segments must expose app names") |
| | | require(all(isinstance(segment.get("frame"), dict) for segment in lane_segments), "Space Lane segments must expose content frames") |
| | | require(all(isinstance(segment.get("visibleFrame"), dict) for segment in lane_segments), "Space Lane segments must expose visible frames") |
| | | require(all(isinstance(segment.get("borderColor"), dict) for segment in lane_segments), "Space Lane segments must expose border colors") |
| | | require(all(isinstance(segment.get("windowBlockColors"), list) for segment in lane_segments), "Space Lane segments must expose window block colors") |
| | | occupied_segments = [segment for segment in lane_segments if segment.get("windowCount", 0) > 0] |
| | | empty_segments = [segment for segment in lane_segments if segment.get("windowCount", 0) == 0] |
| | | require(all(is_blue(segment.get("borderColor"), min_alpha=0.34) for segment in occupied_segments), "occupied Space segments must use blue borders") |
| | | require(all(not is_blue(segment.get("borderColor"), min_alpha=0.34) for segment in empty_segments), "empty Space segments must not use blue borders") |
| | | occupied_floating_segments = [segment for segment in occupied_segments if segment.get("type") != "fullscreen"] |
| | | require(all(segment.get("windowBlockCount", 0) > 0 for segment in occupied_floating_segments), "occupied non-fullscreen Spaces must expose window blocks") |
| | | for segment in occupied_floating_segments: |
| | | require(all(is_blue(color, min_alpha=0.50) for color in segment.get("windowBlockColors", [])), "occupied Space window blocks must be blue") |
| | | same_display_gaps = [] |
| | | cross_display_gaps = [] |
| | | for previous, current in zip(lane_segments, lane_segments[1:]): |
| | | previous_frame = previous.get("visibleFrame", {}) |
| | | current_frame = current.get("visibleFrame", {}) |
| | | gap = current_frame.get("x", 0) - (previous_frame.get("x", 0) + previous_frame.get("width", 0)) |
| | | if previous.get("displayUUID") == current.get("displayUUID"): |
| | | same_display_gaps.append(gap) |
| | | else: |
| | | cross_display_gaps.append(gap) |
| | | if cross_display_gaps: |
| | | require(all(gap >= 24 for gap in cross_display_gaps), "Space Lane must leave a visible gap between displays") |
| | | if same_display_gaps: |
| | | require(min(cross_display_gaps) > max(same_display_gaps) + 8, "display gap must be clearly larger than same-display Space gaps") |
| | | current_labels = root_view.get("spaceLaneCurrentLabels", []) |
| | | fullscreen_labels = root_view.get("spaceLaneFullscreenLabels", []) |
| | | require(len(current_labels) >= 1, "Space Lane must mark at least one current Space") |
| | |
| | | fullscreen_segments = [segment for segment in lane_segments if segment.get("type") == "fullscreen"] |
| | | require([segment.get("label") for segment in fullscreen_segments] == fullscreen_labels, "fullscreen segment reports must match fullscreen labels") |
| | | require(all(segment.get("fullscreenMarkerVisible") is True for segment in fullscreen_segments), "fullscreen segments must expose fullscreen marker") |
| | | require(all(segment.get("fullscreenMarkerKind") == "cornerBracket" for segment in fullscreen_segments), "fullscreen segments must use corner bracket marker") |
| | | require(all(segment.get("windowBlockCount") == 0 for segment in fullscreen_segments), "fullscreen segments must not expose floating-window blocks") |
| | | non_fullscreen_segments = [segment for segment in lane_segments if segment.get("type") != "fullscreen"] |
| | | require(all(segment.get("fullscreenMarkerKind") == "none" for segment in non_fullscreen_segments), "non-fullscreen segments must not expose fullscreen marker") |
| | | for segment in fullscreen_segments: |
| | | require("fullscreen" in segment.get("visualStates", []), "fullscreen segments must expose fullscreen visual state") |
| | | marker_frame = segment.get("fullscreenMarkerFrame", {}) |
| | | app_frame = segment.get("appFrame", {}) |
| | | require(isinstance(marker_frame, dict), "fullscreen segments must expose marker frame") |
| | | require(isinstance(app_frame, dict), "fullscreen segments must expose centered App label frame") |
| | | marker_mid_y = marker_frame.get("y", 0) + marker_frame.get("height", 0) / 2 |
| | | app_mid_y = app_frame.get("y", 0) + app_frame.get("height", 0) / 2 |
| | | require(abs(marker_mid_y - app_mid_y) <= 2, "fullscreen App label must be vertically centered in marker") |
| | | for segment in lane_segments: |
| | | if segment.get("isCurrent") is True: |
| | | require("current" in segment.get("visualStates", []), "current segment must expose current visual state") |
| | |
| | | require(lane_max_scroll_offset > 0, "overflowing Space Lane must expose positive max scroll offset") |
| | | else: |
| | | require(root_view.get("spaceLaneScrollable") is False, "non-overflowing Space Lane should not report scrollable") |
| | | if lane_segments: |
| | | first_frame = lane_segments[0].get("visibleFrame", {}) |
| | | last_frame = lane_segments[-1].get("visibleFrame", {}) |
| | | left_blank = first_frame.get("x", 0) |
| | | right_blank = lane_visible_width - (last_frame.get("x", 0) + last_frame.get("width", 0)) |
| | | require(abs(left_blank - right_blank) <= 2, "non-overflowing Space Lane segments must be centered") |
| | | app_shelf_items = root_view.get("appShelfItems", []) |
| | | app_shelf_names = root_view.get("appShelfNames", []) |
| | | require(root_view.get("appShelfItemCount") == report.get("appCount"), "App Shelf item count must match appCount") |
| | |
| | | require(all(isinstance(item.get("frame"), dict) for item in app_shelf_items), "App Shelf items must expose frames") |
| | | require(all(isinstance(item.get("iconFrame"), dict) for item in app_shelf_items), "App Shelf items must expose icon frames") |
| | | for item in app_shelf_items: |
| | | if item.get("isSelected") is True: |
| | | expected_icon_size = root_view.get("appShelfSelectedIconSize") |
| | | elif item.get("isHovered") is True: |
| | | if item.get("isHovered") is True: |
| | | expected_icon_size = root_view.get("appShelfHoverIconSize") |
| | | else: |
| | | expected_icon_size = icon_size |
| | | if item.get("isSelected") is True and item.get("isHovered") is not True: |
| | | require("selectedVisualSuppressed" in item.get("visualStates", []), "non-hovered selected App Shelf item must suppress selected visual state") |
| | | require(abs(item.get("iconFrame", {}).get("width", -1) - expected_icon_size) < 0.01, "App Shelf icon frame width must match visual icon size") |
| | | require(abs(item.get("iconFrame", {}).get("height", -1) - expected_icon_size) < 0.01, "App Shelf icon frame height must match visual icon size") |
| | | row_y_values = {round(item.get("frame", {}).get("y", 0), 2) for item in app_shelf_items} |
| | |
| | | if card.get("screenshotSource") == "notRequested": |
| | | require(card.get("screenshotNotRequestedReason") is not None, "not-requested screenshot cards must expose reason") |
| | | require(isinstance(card.get("thumbnailFrame"), dict), "Waterfall cards must expose thumbnail frames") |
| | | require(isinstance(card.get("titleBarFrame"), dict), "Waterfall cards must expose title bar frames") |
| | | require(card.get("titleBarBorderWidth") == 0, "Waterfall title area must not draw an enclosing rounded rectangle") |
| | | require(isinstance(card.get("titleFrame"), dict), "Waterfall cards must expose title frames") |
| | | card_frame = card.get("frame", {}) |
| | | thumbnail_frame = card.get("thumbnailFrame", {}) |
| | | title_bar_frame = card.get("titleBarFrame", {}) |
| | | require(thumbnail_frame.get("width", 0) >= card_frame.get("width", 0) * 0.82, "Waterfall thumbnail must use most of the card width") |
| | | require(title_bar_frame.get("y", 0) > thumbnail_frame.get("y", 0) + thumbnail_frame.get("height", 0), "Waterfall title bar must sit above the thumbnail") |
| | | require(isinstance(card.get("appIconFrame"), dict), "Waterfall cards must expose App icon frames") |
| | | require(isinstance(card.get("visualStates"), list), "Waterfall cards must expose visual states") |
| | | require(card.get("titleTruncationMode") == "middle", "Waterfall card titles must use middle truncation") |
| | |
| | | require(root_view.get("screenshotResolvedCount") + root_view.get("screenshotPendingCount") == root_view.get("screenshotEligibleCount"), "resolved + pending screenshots must match eligible count") |
| | | require(root_view.get("screenshotEligibleCount") + root_view.get("screenshotNotRequestedCount") == waterfall_card_count, "eligible + not-requested screenshots must cover all cards") |
| | | require(global_indexes == sorted(global_indexes), "Waterfall global indexes must be monotonic across columns") |
| | | if root_view.get("activeSpaceFocusID") is None: |
| | | require( |
| | | all("spaceFocused" not in card.get("visualStates", []) for column in waterfall_columns for card in column.get("cards", [])), |
| | | "Waterfall cards must not expose spaceFocused when no Space Lane focus is active" |
| | | ) |
| | | selected_cards = [ |
| | | card |
| | | for column in waterfall_columns |
| | |
| | | if card.get("isSelected") is True |
| | | ] |
| | | require(len(selected_cards) == 1, "Waterfall must expose exactly one selected card") |
| | | require("selected" in selected_cards[0].get("visualStates", []), "selected Waterfall card must expose selected visual state") |
| | | require(selected_cards[0].get("shineVisible") is True, "selected Waterfall card must expose shine layer") |
| | | require(selected_cards[0].get("zPosition", 0) > 0, "selected Waterfall card must be above normal cards") |
| | | require("selectedVisualSuppressed" in selected_cards[0].get("visualStates", []), "non-hovered selected Waterfall card must suppress selected visual state") |
| | | require(selected_cards[0].get("shineVisible") is False, "non-hovered selected Waterfall card must not expose shine layer") |
| | | require(selected_cards[0].get("zPosition", 0) == 0, "non-hovered selected Waterfall card must not float above normal cards") |
| | | require(isinstance(report.get("overlayOpenElapsedMilliseconds"), (int, float)), "overlay open timing must exist") |
| | | require(isinstance(report.get("snapshotStartElapsedMilliseconds"), (int, float)), "snapshot start timing must exist") |
| | | require(report["snapshotStartElapsedMilliseconds"] >= report["overlayOpenElapsedMilliseconds"], "snapshot must start after overlay open path") |