Repository navigation
Test coverage: UI-automation input helpers to >=95% - #649
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
pr-review follow-ups on the input-helper coverage work: - Fix a test-isolation defect (multi-model HIGH): KeyboardInput, MouseInput and ForegroundGuard [TestCleanup] reset their process-global native seams to test fakes/no-ops, leaking faked state to any later test that exercises the real path. Add internal ResetNativeSeams() to each product helper (extracting the production P/Invoke defaults to named methods) and point [TestCleanup] at it so cleanup restores real delegates. Deterministic fakes stay in [TestInitialize] for within-class isolation. Mirrors the existing SystemUiQuery/RealOwnedWindowFinder pattern. - Fix a vacuous RealOwnedWindowFinder test (asserted nothing) to assert a stable, idempotent native read. - Add delegation tests for the RealKeyboardInput and RealForegroundGuard thin adapters (were 0%, now 100%), matching the existing RealMouseInput test. Debug + Release (both projects) build 0W/0E. Input cluster all >=95% (KeyboardInput 95.7%, MouseInput 95.8%, ForegroundGuard 98.1%, SystemUiQuery 99.2%, adapters/gesture/owned-window 100%). 61 input tests pass. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds native seams and tests to raise UI-automation input-helper coverage above 95%.
Changes:
- Extracts Win32 calls behind resettable test seams.
- Adds deterministic helper and adapter tests.
- Expands gesture-targeting coverage.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
Services/SystemUiQuery.cs |
Adds native query seams. |
Helpers/RealOwnedWindowFinder.cs |
Adds window-enumeration seams. |
Helpers/MouseInput.cs |
Extracts and tests input-building logic. |
Helpers/KeyboardInput.cs |
Extracts keyboard batching and native calls. |
Helpers/ForegroundGuard.cs |
Adds foreground-window seams. |
SystemUiQueryTests.cs |
Tests process and window queries. |
RealOwnedWindowFinderTests.cs |
Tests owned-window filtering. |
MouseInputTests.cs |
Tests mouse gestures and failures. |
KeyboardInputTests.cs |
Tests keyboard batching and failures. |
GestureTargetingTests.cs |
Tests stable-target resolution. |
ForegroundGuardTests.cs |
Tests foreground classification and adapter delegation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [TestCleanup] | ||
| public void Cleanup() => ResetSeams(); |
There was a problem hiding this comment.
Good catch — fixed in b2a1c56. Cleanup() now calls the product SystemUiQuery.ResetNativeSeams(), which restores the real native delegates, instead of the local ResetSeams() fake-installer. Since the seams are static, teardown no longer leaks fakes into other test classes. [TestInitialize] still installs the deterministic fake base per test.
| [TestCleanup] | ||
| public void Cleanup() => ResetSeams(); |
There was a problem hiding this comment.
Fixed in b2a1c56 — same fix as the SystemUiQuery cleanup. Cleanup() now calls RealOwnedWindowFinder.ResetNativeSeams() to restore the production delegates, so the static seams do not persist fakes across classes. It also brings RealOwnedWindowFinder.cs to 100%, since ResetNativeSeams now runs on every cleanup.
| // Enumerating the first top-level window from a null handle must be a stable, side-effect-free | ||
| // read: two back-to-back native calls return the same handle (covers the production delegate | ||
| // without depending on which specific window happens to be topmost on the agent). | ||
| var firstTopLevel = RealOwnedWindowFinder.s_findNextTopLevelWindow(HWND.Null); | ||
| Assert.AreEqual(firstTopLevel, RealOwnedWindowFinder.s_findNextTopLevelWindow(HWND.Null)); |
There was a problem hiding this comment.
Agreed — fixed in b2a1c56. The two live FindWindowEx(Null) calls were Z-order-dependent and could differ if the topmost window changed between them. Now the production enumeration delegate is invoked once for coverage with no assertion on the volatile handle; the deterministic Null-handle reads (visible=false, owner=Null, pid=0, empty text) remain the stable assertions.
Build Metrics ReportBinary Sizes
Test Results✅ 0 passed out of 0 tests in 0.0s (-3246 tests, -626.5s vs. baseline) Test Coverage❌ 0% line coverage, 0% branch coverage · CLI Startup Time44ms median (x64, Updated 2026-07-16 05:28:38 UTC · commit |
…ssertion Addresses the Copilot auto-review findings on PR #649: - SystemUiQueryTests / RealOwnedWindowFinderTests [TestCleanup] called the local ResetSeams() helper, which installs FAKE delegates. Because the seams are static, the last test in each class left fakes installed process-wide, which could leak into other test classes that exercise the real SystemUiQuery / RealOwnedWindowFinder. Point Cleanup at the product ResetNativeSeams() so teardown restores the real native delegates. [TestInitialize] still installs the deterministic fake base for each test. (Bonus: RealOwnedWindowFinder.cs is now 100% since ResetNativeSeams runs every cleanup.) - RealOwnedWindowFinderTests.NativeSeams_HandleNullWindowWithoutMutation asserted that two back-to-back live FindWindowEx(Null) calls return the same handle. The topmost window is Z-order-dependent and can change between calls, so this was flaky. Invoke the production enumeration delegate once for coverage instead; keep the deterministic Null-handle reads (visible=false, owner=Null, pid=0, text="") as the stable assertions. Coverage held: SystemUiQuery.cs 99.2%, RealOwnedWindowFinder.cs 100%. Debug 0W/0E; the two affected classes pass 13/13. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…iAutomation fake Main #600 (ui touch/pen) added TryGetWindowRect(long, out PointerRect) to IUiAutomationService. This branch's GestureTargetingTests QueueUiAutomation fake predates it, so the head+main merge build failed (CS0535). Implement it as a safe no-op (returns false / default rect) since the gesture-targeting tests resolve elements via FindSingleElementAsync and do not depend on a window rect. FakeUiAutomationService already implements it (from main). Debug + Release(both) 0W/0E; 69 gesture/input/system tests pass. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
What
Raises per-file test coverage to ≥95% for the UI-automation input helpers, part of the CLI coverage initiative (#630). All 10 files in scope now meet the bar:
How
P/Invokedefaults (SendInput,PostMessage,MapVirtualKey,SetCursorPos,GetForegroundWindow, etc.) into named methods and add aninternal static ResetNativeSeams()that restores those production delegates. No behavior change — production still calls the same native APIs.[TestInitialize](within-class isolation);[TestCleanup]calls the newResetNativeSeams()so process-global seam state is restored to production after each[DoNotParallelize]class finishes, preventing faked state from leaking to later tests that exercise the real path.RealKeyboardInputandRealForegroundGuardthin adapters (matching the existingRealMouseInputtest).Policy
No
[ExcludeFromCodeCoverage], nocoverage.runsettingsedits. The few remaining uncovered lines are innermost native/SendInputboundaries.Validation
-p:UseSharedCompilation=false -nodeReuse:false) 0W/0E each.pr-reviewskill (7 specialists + GPT multi-model) before opening; the multi-model HIGH test-isolation finding and a vacuous test were fixed in this branch.Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com