From 86f0b4bd20cdec86dfb5bdb7978d1f6ff4af111a Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Fri, 14 Aug 2026 22:41:54 +0800
Subject: [PATCH] [verified] feat: export performance diagnostics

---
 C3.tools/round1-waterfall-fixture-qa.sh |   28 +++++++++++++++++++++++++---
 1 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/C3.tools/round1-waterfall-fixture-qa.sh b/C3.tools/round1-waterfall-fixture-qa.sh
index ab6f8c6..c90b454 100755
--- a/C3.tools/round1-waterfall-fixture-qa.sh
+++ b/C3.tools/round1-waterfall-fixture-qa.sh
@@ -119,6 +119,24 @@
     require(column.get("appGroupIndex") == expected_index, "Waterfall appGroupIndex must be sequential")
     require(column.get("appName") == app_names[expected_index], "Waterfall column name must match App Shelf name")
     require(column.get("windowCount") == fixture_windows_per_app, "Waterfall column window count must match fixture")
+    require(column.get("appNameAlignment") == "center", "Waterfall column app name must be center aligned")
+    column_frame = column.get("frame", {})
+    header_frame = column.get("headerFrame", {})
+    app_name_frame = column.get("appNameFrame", {})
+    count_frame = column.get("countFrame", {})
+    header_to_first_card_gap = column.get("headerToFirstCardGap")
+    top_to_first_card_gap = column.get("topToFirstCardGap")
+    require(isinstance(header_frame, dict), "Waterfall column must expose headerFrame")
+    require(isinstance(app_name_frame, dict), "Waterfall column must expose appNameFrame")
+    require(isinstance(count_frame, dict), "Waterfall column must expose countFrame")
+    column_width = column_frame.get("width", 0)
+    app_name_center_x = app_name_frame.get("x", 0) + app_name_frame.get("width", 0) / 2
+    require(abs(app_name_center_x - column_width / 2) <= 1.0, "Waterfall column app name frame must be horizontally centered")
+    require(app_name_frame.get("width", 0) >= column_width * 0.88, "Waterfall column app name frame must span most of the title bar")
+    require(count_frame.get("x", 0) + count_frame.get("width", 0) <= column_width + 1.0, "Waterfall count frame must remain inside the title bar")
+    require(count_frame.get("x", 0) >= column_width * 0.72, "Waterfall count frame must stay in the right side of the title bar")
+    require(abs(header_to_first_card_gap) <= 1.0, "Waterfall first card must sit directly under the title bar")
+    require(top_to_first_card_gap <= header_frame.get("height", 0) + 1.0, "Waterfall title-to-card height must remain compact")
     require(column.get("maxVerticalScrollOffset", 0) > 0, "Long Waterfall column must expose vertical scroll overflow")
     require(column.get("verticalScrollOffset") == 0, "Waterfall column should start at top")
 
@@ -131,6 +149,10 @@
     require(all(card.get("screenshotSource") == "notRequested" for card in cards), "Waterfall fixture cards must not start screenshot refresh")
     require(all(card.get("screenshotNotRequestedReason") == "disabledByLaunchOption" for card in cards), "Waterfall fixture screenshot refresh must be disabled explicitly")
     require(all(isinstance(card.get("thumbnailFrame"), dict) for card in cards), "Waterfall cards must expose thumbnail frames")
+    require(all(isinstance(card.get("titleBarFrame"), dict) for card in cards), "Waterfall cards must expose title bar frames")
+    require(all(card.get("titleBarBorderWidth") == 0 for card in cards), "Waterfall title area must not draw an enclosing rounded rectangle")
+    require(all(card.get("thumbnailFrame", {}).get("width", 0) >= card.get("frame", {}).get("width", 0) * 0.82 for card in cards), "Waterfall thumbnails must use most of the card width")
+    require(all(card.get("titleBarFrame", {}).get("y", 0) > card.get("thumbnailFrame", {}).get("y", 0) + card.get("thumbnailFrame", {}).get("height", 0) for card in cards), "Waterfall title bars must sit above thumbnails")
     require(all(isinstance(card.get("appIconFrame"), dict) for card in cards), "Waterfall cards must expose App icon frames")
     require(any(card.get("frame", {}).get("y", 0) < 0 for card in cards), "Long Waterfall column must have below-viewport cards at offset zero")
 
@@ -142,9 +164,9 @@
 selected_cards = [card for column in columns for card in column.get("cards", []) if card.get("isSelected") is True]
 require(len(selected_cards) == 1, "Waterfall must expose exactly one selected card")
 selected = selected_cards[0]
-require("selected" in selected.get("visualStates", []), "selected Waterfall card must expose selected visual state")
-require(selected.get("shineVisible") is True, "selected Waterfall card must expose shine layer")
-require(selected.get("zPosition", 0) > 0, "selected Waterfall card must be above normal cards")
+require("selectedVisualSuppressed" in selected.get("visualStates", []), "non-hovered selected Waterfall card must suppress selected visual state")
+require(selected.get("shineVisible") is False, "non-hovered selected Waterfall card must not expose shine layer")
+require(selected.get("zPosition", 0) == 0, "non-hovered selected Waterfall card must not float above normal cards")
 normal_cards = [card for column in columns for card in column.get("cards", []) if card.get("isSelected") is not True]
 require(normal_cards, "Waterfall fixture must include normal cards")
 require(all(card.get("shineVisible") is False for card in normal_cards), "non-selected Waterfall cards must not show shine")

--
Gitblit v1.9.3