[Windows] Fix CollectionView ScrollTo related test cases failed in CI#34907
[Windows] Fix CollectionView ScrollTo related test cases failed in CI#34907kubaflo merged 2 commits intodotnet:inflight/currentfrom
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34907Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34907" |
|
Hey there @@HarishwaranVijayakumar! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
There was a problem hiding this comment.
Pull request overview
Improves Windows CI reliability for CollectionView ScrollTo-related UI tests that became flaky after ScrollIntoView started running asynchronously on Windows (via DispatcherQueue.TryEnqueue).
Changes:
- Re-enabled previously skipped Windows UI tests for CollectionView scrolling/ScrollTo scenarios.
- Added a delay before resetting scroll event labels on the scrolling feature-matrix page to avoid deferred scroll callbacks overwriting the reset state.
- Disabled animated
ScrollToon Windows for Issue33614’s HostApp page to reduce timing-related flakiness.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33614.cs | Removes Windows-only compilation guard so the Issue33614 UI test runs on Windows again. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs | Removes/relaxes Windows skip conditions so ScrollTo-related feature-matrix tests run on Windows. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue33614.cs | Makes Issue33614’s ScrollTo non-animated on Windows to reduce flaky timing in the HostApp scenario. |
| src/Controls/tests/TestCases.HostApp/FeatureMatrix/CollectionView/ScrollingFeature/CollectionViewScrollPage.xaml.cs | Adds an awaitable delay before resetting scroll event labels to avoid deferred Windows callbacks overwriting expected label state. |
|
/azp run maui-pr-uitests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
kubaflo
left a comment
There was a problem hiding this comment.
Could you please review ai's suggestions
🤖 AI Summary
📊 Review Session —
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #34907 | Test-only: add Task.Delay(300) on Windows before label reset + disable animation on Windows for Issue33614 + remove TEST_FAILS_ON_WINDOWS guards |
⏳ PENDING (Gate failed: test-only PR, no fix files) | CollectionViewScrollPage.xaml.cs, Issue33614.cs, CollectionView_ScrollingFeatureTests.cs, Issue33614.cs (tests) |
Original PR |
🔬 Code Review — Deep Analysis
Code Review — PR #34907
Independent Assessment
What this changes: Four files, all in the test layer:
- A
#if WINDOWSTask.Delay(300)inNavigateToOptionsPage_ClickedbeforeResetScrollEventLabels()in HostApp - A
#if WINDOWSswitch fromanimate: true→animate: falseinIssue33614's scroll button handler - Removal of
TEST_FAILS_ON_WINDOWSguards from theIssue33614UI test class - Narrowing
#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_WINDOWS→#if TEST_FAILS_ON_ANDROIDonVerifyKeepScrollOffsetWithObservableList - Removal of
#if TEST_FAILS_ON_WINDOWSblock guardingVerifyScrollToByIndexWithMakeVisiblePositionAndVerticalList_Carrotand following ScrollTo tests
Inferred motivation: Windows CollectionView ScrollTo tests were racing against async scroll triggered by items loading. PR #24867 wrapped ListViewBase.ScrollIntoView in DispatcherQueue.TryEnqueue(), making the initial auto-scroll deferred — labels get reset before the deferred callback fires, then overwritten.
Reconciliation with PR Narrative
Agreement: Root cause analysis precisely matches the code. The Task.Delay(300) lets the dispatcher queue flush before label reset. The animate: false avoids intermediate Scrolled events from animation that would set a non-final FirstVisibleItemIndex when the test reads it. Both are technically sound workarounds.
Findings
⚠️ Warning — Task.Delay(300) may be larger than necessary and risks future flakiness
File: CollectionViewScrollPage.xaml.cs:25
#if WINDOWS
await Task.Delay(300);
#endifOn WinUI, await checkpoints yield control back to the DispatcherQueue, meaning the enqueued callback will process when the await completes — not after 300ms of wall-clock time. This means await Task.Delay(0) (or await Task.Yield()) would achieve the same flush semantics.
The 300ms:
- Adds 300ms to every test that navigates through this page on Windows
- Doesn't provide stronger guarantees than
Task.Delay(0)for the stated use case - Could theoretically fail on a severely degraded CI machine
Recommendation: await Task.Delay(0) or await Task.Yield() for semantically clearer, faster, equally correct behavior.
💡 Suggestion — [Issue] attribute PlatformAffected doesn't reflect Windows coverage
File: src/Controls/tests/TestCases.HostApp/Issues/Issue33614.cs:5
[Issue(IssueTracker.Github, 33614, "...", PlatformAffected.iOS | PlatformAffected.macOS)]This HostApp page now includes Windows-specific code. The PlatformAffected annotation should be updated to include Windows.
💡 Suggestion — Trailing space in comment
File: src/Controls/tests/TestCases.HostApp/Issues/Issue33614.cs:75
// Disable animation on Windows to avoid flaky test results Minor trailing whitespace.
Blast Radius
Scope: Test files only. No production code path affected. No handler, renderer, or platform layer changed.
Impacted test categories: CollectionView, ScrollView (indirectly)
Failure modes:
Task.Delay(300)not long enough →scrolledEventLabel.Text= "Fired" when test expects "Not Fired" → test fails obviously (no silent pass risk)- Animation disabled on Windows for Issue33614 → reduces coverage of animated-scroll path on Windows (known accepted trade-off)
Verdict: LGTM
Confidence: high
Summary: Pure test-layer fix. Removes Windows skip guards and adds targeted workarounds for known Windows async dispatch behavior. Task.Delay(300) could be Task.Delay(0) for equivalent correctness and faster tests, and PlatformAffected should include Windows, but neither is a blocking issue. No production code changed.
🔧 Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix (claude-opus-4.6) | Replace Task.Delay(300) with Task.Yield() for dispatcher-flush semantics |
CollectionViewScrollPage.xaml.cs, Issue33614.cs, test files |
Test-only PR, no fix files for baseline script | |
| 2 | try-fix (claude-sonnet-4.6) | DispatcherQueue.TryEnqueue(Low priority) + TaskCompletionSource for deterministic flush |
CollectionViewScrollPage.xaml.cs, Issue33614.cs |
Test-only PR, deterministic but cannot be tested | |
| 3 | try-fix (gpt-5.3-codex) | Deterministic label polling in UI test assertions; remove animate:false |
All 4 test files | Test-only PR, Windows UI tests cannot run on Android agent | |
| 4 | try-fix (gpt-5.4) | Production code fix in ItemsViewHandler.Windows.cs — suppress auto-scroll when ListViewBase.IsLoaded is false |
ItemsViewHandler.Windows.cs |
Only attempt targeting production code; cannot run Windows UI tests on Android | |
| PR | PR #34907 | Test-only: Task.Delay(300) on Windows before label reset + animate:false on Windows + remove TEST_FAILS_ON_WINDOWS guards |
❌ Gate FAILED (test-only, no fix files detected) | 4 test files | Original PR |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-opus-4.6 | 2 | No | All approaches identified correctly. Attempt 4 (production code fix in ItemsViewHandler.Windows.cs) is the right direction but needs Windows agent. |
Exhausted: Yes
Selected Fix: PR's fix — No test-executable alternative found (all blocked due to test-only PR + Android-only agent). PR's test-only approach is the pragmatic choice and code review rated LGTM.
Notes
- All try-fix attempts were BLOCKED because: (1) this is a test-only PR with no non-test source files changed, so
EstablishBrokenBaseline.ps1cannot establish a broken baseline; (2) the target platform is Android but the issue and tests are Windows-specific - Attempt 4 proposed a potentially stronger production code fix in
ItemsViewHandler.Windows.csthat would eliminate the root cause entirely, but cannot be empirically tested on this agent
📋 Report — Final Recommendation
⚠️ Final Recommendation: REQUEST CHANGES
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | ✅ COMPLETE | Test-only PR, issue #34772, Windows CollectionView ScrollTo flakiness |
| Code Review | LGTM (high) | 0 errors, 1 warning, 2 suggestions |
| Gate | ❌ FAILED | Android — "No fix files detected" (expected: test-only PR) |
| Try-Fix | ✅ COMPLETE | 4 attempts, 0 passing (all BLOCKED: test-only + Android agent) |
| Report | ✅ COMPLETE |
Code Review Impact on Try-Fix
The code review Task.Delay(300) being replaceable with Task.Yield() or Task.Delay(0) was reflected in Attempts 1 and 2, which explored Task.Yield() and a DispatcherQueue.TryEnqueue(Low) + TaskCompletionSource flush respectively. Attempt 4 (gpt-5.4) went further and proposed a production-code fix in ItemsViewHandler.Windows.cs to eliminate the root cause entirely. The code review finding guided all models toward more deterministic synchronization approaches.
Summary
PR #34907 is a test-only fix for Windows CollectionView ScrollTo flakiness caused by PR #24867's async DispatcherQueue.TryEnqueue wrapper. The fix is pragmatically sound: a Task.Delay(300) to allow deferred callbacks to complete before resetting labels, animate:false on Windows to avoid intermediate scroll events, and removal of TEST_FAILS_ON_WINDOWS guards. Code review rated LGTM with one warning.
Recommendation is REQUEST CHANGES for the following reasons:
- Gate failed — tests did not behave as expected (per prompt). While the gate failure is due to a test-only PR detection issue (not actual test failures), the gate outcome is ❌ FAILED.
- Stronger alternative identified — Try-Fix Attempt 4 proposed a production-code fix in
ItemsViewHandler.Windows.csthat would suppress the auto-scroll on pre-load item population (!ListViewBase.IsLoaded). This would fix the root cause instead of working around it in tests, and would benefit all users — not just test reliability. Task.Delay(300)is fragile — The 300ms arbitrary delay could be replaced withTask.Delay(0)or aDispatcherQueue.TryEnqueue(Low)flush for equivalent correctness. As noted by Copilot's inline review comment (which the author dismissed), the timing-based approach may still be flaky on heavily loaded CI machines.
Root Cause
PR #24867 changed ScrollIntoView in OnItemsVectorChanged from synchronous to asynchronous via DispatcherQueue.TryEnqueue() on Windows. This introduced a race: when a test navigates to the scroll page, items load → OnItemsVectorChanged fires → ScrollIntoView is queued async → test code resets labels → queued scroll fires → labels overwritten with "Fired" instead of "Not Fired".
Fix Quality
The PR's test-layer fix is reasonable and pragmatic for immediate CI stabilization. However:
Task.Delay(300)is an arbitrary timing heuristic — it works in practice but could silently become flaky if CI machines are slower, or waste 300ms whenTask.Delay(0)would be sufficient- Disabling animation on Windows for Issue33614 reduces test coverage of the animated scroll path (this concern was raised by Copilot inline review but dismissed by the author)
- Attempt 4's
!ListViewBase.IsLoadedcheck inItemsViewHandler.Windows.csoffers a cleaner production-code fix that would make the test-layer workarounds unnecessary
Suggested improvements:
- Replace
await Task.Delay(300)withawait Task.Delay(0)(dispatcher flush) or a deterministicDispatcherQueue-based flush helper - Consider the production code fix: in
ItemsViewHandler.Windows.csOnItemsVectorChanged, capture!ListViewBase.IsLoadedbeforeTryEnqueueand skipScrollIntoViewiftrue - Update
PlatformAffectedinIssue33614's[Issue]attribute to includePlatformAffected.Windows
…#34907) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause - PR [24867](#24867) fixed a COM exception on Windows by wrapping [ListViewBase.ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) inside [DispatcherQueue.TryEnqueue()](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) in [ItemsViewHandler.Windows.cs](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) → [OnItemsVectorChanged](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html). This changed [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) from synchronous to asynchronous execution, introducing a race condition in ScrollTo-related UI tests on Windows. - Before [24867](#24867) - Items load → [OnItemsVectorChanged](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) → [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) fires (sync) → Scrolled event updates label → Test resets label → Label = "Not Fired" - After [24867](#24867) (async via TryEnqueue): - Items load → [OnItemsVectorChanged](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) → [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) is queued (async) → Test resets label to "Not Fired" → Queued [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) fires → Scrolled event overwrites label = "Fired" - The deferred [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) callback executes after the test has already reset the scroll event labels, causing stale scroll events to overwrite the expected state. Similarly, for [ScrollTo(animate: true)](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) tests, the animated scroll produces intermediate [Scrolled](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) events that haven't settled to the final index when the test reads the label value. ### Description of Change <!-- Enter description of the fix in this section --> **Test reliability improvements:** * Added a delay in `CollectionViewScrollPage.xaml.cs` before resetting scroll event labels to ensure deferred callbacks complete, preventing test flakiness on Windows. * Disabled animation for `ScrollTo` actions on Windows in `Issue33614.cs` to avoid flaky test results. **Test coverage and platform-specific adjustments:** * Removed Windows-specific test skip conditions in `Issue33614.cs` and `CollectionView_ScrollingFeatureTests.cs`, re-enabling these tests on Windows as the related issues have been resolved. [[1]](diffhunk://#diff-d98964fb2b3496a40f82c4700a38b02be920ba2dc4c500cd6f020d1f74b847d1L1) [[2]](diffhunk://#diff-d98964fb2b3496a40f82c4700a38b02be920ba2dc4c500cd6f020d1f74b847d1L24) [[3]](diffhunk://#diff-d0158d1415828d2b2a784462d5b03cadbc262b1cd822351d96b35b146976da66L1580) [[4]](diffhunk://#diff-d0158d1415828d2b2a784462d5b03cadbc262b1cd822351d96b35b146976da66L1793) * Updated conditional compilation for a grouped list test to only skip on Android, as the Windows issue has been addressed. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #34772 | Before | After | |----------|----------| | <img src="https://github.com/user-attachments/assets/7db67c75-c970-43b0-bcb8-3232af341fa4"> | <img src="https://github.com/user-attachments/assets/998d74ee-5d4b-48b2-8632-47dc89d2e3e7"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
…#34907) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause - PR [24867](#24867) fixed a COM exception on Windows by wrapping [ListViewBase.ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) inside [DispatcherQueue.TryEnqueue()](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) in [ItemsViewHandler.Windows.cs](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) → [OnItemsVectorChanged](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html). This changed [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) from synchronous to asynchronous execution, introducing a race condition in ScrollTo-related UI tests on Windows. - Before [24867](#24867) - Items load → [OnItemsVectorChanged](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) → [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) fires (sync) → Scrolled event updates label → Test resets label → Label = "Not Fired" - After [24867](#24867) (async via TryEnqueue): - Items load → [OnItemsVectorChanged](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) → [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) is queued (async) → Test resets label to "Not Fired" → Queued [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) fires → Scrolled event overwrites label = "Fired" - The deferred [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) callback executes after the test has already reset the scroll event labels, causing stale scroll events to overwrite the expected state. Similarly, for [ScrollTo(animate: true)](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) tests, the animated scroll produces intermediate [Scrolled](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) events that haven't settled to the final index when the test reads the label value. ### Description of Change <!-- Enter description of the fix in this section --> **Test reliability improvements:** * Added a delay in `CollectionViewScrollPage.xaml.cs` before resetting scroll event labels to ensure deferred callbacks complete, preventing test flakiness on Windows. * Disabled animation for `ScrollTo` actions on Windows in `Issue33614.cs` to avoid flaky test results. **Test coverage and platform-specific adjustments:** * Removed Windows-specific test skip conditions in `Issue33614.cs` and `CollectionView_ScrollingFeatureTests.cs`, re-enabling these tests on Windows as the related issues have been resolved. [[1]](diffhunk://#diff-d98964fb2b3496a40f82c4700a38b02be920ba2dc4c500cd6f020d1f74b847d1L1) [[2]](diffhunk://#diff-d98964fb2b3496a40f82c4700a38b02be920ba2dc4c500cd6f020d1f74b847d1L24) [[3]](diffhunk://#diff-d0158d1415828d2b2a784462d5b03cadbc262b1cd822351d96b35b146976da66L1580) [[4]](diffhunk://#diff-d0158d1415828d2b2a784462d5b03cadbc262b1cd822351d96b35b146976da66L1793) * Updated conditional compilation for a grouped list test to only skip on Android, as the Windows issue has been addressed. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #34772 | Before | After | |----------|----------| | <img src="https://github.com/user-attachments/assets/7db67c75-c970-43b0-bcb8-3232af341fa4"> | <img src="https://github.com/user-attachments/assets/998d74ee-5d4b-48b2-8632-47dc89d2e3e7"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
…ability (#35133) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! > **Depends on #35136** (pipeline category detection — should merge first) ## What this does Two things: ### 1. UI test category detection in PR review During the PR review workflow, Step 0.5 detects which UI test categories the PR impacts and writes the result to the AI summary comment. This gives reviewers visibility into which UI tests are relevant. **Detection** reuses the 3-tier script from #35136 (test attributes → source paths → AI reasoning). **AI summary** shows a new 🧪 UI Tests section with detected categories before the gate section. ### 2. Gate reliability fixes Multiple fixes to make the gate (`verify-tests-fail.ps1`) more deterministic: | Fix | Problem it solves | |-----|-------------------| | **Absolute path resolution** | Gate scripts not found on Linux CI agents (`Resolve-Path`, `GetFullPath`) | | **File existence check** | Instant cryptic failure when verify script is missing — now logs clear error | | **3x retry on ENV ERROR** | Emulator timeouts, ADB failures, app crashes — transient issues that pass on retry | | **Strip bad report blocks** | Old verify script produces `Passed: False` with empty counts — stripped instead of shown | | **Gate log in fallback** | When report is missing, shows last 20 lines of gate output instead of just `❌ FAILED / Platform: IOS` | ## Files | File | Changes | |------|---------| | `.github/scripts/Review-PR.ps1` | Step 0.5 category detection + all 5 gate fixes | | `.github/scripts/post-ai-summary-comment.ps1` | Add `uitests` phase to render detected categories | | `.github/pr-review/pr-preflight.md` | Step 7: AI identifies impacted UI test categories | ## Validation — PR reviewer builds (Apr 26) 10 builds against real PRs — all succeeded ✅. Category detection shown in AI summary comment. | PR | Categories Detected | Build | AI Summary | |----|-------------------|-------|------------| | #35037 (WebView theme) | `ViewBaseTests,WebView` | [13940071](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940071) | [comment](#35037 (comment)) | | #35031 (Shell memory leak) | `Shell` | [13940072](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940072) | [comment](#35031 (comment)) | | #35020 (XAML Hot Reload) | _(none — XAML only)_ | [13940073](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940073) | ✅ Shows "No UI test categories" | | #35008 (Shell SearchHandler) | `Shell` | [13940074](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940074) | ✅ | | #34997 (RadioButton gradient) | `RadioButton,ViewBaseTests` | [13940075](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940075) | ✅ | | #34980 (DatePicker rotation) | `ViewBaseTests` | [13940076](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940076) | ✅ | | #34974 (Picker CharacterSpacing) | `ViewBaseTests` | [13940077](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940077) | ✅ | | #34923 (SwipeView threshold) | `SwipeView,ViewBaseTests` | [13940078](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940078) | ✅ | | #34907 (CollectionView ScrollTo) | `CollectionView` | [13940079](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940079) | ✅ | | #34845 (RefreshView binding) | `RefreshView,ViewBaseTests` | [13940080](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940080) | ✅ | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…#34907) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause - PR [24867](#24867) fixed a COM exception on Windows by wrapping [ListViewBase.ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) inside [DispatcherQueue.TryEnqueue()](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) in [ItemsViewHandler.Windows.cs](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) → [OnItemsVectorChanged](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html). This changed [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) from synchronous to asynchronous execution, introducing a race condition in ScrollTo-related UI tests on Windows. - Before [24867](#24867) - Items load → [OnItemsVectorChanged](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) → [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) fires (sync) → Scrolled event updates label → Test resets label → Label = "Not Fired" - After [24867](#24867) (async via TryEnqueue): - Items load → [OnItemsVectorChanged](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) → [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) is queued (async) → Test resets label to "Not Fired" → Queued [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) fires → Scrolled event overwrites label = "Fired" - The deferred [ScrollIntoView](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) callback executes after the test has already reset the scroll event labels, causing stale scroll events to overwrite the expected state. Similarly, for [ScrollTo(animate: true)](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) tests, the animated scroll produces intermediate [Scrolled](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) events that haven't settled to the final index when the test reads the label value. ### Description of Change <!-- Enter description of the fix in this section --> **Test reliability improvements:** * Added a delay in `CollectionViewScrollPage.xaml.cs` before resetting scroll event labels to ensure deferred callbacks complete, preventing test flakiness on Windows. * Disabled animation for `ScrollTo` actions on Windows in `Issue33614.cs` to avoid flaky test results. **Test coverage and platform-specific adjustments:** * Removed Windows-specific test skip conditions in `Issue33614.cs` and `CollectionView_ScrollingFeatureTests.cs`, re-enabling these tests on Windows as the related issues have been resolved. [[1]](diffhunk://#diff-d98964fb2b3496a40f82c4700a38b02be920ba2dc4c500cd6f020d1f74b847d1L1) [[2]](diffhunk://#diff-d98964fb2b3496a40f82c4700a38b02be920ba2dc4c500cd6f020d1f74b847d1L24) [[3]](diffhunk://#diff-d0158d1415828d2b2a784462d5b03cadbc262b1cd822351d96b35b146976da66L1580) [[4]](diffhunk://#diff-d0158d1415828d2b2a784462d5b03cadbc262b1cd822351d96b35b146976da66L1793) * Updated conditional compilation for a grouped list test to only skip on Android, as the Windows issue has been addressed. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #34772 | Before | After | |----------|----------| | <img src="https://github.com/user-attachments/assets/7db67c75-c970-43b0-bcb8-3232af341fa4"> | <img src="https://github.com/user-attachments/assets/998d74ee-5d4b-48b2-8632-47dc89d2e3e7"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Root Cause
PR 24867 fixed a COM exception on Windows by wrapping ListViewBase.ScrollIntoView inside DispatcherQueue.TryEnqueue() in ItemsViewHandler.Windows.cs → OnItemsVectorChanged. This changed ScrollIntoView from synchronous to asynchronous execution, introducing a race condition in ScrollTo-related UI tests on Windows.
Before 24867
After 24867 (async via TryEnqueue):
The deferred ScrollIntoView callback executes after the test has already reset the scroll event labels, causing stale scroll events to overwrite the expected state. Similarly, for ScrollTo(animate: true) tests, the animated scroll produces intermediate Scrolled events that haven't settled to the final index when the test reads the label value.
Description of Change
Test reliability improvements:
CollectionViewScrollPage.xaml.csbefore resetting scroll event labels to ensure deferred callbacks complete, preventing test flakiness on Windows.ScrollToactions on Windows inIssue33614.csto avoid flaky test results.Test coverage and platform-specific adjustments:
Issue33614.csandCollectionView_ScrollingFeatureTests.cs, re-enabling these tests on Windows as the related issues have been resolved. [1] [2] [3] [4]Issues Fixed
Fixes #34772