Repository navigation
Make UIA gate popup activation deterministic and attribute wait timeouts - #631
Merged
Merged
Conversation
On an interactive desktop, synthesized SendInput mouse clicks reach the low-level hook chain but are not delivered to the target window, so the gate's popup-menu activation silently relied on its posted-Enter fallback. Enter with no hilited item ends TrackPopupMenu with command 0, which closes the popup exactly like a successful selection, and the gate's WM_COMMAND fallbacks to the shell window are no-ops because TPM_RETURNCMD menus never route those IDs. Runs then failed at whichever modal wait came next. - Re-select the intended item with MN_SELECTITEM and prove its hilite immediately before the Enter fallback; fail loudly if it cannot be proved. - Reveal the Promote to submenu with keyboard navigation of the real menu instead of the no-op WM_COMMAND fallback. - Record UIA_WAIT_TIMEOUT_ATTRIBUTION for wait timeouts and gate failures: step, elapsed vs deadline, foreground owner process and class only, every top-level shell window, the shell status text, and PrintWindow captures of shell-owned windows only. Late UIA selection events are measured without changing the on-time assertions. - Stop logging other applications' window titles and focused element names. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Colin Neilens <coneilen@microsoft.com>
This was referenced Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Windows UIA live gate failed locally at a different step each run (Edit edge, Promote ... to Goal/Turn, multi-project convergence) while passing on hosted CI. On the interactive desktop, synthesized
SendInputpopup-menu clicks are intermittently not delivered. When that happens, the gate's posted-Enter fallback can endTrackPopupMenuwith command 0 (no item hilited), which closes the popup exactly like a successful selection. ItsWM_COMMANDfallbacks can't recover either, because the product never routes the menu IDs throughWM_COMMAND. This PR makes popup activation deterministic and attributes every UIA wait timeout. It is a gate-only change; no product code changes.Root cause (what was proven, and what was not)
Local reproduction on main 8ffa38e with the standalone gate (pinned bootstrap, scratch USERPROFILE/LOCALAPPDATA/TEMP, Pester 5.7.1):
SetCursorPos+ hover +SendInputsequence against a realTrackPopupMenu(TPM_RETURNCMD)popup. Hit-test was the popup andSendInputreturned 2/2. OurWH_MOUSE_LLhook saw both injected events within 6–20 ms, yet no click reached the menu or even a plain foreground window (0 of about 60). Two hours later the same probe delivered 5/5, so the condition is intermittent and environmental. Mouse/input-hooking utilities run on this desktop (Synergy, MagicMouseUtilities, PowerToys); which one is responsible is not proven.keyboardFallbackwas false 8/8.MN_SELECTITEMre-selected the item.hiliteAtEnterFallback=False hiliteBeforeEnter=Truefor 5120 and then opened "Create or edit edge". Without re-selection, that state is the b6 failure.MainWindow.Commandhas no 51xx IDs. The context-menu IDs only exist asTrackPopupMenureturn values, soSendCommand(shell, 5110/5116-5120)is a no-op. In c2, when the Turn submenu hover did not reveal the submenu, that no-op fallback ran and the modal wait failed.Changes
ClickPopupMenuItem: before the Enter fallback, record whether the intended item is still hilited, re-select it withMN_SELECTITEM, and throw if its hilite cannot be proved. NewHiliteAtEnterFallback/HiliteBeforeEnterevidence is logged asUIA_EDGE_MENU_CLICK/UIA_SKETCH_MENU_CLICK.Sketch "Promote to" submenu: if hover does not open the real submenu, open it by keyboard navigation of the same native menu (
RevealSubmenuByKeyboard:MN_SELECTITEMon the parent, thenVK_RIGHT). This replaces the no-opWM_COMMAND; if it still doesn't open, the gate fails with an explicit message.UIA_WAIT_TIMEOUT_ATTRIBUTIONis written for:FindFirsttiming) and foreground waitsEach record contains:
statustextPrintWindowcaptures of shell-owned windows only (never the screen), saved in the retained sandboxlogsSelection event waits keep their 1 s on-time assertion. On a miss they observe for 10 s more, purely to log late vs absent delivery, and then still fail.
Get-FocusDiagnosticsno longer logs other applications' window titles or focused element names.ValidationRunner.Tests.ps1: new contracts for the re-select-before-Enter fallback, keyboard submenu reveal (and absence of the no-op submenu command), and the attribution hooks.Not changed: no timeouts were raised and no retries were added. The other existing no-op
WM_COMMANDfallbacks in the edge path are left in place (existing contracts pin them); they cannot mask a failure because the modal assertion still follows them.Test plan
RED: pwsh -NoProfile -File Tools\windows\Tests\ValidationRunner.Tests.ps1 with the main 8ffa38e gate -> exit 1, "RED: UIA popup Enter fallback can close the menu without choosing the intended item"
GREEN: pwsh -NoProfile -File Tools\windows\Tests\ValidationRunner.Tests.ps1 at 261f7a4 -> exit 0, "ValidationRunner.Tests.ps1: PASS" (multi-project contracts executed=380)
REGRESSION: uia-live-gate.ps1 on the built shell at 261f7a4, 8 consecutive local runs (d1-d8) -> 8/8 EXIT=0, each with the final summary JSON
Additional local live evidence. I used a scoped
WH_MOUSE_LLsimulator that drops injected button events only on#32768popups owned by this worktree'sgraphcode-windows.exe, and clears the menu hilite, reproducing the c1 state:hilite:true, keyboardFallback:true)Limits:
validate.ps1 -Task windows-shellwas not re-run locally after the change; exact-head CI is the regression authority for the unit/integration suites.Checklist
git commit -s) per the DCOmake test): macOS targets, not run for this Windows gate changemake check): macOS Swift lint, not applicable to the changed PowerShell files