Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 98 additions & 11 deletions Tools/windows/Tests/ValidationRunner.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,66 @@ function Test-MultiProjectProtocolContracts([string] $stubSource, [string] $gate
}
throw "RED: multi-project expected actual $prefix rejection"
}
Invoke-MultiCase "compact overview narrow client uses the 806 lane floor" {
$geometry = Get-MultiProjectLaneGeometry @(220,34,1028,900) @(262,118,512,214)
Assert-MultiCase (($geometry.band -join ",") -ceq "244,72,1050,248" -and
($geometry.open -join ",") -ceq "918,82,974,102") "250x96 card or 806-pixel floor differs"
$worktrees = @(($geometry.band[2] - 72),82,($geometry.band[2] - 18),102)
$clipped = Get-MultiProjectClippedRectangle $worktrees @(220,34,1028,900)
Assert-MultiCase (($worktrees -join ",") -ceq "978,82,1032,102" -and
($clipped -join ",") -ceq "978,82,1028,102") "narrow Worktrees clipping was hidden"
return "1028-client boundary: Open fully visible, Worktrees has 50 of 54 pixels visible; not whole-button visibility proof"
}
Invoke-MultiCase "compact overview wide client and DPI preserve exact geometry" {
$geometry = Get-MultiProjectLaneGeometry @(220,34,1200,900) @(262,118,512,214)
Assert-MultiCase (($geometry.band -join ",") -ceq "244,72,1176,248") "wide lane changed its viewport-derived width"
$scaled = Get-MultiProjectLaneGeometry @(330,51,1542,1350) @(393,177,768,321)
Assert-MultiCase (($scaled.band -join ",") -ceq "366,108,1575,372" -and
($scaled.open -join ",") -ceq "1377,123,1461,153") "144-DPI narrow geometry was scaled more than once"
return "Literal narrow/wide and once-only 144-DPI source geometry"
}
Invoke-MultiCase "compact overview rejects obsolete 220x86 card geometry" -Negative {
return Reject-MultiCase { Get-MultiProjectLaneGeometry @(220,34,1200,900) @(262,118,482,204) } "MULTIPROJECT_BOUNDS"
}
Invoke-MultiCase "compact overview rejects the obsolete 760-pixel lane floor" -Negative {
$geometry = Get-MultiProjectLaneGeometry @(220,34,1028,900) @(262,118,512,214)
Assert-MultiCase (($geometry.band -join ",") -cne "244,72,1004,248" -and
($geometry.open -join ",") -cne "872,82,928,102") "old 760-pixel action geometry was accepted"
return "New source geometry rejects the old narrow-window lane/action coordinates"
}
Invoke-MultiCase "actual early Worktrees click assignment uses current narrow and wide lane geometry" {
$gateAst = [Management.Automation.Language.Parser]::ParseInput($gateSource, [ref]$null, [ref]$null)
$assignments = @($gateAst.FindAll({
param($node)
$node -is [Management.Automation.Language.AssignmentStatementAst] -and
$node.Left -is [Management.Automation.Language.VariableExpressionAst] -and
$node.Left.VariablePath.UserPath -ceq "laneWorktreesScreenX"
}, $true))
Assert-MultiCase ($assignments.Count -eq 1) "actual Worktrees click assignment missing or ambiguous"
$evaluate = [scriptblock]::Create('param($graph) ' + $assignments[0].Extent.Text + '; return $laneWorktreesScreenX')
foreach ($case in @(
@{ left = 220; right = 1028; expected = 1005; minimum = 978; maximum = 1032 },
@{ left = 220; right = 1200; expected = 1131; minimum = 1104; maximum = 1158 },
@{ left = 228; right = 1036; expected = 1013; minimum = 986; maximum = 1040 }
)) {
$graph = [pscustomobject]@{ Current = [pscustomobject]@{ BoundingRectangle = [pscustomobject]@{
Left = $case.left; Right = $case.right; Width = $case.right - $case.left
} } }
$actual = & $evaluate $graph
Assert-MultiCase ($actual -eq $case.expected -and $actual -ge $case.minimum -and $actual -lt $case.maximum) `
"actual production Worktrees point expected $($case.expected), found $actual"
$geometry = Get-MultiProjectLaneGeometry @($case.left,34,$case.right,900) @(($case.left+42),118,($case.left+292),214)
$control = @(($geometry.band[2]-72),82,($geometry.band[2]-18),102)
$visible = Get-MultiProjectClippedRectangle $control @($case.left,34,$case.right,900)
Assert-MultiCase ($actual -ge $visible[0] -and $actual -lt $visible[2]) "actual Worktrees point misses its visible clipped control"
if ($case.right - $case.left -eq 808) {
$obsolete = $case.right - 69
Assert-MultiCase ($obsolete -ge $geometry.open[0] -and $obsolete -lt $geometry.open[2] -and
($obsolete -lt $control[0] -or $obsolete -ge $control[2])) "obsolete narrow point was not rejected as Open rather than Worktrees"
}
}
return "Executed the production assignment AST at 1028-client, wide and translated bounds; no desktop invocation"
}
$eventStart = [DateTime]::Parse("2026-10-01T18:29:43.1462496Z").ToUniversalTime()
$eventEnd = $eventStart.AddSeconds(1)
$eventProcess = [pscustomobject]@{ Id = 5832; StartTime = $eventStart }
Expand Down Expand Up @@ -1456,10 +1516,17 @@ function Test-MultiProjectProtocolContracts([string] $stubSource, [string] $gate
foreignCardFragmentCount = 0; foreignProjectFragmentCount = 0
canvasBounds = @(228,85,1036,780)
}
Invoke-MultiCase "retained hosted four-fragment source-supported overview" {
Assert-MultiCase (Test-MultiProjectObservedRoster "overview" $retainedProjection $retainedOwners $null 3140) `
"retained hosted 716 overview rejected legitimate two-node/two-summary complete roster"
return "Exact hosted identities/names/node bounds; summary rectangles independently source-derived, not a native bounds measurement"
Invoke-MultiCase "retained hosted identities with current compact geometry" {
Assert-MultiCase (-not (Test-MultiProjectObservedRoster "overview" $retainedProjection $retainedOwners $null 3140)) `
"historical 220x86 hosted geometry passed the current compact-card predicate"
$compactProjection = Copy-MultiProjectValue $retainedProjection
$compactProjection.cards[0].bounds = @(632,133,918,153)
$compactProjection.cards[1].bounds = @(270,169,520,265)
$compactProjection.cards[2].bounds = @(632,329,918,349)
$compactProjection.cards[3].bounds = @(270,365,520,461)
Assert-MultiCase (Test-MultiProjectObservedRoster "overview" $compactProjection $retainedOwners $null 3140) `
"compact geometry rejected the same exact two-node/two-summary identities and names"
return "Original hosted bounds remain unchanged and are rejected; synthetic current-geometry projection of the same four identities is accepted, not a new native capture"
}
Invoke-MultiCase "source summary identity independent fixture and hosted goldens" {
Assert-MultiCase ((Get-MultiProjectAutomationId "overview-worktree-notice" "A") -ceq
Expand Down Expand Up @@ -1545,9 +1612,9 @@ function Test-MultiProjectProtocolContracts([string] $stubSource, [string] $gate
)
cards = @(
[ordered]@{ automationId = "canvas-card-1294898434078301384"; name = "Worktrees not inspected"; processId = 4242; bounds = @(750,82,1036,102) },
[ordered]@{ automationId = "canvas-card-1929002346198335884"; name = "Alpha loop"; processId = 4242; bounds = @(262,118,482,204) },
[ordered]@{ automationId = "canvas-card-1929002346198335884"; name = "Alpha loop"; processId = 4242; bounds = @(262,118,512,214) },
[ordered]@{ automationId = "canvas-card-1294901732613186017"; name = "Worktrees not inspected"; processId = 4242; bounds = @(750,278,1036,298) },
[ordered]@{ automationId = "canvas-card-1616358459734844849"; name = "Beta loop"; processId = 4242; bounds = @(262,314,482,400) }
[ordered]@{ automationId = "canvas-card-1616358459734844849"; name = "Beta loop"; processId = 4242; bounds = @(262,314,512,410) }
)
foreignCardFragmentCount = 0; foreignProjectFragmentCount = 0
canvasBounds = @(220,34,1200,900)
Expand All @@ -1558,6 +1625,26 @@ function Test-MultiProjectProtocolContracts([string] $stubSource, [string] $gate
"literal two-owner/two-node plus two-summary whole roster rejected"
return "Historical two-card case counts NODE cards: complete owned canvas roster is four (two nodes plus two summaries); no live app claim"
}
Invoke-MultiCase "compact overview roster rejects obsolete card dimensions" -Negative {
$projection = New-MultiRosterProjection
$projection.cards[1].bounds = @(262,118,482,204)
Assert-MultiCase (-not (Test-MultiProjectObservedRoster "overview" $projection $rosterOwners $null 4242)) `
"old 220x86 card passed the actual complete-roster predicate"
return "Named Alpha node geometry rejected; no broad canvas count"
}
Invoke-MultiCase "compact overview roster rejects obsolete narrow summary position" -Negative {
$projection = New-MultiRosterProjection
$projection.canvasBounds = @(220,34,1028,900)
$projection.cards[0].bounds = @(578,82,864,102)
$projection.cards[2].bounds = @(578,278,864,298)
Assert-MultiCase (-not (Test-MultiProjectObservedRoster "overview" $projection $rosterOwners $null 4242)) `
"old 760-pixel floor summary positions passed the actual complete-roster predicate"
$projection.cards[0].bounds = @(624,82,910,102)
$projection.cards[2].bounds = @(624,278,910,298)
Assert-MultiCase (Test-MultiProjectObservedRoster "overview" $projection $rosterOwners $null 4242) `
"corrected 806-pixel floor summary positions were rejected"
return "Same exact four named fragments: old floor rejected, current narrow geometry accepted"
}
Invoke-MultiCase "fresh owned content cannot bless an overview missing its peer card" -Negative {
$mock = New-MultiCaptureMock @((New-MultiCaptureState),(New-MultiCaptureState),(New-MultiCaptureState))
$evidence = Get-MultiProjectElementEvidence $mock 4242 $capturePrior "functional/missing-peer" $captureReader
Expand Down Expand Up @@ -1613,9 +1700,9 @@ function Test-MultiProjectProtocolContracts([string] $stubSource, [string] $gate
return "Full roster four, node two, per-owner summary two"
}
Invoke-MultiCase "source summary geometry is separate from node Open geometry" {
$geometry = Get-MultiProjectLaneGeometry @(228,85,1036,780) @(270,169,490,255)
Assert-MultiCase (($geometry.summary -join ",") -ceq "586,133,872,153" -and
($geometry.open -join ",") -ceq "880,133,936,153") "actual-canvas source summary/Open rectangles differ"
$geometry = Get-MultiProjectLaneGeometry @(228,85,1036,780) @(270,169,520,265)
Assert-MultiCase (($geometry.summary -join ",") -ceq "632,133,918,153" -and
($geometry.open -join ",") -ceq "926,133,982,153") "actual-canvas source summary/Open rectangles differ"
return "Derived from actual NODE bounds and canvas; not summary-as-node geometry"
}
foreach ($mutation in @("two-nodes-unknown", "unknown-summary", "duplicate-summary", "wrong-summary-owner",
Expand All @@ -1642,10 +1729,10 @@ function Test-MultiProjectProtocolContracts([string] $stubSource, [string] $gate
}
}
Invoke-MultiCase "literal lane geometry and DPI scaling" {
$geometry = Get-MultiProjectLaneGeometry @(220,34,1200,900) @(262,118,482,204)
$geometry = Get-MultiProjectLaneGeometry @(220,34,1200,900) @(262,118,512,214)
Assert-MultiCase (($geometry.band -join ",") -ceq "244,72,1176,248" -and
($geometry.open -join ",") -ceq "1044,82,1100,102") "96-DPI literal source-derived bounds differ"
$scaled = Get-MultiProjectLaneGeometry @(330,51,1800,1350) @(393,177,723,306)
$scaled = Get-MultiProjectLaneGeometry @(330,51,1800,1350) @(393,177,768,321)
Assert-MultiCase (($scaled.open -join ",") -ceq "1566,123,1650,153") "144-DPI source-derived bounds differ"
return "literal band/Open bounds; not UIA caption evidence"
}
Expand Down
18 changes: 9 additions & 9 deletions Tools/windows/uia-live-gate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3275,8 +3275,8 @@ function Test-MultiProjectObservedRoster([string] $surface, $projection, $expect
$summaryId = Get-MultiProjectAutomationId "overview-worktree-notice" $owner.path
$node = @($projection.cards | Where-Object { $_.automationId -ceq $nodeId })[0]
$summary = @($projection.cards | Where-Object { $_.automationId -ceq $summaryId })[0]
$scale = ($node.bounds[2] - $node.bounds[0]) / 220
if ([Math]::Abs(($node.bounds[3] - $node.bounds[1]) / $scale - 86) -gt 1) { return $false }
$scale = ($node.bounds[2] - $node.bounds[0]) / 250
if ([Math]::Abs(($node.bounds[3] - $node.bounds[1]) / $scale - 96) -gt 1) { return $false }
$geometry = Get-MultiProjectLaneGeometry $projection.canvasBounds $node.bounds
for ($index = 0; $index -lt 4; $index++) {
if ([Math]::Abs($summary.bounds[$index] - $geometry.summary[$index]) -gt 1) { return $false }
Expand Down Expand Up @@ -4181,13 +4181,13 @@ function Get-MultiProjectLaneGeometry([double[]] $canvas, [double[]] $card) {
$canvas[3] -le $canvas[1] -or $card[2] -le $card[0] -or $card[3] -le $card[1]) {
throw "MULTIPROJECT_BOUNDS: positive live canvas/card rectangles required"
}
$scale = ($card[2] - $card[0]) / 220
if ([Math]::Abs(($card[3] - $card[1]) / $scale - 86) -gt 1) {
$scale = ($card[2] - $card[0]) / 250
if ([Math]::Abs(($card[3] - $card[1]) / $scale - 96) -gt 1) {
throw "MULTIPROJECT_BOUNDS: overview-card scale differs from source geometry"
}
$laneLeft = $canvas[0] + 24 * $scale
$laneTop = $card[1] - 46 * $scale
$laneRight = $laneLeft + [Math]::Max(760, ($canvas[2] - $canvas[0]) / $scale - 48) * $scale
$laneRight = $laneLeft + [Math]::Max(806, ($canvas[2] - $canvas[0]) / $scale - 48) * $scale
return [ordered]@{
provenance = "GraphCanvas source-derived one-root lane; not a native UIA caption fragment"
scale = $scale
Expand Down Expand Up @@ -6010,7 +6010,7 @@ try {
# Folder lanes/bands: the lane's Open and Worktrees actions have no dedicated UIA
# elements (GraphCanvas.overviewLaneActionAt is a pure hit test painted by GDI), so
# this derives their real screen position from GraphCanvas.overviewLaneBounds'
# actual formula (lane.left = graph.Left + 24, lane width = max(760,
# actual formula (lane.left = graph.Left + 24, lane width = max(806,
# graph.Width - 48)) and posts real WM_LBUTTONDOWN/UP client-coordinate clicks at
# those points, exercising the exact App.zig click routing a physical mouse would
# drive. A genuine surface transition (not merely re-invoking the same overview
Expand All @@ -6019,7 +6019,7 @@ try {
# the free-form project-canvas layout.
#
# An earlier version of this block instead tried to force the shell window wide
# enough that graph.Width - 48 would exceed the 760 floor, first via SW_MAXIMIZE,
# enough that graph.Width - 48 would exceed the then-current 760 floor, first via SW_MAXIMIZE,
# then via a growing SetWindowPos request -- but on a CI runner with a small
# virtual desktop, requesting an ever-larger window rect does not produce an
# ever-larger client rect: repeated attempts up to a 6000x2687 request all landed
Expand Down Expand Up @@ -6050,7 +6050,7 @@ try {
((@($overviewCards | ForEach-Object { $_.Current.Name }) -join "|") -eq "UIA loop A|UIA loop B")) `
"Overview did not expose synchronized cards after resetting zoom/pan to actual size"
$graphBounds = $graph.Current.BoundingRectangle
$laneWidth = [Math]::Max(760, [int]$graphBounds.Width - 48)
$laneWidth = [Math]::Max(806, [int]$graphBounds.Width - 48)
$laneRight = [int]$graphBounds.Left + 24 + $laneWidth
$laneGridCardTop = $overviewCards[0].Current.BoundingRectangle.Top
$laneOpenScreenX = $laneRight - 104
Expand Down Expand Up @@ -6084,7 +6084,7 @@ try {
$_.Current.AutomationId -match '^canvas-card-' -and $_.Current.Name -match '^UIA loop '
})
Require ($overviewCards.Count -eq 2) "overview did not restore synchronized cards before the Worktrees lane check"
$laneWorktreesScreenX = [int]$graph.Current.BoundingRectangle.Right - 69
$laneWorktreesScreenX = [int]$graph.Current.BoundingRectangle.Left + 24 + [Math]::Max(806, [int]$graph.Current.BoundingRectangle.Width - 48) - 45
$laneWorktreesScreenY = [int]$overviewCards[0].Current.BoundingRectangle.Top - 26
$worktrees = Find-FragmentById $root "worktrees" $rawWalker
Require ($null -ne $worktrees) "missing Worktrees fragment before the overview lane Worktrees check"
Expand Down
Loading
Loading