Browse Source

Wait for the click target instead of counting frames

Right_Clicking_A_Second_Row_Moves_The_Context_Highlight_To_It timed out on
the Windows CI agent waiting for the second context menu to open. A closed
popup's light-dismiss overlay keeps answering hit tests until the scene is
rendered again, and a press that lands on it raises no ContextRequested at
all, so the menu never opens. The test pumped a fixed four frames after
dismissing the first menu to get past that, which is a guess about how long
the overlay survives: enough on a fast machine, not on a loaded agent.

Hit testing the point is the same question the context-request handler asks,
so waiting for it to reach the row is the actual precondition for the click,
whatever number of frames that takes. The failure could not be reproduced
locally - removing the frames entirely still passes here - so this fixes the
documented mechanism rather than a reproduction, and a timeout now reports
which of the two conditions was not met.

Assisted-by: Claude:claude-opus-5[1m]:Claude Code
pull/4073/head
Siegfried Pammer 3 weeks ago
parent
commit
170aea4408
  1. 16
      ILSpy.Tests/ContextMenus/DecompileInNewViewTests.cs

16
ILSpy.Tests/ContextMenus/DecompileInNewViewTests.cs

@ -257,6 +257,15 @@ public class DecompileInNewViewTests @@ -257,6 +257,15 @@ public class DecompileInNewViewTests
var row = Row(node);
var clickX = System.Math.Min(row.Bounds.Width, grid.Bounds.Width) / 2;
var pt = row.TranslatePoint(new Point(clickX, row.Bounds.Height / 2), window);
// A popup's light-dismiss overlay keeps answering hit tests for as long as the frame
// that still shows it, and it swallows a press without raising ContextRequested - so
// nothing becomes the context target. Hit testing the point is the same question the
// context-request handler asks, so waiting for it to reach the row is exactly the
// precondition for this click, however many frames the overlay takes to disappear.
await Waiters.WaitForAsync(
() => window.InputHitTest(pt!.Value) is Visual hit
&& ReferenceEquals(hit.FindAncestorOfType<ICSharpCode.ILSpy.Controls.TreeView.SharpTreeViewItem>(includeSelf: true), row),
description: "the row to answer hit tests at the point about to be right-clicked");
HeadlessWindowExtensions.MouseDown(window, pt!.Value, MouseButton.Right);
HeadlessWindowExtensions.MouseUp(window, pt.Value, MouseButton.Right);
// The highlight is scoped to the popup - set while the menu is being requested, dropped
@ -269,13 +278,6 @@ public class DecompileInNewViewTests @@ -269,13 +278,6 @@ public class DecompileInNewViewTests
{
window.KeyPress(Key.Escape, RawInputModifiers.None, PhysicalKey.Escape, keySymbol: null);
await Waiters.WaitForAsync(() => !menu.IsOpen, description: "the context menu to close");
// IsOpen flips the moment the popup is torn down, but the frame that still shows its
// light-dismiss overlay is what answers hit tests until the scene is rendered again.
// Right-clicking into that frame delivers press and release to the vanishing overlay
// instead of the row: no ContextRequested is raised at all, so nothing becomes the
// context target and the next assertion sees a row with no classes on it.
for (int i = 0; i < 4; i++)
Waiters.PumpUI();
}
await RightClick(nodeB);

Loading…
Cancel
Save