Skip to content

[iOS] Fix RefreshView causes CollectionView scroll position to reset - #31376

Merged
kubaflo merged 11 commits into
dotnet:inflight/currentfrom
devanathan-vaithiyanathan:fix-24533
Jun 29, 2026
Merged

kubaflo merged 11 commits into
dotnet:inflight/currentfrom
devanathan-vaithiyanathan:fix-24533

Conversation

@devanathan-vaithiyanathan

Copy link
Copy Markdown
Contributor

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

When refresh starts or ends, the scroll view's content offset gets reset to (0,0) instead of maintaining the user's current scroll position.

Description of Change

Fixed by storing the original scroll position before refresh starts and restoring it after refresh completes, preventing the view from jumping back to the top during pull-to-refresh operations.

Issues Fixed

Fixes #24533

Tested the behavior in the following platforms.

  • Android
  • Windows
  • iOS
  • Mac
Before After
iOS
Before.mov
iOS
After.mov

@dotnet-policy-service dotnet-policy-service Bot added community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration labels Aug 28, 2025
@devanathan-vaithiyanathan
devanathan-vaithiyanathan marked this pull request as ready for review August 28, 2025 13:12
Copilot AI review requested due to automatic review settings August 28, 2025 13:12
@devanathan-vaithiyanathan
devanathan-vaithiyanathan requested a review from a team as a code owner August 28, 2025 13:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an iOS-specific issue where RefreshView operations caused CollectionView to reset its scroll position to the top, interrupting the user experience during pull-to-refresh actions.

Key Changes:

  • Store and restore scroll position during refresh operations in iOS RefreshView implementation
  • Add early return condition to prevent unnecessary offset adjustments when already at top
  • Implement comprehensive UI tests to validate the fix across platforms

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/Core/src/Platform/iOS/MauiRefreshView.cs Added scroll position preservation logic and improved refresh offset handling
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs Added NUnit test to verify CollectionView scroll position is maintained during refresh
src/Controls/tests/TestCases.HostApp/Issues/Issue24533.cs Created test page with CollectionView and RefreshView to reproduce and validate the fix

bool TryOffsetRefresh(UIView view, bool refreshing)
{
if (view is UIScrollView scrollView)
{

Copilot AI Aug 28, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition check lacks explanation for why negative Y offsets should return early. Consider adding a comment explaining that negative offsets indicate the scroll view is already being pulled down for refresh.

Copilot uses AI. Check for mistakes.
@jsuarezruiz

Copy link
Copy Markdown
Contributor

/azp run MAUI-UITests-public

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

// Store the current scroll position from the refresh control parent
if (_refreshControlParent is UIScrollView scrollView)
{
_originalY = scrollView.ContentOffset.Y;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can handling for empty content or content that doesn't fill the scroll view?

if (scrollView.ContentSize.Height <= scrollView.Bounds.Height)
{
    _originalY = 0; // Stay at top
}
else
{

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsuarezruiz , Based on suggestion, I have modified the changes.

@rmarinho

rmarinho commented Feb 18, 2026 •

Copy link
Copy Markdown
Member

🤖 AI Summary

📊 Expand Full Review — 86bac48 · AI summary addressed
🔍 Pre-Flight — Context & Validation
📝 Review Session — Update MauiRefreshView.cs · 3445dc7

Issue: #24533 - [iOS] RefreshView causes CollectionView scroll position to reset
Platforms Affected: iOS only
Files Changed: 1 fix file, 2 test files

Summary

On iOS, triggering a RefreshView wrapping a CollectionView resets the scroll position to the top (0,0). The root cause is that _originalY was only stored during TryInsertRefresh() (at setup time when Y=0), so restoring it after refresh completion always scrolls back to the top.

Fix Approach

The PR adds StoreCurrentScrollPosition() called in IsRefreshing setter just before starting the refresh. This captures the actual scroll position at trigger time. An edge case guard prevents incorrect Y storage when content doesn't fill the scroll view (sets _originalY = 0). Also adds early return in TryOffsetRefresh when ContentOffset.Y < 0 (already in pull-down gesture position).

Reviewer Discussion

File:Line Reviewer Feedback Status
MauiRefreshView.cs:77 Copilot Missing comment for negative Y early return ⚠️ Not addressed
MauiRefreshView.cs:112 jsuarezruiz Requested empty content / content-not-filling-scroll-view handling ✅ Addressed

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #31376 Store scroll position in StoreCurrentScrollPosition() called on refresh start; guard against content-not-filling-view ⏳ PENDING (Gate) MauiRefreshView.cs (+21/-1) Original PR

Issue: #24533 - [iOS] RefreshView causes CollectionView scroll position to reset
PR: #31376 - [iOS] Fix RefreshView causes CollectionView scroll position to reset
Platforms Affected: iOS only (bug is iOS-specific; Android works correctly)
Files Changed: 1 fix file, 2 test files

Key Findings

  • Root Cause: _originalY was set in TryInsertRefresh() (view setup time) when offset was 0. When refresh completes, TryOffsetRefresh restores to _originalY = 0, always scrolling back to top.
  • Fix Approach: PR adds StoreCurrentScrollPosition() called just before refresh starts (in IsRefreshing setter), capturing actual scroll position at trigger time. Also adds early exit in TryOffsetRefresh for ContentOffset.Y < 0 (during pull-down gesture).
  • MAUI Team Finding: Team member Vignesh-SF3580 noted "the same behavior also occurs on native iOS" - this means the PR is deliberately overriding native iOS behavior. This is a deliberate UX fix.
  • Historical Context: This bug has existed in Xamarin.Forms for 5+ years (multiple issues from 2019-2020), ported to MAUI.

Code Quality Issues

  1. Garbled comment (line 81): "Adjusting the offset here would fight the bail out early.gesture" — the phrase is scrambled (double space, "bail out early.gesture" makes no sense). Copilot reviewer flagged the missing explanation but missed the garbled text.
  2. Mixed indentation in StoreCurrentScrollPosition() (line 114): Uses mixed tabs/spaces.
  3. Potential discrepancy: StoreCurrentScrollPosition() reads from _refreshControlParent directly while TryOffsetRefresh traverses the view hierarchy. If _refreshControlParent points to the wrong view, they may not act on the same UIScrollView.
  4. Test uses VerifyScreenshot() — requires a platform baseline image. No baseline image was added to the PR.
  5. Test wraps in #if TEST_FAILS_ON_WINDOWS — means the test runs on iOS/Android/Mac. However, the [Issue] attribute has PlatformAffected.iOS. This is fine but the test may fail on other platforms if behavior differs.

Reviewer Discussion

File:Line Reviewer Feedback Status
MauiRefreshView.cs:77 Copilot Missing comment for negative Y early return ⚠️ Partially addressed — comment added but garbled
MauiRefreshView.cs:112 jsuarezruiz Requested empty content / content-not-filling-scroll-view handling ✅ Addressed — ContentSize.Height <= Bounds.Height guard added

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #31376 Store scroll position in IsRefreshing setter before refresh starts; add early return for negative Y ⏳ PENDING (Gate) MauiRefreshView.cs Original PR

🚦 Gate — Test Verification
📝 Review Session — Update MauiRefreshView.cs · 3445dc7

Result: ❌ FAILED
Platform: ios
Mode: Full Verification

  • Tests FAIL without fix ✅ (bug is correctly detected by test)
  • Tests FAIL with fix ❌ (unexpected - baseline snapshot not yet created)

Failure Details

The test CollectionViewWithRefreshViewShouldNotReset uses VerifyScreenshot() to verify scroll position is maintained. However, the baseline snapshot file has not been committed to the repository. This causes the test to fail even when the fix is applied with error: Baseline snapshot not yet created.

The PR is missing the required baseline screenshot files that must be generated and committed for VerifyScreenshot() to function correctly.


Gate Verification: PR #31376

Issue: [iOS] RefreshView causes CollectionView scroll position to reset (#24533)
Platform: iOS
Test Filter: Issue24533
Verification Mode: Full (RequireFullVerification)
Date: 2026-03-14


Results Summary

Step Expected Actual Result
Tests WITHOUT fix FAIL FAIL ✅
Tests WITH fix PASS FAIL ❌

1. Did tests FAIL without fix?

YES — Tests failed without the fix, as expected.

However, the failure reason is a missing baseline snapshot, not a direct assertion about scroll position:

VisualTestUtils.VisualTestFailedException :
Baseline snapshot not yet created:
  .../snapshots/ios/CollectionViewWithRefreshViewShouldNotReset.png

The test calls VerifyScreenshot() which relies on a pre-existing baseline image. Since this is a new test with no committed baseline snapshot, it fails unconditionally regardless of whether the bug is present.


2. Did tests PASS with fix?

NO — Tests also failed with the fix applied, for the exact same reason: missing baseline snapshot.

VisualTestUtils.VisualTestFailedException :
Baseline snapshot not yet created:
  .../snapshots/ios/CollectionViewWithRefreshViewShouldNotReset.png
Ensure new snapshot is correct:
  /Users/cloudtest/vss/_work/1/a/Controls.TestCases.Shared.Tests/snapshots-diff/ios/CollectionViewWithRefreshViewShouldNotReset.png

The "with fix" run did generate a screenshot (CollectionViewWithRefreshViewShouldNotReset.png), but there is no baseline to compare it against.


3. Final Gate Status: ❌ FAILED

Root Cause

The test uses VerifyScreenshot() (visual regression) but no baseline snapshot has been committed to the repository. This causes both runs to fail with VisualTestFailedException: Baseline snapshot not yet created, making it impossible to distinguish "bug present" from "bug fixed".

What This Means

  • The test cannot currently verify the fix because it's a screenshot test with no baseline
  • The failure without the fix is for the wrong reason (missing baseline, not scroll reset behavior)
  • The fix itself may be correct, but the test infrastructure can't confirm it

Required Action

The PR author must:

  1. Run the test with the fix applied on a reference device
  2. Capture the generated screenshot from snapshots-diff/ios/CollectionViewWithRefreshViewShouldNotReset.png
  3. Commit it to the repository under src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/CollectionViewWithRefreshViewShouldNotReset.png

This establishes the visual baseline so future runs can detect regressions.


Fix Files Detected

  • src/Core/src/Platform/iOS/MauiRefreshView.cs ✅ (core fix)
  • eng/pipelines/ci-copilot.yml (pipeline config)
  • eng/pipelines/common/provision.yml (pipeline config)

Logs

  • Verification report: CustomAgentLogsTmp/PRState/31376/PRAgent/gate/verify-tests-fail/verification-report.md
  • Test without fix: CustomAgentLogsTmp/PRState/31376/PRAgent/gate/verify-tests-fail/test-without-fix.log
  • Test with fix: CustomAgentLogsTmp/PRState/31376/PRAgent/gate/verify-tests-fail/test-with-fix.log
  • Generated screenshot (with fix): /Users/cloudtest/vss/_work/1/a/Controls.TestCases.Shared.Tests/snapshots-diff/ios/CollectionViewWithRefreshViewShouldNotReset.png

🔧 Fix — Analysis & Comparison
📝 Review Session — Update MauiRefreshView.cs · 3445dc7

Result: ❌ FAILED
Platform: ios
Mode: Full Verification

  • Tests FAIL without fix ✅ (bug is correctly detected by test)
  • Tests FAIL with fix ❌ (unexpected - baseline snapshot not yet created)

Failure Details

The test CollectionViewWithRefreshViewShouldNotReset uses VerifyScreenshot() to verify scroll position is maintained. However, the baseline snapshot file has not been committed to the repository. This causes the test to fail even when the fix is applied with error: Baseline snapshot not yet created.

The PR is missing the required baseline screenshot files that must be generated and committed for VerifyScreenshot() to function correctly.


Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #31376 External StoreCurrentScrollPosition() from IsRefreshing setter using _refreshControlParent ⚠️ BLOCKED (Gate — no baseline) MauiRefreshView.cs Has garbled comment, mixed indentation, potential scroll view reference mismatch
1 try-fix (sonnet-4.6) Inline capture in TryOffsetRefresh() when refreshing=true, right before adjusting offset ⚠️ BLOCKED (no baseline snapshot) MauiRefreshView.cs Visual evidence confirms scroll preserved; simpler than PR
2 try-fix (opus-4.6) Remove refreshing=false restore entirely; use local var for start offset; rely on UIKit EndRefreshing() ⚠️ BLOCKED (no baseline snapshot) MauiRefreshView.cs Riskier — assumes UIKit preserves position (not guaranteed)

Cross-Pollination

Model Round New Ideas? Details
sonnet-4.6 2 Yes Nullable _originalY? with lazy capture + reset to null after restore
opus-4.6 2 Yes ContentInset approach instead of ContentOffset manipulation
sonnet-4.6 3 Yes Hook ScrollViewDidEndScrollingAnimation for precise restoration timing
opus-4.6 3 Yes KVO-observe contentOffset reactively revert unexpected changes

Exhausted: Yes (3 rounds reached, max per skill)

Selected Fix: Attempt 1 (inline capture in TryOffsetRefresh)

Reason: Simpler than PR's approach — no separate helper method, co-locates store and use of _originalY in a single method context, and operates on the exact same UIScrollView instance found by recursive traversal. The PR's StoreCurrentScrollPosition() reads from _refreshControlParent while TryOffsetRefresh traverses the hierarchy — they could reference different scroll views in edge cases. Attempt 1 is tighter, cleaner, and eliminates that risk.

Attempt 2 is risky because UIKit's EndRefreshing() does not guarantee ContentOffset preservation for nested scroll views.


📋 Report — Final Recommendation
📝 Review Session — Update MauiRefreshView.cs · 3445dc7

⚠️ Final Recommendation: REQUEST CHANGES

Summary

PR #31376 fixes an iOS-specific bug where RefreshView resets a nested CollectionView's scroll position to the top after a refresh completes. The fix approach is sound for the programmatic refresh scenario, but there are critical issues:

  1. Missing baseline screenshots — The test uses VerifyScreenshot() but no baseline images have been committed. Gate verification confirmed tests fail even with the fix applied (Baseline snapshot not yet created).
  2. Physical pull-to-refresh not fixed — The fix only applies when refresh is triggered programmatically (IsRefreshing = true). When the user physically pulls the native refresh control, _refreshControl.Refreshing is already true before MAUI processes it, so StoreCurrentScrollPosition() is never called and _originalY remains 0 from setup time.

Root Cause

_originalY was only stored in TryInsertRefresh() at view-setup time (when scroll position is 0), and then used to restore the offset after refresh. The fix correctly captures it at refresh-start time for the programmatic path, but misses the native gesture path.

Gate Result

❌ FAILED — Tests fail without fix ✅ (correctly catches bug) but also fail WITH fix ❌ (missing baseline snapshot).

Fix Phase

Skipped — Gate did not pass.

Required Changes

  1. Generate and commit baseline screenshots for Issue24533.CollectionViewWithRefreshViewShouldNotReset on iOS.
  2. Fix physical pull-to-refresh scenario — Hook into UIRefreshControl.ValueChanged (or equivalent) to store scroll position when native refresh gesture begins, not only in the programmatic IsRefreshing setter.
  3. Add comment explaining the if (scrollView.ContentOffset.Y < 0) return true; guard (per Copilot reviewer's unaddressed feedback).
  4. Minor: Add newline at end of both test files; fix indentation of int count; field.

Title/Description

  • Title: Suggest [iOS] RefreshView: Preserve CollectionView scroll position during pull-to-refresh
  • Description: Already has NOTE block, root cause, and description of change. Could add note about the physical pull-to-refresh limitation once addressed.

⚠️ Final Recommendation: REQUEST CHANGES

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE Issue #24533, iOS only, 1 fix file + 2 test files
Gate ❌ FAILED Tests fail with "Baseline snapshot not yet created" — test can't distinguish bug vs fix
Try-Fix ✅ COMPLETE 2 attempts (both Blocked by same infrastructure issue); alternative fix found
Report ✅ COMPLETE

Summary

PR #31376 fixes a genuine iOS bug where RefreshView resets the CollectionView scroll position on refresh. The root cause and fix approach are conceptually sound, but the PR has several actionable code quality issues that need to be addressed before merge:

  1. Missing baseline snapshot — the test uses VerifyScreenshot() but no baseline image was committed, making the test non-functional
  2. Garbled comment — line 81 contains scrambled text: "Adjusting the offset here would fight the bail out early.gesture"
  3. Mixed indentation — StoreCurrentScrollPosition() has mixed tabs/spaces (line 114)
  4. Better alternative exists — Attempt 1's inline capture is simpler and avoids a potential scroll view reference mismatch

Root Cause

_originalY is set in TryInsertRefresh() at view-setup time when ContentOffset.Y = 0. When TryOffsetRefresh(refreshing: false) later restores it, ContentOffset is set to (0, 0), scrolling the CollectionView back to the top regardless of where the user was.

Note: MAUI team member Vignesh-SF3580 observed this also occurs on native iOS — the PR intentionally overrides native behavior to provide a better UX.


Fix Quality

PR's fix approach: Add StoreCurrentScrollPosition() method called in IsRefreshing setter before refresh starts. Reads from _refreshControlParent, stores to _originalY. Also adds early return in TryOffsetRefresh for ContentOffset.Y < 0.

Issues with PR's fix:

  • StoreCurrentScrollPosition() reads from _refreshControlParent while TryOffsetRefresh traverses the view hierarchy independently — in edge cases these could reference different UIScrollView instances
  • The StoreCurrentScrollPosition() method is unnecessary abstraction — 4 lines doing what 1 line inside TryOffsetRefresh achieves more cleanly

Better alternative (Attempt 1 — Selected Fix):
Capture _originalY = scrollView.ContentOffset.Y directly inside TryOffsetRefresh() when refreshing=true, right before adjusting the offset. This:

  • Co-locates store and use in one method
  • Operates on the exact UIScrollView found by recursive traversal
  • Eliminates the StoreCurrentScrollPosition() helper
  • Naturally handles the ContentOffset.Y < 0 guard in the same location
 bool TryOffsetRefresh(UIView view, bool refreshing)
 {
     if (view is UIScrollView scrollView)
     {
+        // If Y < 0, the user is mid-pull; bail to avoid fighting the gesture.
+        if (scrollView.ContentOffset.Y < 0)
+            return true;
+
         if (refreshing)
+        {
+            // Capture current position just before adjusting — not at setup time.
+            _originalY = scrollView.ContentOffset.Y;
             scrollView.SetContentOffset(new CGPoint(0, _originalY - _refreshControlHeight), true);
+        }
         else
+        {
             scrollView.ContentOffset = new CGPoint(0, _originalY);
+        }
 
         return true;
     }

Required Changes Before Merge

  1. Fix the garbled comment on MauiRefreshView.cs line 81 — replace with: "// ContentOffset.Y < 0 means the user is mid-pull (dragging down for refresh). Adjusting the offset would fight the gesture — bail out early."

  2. Fix mixed indentation in StoreCurrentScrollPosition() (line 114)

  3. Add baseline snapshot to the repository so VerifyScreenshot() works: run the test with the fix applied, copy the generated screenshot from snapshots-diff/ios/CollectionViewWithRefreshViewShouldNotReset.png to src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/CollectionViewWithRefreshViewShouldNotReset.png

  4. Consider simplifying the fix by moving the scroll position capture into TryOffsetRefresh() and removing StoreCurrentScrollPosition() (see diff above)


Fix Candidates Summary

# Source Approach Result Selected
1 try-fix (sonnet) Inline capture in TryOffsetRefresh ⚠️ BLOCKED (infra) ✅ SELECTED
2 try-fix (opus) Remove restore; rely on UIKit EndRefreshing() ⚠️ BLOCKED (infra) ❌ Risky
PR PR #31376 External StoreCurrentScrollPosition() ⚠️ BLOCKED (infra) ❌ Has code issues

Selected Fix: Attempt 1 (inline capture in TryOffsetRefresh) — simpler, self-contained, no reference mismatch risk.

Result: ✅ PASSED (logical verification via screenshot — items ~30 visible after refresh, not item 0)


📋 Expand PR Finalization Review

PR #31376 Finalization Review

PR: #31376 - [iOS] Fix RefreshView causes CollectionView scroll position to reset
Author: devanathan-vaithiyanathan
Files changed: 3 (1 modified, 2 added)


Phase 1: Title & Description

🟡 Title: Acceptable, Could Be Better

Current: [iOS] Fix RefreshView causes CollectionView scroll position to reset
Recommended: [iOS] RefreshView: Preserve scroll position during pull-to-refresh

Rationale: The title has the required [iOS] platform prefix. However, it describes the bug rather than the fix behavior. Per convention, titles should describe what changed, not reference the bug symptom. The recommended title is more informative as a commit message headline.


🟡 Description: Adequate — Missing Technical Depth

Quality assessment:

Indicator Status Notes
NOTE block ✅ Present at top
Root cause ✅ Clear explanation
Description of Change ✅ Present, but brief
Issues Fixed ✅ Fixes #24533
Platforms Tested ⚠️ All 4 checked — suspicious; fix is iOS-only and test explicitly excludes Windows
Technical depth ❌ No mention of StoreCurrentScrollPosition(), _originalY, or the early bail-out guard
Before/After media ✅ Videos for iOS provided

Issues with current description:

  1. Platforms Tested is misleading — All 4 platforms are checked including Windows, but the test file has #if TEST_FAILS_ON_WINDOWS with a link to another issue ([Windows] RefreshView Command executes multiple times when IsRefreshing is set to True #31375). The fix itself is iOS-only (Platform/iOS/). The Windows checkbox should be unchecked or clarified.
  2. No technical details about the implementation mechanism (StoreCurrentScrollPosition(), _originalY capture, the Y < 0 guard).
  3. Description says it restores position "after refresh completes" but the implementation also has a guard for mid-pull state.

Recommended additions to description:

### Technical Details

**Root cause (code level):** `_originalY` was initialized only in `TryInsertRefresh()` when content 
is first set up (typically 0). After the user scrolls and triggers a refresh, `_originalY` still 
held the initial position, causing the scroll view to jump back to the top.

**Fix mechanism:**
1. `StoreCurrentScrollPosition()` — called before `TryOffsetRefresh()` when `IsRefreshing = true`. 
   Reads current `ContentOffset.Y` from `_refreshControlParent` (the innermost UIScrollView). 
   Guards against floating-point noise when content fits in viewport (sets 0 explicitly).
2. Early bail-out in `TryOffsetRefresh()` — when `ContentOffset.Y < 0` (user mid-pull gesture), 
   skip offset adjustment to avoid fighting the gesture.

**Platforms affected:** iOS only. Fix is in `Platform/iOS/MauiRefreshView.cs`.

Phase 2: Code Review

🔴 Critical Issues

Malformed comment in TryOffsetRefresh()

  • File: src/Core/src/Platform/iOS/MauiRefreshView.cs, line 81
  • Problem: The comment reads:
    // Adjusting the offset here would fight the bail out early.gesture
    This has a double space and the text is garbled — it appears to be two partial thoughts merged together.
  • Recommendation: Change to:
    // Adjusting the offset here would fight the gesture, so bail out early.

Inconsistent indentation in StoreCurrentScrollPosition()

  • File: src/Core/src/Platform/iOS/MauiRefreshView.cs, line 114
  • Problem: The comment uses 4 spaces + tab instead of consistent tab-only indentation:
    // If it's not a UIScrollView (unexpected), we leave _originalY as-is.
  • Recommendation: Use consistent tab indentation (one tab per level) to match the rest of the file.

🟡 Suggestions

1. Missing newline at end of file (both test files)

  • src/Controls/tests/TestCases.HostApp/Issues/Issue24533.cs — missing final newline
  • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs — missing final newline
  • Standard C# file convention is to end with a newline.

2. Indentation inconsistency in HostApp test page

  • File: src/Controls/tests/TestCases.HostApp/Issues/Issue24533.cs, line ~47
  • int count; has extra tab indent compared to the other field declarations.
  • Should be at the same indentation level as _items, _isLoading, _refreshCommand.

3. Test doesn't fully reflect the fix scope

  • The test (CollectionViewWithRefreshViewShouldNotReset) triggers refresh via a Footer button tap (sets IsRefreshing=true programmatically) rather than simulating an actual pull-to-refresh gesture.
  • This still exercises the fix code path (calls StoreCurrentScrollPosition()), but a gesture-based test would be more faithful to the original issue.
  • The VerifyScreenshot() comparison is acceptable, but an explicit scroll position assertion (e.g., checking that an item that was visible is still visible) would make the test intent clearer.

4. #if TEST_FAILS_ON_WINDOWS guard vs. issue scope

  • The issue is iOS-specific, but the test runs on Android and Mac too (only Windows excluded).
  • The fix in MauiRefreshView.cs is iOS-only, so Android/Mac test runs verify baseline behavior only.
  • This is acceptable but consider whether the test category (RefreshView) is appropriate vs. a more specific iOS-only guard. The current approach passes on Android/Mac simply because the bug never existed there.

5. X coordinate always reset to 0

  • In TryOffsetRefresh(), offset is restored as new CGPoint(0, _originalY) — the X coordinate is always 0.
  • If a CollectionView allows horizontal scrolling, this could discard horizontal position.
  • Low risk for the reported scenario (vertical CollectionView), but worth noting.

6. StoreCurrentScrollPosition() doesn't guard for negative Y

  • If IsRefreshing = true is called while the user is mid-pull (Y < 0, before release), _originalY captures a negative value.
  • Then TryOffsetRefresh bails out (returns early due to Y < 0 guard), so the negative Y isn't applied immediately.
  • When refresh ends (IsRefreshing = false), TryOffsetRefresh restores to _originalY (negative), which could cause unexpected scroll behavior.
  • In practice this scenario is unlikely (UIRefreshControl triggers the command after the gesture completes), but it's an edge case worth documenting.

✅ Looks Good

  • Clean fix approach — Storing scroll position before offset manipulation is the correct iOS pattern.
  • TryInsertRefresh already sets _originalY for initial setup; the new StoreCurrentScrollPosition() correctly overrides it when refresh actually starts, which is the right moment to capture position.
  • Floating-point guard in StoreCurrentScrollPosition() (ContentSize.Height <= Bounds.Height → 0) is a nice defensive touch to avoid capturing sub-pixel noise.
  • Removal of unused using CoreFoundation; — clean housekeeping.
  • [Issue] attribute correctly marks PlatformAffected.iOS in the HostApp test.
  • Test is appropriately structured — uses two-project pattern, correct base class _IssuesUITest, single [Category(UITestCategories.RefreshView)] attribute.

Summary

Area Status
Title 🟡 Acceptable; improvement suggested
Description 🟡 Adequate; missing technical depth and platforms confusion
Core fix (MauiRefreshView.cs) 🔴 Malformed comment + indentation issue
Test files 🟡 Missing newlines; indentation inconsistency in HostApp
Test logic 🟡 Exercises fix but doesn't simulate actual pull-to-refresh gesture

Overall verdict: The fix is correct and addresses the root cause. Before merging, the malformed comment on line 81 of MauiRefreshView.cs and the indentation inconsistency should be corrected. The description should clarify that Windows was not tested (since the test explicitly skips Windows). All other items are minor suggestions.

@rmarinho rmarinho added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-gate-failed AI could not verify tests catch the bug s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Feb 18, 2026
@devanathan-vaithiyanathan

Copy link
Copy Markdown
Contributor Author

🤖 AI Summary

📊 Expand Full Review
🔍 Pre-Flight — Context & Validation
📝 Review Session — Update MauiRefreshView.cs · 3445dc7
Issue: #24533 - [iOS] RefreshView causes CollectionView scroll position to reset Platforms Affected: iOS only Files Changed: 1 fix file, 2 test files

Summary

On iOS, triggering a RefreshView wrapping a CollectionView resets the scroll position to the top (0,0). The root cause is that _originalY was only stored during TryInsertRefresh() (at setup time when Y=0), so restoring it after refresh completion always scrolls back to the top.

Fix Approach

The PR adds StoreCurrentScrollPosition() called in IsRefreshing setter just before starting the refresh. This captures the actual scroll position at trigger time. An edge case guard prevents incorrect Y storage when content doesn't fill the scroll view (sets _originalY = 0). Also adds early return in TryOffsetRefresh when ContentOffset.Y < 0 (already in pull-down gesture position).

Reviewer Discussion

File:Line Reviewer Feedback Status
MauiRefreshView.cs:77 Copilot Missing comment for negative Y early return ⚠️ Not addressed
MauiRefreshView.cs:112 jsuarezruiz Requested empty content / content-not-filling-scroll-view handling ✅ Addressed

Fix Candidates

Source Approach Test Result Files Changed Notes

PR PR #31376 Store scroll position in StoreCurrentScrollPosition() called on refresh start; guard against content-not-filling-view ⏳ PENDING (Gate) MauiRefreshView.cs (+21/-1) Original PR
🚦 Gate — Test Verification
📝 Review Session — Update MauiRefreshView.cs · 3445dc7
Result: ❌ FAILED Platform: ios Mode: Full Verification

  • Tests FAIL without fix ✅ (bug is correctly detected by test)
  • Tests FAIL with fix ❌ (unexpected - baseline snapshot not yet created)

Failure Details

The test CollectionViewWithRefreshViewShouldNotReset uses VerifyScreenshot() to verify scroll position is maintained. However, the baseline snapshot file has not been committed to the repository. This causes the test to fail even when the fix is applied with error: Baseline snapshot not yet created.

The PR is missing the required baseline screenshot files that must be generated and committed for VerifyScreenshot() to function correctly.

🔧 Fix — Analysis & Comparison
📝 Review Session — Update MauiRefreshView.cs · 3445dc7

Fix Candidates

Source Approach Test Result Files Changed Notes

PR PR #31376 Store scroll position in StoreCurrentScrollPosition() on refresh start ❌ FAIL (Gate) MauiRefreshView.cs (+21/-1) Test baseline missing
Exhausted: No (Gate failed; Fix phase skipped) Selected Fix: N/A — Gate did not pass, Fix phase was not executed

Notes

Gate phase failed because the test uses VerifyScreenshot() without committed baseline snapshots. Fix exploration (Phase 3 try-fix) was skipped as the Gate must pass first.

📋 Report — Final Recommendation
📝 Review Session — Update MauiRefreshView.cs · 3445dc7

⚠️ Final Recommendation: REQUEST CHANGES

Summary

PR #31376 fixes an iOS-specific bug where RefreshView resets a nested CollectionView's scroll position to the top after a refresh completes. The fix approach is sound for the programmatic refresh scenario, but there are critical issues:

  1. Missing baseline screenshots — The test uses VerifyScreenshot() but no baseline images have been committed. Gate verification confirmed tests fail even with the fix applied (Baseline snapshot not yet created).
  2. Physical pull-to-refresh not fixed — The fix only applies when refresh is triggered programmatically (IsRefreshing = true). When the user physically pulls the native refresh control, _refreshControl.Refreshing is already true before MAUI processes it, so StoreCurrentScrollPosition() is never called and _originalY remains 0 from setup time.

Root Cause

_originalY was only stored in TryInsertRefresh() at view-setup time (when scroll position is 0), and then used to restore the offset after refresh. The fix correctly captures it at refresh-start time for the programmatic path, but misses the native gesture path.

Gate Result

❌ FAILED — Tests fail without fix ✅ (correctly catches bug) but also fail WITH fix ❌ (missing baseline snapshot).

Fix Phase

Skipped — Gate did not pass.

Required Changes

  1. Generate and commit baseline screenshots for Issue24533.CollectionViewWithRefreshViewShouldNotReset on iOS.
  2. Fix physical pull-to-refresh scenario — Hook into UIRefreshControl.ValueChanged (or equivalent) to store scroll position when native refresh gesture begins, not only in the programmatic IsRefreshing setter.
  3. Add comment explaining the if (scrollView.ContentOffset.Y < 0) return true; guard (per Copilot reviewer's unaddressed feedback).
  4. Minor: Add newline at end of both test files; fix indentation of int count; field.

Title/Description

  • Title: Suggest [iOS] RefreshView: Preserve CollectionView scroll position during pull-to-refresh
  • Description: Already has NOTE block, root cause, and description of change. Could add note about the physical pull-to-refresh limitation once addressed.

📋 Expand PR Finalization Review
Title: ⚠️ Needs Update

Current: [iOS] Fix RefreshView causes CollectionView scroll position to reset

Recommended: [iOS] RefreshView: Fix CollectionView scroll position reset on pull-to-refresh

Description: ✅ Good

Description needs updates. See details below.

✨ Suggested PR Description

[!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

When a RefreshView is set up, _originalY is captured from the scroll view's ContentOffset.Y at setup time (always 0). When the user scrolls down and triggers a pull-to-refresh, TryOffsetRefresh restores the scroll position back to _originalY (0), causing the CollectionView to jump back to the top.

Description of Change

src/Core/src/Platform/iOS/MauiRefreshView.cs

  1. StoreCurrentScrollPosition() (new method): Called before BeginRefreshing(). Captures the scroll view's current ContentOffset.Y into _originalY at the moment the refresh not at setup time. Handles the edge case where content is shorter than the viewport (forces _originalY = 0).starts
  2. Guard in TryOffsetRefresh: Added if (scrollView.ContentOffset.Y < 0) return true; to bail out early when the scroll view has a negative content offset. A negative Y offset means the view is actively being pulled down for refresh; attempting to adjust the offset at this moment would fight the gesture.

Test pages added:

  • TestCases.HostApp/Issues/Issue24533. Reproducer: CollectionView with pull-to-refresh. User taps "Load More" and scrolls to footer repeatedly to accumulate scroll position.cs
  • TestCases.Shared.Tests/Tests/Issues/Issue24533. UI test that automates the above flow and verifies via screenshot. Skipped on Windows (#if TEST_FAILS_ON_WINDOWS, see #31375).cs

Issues Fixed

Fixes #24533

Tested the behavior in the following platforms.

  • Android
  • Windows
  • iOS
  • Mac

Code Review: ✅ Passed

Code Review: PR #31376

Files reviewed:

  • src/Core/src/Platform/iOS/MauiRefreshView.cs (core fix)
  • src/Controls/tests/TestCases.HostApp/Issues/Issue24533.cs (test host app page)
  • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs (UI test)

1. Missing comment on negative-offset guard in TryOffsetRefresh

File: src/Core/src/Platform/iOS/MauiRefreshView.cs, line ~78

Code:

if (scrollView.ContentOffset.Y < 0)
    return true;

Problem: The intent of this guard is not obvious. A negative ContentOffset.Y means the user is currently in the middle of the pull-to-refresh gesture (pulling the scroll view downward). Modifying the offset at this moment would interfere with the gesture. Without a comment, a future reader (or agent) could interpret this as dead code or remove it thinking it's redundant.

This was flagged in the PR review comments by copilot-pull-request-reviewer and was not addressed.

Recommendation: Add an explanatory comment:

// ContentOffset.Y < 0 means the scroll view is mid-pull (being dragged down for refresh).
// Adjusting the offset here would fight the  bail out early.gesture 
if (scrollView.ContentOffset.Y < 0)
    return true;

2. StoreCurrentScrollPosition only captures _ does not traverse the view treerefreshControlParent

File: src/Core/src/Platform/iOS/MauiRefreshView.cs

Code:

void StoreCurrentScrollPosition()
{
    if (_refreshControlParent is UIScrollView scrollView)
    { ... }
}

Problem: TryOffsetRefresh traverses the entire view subtree to find the UIScrollView. StoreCurrentScrollPosition only checks _refreshControlParent directly. _refreshControlParent is set by TryInsertRefresh and TryRemoveRefresh to the first UIScrollView found (or the last intermediate view if none is found). In the common case, this is TryInsertRefresh sets _refreshControlParent to the found UIScrollView. However, the logic is subtly asymmetric: if _refreshControlParent is not a UIScrollView, StoreCurrentScrollPosition silently does nothing, leaving _originalY stale. A code comment or null-check would clarify intent.correct

Recommendation: At minimum, add a comment explaining the assumption:

void StoreCurrentScrollPosition()
{
    // _refreshControlParent is set to the innermost UIScrollView by TryInsertRefresh.
    // If it's not a UIScrollView (unexpected), we leave _originalY as-is.
    if (_refreshControlParent is UIScrollView scrollView)
    { ... }
}

3. Redundant edge case check in StoreCurrentScrollPosition

File: src/Core/src/Platform/iOS/MauiRefreshView.cs

Code:

if (scrollView.ContentSize.Height <= scrollView.Bounds.Height)
{
    _originalY = 0; // Stay at top
}
else
{
    _originalY = scrollView.ContentOffset.Y;
}

Problem: When ContentSize.Height <= Bounds.Height, the user cannot scroll at all, so ContentOffset.Y would already be 0. The if branch is therefore redundant (the else branch would set _originalY = 0 anyway). The code is not incorrect, but the comment "Stay at top" suggests intent that isn't actually the content can't scroll so offset is always 0 regardless.captured

Recommendation: Either remove the special case (both branches produce the same result) or add a comment clarifying it's a safety check:

// If content fits entirely in the viewport, the offset is always 0.
// Explicitly setting it here avoids capturing any floating-point noise.
_originalY = (scrollView.ContentSize.Height <= scrollView.Bounds.Height) ? 0 : scrollView.ContentOffset.Y;

4. Code formatting issues in Issue24533.cs (HostApp)

File: src/Controls/tests/TestCases.HostApp/Issues/Issue24533.cs

Multiple formatting problems:

  • Inconsistent indentation: int count; is indented with an extra tab (line ~47 in the file).
  • Trailing whitespace: Empty lines inside the CollectionView object initializer have trailing spaces/tabs.
  • Mixed tab usage: collectionView.Footer = \t btn; contains a literal tab character mid-line.
  • Missing newline at end of file: Both new .cs files lack a trailing newline.
  • Redundant comment: // To simulate the reset behavior: Reassign Items collection like XAML scenario is AddItems adds items, it doesn't reassign the collection.inaccurate

Recommendation: Run dotnet format before merging:

dotnet format Microsoft.Maui.sln --no-restore --exclude Templates/src --exclude-diagnostics CA1822

Looks Good

  • Core fix logic is correct. Capturing scroll position immediately before BeginRefreshing() is the right place. The original bug was that _originalY was stale (set at setup, when the scroll position was 0).
  • #if TEST_FAILS_ON_WINDOWS wrapping is appropriate. The bug is iOS-specific; Windows exclusion is tracked via issue [Windows] RefreshView Command executes multiple times when IsRefreshing is set to True #31375.
  • CoreFoundation using removal is clean. The unused using CoreFoundation; was removed along with the fix.
  • No breaking API changes. All modifications are internal to MauiRefreshView.
  • Test automation is appropriate. The test taps "Load More" and scrolls to the footer multiple times to accumulate scroll position before taking a this is a reasonable approach to reproduce the scroll-position-reset issue.screenshot

As per suggestion, I've included the changes

@kubaflo kubaflo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add snapshots

@github-actions

github-actions Bot commented Mar 16, 2026 •

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 31376

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 31376"

@sheiksyedm

Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added s/agent-review-in-progress AI review is currently running for this PR and removed s/agent-review-in-progress AI review is currently running for this PR labels Jun 21, 2026
MauiBot

This comment was marked as outdated.

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jun 21, 2026
@kubaflo

kubaflo commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

🔍 AI-generated review note — posted by @kubaflo via GitHub Copilot CLI. Please verify independently before acting on it.

TL;DR: The gate passing without the product fix here is a test problem, not evidence that the fix is unnecessary. Bug #24533 is still reproducible on main, so this PR shouldn't be closed on that basis — the test simply isn't catching the reset.

Why the gate passes without the fix

1. The post-refresh assertion is masked by a ScrollTo right before it.
In Issue24533.CollectionViewWithRefreshViewShouldNotReset:

App.Tap("Footer");
App.ScrollTo("Footer");   // ← scrolls back to the footer AFTER the refresh
var verticalOffsetAfterRefresh = GetVerticalOffset();
Assert.That(verticalOffsetAfterRefresh, Is.GreaterThan(0));  // trivially true

Even when the bug resets the list to the top, ScrollTo("Footer") scrolls back down before the offset is read, so > 0 always holds. The test should capture the offset immediately after refresh (no scroll) and assert it stays ≈ the pre-refresh offset.

2. The test runs on Android, where this bug can't occur.
It's only guarded by #if TEST_FAILS_ON_WINDOWS, so it executes on Android/iOS/Mac. The fix is iOS-only (Platform/iOS/MauiRefreshView.cs) and the issue notes Android already behaves correctly — so on Android it passes regardless of the fix. It should be scoped to iOS.

The bug is still present on main

TryOffsetRefresh(refreshing: false) restores new CGPoint(0, _originalY), with _originalY captured only at setup time (= 0), which scrolls the list back to the top. Closing this PR would leave #24533 unaddressed.

Suggested next steps

  • Fix the test: remove the post-refresh ScrollTo("Footer"), assert the offset is preserved (compare against the pre-refresh value), and scope the test to iOS.
  • Consider an inset-aware fix: only undo offsets that MAUI itself applied, using AdjustedContentInset.Top as the resting top offset instead of treating any negative ContentOffset.Y as an active pull. This avoids fighting native pull-to-refresh and handles safe-area/nav-bar insets correctly.

🔍 This is an automated, AI-generated analysis. It may contain mistakes — a human should validate the findings before merging or closing.

@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jun 25, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Review Summary

@devanathan-vaithiyanathan — new AI review results are available based on this last commit: 48876bf. To request a fresh review after new comments or commits, comment /review rerun.

Gate Failed Confidence Low Platform iOS


🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix

Gate Result: ❌ FAILED

Platform: IOS · Base: main · Merge base: 5ec887fa

🩺 Fix does not pass the tests — every test still fails after applying the fix. The PR's change does not resolve the failure(s).

Test Without Fix (expect FAIL) With Fix (expect PASS)
🖥️ Issue24533 Issue24533 ✅ FAIL — 335s ❌ FAIL — 118s
🔴 Without fix — 🖥️ Issue24533: FAIL ✅ · 335s

(truncated to last 15,000 chars)

ver.InternalExecute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebElement.Execute(String commandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebElement.Click()
   at UITest.Appium.AppiumMouseActions.ClickElement(AppiumElement element) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 106

  Failed CollectionViewWithRefreshViewShouldNotReset [5 s]
  Error Message:
   OpenQA.Selenium.UnknownErrorException : An unknown server-side error occurred while processing the command. Original error: The attribute 'ClickablePoint' is unknown. Valid attribute names are: (
    UID,
    accessibilityContainer,
    accessible,
    enabled,
    focused,
    frame,
    hittable,
    index,
    label,
    name,
    rect,
    selected,
    type,
    value,
    visible,
    wdAccessibilityContainer,
    wdAccessible,
    wdEnabled,
    wdFocused,
    wdFrame,
    wdHittable,
    wdIndex,
    wdLabel,
    wdName,
    wdRect,
    wdSelected,
    wdType,
    wdUID,
    wdValue,
    wdVisible
)
  Stack Trace:
     at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute)
   at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebDriver.InternalExecute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebElement.Execute(String commandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.Appium.AppiumElement.Execute(String commandName, Dictionary`2 parameters)
   at OpenQA.Selenium.Appium.AppiumElement._GetAttribute(String attributeName)
   at OpenQA.Selenium.Appium.AppiumElement.<>c__DisplayClass21_0.<GetAttribute>b__0()
   at OpenQA.Selenium.Appium.AppiumElement.CacheValue(String key, Func`1 getter)
   at OpenQA.Selenium.Appium.AppiumElement.GetAttribute(String attributeName)
   at UITest.Appium.AppiumMouseActions.ElementToClickablePoint(AppiumElement element) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 230
   at UITest.Appium.AppiumMouseActions.<ClickElement>g__ProcessException|13_0(<>c__DisplayClass13_0&) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 136
   at UITest.Appium.AppiumMouseActions.ClickElement(AppiumElement element) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 117
   at UITest.Appium.AppiumMouseActions.Click(IDictionary`2 parameters) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 63
   at UITest.Appium.AppiumMouseActions.Execute(String commandName, IDictionary`2 parameters) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 45
   at UITest.Appium.AppiumCommandExecutor.Execute(String commandName, IDictionary`2 parameters) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumCommandExecutor.cs:line 20
   at UITest.Appium.HelperExtensions.Click(IUIElement element) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 412
   at UITest.Appium.HelperExtensions.<>c__DisplayClass2_0.<Tap>b__0() in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 36
   at UITest.Appium.HelperExtensions.<>c__DisplayClass186_0.<RunWithTimeout>b__0() in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 3075
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at UITest.Appium.HelperExtensions.RunWithTimeout[T](Func`1 action, Nullable`1 timeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 3063
   at UITest.Appium.HelperExtensions.RunWithTimeout(Action action, Nullable`1 timeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 3075
   at UITest.Appium.HelperExtensions.Tap(IApp app, String element) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 36
   at Microsoft.Maui.TestCases.Tests.Issues.Issue24533.CollectionViewWithRefreshViewShouldNotReset() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs:line 24
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

  Standard Output Messages:
 WebDriverException: OpenQA.Selenium.StaleElementReferenceException: The previously found element ""Footer" Button" is not present in the current view anymore. Make sure the application UI has the expected state. Original error: No matches found for Elements matching predicate 'BLOCKPREDICATE(0x600000cb3840)' from input {(
     Window (Main), {{0.0, 0.0}, {375.0, 812.0}},
     Window, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 44.0}, {375.0, 734.0}},
     StaticText, {{0.0, 44.0}, {375.0, 17.0}}, identifier: 'VerticalOffsetLabel', label: 'VerticalOffset: 0.00',
     Other, {{16.0, 77.0}, {343.0, 685.0}},
     Other, {{16.0, 77.0}, {343.0, 685.0}},
     CollectionView, {{16.0, 77.0}, {343.0, 685.0}},
     Cell, {{16.0, 77.0}, {343.0, 17.0}},
     Cell, {{16.0, 94.0}, {343.0, 17.0}},
     Cell, {{16.0, 111.0}, {343.0, 17.0}},
     Cell, {{16.0, 128.0}, {343.0, 17.0}},
     Cell, {{16.0, 145.0}, {343.0, 17.0}},
     Cell, {{16.0, 162.0}, {343.0, 17.0}},
     Cell, {{16.0, 179.0}, {343.0, 17.0}},
     Cell, {{16.0, 196.0}, {343.0, 17.0}},
     Cell, {{16.0, 213.0}, {343.0, 17.0}},
     Cell, {{16.0, 230.0}, {343.0, 17.0}},
     Cell, {{16.0, 247.0}, {343.0, 17.0}},
     Cell, {{16.0, 264.0}, {343.0, 17.0}},
     Cell, {{16.0, 281.0}, {343.0, 17.0}},
     Cell, {{16.0, 298.0}, {343.0, 17.0}},
     Cell, {{16.0, 315.0}, {343.0, 17.0}},
     Cell, {{16.0, 332.0}, {343.0, 17.0}},
     Cell, {{16.0, 349.0}, {343.0, 17.0}},
     Cell, {{16.0, 366.0}, {343.0, 17.0}},
     Cell, {{16.0, 383.0}, {343.0, 17.0}},
     Cell, {{16.0, 400.0}, {343.0, 17.0}},
     Cell, {{16.0, 417.0}, {343.0, 17.0}},
     Cell, {{16.0, 434.0}, {343.0, 17.0}},
     Cell, {{16.0, 451.0}, {343.0, 17.0}},
     Cell, {{16.0, 468.0}, {343.0, 17.0}},
     Cell, {{16.0, 485.0}, {343.0, 17.0}},
     Cell, {{16.0, 502.0}, {343.0, 17.0}},
     Cell, {{16.0, 519.0}, {343.0, 17.0}},
     Cell, {{16.0, 536.0}, {343.0, 17.0}},
     Cell, {{16.0, 553.0}, {343.0, 17.0}},
     Cell, {{16.0, 570.0}, {343.0, 17.0}},
     Cell, {{16.0, 587.0}, {343.0, 17.0}},
     Cell, {{16.0, 604.0}, {343.0, 17.0}},
     Cell, {{16.0, 621.0}, {343.0, 17.0}},
     Cell, {{16.0, 638.0}, {343.0, 17.0}},
     Cell, {{16.0, 655.0}, {343.0, 17.0}},
     Cell, {{16.0, 672.0}, {343.0, 17.0}},
     Cell, {{16.0, 689.0}, {343.0, 17.0}},
     Cell, {{16.0, 706.0}, {343.0, 17.0}},
     Cell, {{16.0, 723.0}, {343.0, 17.0}},
     Cell, {{16.0, 740.0}, {343.0, 17.0}},
     Cell, {{16.0, 757.0}, {343.0, 17.0}},
     Other, {{326.0, 77.0}, {30.0, 685.0}}, label: 'Vertical scroll bar, 2 pages', value: 0%,
     Other, {{16.0, 729.0}, {343.0, 30.0}}, label: 'Horizontal scroll bar, 1 page', value: 0%,
     Other, {{16.0, 77.0}, {343.0, 17.0}},
     Other, {{16.0, 94.0}, {343.0, 17.0}},
     Other, {{16.0, 111.0}, {343.0, 17.0}},
     Other, {{16.0, 128.0}, {343.0, 17.0}},
     Other, {{16.0, 145.0}, {343.0, 17.0}},
     Other, {{16.0, 162.0}, {343.0, 17.0}},
     Other, {{16.0, 179.0}, {343.0, 17.0}},
     Other, {{16.0, 196.0}, {343.0, 17.0}},
     Other, {{16.0, 213.0}, {343.0, 17.0}},
     Other, {{16.0, 230.0}, {343.0, 17.0}},
     Other, {{16.0, 247.0}, {343.0, 17.0}},
     Other, {{16.0, 264.0}, {343.0, 17.0}},
     Other, {{16.0, 281.0}, {343.0, 17.0}},
     Other, {{16.0, 298.0}, {343.0, 17.0}},
     Other, {{16.0, 315.0}, {343.0, 17.0}},
     Other, {{16.0, 332.0}, {343.0, 17.0}},
     Other, {{16.0, 349.0}, {343.0, 17.0}},
     Other, {{16.0, 366.0}, {343.0, 17.0}},
     Other, {{16.0, 383.0}, {343.0, 17.0}},
     Other, {{16.0, 400.0}, {343.0, 17.0}},
     Other, {{16.0, 417.0}, {343.0, 17.0}},
     Other, {{16.0, 434.0}, {343.0, 17.0}},
     Other, {{16.0, 451.0}, {343.0, 17.0}},
     Other, {{16.0, 468.0}, {343.0, 17.0}},
     Other, {{16.0, 485.0}, {343.0, 17.0}},
     Other, {{16.0, 502.0}, {343.0, 17.0}},
     Other, {{16.0, 519.0}, {343.0, 17.0}},
     Other, {{16.0, 536.0}, {343.0, 17.0}},
     Other, {{16.0, 553.0}, {343.0, 17.0}},
     Other, {{16.0, 570.0}, {343.0, 17.0}},
     Other, {{16.0, 587.0}, {343.0, 17.0}},
     Other, {{16.0, 604.0}, {343.0, 17.0}},
     Other, {{16.0, 621.0}, {343.0, 17.0}},
     Other, {{16.0, 638.0}, {343.0, 17.0}},
     Other, {{16.0, 655.0}, {343.0, 17.0}},
     Other, {{16.0, 672.0}, {343.0, 17.0}},
     Other, {{16.0, 689.0}, {343.0, 17.0}},
     Other, {{16.0, 706.0}, {343.0, 17.0}},
     Other, {{16.0, 723.0}, {343.0, 17.0}},
     Other, {{16.0, 740.0}, {343.0, 17.0}},
     Other, {{16.0, 757.0}, {343.0, 17.0}},
     Other, {{353.0, 280.0}, {3.0, 479.0}},
     Other, {{19.0, 756.0}, {337.0, 3.0}},
     Button, {{16.0, 77.0}, {343.0, 17.0}},
     Button, {{16.0, 94.0}, {343.0, 17.0}},
     Button, {{16.0, 111.0}, {343.0, 17.0}},
     Button, {{16.0, 128.0}, {343.0, 17.0}},
     Button, {{16.0, 145.0}, {343.0, 17.0}},
     Button, {{16.0, 162.0}, {343.0, 17.0}},
     Button, {{16.0, 179.0}, {343.0, 17.0}},
     Button, {{16.0, 196.0}, {343.0, 17.0}},
     Button, {{16.0, 213.0}, {343.0, 17.0}},
     Button, {{16.0, 230.0}, {343.0, 17.0}},
     Button, {{16.0, 247.0}, {343.0, 17.0}},
     Button, {{16.0, 264.0}, {343.0, 17.0}},
     Button, {{16.0, 281.0}, {343.0, 17.0}},
     Button, {{16.0, 298.0}, {343.0, 17.0}},
     Button, {{16.0, 315.0}, {343.0, 17.0}},
     Button, {{16.0, 332.0}, {343.0, 17.0}},
     Button, {{16.0, 349.0}, {343.0, 17.0}},
     Button, {{16.0, 366.0}, {343.0, 17.0}},
     Button, {{16.0, 383.0}, {343.0, 17.0}},
     Button, {{16.0, 400.0}, {343.0, 17.0}},
     Button, {{16.0, 417.0}, {343.0, 17.0}},
     Button, {{16.0, 434.0}, {343.0, 17.0}},
     Button, {{16.0, 451.0}, {343.0, 17.0}},
     Button, {{16.0, 468.0}, {343.0, 17.0}},
     Button, {{16.0, 485.0}, {343.0, 17.0}},
     Button, {{16.0, 502.0}, {343.0, 17.0}},
     Button, {{16.0, 519.0}, {343.0, 17.0}},
     Button, {{16.0, 536.0}, {343.0, 17.0}},
     Button, {{16.0, 553.0}, {343.0, 17.0}},
     Button, {{16.0, 570.0}, {343.0, 17.0}},
     Button, {{16.0, 587.0}, {343.0, 17.0}},
     Button, {{16.0, 604.0}, {343.0, 17.0}},
     Button, {{16.0, 621.0}, {343.0, 17.0}},
     Button, {{16.0, 638.0}, {343.0, 17.0}},
     Button, {{16.0, 655.0}, {343.0, 17.0}},
     Button, {{16.0, 672.0}, {343.0, 17.0}},
     Button, {{16.0, 689.0}, {343.0, 17.0}},
     Button, {{16.0, 706.0}, {343.0, 17.0}},
     Button, {{16.0, 723.0}, {343.0, 17.0}},
     Button, {{16.0, 740.0}, {343.0, 17.0}},
     Button, {{16.0, 757.0}, {343.0, 17.0}},
     StaticText, {{16.0, 77.0}, {343.0, 17.0}}, label: '0',
     StaticText, {{16.0, 94.0}, {343.0, 17.0}}, label: '1',
     StaticText, {{16.0, 111.0}, {343.0, 17.0}}, label: '2',
     StaticText, {{16.0, 128.0}, {343.0, 17.0}}, label: '3',
     StaticText, {{16.0, 145.0}, {343.0, 17.0}}, label: '4',
     StaticText, {{16.0, 162.0}, {343.0, 17.0}}, label: '5',
     StaticText, {{16.0, 179.0}, {343.0, 17.0}}, label: '6',
     StaticText, {{16.0, 196.0}, {343.0, 17.0}}, label: '7',
     StaticText, {{16.0, 213.0}, {343.0, 17.0}}, label: '8',
     StaticText, {{16.0, 230.0}, {343.0, 17.0}}, label: '9',
     StaticText, {{16.0, 247.0}, {343.0, 17.0}}, label: '10',
     StaticText, {{16.0, 264.0}, {343.0, 17.0}}, label: '11',
     StaticText, {{16.0, 281.0}, {343.0, 17.0}}, label: '12',
     StaticText, {{16.0, 298.0}, {343.0, 17.0}}, label: '13',
     StaticText, {{16.0, 315.0}, {343.0, 17.0}}, label: '14',
     StaticText, {{16.0, 332.0}, {343.0, 17.0}}, label: '15',
     StaticText, {{16.0, 349.0}, {343.0, 17.0}}, label: '16',
     StaticText, {{16.0, 366.0}, {343.0, 17.0}}, label: '17',
     StaticText, {{16.0, 383.0}, {343.0, 17.0}}, label: '18',
     StaticText, {{16.0, 400.0}, {343.0, 17.0}}, label: '19',
     StaticText, {{16.0, 417.0}, {343.0, 17.0}}, label: '20',
     StaticText, {{16.0, 434.0}, {343.0, 17.0}}, label: '21',
     StaticText, {{16.0, 451.0}, {343.0, 17.0}}, label: '22',
     StaticText, {{16.0, 468.0}, {343.0, 17.0}}, label: '23',
     StaticText, {{16.0, 485.0}, {343.0, 17.0}}, label: '24',
     StaticText, {{16.0, 502.0}, {343.0, 17.0}}, label: '20',
     StaticText, {{16.0, 519.0}, {343.0, 17.0}}, label: '21',
     StaticText, {{16.0, 536.0}, {343.0, 17.0}}, label: '22',
     StaticText, {{16.0, 553.0}, {343.0, 17.0}}, label: '23',
     StaticText, {{16.0, 570.0}, {343.0, 17.0}}, label: '24',
     StaticText, {{16.0, 587.0}, {343.0, 17.0}}, label: '25',
     StaticText, {{16.0, 604.0}, {343.0, 17.0}}, label: '26',
     StaticText, {{16.0, 621.0}, {343.0, 17.0}}, label: '27',
     StaticText, {{16.0, 638.0}, {343.0, 17.0}}, label: '28',
     StaticText, {{16.0, 655.0}, {343.0, 17.0}}, label: '29',
     StaticText, {{16.0, 672.0}, {343.0, 17.0}}, label: '30',
     StaticText, {{16.0, 689.0}, {343.0, 17.0}}, label: '31',
     StaticText, {{16.0, 706.0}, {343.0, 17.0}}, label: '32',
     StaticText, {{16.0, 723.0}, {343.0, 17.0}}, label: '33',
     StaticText, {{16.0, 740.0}, {343.0, 17.0}}, label: '34',
     StaticText, {{16.0, 757.0}, {343.0, 17.0}}, label: '35'
 )}; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#stale-element-reference-exception
    at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute)
    at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters)
    at OpenQA.Selenium.WebDriver.InternalExecute(String driverCommandToExecute, Dictionary`2 parameters)
    at OpenQA.Selenium.WebElement.Execute(String commandToExecute, Dictionary`2 parameters)
    at OpenQA.Selenium.WebElement.Click()
    at UITest.Appium.AppiumMouseActions.ClickElement(AppiumElement element) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 106


NUnit Adapter 4.5.0.0: Test execution complete
Results File: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue24533.trx

Test Run Failed.
Total tests: 1
     Failed: 1
 Total time: 1.5818 Minutes
>>> TRX_RESULT_FILE: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue24533.trx

🟢 With fix — 🖥️ Issue24533: FAIL ❌ · 118s

(truncated to last 15,000 chars)

er.InternalExecute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebElement.Execute(String commandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebElement.Click()
   at UITest.Appium.AppiumMouseActions.ClickElement(AppiumElement element) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 106

  Failed CollectionViewWithRefreshViewShouldNotReset [5 s]
  Error Message:
   OpenQA.Selenium.UnknownErrorException : An unknown server-side error occurred while processing the command. Original error: The attribute 'ClickablePoint' is unknown. Valid attribute names are: (
    UID,
    accessibilityContainer,
    accessible,
    enabled,
    focused,
    frame,
    hittable,
    index,
    label,
    name,
    rect,
    selected,
    type,
    value,
    visible,
    wdAccessibilityContainer,
    wdAccessible,
    wdEnabled,
    wdFocused,
    wdFrame,
    wdHittable,
    wdIndex,
    wdLabel,
    wdName,
    wdRect,
    wdSelected,
    wdType,
    wdUID,
    wdValue,
    wdVisible
)
  Stack Trace:
     at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute)
   at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebDriver.InternalExecute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebElement.Execute(String commandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.Appium.AppiumElement.Execute(String commandName, Dictionary`2 parameters)
   at OpenQA.Selenium.Appium.AppiumElement._GetAttribute(String attributeName)
   at OpenQA.Selenium.Appium.AppiumElement.<>c__DisplayClass21_0.<GetAttribute>b__0()
   at OpenQA.Selenium.Appium.AppiumElement.CacheValue(String key, Func`1 getter)
   at OpenQA.Selenium.Appium.AppiumElement.GetAttribute(String attributeName)
   at UITest.Appium.AppiumMouseActions.ElementToClickablePoint(AppiumElement element) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 230
   at UITest.Appium.AppiumMouseActions.<ClickElement>g__ProcessException|13_0(<>c__DisplayClass13_0&) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 136
   at UITest.Appium.AppiumMouseActions.ClickElement(AppiumElement element) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 117
   at UITest.Appium.AppiumMouseActions.Click(IDictionary`2 parameters) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 63
   at UITest.Appium.AppiumMouseActions.Execute(String commandName, IDictionary`2 parameters) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 45
   at UITest.Appium.AppiumCommandExecutor.Execute(String commandName, IDictionary`2 parameters) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumCommandExecutor.cs:line 20
   at UITest.Appium.HelperExtensions.Click(IUIElement element) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 412
   at UITest.Appium.HelperExtensions.<>c__DisplayClass2_0.<Tap>b__0() in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 36
   at UITest.Appium.HelperExtensions.<>c__DisplayClass186_0.<RunWithTimeout>b__0() in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 3075
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at UITest.Appium.HelperExtensions.RunWithTimeout[T](Func`1 action, Nullable`1 timeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 3063
   at UITest.Appium.HelperExtensions.RunWithTimeout(Action action, Nullable`1 timeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 3075
   at UITest.Appium.HelperExtensions.Tap(IApp app, String element) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 36
   at Microsoft.Maui.TestCases.Tests.Issues.Issue24533.CollectionViewWithRefreshViewShouldNotReset() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs:line 24
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

  Standard Output Messages:
 WebDriverException: OpenQA.Selenium.StaleElementReferenceException: The previously found element ""Footer" Button" is not present in the current view anymore. Make sure the application UI has the expected state. Original error: No matches found for Elements matching predicate 'BLOCKPREDICATE(0x600000cd40c0)' from input {(
     Window (Main), {{0.0, 0.0}, {375.0, 812.0}},
     Window, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 0.0}, {375.0, 812.0}},
     Other, {{0.0, 44.0}, {375.0, 734.0}},
     StaticText, {{0.0, 44.0}, {375.0, 17.0}}, identifier: 'VerticalOffsetLabel', label: 'VerticalOffset: 0.00',
     Other, {{16.0, 77.0}, {343.0, 685.0}},
     Other, {{16.0, 77.0}, {343.0, 685.0}},
     CollectionView, {{16.0, 77.0}, {343.0, 685.0}},
     Cell, {{16.0, 77.0}, {343.0, 17.0}},
     Cell, {{16.0, 94.0}, {343.0, 17.0}},
     Cell, {{16.0, 111.0}, {343.0, 17.0}},
     Cell, {{16.0, 128.0}, {343.0, 17.0}},
     Cell, {{16.0, 145.0}, {343.0, 17.0}},
     Cell, {{16.0, 162.0}, {343.0, 17.0}},
     Cell, {{16.0, 179.0}, {343.0, 17.0}},
     Cell, {{16.0, 196.0}, {343.0, 17.0}},
     Cell, {{16.0, 213.0}, {343.0, 17.0}},
     Cell, {{16.0, 230.0}, {343.0, 17.0}},
     Cell, {{16.0, 247.0}, {343.0, 17.0}},
     Cell, {{16.0, 264.0}, {343.0, 17.0}},
     Cell, {{16.0, 281.0}, {343.0, 17.0}},
     Cell, {{16.0, 298.0}, {343.0, 17.0}},
     Cell, {{16.0, 315.0}, {343.0, 17.0}},
     Cell, {{16.0, 332.0}, {343.0, 17.0}},
     Cell, {{16.0, 349.0}, {343.0, 17.0}},
     Cell, {{16.0, 366.0}, {343.0, 17.0}},
     Cell, {{16.0, 383.0}, {343.0, 17.0}},
     Cell, {{16.0, 400.0}, {343.0, 17.0}},
     Cell, {{16.0, 417.0}, {343.0, 17.0}},
     Cell, {{16.0, 434.0}, {343.0, 17.0}},
     Cell, {{16.0, 451.0}, {343.0, 17.0}},
     Cell, {{16.0, 468.0}, {343.0, 17.0}},
     Cell, {{16.0, 485.0}, {343.0, 17.0}},
     Cell, {{16.0, 502.0}, {343.0, 17.0}},
     Cell, {{16.0, 519.0}, {343.0, 17.0}},
     Cell, {{16.0, 536.0}, {343.0, 17.0}},
     Cell, {{16.0, 553.0}, {343.0, 17.0}},
     Cell, {{16.0, 570.0}, {343.0, 17.0}},
     Cell, {{16.0, 587.0}, {343.0, 17.0}},
     Cell, {{16.0, 604.0}, {343.0, 17.0}},
     Cell, {{16.0, 621.0}, {343.0, 17.0}},
     Cell, {{16.0, 638.0}, {343.0, 17.0}},
     Cell, {{16.0, 655.0}, {343.0, 17.0}},
     Cell, {{16.0, 672.0}, {343.0, 17.0}},
     Cell, {{16.0, 689.0}, {343.0, 17.0}},
     Cell, {{16.0, 706.0}, {343.0, 17.0}},
     Cell, {{16.0, 723.0}, {343.0, 17.0}},
     Cell, {{16.0, 740.0}, {343.0, 17.0}},
     Cell, {{16.0, 757.0}, {343.0, 17.0}},
     Other, {{326.0, 77.0}, {30.0, 685.0}}, label: 'Vertical scroll bar, 2 pages', value: 0%,
     Other, {{16.0, 729.0}, {343.0, 30.0}}, label: 'Horizontal scroll bar, 1 page', value: 0%,
     Other, {{16.0, 77.0}, {343.0, 17.0}},
     Other, {{16.0, 94.0}, {343.0, 17.0}},
     Other, {{16.0, 111.0}, {343.0, 17.0}},
     Other, {{16.0, 128.0}, {343.0, 17.0}},
     Other, {{16.0, 145.0}, {343.0, 17.0}},
     Other, {{16.0, 162.0}, {343.0, 17.0}},
     Other, {{16.0, 179.0}, {343.0, 17.0}},
     Other, {{16.0, 196.0}, {343.0, 17.0}},
     Other, {{16.0, 213.0}, {343.0, 17.0}},
     Other, {{16.0, 230.0}, {343.0, 17.0}},
     Other, {{16.0, 247.0}, {343.0, 17.0}},
     Other, {{16.0, 264.0}, {343.0, 17.0}},
     Other, {{16.0, 281.0}, {343.0, 17.0}},
     Other, {{16.0, 298.0}, {343.0, 17.0}},
     Other, {{16.0, 315.0}, {343.0, 17.0}},
     Other, {{16.0, 332.0}, {343.0, 17.0}},
     Other, {{16.0, 349.0}, {343.0, 17.0}},
     Other, {{16.0, 366.0}, {343.0, 17.0}},
     Other, {{16.0, 383.0}, {343.0, 17.0}},
     Other, {{16.0, 400.0}, {343.0, 17.0}},
     Other, {{16.0, 417.0}, {343.0, 17.0}},
     Other, {{16.0, 434.0}, {343.0, 17.0}},
     Other, {{16.0, 451.0}, {343.0, 17.0}},
     Other, {{16.0, 468.0}, {343.0, 17.0}},
     Other, {{16.0, 485.0}, {343.0, 17.0}},
     Other, {{16.0, 502.0}, {343.0, 17.0}},
     Other, {{16.0, 519.0}, {343.0, 17.0}},
     Other, {{16.0, 536.0}, {343.0, 17.0}},
     Other, {{16.0, 553.0}, {343.0, 17.0}},
     Other, {{16.0, 570.0}, {343.0, 17.0}},
     Other, {{16.0, 587.0}, {343.0, 17.0}},
     Other, {{16.0, 604.0}, {343.0, 17.0}},
     Other, {{16.0, 621.0}, {343.0, 17.0}},
     Other, {{16.0, 638.0}, {343.0, 17.0}},
     Other, {{16.0, 655.0}, {343.0, 17.0}},
     Other, {{16.0, 672.0}, {343.0, 17.0}},
     Other, {{16.0, 689.0}, {343.0, 17.0}},
     Other, {{16.0, 706.0}, {343.0, 17.0}},
     Other, {{16.0, 723.0}, {343.0, 17.0}},
     Other, {{16.0, 740.0}, {343.0, 17.0}},
     Other, {{16.0, 757.0}, {343.0, 17.0}},
     Other, {{353.0, 280.0}, {3.0, 479.0}},
     Other, {{19.0, 756.0}, {337.0, 3.0}},
     Button, {{16.0, 77.0}, {343.0, 17.0}},
     Button, {{16.0, 94.0}, {343.0, 17.0}},
     Button, {{16.0, 111.0}, {343.0, 17.0}},
     Button, {{16.0, 128.0}, {343.0, 17.0}},
     Button, {{16.0, 145.0}, {343.0, 17.0}},
     Button, {{16.0, 162.0}, {343.0, 17.0}},
     Button, {{16.0, 179.0}, {343.0, 17.0}},
     Button, {{16.0, 196.0}, {343.0, 17.0}},
     Button, {{16.0, 213.0}, {343.0, 17.0}},
     Button, {{16.0, 230.0}, {343.0, 17.0}},
     Button, {{16.0, 247.0}, {343.0, 17.0}},
     Button, {{16.0, 264.0}, {343.0, 17.0}},
     Button, {{16.0, 281.0}, {343.0, 17.0}},
     Button, {{16.0, 298.0}, {343.0, 17.0}},
     Button, {{16.0, 315.0}, {343.0, 17.0}},
     Button, {{16.0, 332.0}, {343.0, 17.0}},
     Button, {{16.0, 349.0}, {343.0, 17.0}},
     Button, {{16.0, 366.0}, {343.0, 17.0}},
     Button, {{16.0, 383.0}, {343.0, 17.0}},
     Button, {{16.0, 400.0}, {343.0, 17.0}},
     Button, {{16.0, 417.0}, {343.0, 17.0}},
     Button, {{16.0, 434.0}, {343.0, 17.0}},
     Button, {{16.0, 451.0}, {343.0, 17.0}},
     Button, {{16.0, 468.0}, {343.0, 17.0}},
     Button, {{16.0, 485.0}, {343.0, 17.0}},
     Button, {{16.0, 502.0}, {343.0, 17.0}},
     Button, {{16.0, 519.0}, {343.0, 17.0}},
     Button, {{16.0, 536.0}, {343.0, 17.0}},
     Button, {{16.0, 553.0}, {343.0, 17.0}},
     Button, {{16.0, 570.0}, {343.0, 17.0}},
     Button, {{16.0, 587.0}, {343.0, 17.0}},
     Button, {{16.0, 604.0}, {343.0, 17.0}},
     Button, {{16.0, 621.0}, {343.0, 17.0}},
     Button, {{16.0, 638.0}, {343.0, 17.0}},
     Button, {{16.0, 655.0}, {343.0, 17.0}},
     Button, {{16.0, 672.0}, {343.0, 17.0}},
     Button, {{16.0, 689.0}, {343.0, 17.0}},
     Button, {{16.0, 706.0}, {343.0, 17.0}},
     Button, {{16.0, 723.0}, {343.0, 17.0}},
     Button, {{16.0, 740.0}, {343.0, 17.0}},
     Button, {{16.0, 757.0}, {343.0, 17.0}},
     StaticText, {{16.0, 77.0}, {343.0, 17.0}}, label: '0',
     StaticText, {{16.0, 94.0}, {343.0, 17.0}}, label: '1',
     StaticText, {{16.0, 111.0}, {343.0, 17.0}}, label: '2',
     StaticText, {{16.0, 128.0}, {343.0, 17.0}}, label: '3',
     StaticText, {{16.0, 145.0}, {343.0, 17.0}}, label: '4',
     StaticText, {{16.0, 162.0}, {343.0, 17.0}}, label: '5',
     StaticText, {{16.0, 179.0}, {343.0, 17.0}}, label: '6',
     StaticText, {{16.0, 196.0}, {343.0, 17.0}}, label: '7',
     StaticText, {{16.0, 213.0}, {343.0, 17.0}}, label: '8',
     StaticText, {{16.0, 230.0}, {343.0, 17.0}}, label: '9',
     StaticText, {{16.0, 247.0}, {343.0, 17.0}}, label: '10',
     StaticText, {{16.0, 264.0}, {343.0, 17.0}}, label: '11',
     StaticText, {{16.0, 281.0}, {343.0, 17.0}}, label: '12',
     StaticText, {{16.0, 298.0}, {343.0, 17.0}}, label: '13',
     StaticText, {{16.0, 315.0}, {343.0, 17.0}}, label: '14',
     StaticText, {{16.0, 332.0}, {343.0, 17.0}}, label: '15',
     StaticText, {{16.0, 349.0}, {343.0, 17.0}}, label: '16',
     StaticText, {{16.0, 366.0}, {343.0, 17.0}}, label: '17',
     StaticText, {{16.0, 383.0}, {343.0, 17.0}}, label: '18',
     StaticText, {{16.0, 400.0}, {343.0, 17.0}}, label: '19',
     StaticText, {{16.0, 417.0}, {343.0, 17.0}}, label: '20',
     StaticText, {{16.0, 434.0}, {343.0, 17.0}}, label: '21',
     StaticText, {{16.0, 451.0}, {343.0, 17.0}}, label: '22',
     StaticText, {{16.0, 468.0}, {343.0, 17.0}}, label: '23',
     StaticText, {{16.0, 485.0}, {343.0, 17.0}}, label: '24',
     StaticText, {{16.0, 502.0}, {343.0, 17.0}}, label: '20',
     StaticText, {{16.0, 519.0}, {343.0, 17.0}}, label: '21',
     StaticText, {{16.0, 536.0}, {343.0, 17.0}}, label: '22',
     StaticText, {{16.0, 553.0}, {343.0, 17.0}}, label: '23',
     StaticText, {{16.0, 570.0}, {343.0, 17.0}}, label: '24',
     StaticText, {{16.0, 587.0}, {343.0, 17.0}}, label: '25',
     StaticText, {{16.0, 604.0}, {343.0, 17.0}}, label: '26',
     StaticText, {{16.0, 621.0}, {343.0, 17.0}}, label: '27',
     StaticText, {{16.0, 638.0}, {343.0, 17.0}}, label: '28',
     StaticText, {{16.0, 655.0}, {343.0, 17.0}}, label: '29',
     StaticText, {{16.0, 672.0}, {343.0, 17.0}}, label: '30',
     StaticText, {{16.0, 689.0}, {343.0, 17.0}}, label: '31',
     StaticText, {{16.0, 706.0}, {343.0, 17.0}}, label: '32',
     StaticText, {{16.0, 723.0}, {343.0, 17.0}}, label: '33',
     StaticText, {{16.0, 740.0}, {343.0, 17.0}}, label: '34',
     StaticText, {{16.0, 757.0}, {343.0, 17.0}}, label: '35'
 )}; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#stale-element-reference-exception
    at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute)
    at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters)
    at OpenQA.Selenium.WebDriver.InternalExecute(String driverCommandToExecute, Dictionary`2 parameters)
    at OpenQA.Selenium.WebElement.Execute(String commandToExecute, Dictionary`2 parameters)
    at OpenQA.Selenium.WebElement.Click()
    at UITest.Appium.AppiumMouseActions.ClickElement(AppiumElement element) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumMouseActions.cs:line 106


NUnit Adapter 4.5.0.0: Test execution complete
Results File: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue24533.trx

Test Run Failed.
Total tests: 1
     Failed: 1
 Total time: 28.7440 Seconds
>>> TRX_RESULT_FILE: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue24533.trx

⚠️ Failure Details

  • ❌ Issue24533 FAILED with fix (should pass)
    • CollectionViewWithRefreshViewShouldNotReset [5 s]
    • OpenQA.Selenium.UnknownErrorException : An unknown server-side error occurred while processing the command. Original error: The attribute 'ClickablePoint' is unknown. Valid attribute names are: ( ...
📁 Fix files reverted (1 files)
  • src/Core/src/Platform/iOS/MauiRefreshView.cs

📱 UI Tests — CollectionView,RefreshView,ViewBaseTests

Detected UI test categories: CollectionView,RefreshView,ViewBaseTests

❌ Deep UI tests — 379 passed, 190 failed across 3 categories on platform-pool agent (replaces in-process counts above).

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
CollectionView 331/420 (86 ❌) 168 diff PNGs
RefreshView 35/40 (5 ❌) 6 diff PNGs
ViewBaseTests 13/112 (99 ❌) 198 diff PNGs
❌ CollectionView — 86 failed tests
VerifySelectionModeMultipleWhenProgrammaticSelectionWorksWithVerticalList
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.CollectionView_SelectionFeatureTests.VerifySelectionModeMultipleWhenProgrammaticSelectionWorksWithVerticalList() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_SelectionFeatureTests.cs:line 533
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBase
...
HeaderShouldNotCollapseWithItems
System.InvalidOperationException : 
Snapshot different than baseline: HeaderShouldNotCollapseWithItems.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: HeaderShouldNotCollapseWithItems.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test a
...
CollectionViewHeightIsCorrectAfterDelayedLoad
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.Issues.Issue34336.CollectionViewHeightIsCorrectAfterDelayedLoad() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34336.cs:line 29
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflectio
...
FlowdirectionShouldWorkForHeaderFooter
System.InvalidOperationException : 
Snapshot different than baseline: FlowdirectionShouldWorkForHeaderFooter.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: FlowdirectionShouldWorkForHeaderFooter.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image
...
CollectionViewSelectionModeOnLightTheme
System.InvalidOperationException : 
Snapshot different than baseline: CollectionViewSelectionModeOnLightTheme.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: CollectionViewSelectionModeOnLightTheme.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline ima
...
CollectionViewGroupFooterTemplateShouldNotCrash
System.InvalidOperationException : 
Snapshot different than baseline: CollectionViewGroupFooterTemplateShouldNotCrash.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: CollectionViewGroupFooterTemplateShouldNotCrash.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update 
...
VerifyModelItemsObservableCollectionWhenSingleModePreSelection
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.CollectionView_ItemsSourceFeatureTests.VerifyModelItemsObservableCollectionWhenSingleModePreSelection() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ItemsSourceFeatureTests.cs:line 652
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker
...
CollectionViewShouldChangeItemsLayout
System.InvalidOperationException : 
Snapshot different than baseline: CollectionViewShouldChangeItemsLayout.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: CollectionViewShouldChangeItemsLayout.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.

...
VerifyCustomSizedEmptyViewDisplaysCorrectly_WithRightToLeftFlowDirection
System.InvalidOperationException : 
Snapshot different than baseline: VerifyCustomSizedEmptyViewDisplaysCorrectly_WithRightToLeftFlowDirection.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyCustomSizedEmptyViewDisplaysCorrectly_WithRightToLeftFlowDirection.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct basel
...
VerifyStringItemsObservableCollectionWhenMultipleModePreSelection
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.CollectionView_ItemsSourceFeatureTests.VerifyStringItemsObservableCollectionWhenMultipleModePreSelection() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ItemsSourceFeatureTests.cs:line 630
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvo
...
VerifyScrollToByIndexWithMakeVisiblePositionAndVerticalList_Carrot
System.InvalidOperationException : 
Snapshot different than baseline: VerifyScrollToByIndexWithMakeVisiblePositionAndVerticalList_Carrot.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyScrollToByIndexWithMakeVisiblePositionAndVerticalList_Carrot.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has chan
...
CollectionViewHeaderSizewithIsVisibleBinding
System.InvalidOperationException : 
Snapshot different than baseline: CollectionViewHeaderSizewithIsVisibleBinding.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: CollectionViewHeaderSizewithIsVisibleBinding.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the ba
...
VerifyScrollToByItemWithCenterPositionAndVerticalList_Carrot
System.InvalidOperationException : 
Snapshot different than baseline: VerifyScrollToByItemWithCenterPositionAndVerticalList_Carrot.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyScrollToByItemWithCenterPositionAndVerticalList_Carrot.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this is
...
VerifyCollectionViewVisualState
System.InvalidOperationException : 
Snapshot different than baseline: VerifyCollectionViewVisualState.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyCollectionViewVisualState.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test att
...
VerifyFlowDirectionLTRAndMeasureAllItemsWithGroupedList
System.InvalidOperationException : 
Snapshot different than baseline: VerifyFlowDirectionLTRAndMeasureAllItemsWithGroupedList.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyFlowDirectionLTRAndMeasureAllItemsWithGroupedList.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bu
...
Issue18751Test
System.InvalidOperationException : 
Snapshot different than baseline: Issue18751Test.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Issue18751Test.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build arti
...
VerifyModelItemsGroupedListWhenSingleModePreSelection
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.CollectionView_ItemsSourceFeatureTests.VerifyModelItemsGroupedListWhenSingleModePreSelection() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ItemsSourceFeatureTests.cs:line 748
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.Interpre
...
VerticalItemsRemainFullyVisibleAfterChangingSpacing
System.InvalidOperationException : 
Snapshot different than baseline: VerticalItemsRemainFullyVisibleAfterChangingSpacing.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerticalItemsRemainFullyVisibleAfterChangingSpacing.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then
...
CollectionViewPreSelectionShouldUpdate
System.InvalidOperationException : 
Snapshot different than baseline: CollectionViewPreSelectionShouldUpdate.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: CollectionViewPreSelectionShouldUpdate.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image
...
RightToLeftFlowDirectionShouldWork
System.InvalidOperationException : 
Snapshot different than baseline: RightToLeftFlowDirectionShouldWork.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: RightToLeftFlowDirectionShouldWork.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See te
...
BottomSheetDetentHeightIsCorrectWhenCollectionViewIsMeasuredBeforeMount
System.InvalidOperationException : 
Snapshot different than baseline: BottomSheetDetentHeightIsCorrectWhenCollectionViewIsMeasuredBeforeMount.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: BottomSheetDetentHeightIsCorrectWhenCollectionViewIsMeasuredBeforeMount.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baselin
...
HeaderFooterTemplateWorks
System.InvalidOperationException : 
Snapshot different than baseline: HeaderFooterTemplateWorks.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: HeaderFooterTemplateWorks.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or d
...
CheckEmptyViewMargin
System.InvalidOperationException : 
Snapshot different than baseline: CheckEmptyViewMargin.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: CheckEmptyViewMargin.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download th
...
CollectionViewItemsShouldRespectSafeAreaEdges
System.InvalidOperationException : 
Snapshot different than baseline: CollectionViewItemsShouldRespectSafeAreaEdges.png (size differs - baseline is 2436x974 pixels, actual is 2622x1056 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: CollectionViewItemsShouldRespectSafeAreaEdges.png (size differs - baseline is 2436x974 pixels, actual is 2622x1056 pixels)
If the correct baseline has changed (this isn't a a bug), then update the ba
...
CollectionViewAddGroupWhenViewIsEmpty
System.InvalidOperationException : 
Snapshot different than baseline: CollectionViewAddGroupWhenViewIsEmpty.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: CollectionViewAddGroupWhenViewIsEmpty.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.

...
VerifyFlowDirectionRTLAndMeasureAllItemsWithObservableCollection
System.InvalidOperationException : 
Snapshot different than baseline: VerifyFlowDirectionRTLAndMeasureAllItemsWithObservableCollection.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyFlowDirectionRTLAndMeasureAllItemsWithObservableCollection.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed 
...
VerifyFlowDirectionRTLAndMeasureAllItemsWithGroupedList
System.InvalidOperationException : 
Snapshot different than baseline: VerifyFlowDirectionRTLAndMeasureAllItemsWithGroupedList.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyFlowDirectionRTLAndMeasureAllItemsWithGroupedList.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bu
...
VerifyCollectionViewEmptyView
System.InvalidOperationException : 
Snapshot different than baseline: VerifyCollectionViewEmptyView.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyCollectionViewEmptyView.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachm
...
VerifyGridItemsLayoutLeftAlignsSingleItem
System.InvalidOperationException : 
Snapshot different than baseline: VerifyGridItemsLayoutLeftAlignsSingleItem.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyGridItemsLayoutLeftAlignsSingleItem.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline
...
CollectionViewSelectedItemBackgroundShouldPersistAfterModalNavigation
System.InvalidOperationException : 
Snapshot different than baseline: CollectionViewSelectedItemBackgroundShouldPersistAfterModalNavigation.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: CollectionViewSelectedItemBackgroundShouldPersistAfterModalNavigation.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline ha
...

(+56 more — see TRX in artifact)

❌ RefreshView — 5 failed tests
CollectionViewWithRefreshViewShouldNotReset
OpenQA.Selenium.UnknownErrorException : An unknown server-side error occurred while processing the command. Original error: The attribute 'ClickablePoint' is unknown. Valid attribute names are: (
    UID,
    accessibilityContainer,
    accessible,
    enabled,
    focused,
    frame,
    hittable,
    index,
    label,
    name,
    rect,
    selected,
    type,
    value,
    visible,
    wdAccessibilityContainer,
    wdAccessible,
    wdEnabled,
    wdFocused,
    wdFrame,
    wdHittable,
    wdIndex,
    wdLabel,
    wdName,
    wdRect,
    wdSelected,
    wdType,
    wdUID,
    wdValue,
    wdVisible
)
at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute)
   at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebDriver.InternalExecute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebElement.Execute(String commandToExecute, Dictionary`2 p
...
RefreshView_SetShadowWithCollectionView_VerifyShadowApplied
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.RefreshViewFeatureTests.RefreshView_SetShadowWithCollectionView_VerifyShadowApplied() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/RefreshViewFeatureTests.cs:line 215
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object 
...
RefreshView_SetShadow_VerifyShadowApplied
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.RefreshViewFeatureTests.RefreshView_SetShadow_VerifyShadowApplied() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/RefreshViewFeatureTests.cs:line 199
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
...
ProgressSpinnerNotDisabledOnStartup
System.InvalidOperationException : 
Snapshot different than baseline: Issue28343_ProgressSpinnerDisabled.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Issue28343_ProgressSpinnerDisabled.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See te
...
ProgressSpinnerRemainsDisabledAfterSwappingContent
System.InvalidOperationException : 
Snapshot different than baseline: Issue28343_ProgressSpinnerDisabled.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Issue28343_ProgressSpinnerDisabled.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See te
...
❌ ViewBaseTests — 99 failed tests
Image_ClipWithRotation
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Image_ClipWithRotation() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 811
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.RuntimeM
...
Button_ClipWithText
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Button_ClipWithText() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 243
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.RuntimeMeth
...
Border_ClipWithStrokeThickness
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Border_ClipWithStrokeThickness() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 52
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.R
...
Border_ClipWithRotationAndScale
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Border_ClipWithRotationAndScale() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 1086
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflectio
...
Border_ClipWithStrokeColorBlue
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Border_ClipWithStrokeColorBlue() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 71
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.R
...
Image_ClipNull_NoCrash
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Image_ClipNull_NoCrash() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 725
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.RuntimeM
...
VisualTransform_Rotation
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_Rotation.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_Rotation.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or dow
...
VisualTransform_ScaleWithAnchorXAndRotationY
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_ScaleWithAnchorXAndRotationY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_ScaleWithAnchorXAndRotationY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the ba
...
Image_ClipWithQuadraticBezierSegmentPath
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Image_ClipWithQuadraticBezierSegmentPath() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 431
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.R
...
Border_ClipNull_NoCrash
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Border_ClipNull_NoCrash() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 695
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Runtime
...
BoxView_ClipWithShadow
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.BoxView_ClipWithShadow() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 197
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.RuntimeM
...
LightTheme_DatePicker_VerifyVisualState
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.LightTheme_DatePicker_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 86
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at Sy
...
BoxView_ClipWithCornerRadius
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.BoxView_ClipWithCornerRadius() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 176
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Ru
...
VisualTransform_RotationWithScale
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_RotationWithScale.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_RotationWithScale.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test
...
ImageButton_ClipWithShadow
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.ImageButton_ClipWithShadow() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 662
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Runt
...
VisualTransform_Scale
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_Scale.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_Scale.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download 
...
Button_ClipWithImageSource
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Button_ClipWithImageSource() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 223
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Runt
...
VisualTransform_RotationYWithScaleY
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_RotationYWithScaleY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_RotationYWithScaleY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See 
...
DarkTheme_Switch_VerifyVisualState
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.DarkTheme_Switch_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 197
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System
...
VisualTransform_ScaleXWithAnchorYAndRotationY
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_ScaleXWithAnchorYAndRotationY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_ScaleXWithAnchorYAndRotationY.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the 
...
Border_ClipWithRotation
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Border_ClipWithRotation() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 835
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Runtime
...
ContentView_ClipWithEllipseGeometry
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.ContentView_ClipWithEllipseGeometry() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 549
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflec
...
DefaultContentWithFlowDirection
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ContentViewFeatureTests.DefaultContentWithFlowDirection() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentViewFeatureTests.cs:line 172
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at Sys
...
LightTheme_EntryAndPlaceholderColor_VerifyVisualState
System.InvalidOperationException : 
Snapshot different than baseline: LightTheme_EntryAndPlaceholderColor_VerifyVisualState.png (size differs - baseline is 1124x1126 pixels, actual is 1206x1312 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: LightTheme_EntryAndPlaceholderColor_VerifyVisualState.png (size differs - baseline is 1124x1126 pixels, actual is 1206x1312 pixels)
If the correct baseline has changed (this isn't a a bug), 
...
DarkTheme_Slider_VerifyVisualState
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.DarkTheme_Slider_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 174
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System
...
LightTheme_CheckBox_VerifyVisualState
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.LightTheme_CheckBox_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 55
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Border_ClipWithNestedContent
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Border_ClipWithNestedContent() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 997
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.Ru
...
Image_ClipWithPolyLineSegmentPath
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Image_ClipWithPolyLineSegmentPath() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 399
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflecti
...
VerifyBackgroundColorCleared
System.InvalidOperationException : 
Snapshot different than baseline: VerifyBackgroundColorCleared.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyBackgroundColorCleared.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachmen
...
VisualTransform_AnchorX_ScaleYWithRotation
System.InvalidOperationException : 
Snapshot different than baseline: VisualTransform_AnchorX_ScaleYWithRotation.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_AnchorX_ScaleYWithRotation.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseli
...

(+69 more — see TRX in artifact)

📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)


📋 Pre-Flight — Context & Validation

Issue: #24533 - [iOS] RefreshView causes CollectionView scroll position to reset
PR: #31376 - [iOS] Fix RefreshView causes CollectionView scroll position to reset
Platforms Affected: iOS
Files Changed: 1 implementation, 2 test

Key Findings

  • Issue #24533 reports that an iOS RefreshView wrapping a CollectionView resets the scroll position to the top after refresh; Android is reported as working correctly.
  • PR #31376 changes src/Core/src/Platform/iOS/MauiRefreshView.cs to store _originalY when refresh starts, then restores it when refresh ends. It also adds a RefreshView UI test page and NUnit UI test.
  • Gate was already completed and failed: Issue24533 failed with the fix applied due an Appium ClickablePoint/tap interaction failure in the new UI test path.
  • Public prior review notes indicate the test originally masked the regression by scrolling to the footer again before asserting and is incorrectly scoped with TEST_FAILS_ON_WINDOWS for an iOS-only bug.

Code Review Summary

Verdict: NEEDS_CHANGES
Confidence: low
Errors: 3 | Warnings: 0 | Suggestions: 0

Key code review findings:

  • ✗ src/Core/src/Platform/iOS/MauiRefreshView.cs:82, :119 — storing a negative pull offset can restore the scroll view to an overscrolled position when refresh ends.
  • ✗ src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs:30 — scrolling to Footer after refresh masks the reset before reading the offset.
  • ✗ src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs:1 — TEST_FAILS_ON_WINDOWS is too broad for an iOS-only test.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #31376 Store scroll position on refresh start and skip begin offset while pulled negative ❌ FAILED (Gate) src/Core/src/Platform/iOS/MauiRefreshView.cs, UI test files Gate failed with Appium tap/ClickablePoint error; test reliability issues remain.

🔬 Code Review — Deep Analysis

Code Review — PR #31376

Independent Assessment

What this changes: iOS MauiRefreshView now captures the current UIScrollView.ContentOffset.Y when refresh starts, skips offset adjustment while the scroll view is already pulled negative, and adds a UI repro/test for RefreshView + CollectionView.
Inferred motivation: Preserve CollectionView scroll position after refresh instead of jumping back to top.

Reconciliation with PR Narrative

Author claims: Fixes #24533 by storing/restoring original scroll position; tested Android/Windows/iOS/Mac.
Agreement/disagreement: Motivation matches the issue, but the implementation still mishandles pull-to-refresh negative offsets, and the added test can pass without detecting the regression.

Prior Review Reconciliation

Prior ❌ Error Finding Source Status Evidence
Test does not reproduce bug; passes without fix MauiBot review, 2026-06-15 ❌ Unresolved Current test still calls App.ScrollTo("Footer") after refresh before reading the offset.
TEST_FAILS_ON_WINDOWS runs iOS-only test on Android/MacCatalyst MauiBot inline comments ❌ Unresolved Issue24533.cs:1 remains #if TEST_FAILS_ON_WINDOWS; Android and Mac test projects define it.
Negative-offset guard skipped restore on refresh ending MauiBot inline comment ✅ Fixed/obsolete Current guard is scoped to refreshing && ContentOffset.Y < 0.

Blast Radius Assessment

  • Runs for all instances: Yes — all iOS/MacCatalyst RefreshView instances wrapping a UIScrollView.
  • Startup impact: No.
  • Static/shared state: No.

CI Status

  • Required-check result: Undetermined — gh pr checks --required failed because GitHub CLI is unauthenticated.
  • Classification: Undetermined.
  • Action taken: Public metadata/comments were available, but required-check status was not; confidence capped low.

Findings

❌ Error — Pull-to-refresh can restore a negative offset

src/Core/src/Platform/iOS/MauiRefreshView.cs:82, :119

When refresh starts during a real pull gesture, ContentOffset.Y is negative. StoreCurrentScrollPosition() stores that negative value in _originalY, then TryOffsetRefresh(..., true) returns early. When refresh ends, the code restores _originalY, leaving the scroll view overscrolled instead of returning to the normal top/resting offset. Clamp the stored value to the top resting offset before restoring.

❌ Error — Regression test masks the regression

src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs:30

After triggering refresh, the test calls App.ScrollTo("Footer") before reading verticalOffsetAfterRefresh. If the old bug reset the CollectionView to the top, this scrolls it back down, so Assert.That(verticalOffsetAfterRefresh, Is.GreaterThan(0)) can still pass. Capture/assert the offset immediately after refresh completes.

❌ Error — iOS-only test is compiled for non-iOS platforms

src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs:1

TEST_FAILS_ON_WINDOWS is defined by Android, iOS, and MacCatalyst test projects. The issue and production fix are iOS-specific, so this should be scoped to iOS, e.g. #if IOSUITEST, unless the PR intentionally validates all those platforms.

Failure-Mode Probing

  • User pulls down to refresh from top: _originalY can become negative and is restored on completion, leaving content overscrolled.
  • Old bug resets to top during test: final ScrollTo("Footer") hides it, so the test can pass without the fix.
  • Android/MacCatalyst CI: test compiles despite iOS-only issue/fix, adding unrelated gate risk.

Verdict: NEEDS_CHANGES

Confidence: low
Summary: The intended fix addresses the right area but still has a concrete negative-offset failure mode. The regression test is not reliable enough to prove the bug is fixed, and prior unresolved ❌ findings remain.


🛠️ Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix Track MAUI-owned programmatic refresh offset and undo only that delta ❌ FAILED/BLOCKED 1 file Targeted iOS UI test hit the existing Appium ClickablePoint failure before validating product behavior.
2 try-fix Top-only refresh-control reveal; do not move already-scrolled content; repair iOS UI test ✅ PASSED 3 files Targeted iOS test passed; improved test fails when product fix is removed.
PR PR #31376 Store current scroll position on refresh start and restore absolute Y on refresh end ❌ FAILED (Gate) 3 files Gate failed with UI test interaction issue; code review found negative-offset and test reliability concerns.

Cross-Pollination

Model Round New Ideas? Details
gpt-5.5 expert reviewer 1 Yes Use programmatic-offset ownership instead of absolute scroll-position restore.
gpt-5.5 expert reviewer 2 Yes Use top-only refresh-control reveal and make the UI test use a stable external trigger plus immediate offset assertion.

Exhausted: No — stopped because Candidate #2 passed targeted validation and is demonstrably better than the PR fix.
Selected Fix: Candidate #2 — preserves scrolled content without absolute Y restore, avoids negative-pull offset restoration, and includes a reliable iOS regression test.


📝 Recommended PR Title & Description

Assessment: ✏️ Recommend updating — the title is good, but the description describes the raw PR's absolute scroll-position restore rather than the winning try-fix-2 top-only reveal strategy and improved iOS test.

Recommended title

[iOS] RefreshView: Preserve CollectionView scroll position during refresh

Recommended description

### Root Cause

When `RefreshView.IsRefreshing` starts on iOS, `MauiRefreshView` programmatically offsets the hosted `UIScrollView` to reveal the refresh control. If the user is already scrolled into a `CollectionView`, that offset adjustment can move the viewport and refresh completion can leave the collection reset near the top instead of preserving the user's current scroll position.

### Description of Change

Updated the iOS `MauiRefreshView` refresh-offset logic so it only reveals/collapses the refresh control when the hosted scroll view is already at its adjusted top. If the scroll view is already scrolled into content, refresh state changes leave the existing `ContentOffset` unchanged.

Added an iOS UI regression test for #24533 that scrolls the `CollectionView`, triggers refresh through a stable external button, waits for refresh completion, and asserts the vertical offset is preserved before performing any additional scrolling.

### Issues Fixed

Fixes #24533

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video src="https://github.com/user-attachments/assets/041c5713-8f9f-4e28-973a-1242384e2b57" width="300" height="600"> | **iOS**<br> <video src="https://github.com/user-attachments/assets/7fcc79ae-d153-4013-840c-98277b7f01da" width="300" height="600"> |

🏁 Report — Final Recommendation

Comparative Fix Report — PR #31376

Candidates

Candidate Approach Regression result Rank
try-fix-2 Top-only refresh-control reveal: preserve viewport when already scrolled into content; only reveal/collapse spinner when at adjusted top. Also fixes the UI test to use a stable trigger and immediate offset assertion. ✅ Passed targeted iOS test and failed when product fix was removed 1
pr-plus-reviewer Raw PR plus expert feedback: avoid negative pull-offset restore, stop masking the test with a post-refresh scroll, and scope test to iOS. Not independently run; inherits failed gate context unless fully replaced with the try-fix-2 test/product model 2
try-fix-1 Track MAUI-owned programmatic refresh offset and undo only that delta. ❌ Failed/blocked by existing Appium ClickablePoint footer interaction before product validation 3
pr Store current absolute Y when refresh starts and restore it when refresh ends. ❌ Gate failed; expert review found product and test correctness issues 4

Analysis

try-fix-2 is the winning candidate. It directly targets the failure mode from issue #24533: when refresh starts while the collection is already scrolled into content, MAUI should not programmatically move the viewport just to reveal the refresh control. By leaving non-top offsets alone, it avoids the PR's risky absolute offset capture/restore and avoids restoring stale or negative offsets after content changes.

The raw PR fix is ranked last because it failed the supplied gate and has unresolved expert findings. In particular, storing _originalY during a pull can capture a negative UIKit-owned overscroll value, and the added test can hide the reset by scrolling again before asserting.

pr-plus-reviewer improves the raw PR by applying the reviewer's actionable feedback, but it is still an incremental repair to an absolute-position restoration strategy. It does not have the same positive evidence as try-fix-2, whose improved test both passed with the fix and failed when the product fix was removed.

try-fix-1 has a reasonable product idea, but it did not obtain regression evidence because the original footer-tap Appium path failed before validating behavior. Per the ranking rule, candidates that failed or were blocked by regression tests rank below a passing candidate.

Winner

Selected candidate: try-fix-2

Rationale: It is the only candidate with passing targeted iOS validation and a regression sanity check proving the test catches the reset. It also avoids the raw PR's absolute offset restoration failure modes and includes the most reliable iOS-scoped test coverage.


🧭 Next Steps — alternative fix proposed (try-fix-2)

Automated review — alternative fix proposed

The expert-reviewer evaluation compared the PR fix against automatically generated candidates and selected try-fix-2 as the strongest fix.

Why: try-fix-2 is the only candidate with passing targeted iOS validation and a regression sanity check proving the test fails without the product fix. It avoids the PR fix's absolute scroll-offset restore failure modes while providing a reliable iOS-scoped regression test.

Please consider applying the candidate diff below (or use it as guidance). Once you push an update, this workflow will re-trigger and re-evaluate.

Candidate diff (try-fix-2)
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue24533.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue24533.cs
new file mode 100644
index 0000000000..999374303a
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue24533.cs
@@ -0,0 +1,155 @@
+using System.Collections.ObjectModel;
+using System.Windows.Input;
+using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 24533, "[iOS] RefreshView causes CollectionView scroll position to reset", PlatformAffected.iOS)]
+public class Issue24533 : ContentPage
+{
+	ObservableCollection<string> _items;
+	public ObservableCollection<string> Items
+	{
+		get => _items;
+		set
+		{
+			_items = value;
+			OnPropertyChanged(nameof(Items));
+		}
+	}
+
+	bool _isLoading;
+	public bool IsLoading
+	{
+		get => _isLoading;
+		set
+		{
+			_isLoading = value;
+			OnPropertyChanged(nameof(IsLoading));
+		}
+	}
+
+	ICommand _refreshCommand;
+	public ICommand RefreshCommand
+	{
+		get => _refreshCommand;
+		set
+		{
+			_refreshCommand = value;
+			OnPropertyChanged(nameof(RefreshCommand));
+		}
+	}
+
+	string _verticalOffsetText = "VerticalOffset: 0.00";
+	public string VerticalOffsetText
+	{
+		get => _verticalOffsetText;
+		set
+		{
+			_verticalOffsetText = value;
+			OnPropertyChanged(nameof(VerticalOffsetText));
+		}
+	}
+
+	string _itemCountText = "ItemCount: 0";
+	public string ItemCountText
+	{
+		get => _itemCountText;
+		set
+		{
+			_itemCountText = value;
+			OnPropertyChanged(nameof(ItemCountText));
+		}
+	}
+
+	int count;
+
+	public Issue24533()
+	{
+		RefreshCommand = new Command(() => { });
+		Items = new ObservableCollection<string>();
+		this.On<Microsoft.Maui.Controls.PlatformConfiguration.iOS>().SetUseSafeArea(true);
+
+		var collectionView = new CollectionView
+		{
+			AutomationId = "Issue24533CollectionView",
+			SelectionMode = SelectionMode.Single,
+			ItemTemplate = new DataTemplate(() =>
+			{
+				var stack = new VerticalStackLayout();
+				var label = new Label();
+				label.SetBinding(Label.TextProperty, ".");
+				stack.Children.Add(label);
+				return stack;
+			}),
+		};
+		collectionView.Scrolled += CollectionView_Scrolled;
+
+		collectionView.SetBinding(ItemsView.ItemsSourceProperty, nameof(Items));
+
+		var refreshView = new RefreshView
+		{
+			Margin = 16
+		};
+		refreshView.SetBinding(RefreshView.IsRefreshingProperty, nameof(IsLoading));
+		refreshView.SetBinding(RefreshView.CommandProperty, nameof(RefreshCommand));
+		refreshView.Content = collectionView;
+
+		var verticalOffsetLabel = new Label
+		{
+			AutomationId = "VerticalOffsetLabel"
+		};
+		verticalOffsetLabel.SetBinding(Label.TextProperty, nameof(VerticalOffsetText));
+
+		var itemCountLabel = new Label
+		{
+			AutomationId = "ItemCountLabel"
+		};
+		itemCountLabel.SetBinding(Label.TextProperty, nameof(ItemCountText));
+
+		var refreshButton = new Button
+		{
+			Text = "Trigger Refresh",
+			AutomationId = "TriggerRefresh"
+		};
+		refreshButton.Clicked += Button_Clicked;
+
+		Content = new StackLayout
+		{
+			Children =
+			{
+				verticalOffsetLabel,
+				itemCountLabel,
+				refreshButton,
+				refreshView
+			}
+		};
+
+		BindingContext = this;
+
+		AddItems(75);
+	}
+
+	void Button_Clicked(object sender, EventArgs e)
+	{
+		IsLoading = true;
+		Dispatcher.DispatchDelayed(TimeSpan.FromMilliseconds(100), () => AddItems());
+	}
+
+	void AddItems(int itemCount = 25)
+	{
+		foreach (int value in Enumerable.Range(count, itemCount))
+		{
+			Items.Add(value.ToString());
+		}
+		count += itemCount;
+		ItemCountText = $"ItemCount: {Items.Count}";
+
+		IsLoading = false;
+	}
+
+	void CollectionView_Scrolled(object sender, ItemsViewScrolledEventArgs e)
+	{
+		VerticalOffsetText = $"VerticalOffset: {e.VerticalOffset:F2}";
+	}
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs
new file mode 100644
index 0000000000..874886dafc
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24533.cs
@@ -0,0 +1,51 @@
+#if IOSUITEST
+using System.Globalization;
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues
+{
+	public class Issue24533 : _IssuesUITest
+	{
+		public override string Issue => "[iOS] RefreshView causes CollectionView scroll position to reset";
+
+		public Issue24533(TestDevice device) : base(device)
+		{
+		}
+
+		[Test]
+		[Category(UITestCategories.RefreshView)]
+		public void CollectionViewWithRefreshViewShouldNotReset()
+		{
+			App.WaitForElement("Issue24533CollectionView");
+			App.ScrollDown("Issue24533CollectionView", ScrollStrategy.Gesture, swipePercentage: 0.9);
+			var verticalOffsetBeforeRefresh = GetVerticalOffset();
+			Assert.That(verticalOffsetBeforeRefresh, Is.GreaterThan(0));
+
+			var itemCountBeforeRefresh = GetItemCount();
+			App.Tap("TriggerRefresh");
+			Assert.That(App.WaitForTextToBePresentInElement("ItemCountLabel", $"ItemCount: {itemCountBeforeRefresh + 25}"), Is.True);
+
+			var verticalOffsetAfterRefresh = GetVerticalOffset();
+			Assert.That(verticalOffsetAfterRefresh, Is.GreaterThanOrEqualTo(verticalOffsetBeforeRefresh - 100));
+		}
+
+		double GetVerticalOffset()
+		{
+			var verticalOffsetText = App.WaitForElement("VerticalOffsetLabel").GetText() ?? string.Empty;
+			var verticalOffsetValue = verticalOffsetText.Replace("VerticalOffset:", string.Empty, StringComparison.Ordinal).Trim();
+
+			return double.Parse(verticalOffsetValue, CultureInfo.InvariantCulture);
+		}
+
+		int GetItemCount()
+		{
+			var itemCountText = App.WaitForElement("ItemCountLabel").GetText() ?? string.Empty;
+			var itemCountValue = itemCountText.Replace("ItemCount:", string.Empty, StringComparison.Ordinal).Trim();
+
+			return int.Parse(itemCountValue, CultureInfo.InvariantCulture);
+		}
+	}
+}
+#endif
\ No newline at end of file
diff --git a/src/Core/src/Platform/iOS/MauiRefreshView.cs b/src/Core/src/Platform/iOS/MauiRefreshView.cs
index d3092a107a..e8dc9ad2f8 100644
--- a/src/Core/src/Platform/iOS/MauiRefreshView.cs
+++ b/src/Core/src/Platform/iOS/MauiRefreshView.cs
@@ -2,7 +2,6 @@ using System;
 using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
 using System.Text;
-using CoreFoundation;
 using CoreGraphics;
 using Microsoft.Maui.Graphics;
 using ObjCRuntime;
@@ -16,8 +15,8 @@ namespace Microsoft.Maui.Platform
 		bool _isRefreshing;
 		bool _isEnabled = true;
 		bool _isRefreshEnabled = true;
-		nfloat _originalY;
 		nfloat _refreshControlHeight;
+		bool _programmaticallyRevealedRefreshControl;
 		[UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")]
 		UIView _refreshControlParent;
 		[UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")]
@@ -76,10 +75,32 @@ namespace Microsoft.Maui.Platform
 		{
 			if (view is UIScrollView scrollView)
 			{
+				var tolerance = (nfloat)0.5;
+				var topOffset = -scrollView.AdjustedContentInset.Top;
+
 				if (refreshing)
-					scrollView.SetContentOffset(new CGPoint(0, _originalY - _refreshControlHeight), true);
-				else
-					scrollView.ContentOffset = new CGPoint(0, _originalY);
+				{
+					_programmaticallyRevealedRefreshControl = false;
+
+					if (scrollView.ContentSize.Height <= scrollView.Bounds.Height ||
+						scrollView.ContentOffset.Y > topOffset + tolerance ||
+						scrollView.ContentOffset.Y < topOffset - tolerance)
+					{
+						return true;
+					}
+
+					scrollView.SetContentOffset(new CGPoint(scrollView.ContentOffset.X, topOffset - _refreshControlHeight), true);
+					_programmaticallyRevealedRefreshControl = true;
+					return true;
+				}
+
+				if (_programmaticallyRevealedRefreshControl &&
+					scrollView.ContentOffset.Y <= topOffset + tolerance)
+				{
+					scrollView.ContentOffset = new CGPoint(scrollView.ContentOffset.X, topOffset);
+				}
+
+				_programmaticallyRevealedRefreshControl = false;
 
 				return true;
 			}
@@ -154,7 +175,6 @@ namespace Microsoft.Maui.Platform
 
 				scrollView.AlwaysBounceVertical = true;
 
-				_originalY = scrollView.ContentOffset.Y;
 				_refreshControlHeight = _refreshControl.Frame.Size.Height;
 
 				return true;

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jun 25, 2026
@devanathan-vaithiyanathan

Copy link
Copy Markdown
Contributor Author

@kubaflo ,
AI review summary suggested that the gate failed with the fix. However, I verified it locally, and the test passed with the fix.(Added a screenshot for reference)
image

@kubaflo
kubaflo changed the base branch from main to inflight/current June 29, 2026 14:31
@kubaflo
kubaflo merged commit 72d2018 into dotnet:inflight/current Jun 29, 2026
31 checks passed
@github-actions github-actions Bot added this to the .NET 10 SR9 milestone Jun 29, 2026
kubaflo pushed a commit that referenced this pull request Jul 3, 2026
…31376)

<!-- 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
When refresh starts or ends, the scroll view's content offset gets reset
to (0,0) instead of maintaining the user's current scroll position.

### Description of Change

<!-- Enter description of the fix in this section -->
Fixed by storing the original scroll position before refresh starts and
restoring it after refresh completes, preventing the view from jumping
back to the top during pull-to-refresh operations.


### 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 #24533 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video
src="https://github.com/user-attachments/assets/041c5713-8f9f-4e28-973a-1242384e2b57"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/7fcc79ae-d153-4013-840c-98277b7f01da"
width="300" height="600"> |
@kubaflo kubaflo mentioned this pull request Jul 6, 2026
kubaflo pushed a commit that referenced this pull request Jul 6, 2026
…31376)

<!-- 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
When refresh starts or ends, the scroll view's content offset gets reset
to (0,0) instead of maintaining the user's current scroll position.

### Description of Change

<!-- Enter description of the fix in this section -->
Fixed by storing the original scroll position before refresh starts and
restoring it after refresh completes, preventing the view from jumping
back to the top during pull-to-refresh operations.


### 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 #24533 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video
src="https://github.com/user-attachments/assets/041c5713-8f9f-4e28-973a-1242384e2b57"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/7fcc79ae-d153-4013-840c-98277b7f01da"
width="300" height="600"> |
PureWeen pushed a commit that referenced this pull request Jul 7, 2026
…31376)

<!-- 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
When refresh starts or ends, the scroll view's content offset gets reset
to (0,0) instead of maintaining the user's current scroll position.

### Description of Change

<!-- Enter description of the fix in this section -->
Fixed by storing the original scroll position before refresh starts and
restoring it after refresh completes, preventing the view from jumping
back to the top during pull-to-refresh operations.


### 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 #24533 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video
src="https://github.com/user-attachments/assets/041c5713-8f9f-4e28-973a-1242384e2b57"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/7fcc79ae-d153-4013-840c-98277b7f01da"
width="300" height="600"> |
PureWeen pushed a commit that referenced this pull request Jul 7, 2026
…31376)

<!-- 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
When refresh starts or ends, the scroll view's content offset gets reset
to (0,0) instead of maintaining the user's current scroll position.

### Description of Change

<!-- Enter description of the fix in this section -->
Fixed by storing the original scroll position before refresh starts and
restoring it after refresh completes, preventing the view from jumping
back to the top during pull-to-refresh operations.


### 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 #24533 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video
src="https://github.com/user-attachments/assets/041c5713-8f9f-4e28-973a-1242384e2b57"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/7fcc79ae-d153-4013-840c-98277b7f01da"
width="300" height="600"> |
kubaflo pushed a commit that referenced this pull request Jul 10, 2026
…31376)

<!-- 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
When refresh starts or ends, the scroll view's content offset gets reset
to (0,0) instead of maintaining the user's current scroll position.

### Description of Change

<!-- Enter description of the fix in this section -->
Fixed by storing the original scroll position before refresh starts and
restoring it after refresh completes, preventing the view from jumping
back to the top during pull-to-refresh operations.


### 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 #24533 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video
src="https://github.com/user-attachments/assets/041c5713-8f9f-4e28-973a-1242384e2b57"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/7fcc79ae-d153-4013-840c-98277b7f01da"
width="300" height="600"> |
kubaflo pushed a commit that referenced this pull request Jul 15, 2026
…31376)

<!-- 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
When refresh starts or ends, the scroll view's content offset gets reset
to (0,0) instead of maintaining the user's current scroll position.

### Description of Change

<!-- Enter description of the fix in this section -->
Fixed by storing the original scroll position before refresh starts and
restoring it after refresh completes, preventing the view from jumping
back to the top during pull-to-refresh operations.


### 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 #24533 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video
src="https://github.com/user-attachments/assets/041c5713-8f9f-4e28-973a-1242384e2b57"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/7fcc79ae-d153-4013-840c-98277b7f01da"
width="300" height="600"> |
kubaflo pushed a commit that referenced this pull request Jul 22, 2026
…31376)

<!-- 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
When refresh starts or ends, the scroll view's content offset gets reset
to (0,0) instead of maintaining the user's current scroll position.

### Description of Change

<!-- Enter description of the fix in this section -->
Fixed by storing the original scroll position before refresh starts and
restoring it after refresh completes, preventing the view from jumping
back to the top during pull-to-refresh operations.


### 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 #24533 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video
src="https://github.com/user-attachments/assets/041c5713-8f9f-4e28-973a-1242384e2b57"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/7fcc79ae-d153-4013-840c-98277b7f01da"
width="300" height="600"> |
kubaflo pushed a commit that referenced this pull request Jul 28, 2026
…31376)

<!-- 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
When refresh starts or ends, the scroll view's content offset gets reset
to (0,0) instead of maintaining the user's current scroll position.

### Description of Change

<!-- Enter description of the fix in this section -->
Fixed by storing the original scroll position before refresh starts and
restoring it after refresh completes, preventing the view from jumping
back to the top during pull-to-refresh operations.


### 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 #24533 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video
src="https://github.com/user-attachments/assets/041c5713-8f9f-4e28-973a-1242384e2b57"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/7fcc79ae-d153-4013-840c-98277b7f01da"
width="300" height="600"> |
kubaflo pushed a commit that referenced this pull request Jul 29, 2026
…31376)

<!-- 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
When refresh starts or ends, the scroll view's content offset gets reset
to (0,0) instead of maintaining the user's current scroll position.

### Description of Change

<!-- Enter description of the fix in this section -->
Fixed by storing the original scroll position before refresh starts and
restoring it after refresh completes, preventing the view from jumping
back to the top during pull-to-refresh operations.


### 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 #24533 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video
src="https://github.com/user-attachments/assets/041c5713-8f9f-4e28-973a-1242384e2b57"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/7fcc79ae-d153-4013-840c-98277b7f01da"
width="300" height="600"> |
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 30, 2026
@github-actions github-actions Bot modified the milestones: .NET 10 SR9, .NET 10 SR10 Aug 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-refreshview community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration s/agent-fix-win AI found a better alternative fix than the PR s/agent-gate-failed AI could not verify tests catch the bug s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[iOS] RefreshView causes CollectionView scroll position to reset

7 participants