Skip to content

[Net11] [iOS/MacCatalyst] Migrate TabbedPage to handler architecture - #36507

Merged
kubaflo merged 13 commits into
net11.0from
Net11.0-iOS-TabbedPage-Handler
Jul 26, 2026
Merged

[Net11] [iOS/MacCatalyst] Migrate TabbedPage to handler architecture#36507
kubaflo merged 13 commits into
net11.0from
Net11.0-iOS-TabbedPage-Handler

Conversation

@Tamilarasan-Paranthaman

Copy link
Copy Markdown
Member

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!

Description of Change

Replaces the monolithic TabbedRenderer (~600 lines, single class that IS a UITabBarController) with a layered TabbedViewHandler architecture for iOS and MacCatalyst. The handler is registered as the default for now; a feature flag opt-in can be introduced if needed.

Issues Fixed

Fixes #33082

Note: The shared Core infrastructure is designed for potential reuse by a future Shell handler, but Shell integration is not part of this PR)

Motivation

The TabbedRenderer is a single class that IS a UITabBarController. It owns all tab management, appearance, lifecycle, reordering, and page lifecycle in one file. This makes it:

  • Hard to maintain — changes to tab bar appearance risk breaking tab selection logic
  • Not reusable — other components that may need UITabBarController management can't reuse anything from the renderer
  • Inconsistent with handler architecture — every other control has moved to handlers; TabbedPage was still using the renderer on iOS
  • Prone to retain cycles — the renderer both IS the UIKit VC and holds event subscriptions, requiring careful manual cleanup

What Changed

New Files (Core layer — src/Core/)

File Purpose
Handlers/TabbedView/TabbedViewHandler.cs Cross-platform handler base: ViewHandler<ITabbedView, PlatformView>, Mapper + CommandMapper
Handlers/TabbedView/TabbedViewHandler.iOS.cs iOS handler: ITabBarManagerDelegate implementation, NativeSelectionInProgress directional sync flag, ConnectHandler/DisconnectHandler lifecycle
Handlers/TabbedView/ITabbedViewHandler.cs Handler interface contract extending IViewHandler
Platform/iOS/TabBarControllerManager/TabBarControllerManager.cs Shared UITabBarController manager: nested MauiTabBarController subclass, WeakReference delegate pattern, tab reordering disabled, iOS 18 DisableiOS18ToolbarTabs() fix, UpdateTabBarVisibility() for MacCatalyst
Platform/iOS/TabBarControllerManager/ITabBarManagerDelegate.cs 7-method interface bridging Core ↔ handler: OnTabSelected, OnViewDidAppear/Disappear, OnViewDidLayoutSubviews, OnTraitCollectionDidChange, OnTabsReordered, GetCurrentPageViewController
Core/ITabbedView.cs Marker interface for tabbed view contract (extends IView)

New Files (Controls layer — src/Controls/)

File Purpose
TabbedPage/TabbedPage.Mapper.cs RemapForControls() — registers 12 mapper methods + PlatformViewFactory for iOS/MacCatalyst
TabbedPage/TabbedPage.iOS.cs All iOS mapper implementations: MapItemsSource (incremental Add/Remove + full rebuild), MapCurrentPage (bidirectional sync), MapBarBackgroundColor/BarTextColor/SelectedTabColor/UnselectedTabColor, MapTranslucencyMode, status bar/home indicator forwarding, platform view factory, cleanup

Modified Files

Area File Change
Handler Registration AppHostBuilderExtensions.cs AddHandler<TabbedPage, TabbedViewHandler>() for iOS/MacCatalyst (unconditional)
Virtual View TabbedPage.cs Implements ITabbedView, adds _pendingPagesChangedArgs for incremental collection sync, OnHandlerChangingCore wires PagesChanged + page PropertyChanged events, PageTabAdapter inner class
Compatibility TabbedRenderer.cs Unchanged — remains in the Compatibility layer for manual fallback
Build targets Microsoft.Maui.Controls.targets Removed RuntimeHostConfigurationOption for UseiOSTabbedViewHandler (no longer needed)
Runtime RuntimeFeature.cs Removed UseiOSTabbedViewHandler feature switch (handler is now unconditional default)

Architecture Overview

Handler Hierarchy

┌──────────────────────────────────────────────────────────┐
│                    CONTROLS LAYER                        │
│  TabbedPage.Mapper.cs           → mappers + factory      │
│  TabbedPage.iOS.cs              → mapper implementations │
│  TabbedPage.cs                  → shared wiring          │
├──────────────────────────────────────────────────────────┤
│                     CORE LAYER                           │
│  TabbedViewHandler.iOS.cs       → lifecycle + delegate   │
│  TabBarControllerManager.cs     → shared UITabBarCtrl    │
│  ITabBarManagerDelegate.cs      → 7-method interface     │
└──────────────────────────────────────────────────────────┘

Key Design Decisions

Decision Rationale
Two-layer split (Core/Controls) Core owns UITabBarController management with no knowledge of Page, BarTextColor, or XAML. Controls injects its behavior via mapper methods and PlatformViewFactory. The Core layer is generic enough that it could potentially be reused by other consumers in the future.
TabBarControllerManager as shared class Extracted UITabBarController lifecycle (tab selection, view lifecycle events, tab reordering, iOS 18 compatibility) into a reusable manager. Currently used by TabbedViewHandler; the ITabBarManagerDelegate interface makes it possible for other consumers to adopt it in the future if needed.
MauiTabBarController nested subclass Intercepts SelectedViewController for tab selection sync. Overrides ViewDidAppear/ViewDidDisappear/ViewDidLayoutSubviews for lifecycle. Uses WeakReference<TabBarControllerManager> to prevent retain cycles.
NativeSelectionInProgress directional flag Breaks the selection sync loop deterministically. When UIKit fires SelectedViewController (user tap), the flag is true → sync native→virtual (read index, set CurrentPage). When CurrentPage changes programmatically, flag is false → sync virtual→native (set SelectedViewController).
Incremental collection changes Uses _previousPages HashSet to track pages across rebuilds. Add/Remove operations create/disconnect only affected pages. Full rebuild diffs against _previousPages to find removed pages. Avoids O(n) teardown+rebuild on every change.
PlatformViewFactory bridge The handler's CreatePlatformView() throws — the Controls layer overrides it via PlatformViewFactory to create and fully configure the TabBarControllerManager before the handler sees the platform view. This avoids circular assembly references.
Handler is unconditional default No feature flag. Registered in AppHostBuilderExtensions.cs. TabbedRenderer still exists for manual opt-out if needed.

ITabBarManagerDelegate Interface (7 methods)

Method Purpose
OnTabSelected(int index) User tapped a tab — sync native→virtual
OnTabsReordered(UIViewController[]) User reordered tabs in "More" tab editor
GetCurrentPageViewController() Returns current page's VC for status bar / home indicator
OnViewDidAppear() UIKit appeared — fire SendAppearing()
OnViewDidDisappear() UIKit disappeared — fire SendDisappearing()
OnViewDidLayoutSubviews() Layout pass — propagate frame via view.Arrange()
OnTraitCollectionDidChange() Trait collection changed — resize tab bar icons

Key Behaviors

Behavior Implementation
Tab selection sync Bidirectional via NativeSelectionInProgress flag — no implicit UIKit no-op reliance
Collection updates Incremental Add/Remove for simple changes; full rebuild with _previousPages diff for Reset/Replace/Move
Tab bar appearance iOS 15+ UITabBarAppearance API, fallback for older versions; supports color, brush, gradient, translucency
iOS 18 compatibility DisableiOS18ToolbarTabs() in MauiTabBarController constructor + UpdateTabBarVisibility() for MacCatalyst
Tab reordering disabled CustomizableViewControllers = null in ViewControllers setter (re-applied after every VC update)
Status bar / Home indicator MauiTabBarController overrides ChildViewControllerForStatusBarHidden/HomeIndicatorAutoHidden via injected GetCurrentPageViewControllerFunc callback
Cleanup Three-phase: OnHandlerChangingPartial (Controls events + UITabBarAppearance), DisconnectHandler (manager disposal), Manager.Dispose (UITabBarController disposal)

Feature Parity

Full parity with TabbedRenderer including:

  • Tab creation with title, icon, accessibility ID
  • Tab selection (user tap + programmatic CurrentPage)
  • Dynamic add/insert/remove pages at runtime
  • Bar background (color, brush, gradient)
  • Bar text color + selected/unselected tab colors
  • Translucency mode (Translucent / Opaque / Default)
  • iOS 15+ UITabBarAppearance styling
  • "More" tab for 5+ tabs (with reordering disabled)
  • Status bar hidden / Home indicator auto-hidden per page
  • Tab bar icon auto-resize on trait collection change
  • iOS 18 toolbar tab suppression
  • MacCatalyst tab bar visibility

Shared Infrastructure Summary

Component Current Consumer Reusable For Scope
TabBarControllerManager TabbedViewHandler Potentially reusable UITabBarController lifecycle, selection, reordering, iOS 18 fixes
MauiTabBarController Same Same Lifecycle callbacks, WeakReference delegate
ITabBarManagerDelegate Same Same 7-method interface bridging Core ↔ consumer

Note: The Core infrastructure (TabBarControllerManager, ITabBarManagerDelegate) is generic enough to be consumed by other components (e.g., a future Shell iOS handler) if needed, but no specific reuse scenario is currently planned. The interface may need adjustments based on future consumer requirements.

Handler as Default

The handler is registered as the unconditional default in AppHostBuilderExtensions.cs — no feature flag or opt-in required.

What Changes By Default

  • TabbedPage uses TabbedViewHandler instead of TabbedRenderer on iOS/MacCatalyst
  • Tab selection sync uses an explicit NativeSelectionInProgress flag instead of relying on UIKit's implicit setter no-op
  • Collection changes are incremental (Add/Remove) instead of always full rebuild
  • Cleanup is three-phase (Controls → Handler → Manager) instead of single-phase Dispose

How to Opt Out

If an app needs to fall back to the renderer, register it manually in MauiProgram.cs:

builder.ConfigureMauiHandlers(handlers =>
{
    handlers.AddHandler<TabbedPage, TabbedRenderer>();
});

TabbedRenderer remains in the Compatibility layer and continues to work.

Migration Guidance for Custom Renderer Users

If you subclassed TabbedRenderer or accessed its internals, this section maps the old patterns to the new handler architecture.

Old → New Mapping

Old (Renderer) New (Handler) Notes
TabbedRenderer (IS a UITabBarController) TabbedViewHandler (HAS a UITabBarController via TabBarControllerManager) Handler is a ViewHandler<ITabbedView, UIView>, not a VC
Override ViewDidAppear Subscribe to manager.ViewDidAppear event Fires via MauiTabBarController.ViewDidAppear → delegate → event
Override ViewDidDisappear Subscribe to manager.ViewDidDisappear event Same pattern
OnPropertyChanged switch Mapper methods in TabbedPage.iOS.cs Declarative — one method per property
SetControllers() full rebuild MapItemsSource() with incremental support Add/Remove changes are handled incrementally
this.TabBar (direct access) GetTabBar(handler) via manager Static helper method
this.SelectedViewController manager.SelectedViewController Through TabBarControllerManager
Dispose(bool) cleanup OnHandlerChangingPartial + DisconnectHandler Three-phase cleanup across layers

Adapter Pattern for Custom Renderers

If you must preserve custom renderer logic, keep using the renderer:

// Keep using TabbedRenderer with your customizations
builder.ConfigureMauiHandlers(handlers =>
{
    handlers.AddHandler<TabbedPage, MyCustomTabbedRenderer>();
});

Testing

  • All existing TabbedPage device tests pass on the handler path
  • Renderer-specific tests continue to work via manual renderer registration

@github-actions

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 -- 36507

Or

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

@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 Jul 12, 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.

Expert Review — 7 findings

See inline comments for details.

Comment thread src/Controls/src/Core/TabbedPage/TabbedPage.Mapper.cs Outdated
Comment thread src/Controls/src/Core/TabbedPage/TabbedPage.Mapper.cs
Comment thread src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs
Comment thread src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs
Comment thread src/Core/src/Handlers/TabbedView/TabbedViewHandler.iOS.cs
Comment thread src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs
Comment thread src/Core/src/Handlers/TabbedView/TabbedViewHandler.iOS.cs
@MauiBot MauiBot added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Jul 12, 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 Jul 12, 2026
@sheiksyedm

Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests , maui-pr-devicetests

@azure-pipelines

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

@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 Jul 13, 2026

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

Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs:755

  • SetTabBarItem is async void. Since it’s invoked from mapper flows, any exception after the first await will crash the process and can’t be observed/logged. Prefer returning Task and invoking it with .FireAndForget(handler) (or otherwise observing/logging) like other handlers do.
		// Tab bar item creation — ported from TabbedRenderer.SetTabBarItem
		async void SetTabBarItem(IPlatformViewHandler renderer, TabBarControllerManager manager)
		{

src/Core/src/Handlers/TabbedView/TabbedViewHandler.iOS.cs:66

  • UpdateValue("CurrentPage") / UpdateValue("ItemsSource") rely on hard-coded mapper keys. Since ITabbedView is currently a marker interface, these strings are easy to mistype and will silently break mapping if keys ever change. Consider centralizing these keys as internal constants in Core (or otherwise exposing shared key names) so both the handler and Controls layer share the same source of truth.
                // Use interface property — typed VirtualView throws after DisconnectHandler
                if (((IElementHandler)this).VirtualView is IElement element)
                {
                    element.Handler?.UpdateValue("CurrentPage");
                }

Comment thread src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs
Comment thread src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs
@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 Jul 23, 2026
MauiBot

This comment was marked as outdated.

@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.

Expert Review — 2 findings

See inline comments for details.

Comment thread src/Controls/src/Core/TabbedPage/TabbedPage.cs
Comment thread src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs
@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jul 24, 2026
@kubaflo

kubaflo commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

/review tests

@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.

Could you please check the ai's suggestions?

@kubaflo

kubaflo commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Tests Failure Analysis

@Tamilarasan-Paranthaman — test-failure review results are available based on commit 50e595d.

Maintainers can request a fresh review after new comments, commits, or CI runs by commenting /review tests.

Overall Not ready Failures 18 Baseline 11 on base Platform iOS/MacCatalyst

Test Failure Review: Not ready - click to expand

Overall verdict: Not ready

One deterministic regression — DropEventCoordinates on the iOS Controls (vlatest) UITest leg — is GREEN across all 5 recent net11.0 base builds and red only on this PR, on the exact platform this PR rewrites (iOS TabbedPage handler + handler registration), so it is Likely PR-caused and caps the merge-readiness at Not ready. The other 17 distinct failures are pre-existing/flaky visual and CollectionView UITests or an iOS-simulator-boot infrastructure failure — 11 of 18 also fail on the base branch — but several could not be attributed deterministically and still need a human before any green verdict.

Coverage: 141 checks · 135 passing · 6 failing · 0 pending · 0 inaccessible · 1 unmapped · 14 unexplained build legs · 0 unaccounted failing checks · 0 aborted failing checks · 0 canceled-build checks · 0 device-test unverified · 17 unattributed · 1 regressed-vs-base. Deterministic ceiling: Not ready — a leg is red on the PR but green on all sampled base builds (DropEventCoordinates); additionally 1 unmapped check (Build Analysis), 14 failed legs with no extractable failure, and 17 undeterminable failures independently forbid a green verdict.

Failure Verdict On base? Evidence
DropEventCoordinates (iOS · Controls (vlatest) Gestures) Likely PR-caused no — regressed deterministicAttribution = regressed-vs-base: leg GREEN on 5/5 sampled net11.0 base builds, red on 0, now red on PR (build 1526457). Assert(dropRelativeToLayout.X > 0 && .Y > 0) Expected True / was False (DragAndDropUITests.cs:398). iOS is the platform this PR rewrites (TabbedViewHandler.iOS.cs, TabBarControllerManager.cs, AppHostBuilderExtensions.cs handler registration).
ValidateDynamic{Item,Footer*,Group*Footer,Group*Header,Header*} templates — 9 CollectionView UITests Needs human investigation yes — also-red OneTimeSetUp cascade "Timed out waiting for Go To Test button to disappear". Exact test+platform also red on base (5/5) but forced to indeterminate (baselineReasonConflict / OneTimeSetUp cascade). CollectionView area, outside this PR's TabbedPage scope.
VerifySelectionModeSingleWhenProgrammaticSelectionWorksWithVerticalList (Windows · visual) Needs human investigation yes — also-red VisualTestUtils.VisualTestFailedException. alsoFailsOnBaseline = true but baselineReasonConflict = true (same name, different failure reason) → indeterminate. Windows, outside this PR's iOS/macOS scope.
CollectionViewSelectionShouldClear (Windows · visual, Issue30363) Needs human investigation yes — also-red VisualTestUtils.VisualTestFailedException (Issue30363.cs:21). baselineReasonConflict = trueindeterminate. Windows/CollectionView, not PR scope.
BottomSheetDetentHeightIsCorrectWhenCollectionViewIsMeasuredBeforeMount Needs human investigation no — flaky-on-base System.TimeoutException waiting for element. Leg flaky on base (green 1 / red 4 of 5) → indeterminate. CollectionView area.
Publish the ios_ui_tests_coreclr_controls_latest test results - build error (×2) Needs human investigation no AzDO publish-results rollup ("one or more test failures detected in result files") for the iOS controls-latest leg; indeterminate. Echoes underlying leg test failures rather than a distinct root cause.
Publish the android_ui_tests_controls_30 test results - build error Needs human investigation no — flaky-on-base Android controls-30 publish rollup; leg flaky on base (green 1 / red 4 of 5) → indeterminate.
Publish the winui_ui_tests_controls test results - build error Needs human investigation yes — also-red WinUI controls publish rollup; leg also-red on base but not attributable → indeterminate. Windows, not PR scope.
RunOniOS_MauiDebug_CoreCLR (maui-pr integration) Likely unrelated n/a — no base data System.InvalidOperationException : Simulator failed to fully boot within timeout (ios-simulator-64_18.5) — infrastructure/provisioning, not PR logic. Also counted by the gate as an unexplained leg.

Recommended action

Hold as Not ready until DropEventCoordinates is resolved: this PR's iOS handler/registration rewrite (TabbedViewHandler.iOS.cs, TabBarControllerManager.cs, AppHostBuilderExtensions.cs) is the only change on the iOS Controls (vlatest) leg, where a previously-green drag-and-drop coordinate assertion (X > 0 && Y > 0) now returns False — verify the migration did not shift the iOS view hierarchy or coordinate origin, then re-run maui-pr-uitests. Independently, a human must open the 14 failed build legs that produced no extractable failure (including Controls TabbedPage,TableView,... and the CollectionView legs) and the unmapped Build Analysis check before any green verdict — the gatherer pulled zero reason from them. The Windows/Android visual and CollectionView UITests and the iOS-simulator-boot timeout are pre-existing/flaky or infrastructure and are not blockers on their own.

Evidence details
  • PR scope: [Net11] [iOS/MacCatalyst] Migrate TabbedPage to handler architecture #36507 @ 50e595d (Net11.0-iOS-TabbedPage-Handlernet11.0). 10 changed files — iOS/MacCatalyst TabbedPage handler migration: TabbedPage.cs, TabbedPage.Mapper.cs, TabbedPage.iOS.cs, AppHostBuilderExtensions.cs, TabbedViewHandler.iOS.cs, TabBarControllerManager.cs, ITabBarManagerDelegate.cs, net-ios/net-maccatalyst PublicAPI.Unshipped.txt. Inferred platforms: ios, macos. Only changed test file is a mac snapshot (DynamicFontImageSourceColorShouldApplyOnTabIcon.png) — none of the failing tests above are in the PR's changed-test set.
  • Regression leg: maui-pr-uitests build 1526457 → iOS UITests CoreCLR Controls (vlatest) Editor,Effects,Essentials,FlyoutPage,Focus,Fonts,Frame,Gestures,GraphicsView (jobIds 2e80461d…, d0d38693…). DropEventCoordinates leg diff: legBaselineResult = succeeded-on-base, legRegressedVsBase = true, baseSampleCount 5 / baseGreenCount 5 / baseFailedCount 0.
  • Builds: maui-pr-uitests 1526457 (failed); maui-pr-devicetests 1526458 (succeeded — Helix aggregates positively confirmed 0 failed work items across all 9 jobs, so deviceTestUnverified = 0); maui-pr 1526456 (succeeded; its single failed record is the RunOniOS_MauiDebug_CoreCLR simulator-boot timeout).
  • Baseline comparison: maui-pr-uitests base 1526898 (failed, 61 baseline failures — only 8/23 failed logs inspected, incomplete); maui-pr-devicetests base 1526785 (failed — inconclusive, XHarness exit-0); maui-pr base 1526768 (failed, 4). 11 of 18 distinct PR failures also fail on the base branch.
  • Gate: verdictCeiling = Not ready. legsRegressedVsBase = 1 (DropEventCoordinates) caps at Not ready; unexplainedFailedLegs = 14, unattributedFailures = 17, unmappedFailingChecks = 1 (Build Analysis) each independently cap at Needs human investigation (subsumed by Not ready). unaccounted / aborted / canceled-build / device-test-unverified = 0.
  • Known issues / ci-scan: Known Build Error registry queried (1 matcher) — 0 matches. [ci-scan] registry queried (51 matchers, net11 family) — 0 matches, 0 regressions demoted.
  • Limitations: The gh-aw runner relies on public build/timeline/log APIs unless a token is provided; here local gathering used an Azure CLI token. The maui-pr-uitests and maui-pr-devicetests baselines were only partially inspected (8 of 23 / 8 of 18 failed logs), so the base-failure list may be incomplete. 14 failing legs produced no extractable failure and require manual log review; the Build Analysis check had no inspectable AzDO build evidence.

Visual failure comparisons

Full-resolution CI baseline, actual, and diff images are embedded below. They supplement the failure classification and do not change the deterministic verdict ceiling.
Relationship labels use deterministic exact test-and-platform baseline evidence plus exact changed snapshot/test scope; missing or mixed evidence remains Needs human investigation.

VerifyDefaultScrollToRequested - android - Needs human investigation - visual comparison

CI reported 0.67% difference in build 1526457.

Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.

CI baselineFresh PR actualCI diff
VerifyDefaultScrollToRequested baseline VerifyDefaultScrollToRequested actual VerifyDefaultScrollToRequested diff
CollectionViewSelectionShouldClear - windows - Needs human investigation - visual comparison

CI reported 0.52% difference in build 1526457.

Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.

CI baselineFresh PR actualCI diff
CollectionViewSelectionShouldClear baseline CollectionViewSelectionShouldClear actual CollectionViewSelectionShouldClear diff
VerifySelectionModeSingleWhenProgrammaticSelectionWorksWithVerticalList - windows - Needs human investigation - visual comparison

CI reported 0.53% difference in build 1526457.

Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.

CI baselineFresh PR actualCI diff
VerifySelectionModeSingleWhenProgrammaticSelectionWorksWithVerticalList baseline VerifySelectionModeSingleWhenProgrammaticSelectionWorksWithVerticalList actual VerifySelectionModeSingleWhenProgrammaticSelectionWorksWithVerticalList diff

@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 Jul 24, 2026
Copilot AI review requested due to automatic review settings July 24, 2026 08:34

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

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

Comments suppressed due to low confidence (3)

src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs:758

  • SetTabBarItem is declared as async void, which can surface exceptions via the synchronization context and makes failures unobservable from callers. Consider using a synchronous wrapper that fire-and-forgets an async Task implementation so exceptions can be logged via TaskExtensions.FireAndForget(...) (consistent with other async mapping patterns in MAUI).
		// Tab bar item creation — ported from TabbedRenderer.SetTabBarItem
		async void SetTabBarItem(IPlatformViewHandler renderer, TabBarControllerManager manager)
		{
			var page = renderer.VirtualView as Page;

src/Core/src/Handlers/TabbedView/TabbedViewHandler.iOS.cs:66

  • Avoid hard-coded mapper keys when calling UpdateValue; using string literals is brittle (renames won’t be caught by the compiler). If Core can’t reference TabbedPage, consider at least centralizing the key in a local const so it’s not duplicated and is easier to audit.
                if (((IElementHandler)this).VirtualView is IElement element)
                {
                    element.Handler?.UpdateValue("CurrentPage");
                }

src/Core/src/Handlers/TabbedView/TabbedViewHandler.iOS.cs:120

  • Avoid hard-coded mapper keys when calling UpdateValue; using string literals is brittle (renames won’t be caught by the compiler). If Core can’t reference TabbedPage, consider at least centralizing the key in a local const so it’s not duplicated and is easier to audit.
            // Trigger icon resize by refreshing all tab bar items
            element.Handler?.UpdateValue("ItemsSource");

#if IOS || MACCATALYST
handlersCollection.AddHandler(typeof(NavigationPage), typeof(Handlers.Compatibility.NavigationRenderer));
handlersCollection.AddHandler(typeof(TabbedPage), typeof(Handlers.Compatibility.TabbedRenderer));
handlersCollection.AddHandler<TabbedPage, TabbedViewHandler>();
@Tamilarasan-Paranthaman

Copy link
Copy Markdown
Member Author

Could you please check the ai's suggestions?

@kubaflo, I have addressed the review suggestions.

@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

@Tamilarasan-Paranthaman — new AI review results are available based on this last commit: 50e595d.

Gate No Tests Confidence Low Platform iOS


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

Gate Result: ⚠️ SKIPPED

No tests were detected in this PR.

Recommendation: Add tests to verify the fix using the write-tests-agent.


📱 UI Tests — TabbedPage,ViewBaseTests

Detected UI test categories: TabbedPage,ViewBaseTests

Deep UI tests — 44 passed, 133 failed across 2 categories on platform-pool agent (replaces in-process counts above).

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
TabbedPage 31/65 (34 ❌) 70 diff PNGs
ViewBaseTests 13/112 (99 ❌) 198 diff PNGs
🔍 AI analysis of failures — PR-related vs unrelated

🔍 AI-generated triage (GitHub Copilot CLI) — a heuristic judgement of whether each deep UI test failure is connected to this PR's changes. Verify before relying on it.

Likely PR-related: one or more failures appear connected to this PR's changes.

  • ✗ PR-related — TabbedPage visual regressions (~30 tests): the PR replaces the MacCatalyst TabbedPage renderer with TabbedViewHandler and rewrites iOS/MacCatalyst tab item, color, flow-direction, icon, selection, and lifecycle handling, matching the many TabbedPage snapshot differences such as TabbedPage_BarTextColor_Verify.
  • ✗ PR-related — TabbedPage lifecycle behavior (1 test): Bugzilla52419Test reports an extra Appearing event, which is plausibly caused by the new TabBarControllerManager ViewDidAppear/ViewDidDisappear forwarding added for TabbedPage on Catalyst.
  • ℹ Uncertain — Navigation/tab-adjacent snapshot failures in the TabbedPage bucket (a few tests): failures such as navigation-bar layout and back-button snapshots may be affected by the new TabbedPage handler hosting/navigation interaction, but the available stack text only shows snapshot deltas rather than a direct functional assertion.
  • ● Unrelated — ViewBase/Clip/VisualTransform/AppTheme/ContentView snapshot failures (90+ tests): these tests exercise broad non-TabbedPage rendering areas not touched by the PR, and the repeated screenshot-baseline mismatch pattern across unrelated controls points to baseline/environment noise rather than this TabbedPage-specific change.

Strongest signal: the Catalyst-scoped PR directly changes TabbedPage rendering and lifecycle code, so TabbedPage failures should be treated as PR-caused first; the large unrelated ViewBase spread should be checked against the platform snapshot baseline/run environment.

TabbedPage — 34 failed tests
TabbedPage_BarTextColor_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_BarTextColor_Verify.png (43.32% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay
...
Issue1323Test
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Issue1323Test.png (42.48% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retr
...
TabbedPage_InsertTabAt_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_InsertTabAt_Verify.png (41.53% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay,
...
TabbedPage_BarTextColor_And_SelectedTabColor_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_BarTextColor_And_SelectedTabColor_Verify.png (43.31% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, 
...
TabbedPage_BarBackground_With_SelectedTabColor_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_BarBackground_With_SelectedTabColor_Verify.png (41.96% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name
...
TabbedPage_IconImageSource_Change_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_IconImageSource_Change_Verify.png (41.82% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 
...
TabbedPage_BarBackground_And_BarTextColor_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_BarBackground_And_BarTextColor_Verify.png (41.94% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nul
...
TabBarIconsShouldAutoscaleTabbedPage
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabBarIconsShouldAutoscaleTabbedPage.png (43.80% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retr
...
TabbedPage_SelectedAndUnselectedTabColor_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_SelectedAndUnselectedTabColor_Verify_1.png (43.35% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nu
...
TabbedPage_ItemSource_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_ItemSource_Verify.png (43.49% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, 
...
FontImageSourceColorShouldApplyOnTabIcon
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: FontImageSourceColorShouldApplyOnTabIcon.png (42.92% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 
...
TabbedPage_BarBackground_With_UnselectedTabColor_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_BarBackground_With_UnselectedTabColor_Verify.png (41.95% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String na
...
TabbedPage_SelectedTabColor_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_SelectedTabColor_Verify.png (43.35% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryD
...
TabbedPageBackButtonUpdated
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPageBackButtonUpdated.png (43.80% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, N
...
TabbedPage_BarBackground_Gradient_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_BarBackground_Gradient_Verify.png (42.29% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 
...
DefaultSelectedTabTextColorShouldApplyProperly
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: DefaultSelectedTabTextColorShouldApplyProperly.png (43.82% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nulla
...
TabbedPageFlowDirectionUpdatesOnRuntimeChange
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPageFlowDirection_DefaultRightToLeftLayout.png (42.71% difference)
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
at Microsoft.Maui.TestCases.Tests.Issues.Issue31121.TabbedPageFlowDirectionUpdatesOnRuntimeChange() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31121.cs:line 29
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
TabbedPage_InitialState_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_InitialState_VerifyVisualState.png (43.35% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1
...
TabbedPage_UnselectedTabColor_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_UnselectedTabColor_Verify.png (43.35% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retr
...
TabbedPage_InitialState_VerifyFunctionalState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_InitialState_VerifyFunctionalState_1.png (43.35% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Null
...
Bugzilla52419Test
Assert.That(App.WaitForElement(AppearanceLabel).GetText(), Is.EqualTo("Times Appeared: 2"))
  String lengths are both 17. Strings differ at index 16.
  Expected: "Times Appeared: 2"
  But was:  "Times Appeared: 3"
  ---------------------------^
at Microsoft.Maui.TestCases.Tests.Issues.Bugzilla52419.Bugzilla52419Test() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Bugzilla/Bugzilla52419.cs:line 43

1)    at Microsoft.Maui.TestCases.Tests.Issues.Bugzilla52419.Bugzilla52419Test() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Bugzilla/Bugzilla52419.cs:line 43
DynamicFontImageSourceColorShouldApplyOnTabIcon
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: DynamicFontImageSourceColorShouldApplyOnTabIcon.png (42.93% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.Issues.Issue26662.DynamicFontImageSourceColorShouldApplyOnTabIcon() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26662.cs:line 27
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHan
...
NavigationBarLayoutWithMixedHasNavigationBar
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: NavigationBarLayoutWithMixedHasNavigationBar.png (43.69% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullabl
...
TabbedPage_BarTextColor_And_UnselectedTabColor_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_BarTextColor_And_UnselectedTabColor_Verify.png (43.30% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name
...
TabbedPage_SelectedItems_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_SelectedItems_Verify.png (43.35% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDela
...
TabbedPage_ItemSource_And_SelectedItems_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_ItemSource_And_SelectedItems_Verify.png (43.30% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nulla
...
Issue22899Test
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Issue22899Test.png (43.72% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 ret
...
TabbedPage_BarBackground_Solid_Verify
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPage_BarBackground_Solid_Verify.png (41.96% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 ret
...
VerifyTabbedPageMenuItemTextColor
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyTabbedPageMenuItemTextColor.png (41.89% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDe
...
TabbedPageUnselectedBarTextColorConsistency
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: TabbedPageUnselectedBarTextColorConsistency.png (43.78% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable
...

(+4 more — see TRX in artifact)

ViewBaseTests — 99 failed tests
VisualTransform_RotationXWithRotationY
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_RotationXWithRotationY.png (43.20% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 re
...
LightTheme_CheckBox_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: LightTheme_CheckBox_VerifyVisualState.png (25.40% difference)
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
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, Boolean includeTitleBar) 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.InvokeWithN
...
VisualTransform_AnchorXWithAnchorY
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_AnchorXWithAnchorY.png (43.01% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryD
...
Button_ClipWithText
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Button_ClipWithText.png (43.77% difference)
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
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, Boolean includeTitleBar) 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.Reflection.
...
DarkTheme_EditorAndPlaceholderColor_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: DarkTheme_EditorAndPlaceholderColor_VerifyVisualState.png (17.37% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.VerifyScreenshotWithPlatformCropping() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 21
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.DarkTheme_EditorAndPlaceholderColor_VerifyVisualState() in /_/src/Control
...
Image_ClipWithPolyQuadraticBezierSegmentPath
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Image_ClipWithPolyQuadraticBezierSegmentPath.png (43.67% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Image_ClipWithPolyQuadraticBezierSegmentPath() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 447
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, Ob
...
Border_ClipWithStrokeThickness
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Border_ClipWithStrokeThickness.png (43.50% difference)
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
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, Boolean includeTitleBar) 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)
   
...
DarkTheme_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: DarkTheme_VerifyVisualState.png (12.50% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.DarkTheme_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 40
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, Bi
...
FirstCustomPageWithCardColorChanged
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: FirstCustomPageWithCardColorChanged.png (25.54% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ContentViewFeatureTests.FirstCustomPageWithCardColorChanged() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentViewFeatureTests.cs:line 289
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, Object
...
VisualTransform_AnchorY_ScaleXWithRotationX
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_AnchorY_ScaleXWithRotationX.png (43.00% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable
...
LightTheme_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: LightTheme_VerifyVisualState.png (19.85% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.LightTheme_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 31
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, 
...
DarkTheme_Slider_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: DarkTheme_Slider_VerifyVisualState.png (17.36% difference)
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
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, Boolean includeTitleBar) 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, ObjectHandleOn
...
DarkTheme_EntryAndPlaceholderColor_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: DarkTheme_EntryAndPlaceholderColor_VerifyVisualState.png (17.32% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.VerifyScreenshotWithPlatformCropping() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 21
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.DarkTheme_EntryAndPlaceholderColor_VerifyVisualState() in /_/src/Controls/
...
LightTheme_Switch_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: LightTheme_Switch_VerifyVisualState.png (25.40% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.LightTheme_Switch_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 185
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandle
...
Image_ClipWithQuadraticBezierSegmentPath
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Image_ClipWithQuadraticBezierSegmentPath.png (43.67% difference)
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
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, Boolean includeTitleBar) 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, ObjectHand
...
Image_ClipWithBezierSegmentPath
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Image_ClipWithBezierSegmentPath.png (43.67% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Image_ClipWithBezierSegmentPath() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 383
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)

...
VerifyBackgroundColorCleared
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyBackgroundColorCleared.png (43.49% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, 
...
Button_ClipWithImageSource
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Button_ClipWithImageSource.png (43.45% difference)
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
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, Boolean includeTitleBar) 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 Syst
...
ImageButton_ClipWithShadow
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: ImageButton_ClipWithShadow.png (43.50% difference)
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
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, Boolean includeTitleBar) 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 Syst
...
ImageButton_ClipWithEllipseGeometry
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: ImageButton_ClipWithEllipseGeometry.png (43.28% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.ImageButton_ClipWithEllipseGeometry() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 625
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack 
...
ImageButton_ClipWithRectangleGeometry
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: ImageButton_ClipWithRectangleGeometry.png (43.39% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.ImageButton_ClipWithRectangleGeometry() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 609
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnSt
...
FirstCustomPageWithFlowDirection
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: FirstCustomPageWithFlowDirection.png (21.81% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ContentViewFeatureTests.FirstCustomPageWithFlowDirection() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentViewFeatureTests.cs:line 245
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandle
...
Image_ClipWithScale
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Image_ClipWithScale.png (43.37% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.ClipFeatureTests.Image_ClipWithScale() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ClipFeatureTests.cs:line 920
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.Reflection.
...
LightTheme_EditorAndPlaceholderColor_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: LightTheme_EditorAndPlaceholderColor_VerifyVisualState.png (25.46% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.VerifyScreenshotWithPlatformCropping() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 21
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.LightTheme_EditorAndPlaceholderColor_VerifyVisualState() in /_/src/Contr
...
DarkTheme_SearchBar_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: DarkTheme_SearchBar_VerifyVisualState.png (17.38% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.DarkTheme_SearchBar_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 266
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHa
...
BoxView_ClipWithShadow
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: BoxView_ClipWithShadow.png (43.79% difference)
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
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, Boolean includeTitleBar) 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.Refle
...
LightTheme_SearchBar_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: LightTheme_SearchBar_VerifyVisualState.png (25.40% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.LightTheme_SearchBar_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 256
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, Object
...
VisualTransform_AnchorX_ScaleYWithRotation
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VisualTransform_AnchorX_ScaleYWithRotation.png (42.81% difference)
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
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 485
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`
...
LightTheme_DatePicker_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: LightTheme_DatePicker_VerifyVisualState.png (25.40% difference)
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
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, Boolean includeTitleBar) 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.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.RuntimeMethodInfo.Invoke(
...
DarkTheme_CheckBox_VerifyVisualState
VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: DarkTheme_CheckBox_VerifyVisualState.png (17.36% difference)
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
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, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.AppThemeFeatureTests.DarkTheme_CheckBox_VerifyVisualState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AppThemeFeatureTests.cs:line 67
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoA
...

(+69 more — see TRX in artifact)

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


📋 Pre-Flight — Context & Validation

Issue: #33082 - Unified iOS TabbedViewHandler
PR: #36507 - [Net11] [iOS/MacCatalyst] Migrate TabbedPage to handler architecture
Platforms Affected: iOS, MacCatalyst
Files Changed: 9 implementation, 1 test snapshot

Key Findings

  • PR globally registers TabbedViewHandler for TabbedPage on iOS/MacCatalyst, replacing the compatibility renderer by default.
  • Linked issue requested a staged rollout behind an AppContext switch disabled by default; PR intentionally removes the switch and makes the handler unconditional.
  • No added test source was detected; gate was previously skipped because no tests were detected.
  • Prior review markers found major concerns that appear mostly addressed; the remaining unresolved item is rollout/default-handler risk and coverage.

Code Review Summary

Verdict: NEEDS_DISCUSSION
Confidence: low
Errors: 0 | Warnings: 1 | Suggestions: 1

Key code review findings:

  • src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs:207 globally flips every iOS/MacCatalyst TabbedPage to the new handler, which conflicts with the linked issue's staged rollout plan unless maintainers explicitly accept the blast radius.
  • src/Core/src/Handlers/TabbedView/TabbedViewHandler.iOS.cs:65 and :120 use raw mapper-key strings ("CurrentPage", "ItemsSource").

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #36507 Replace iOS/MacCatalyst TabbedPage renderer with a layered TabbedViewHandler + TabBarControllerManager; handler registered unconditionally. ⚠️ SKIPPED (Gate: no tests detected) 10 files Original PR; broad rollout risk remains discussion point.

🔬 Code Review — Deep Analysis

Code Review — PR #36507

Independent Assessment

What this changes: Migrates iOS/MacCatalyst TabbedPage from TabbedRenderer to TabbedViewHandler, adding a UITabBarController manager and Controls-layer mapper implementations.
Inferred motivation: Move TabbedPage onto handler architecture and improve reuse/maintainability.

Reconciliation with PR Narrative

Author claims: Handler is now unconditional default; feature flag can be added later if needed.
Agreement/disagreement: Code matches that claim. This differs from linked issue #33082’s stated rollout strategy: gate behind an AppContext switch and keep disabled by default initially.

Prior Review Reconciliation

Prior ❌/Major Finding Source Status Evidence
MacCatalyst missed iOS mapper block MauiBot ✅ Fixed Mapper now uses `#if IOS
Missing preferred status bar animation mapper MauiBot ✅ Fixed MapPreferredStatusBarUpdateAnimation registered and implemented.
Removed pages kept PropertyChanged subscriptions MauiBot ✅ Fixed TabbedPage.cs now detaches e.OldItems and reset-tracked pages.
Native defaults not reset on handler change MauiBot ✅ Fixed TabbedPage.iOS.cs resets default color/translucency state.
Stale async icon updates MauiBot ✅ Fixed Per-page generation guard added around icon load.
Ungated default rollout/test coverage risk MauiBot ❌ Unresolved / needs decision AppHostBuilderExtensions.cs:207 still registers handler unconditionally; no new device/UI regression tests in diff.

Blast Radius Assessment

  • Runs for all instances: yes — every iOS/MacCatalyst TabbedPage uses the new handler by default.
  • Startup impact: yes — handler registration changes global startup behavior.
  • Static/shared state: yes — static mapper/factory registration affects all TabbedPage instances.

CI Status

  • Required-check result: undetermined via required-check API; gh is unauthenticated.
  • Public check-run evidence: latest public check runs for head 50e595d appear successful, with Bump global.json skipped.
  • Classification: CI required-gate status auth-dependent / undetermined.
  • Action taken: capped confidence low; no comments posted.

Findings

⚠️ Warning — Ungated global handler rollout still needs explicit approval

src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs:207 makes the new iOS/MacCatalyst handler the default for all TabbedPage apps. That is high blast radius and conflicts with #33082’s rollout plan to gate the new handler behind a switch disabled by default initially. If maintainers intentionally accept the default flip now, this is fine; otherwise this should be gated or accompanied by broader device/UI parity coverage.

💡 Suggestion — Avoid raw mapper-key strings across Core/Controls boundary

src/Core/src/Handlers/TabbedView/TabbedViewHandler.iOS.cs:65 and :120 use "CurrentPage" / "ItemsSource". Consider a typed delegate/contract or shared constants to avoid silent drift if Controls property names change.

Failure-Mode Probing

  • Removed page changes title/icon later: now detached through e.OldItems/reset tracking, so stale updates should not fire.
  • Handler disconnect during async icon load: generation and manager/handler guards prevent stale application.
  • MacCatalyst-specific mappers: now included via IOS || MACCATALYST.
  • Apps not opting into new handler: still affected because registration is unconditional.

Verdict: NEEDS_DISCUSSION

Confidence: low
Summary: I found no concrete code-correctness error in the current diff, and prior major implementation issues appear addressed. The remaining concern is rollout risk: this globally replaces a renderer path contrary to the linked issue’s staged plan, and required CI status could not be verified with unauthenticated gh.


🛠️ Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 maui-expert-reviewer + try-fix Staged opt-in runtime switch: use TabbedViewHandler only when enabled, otherwise keep TabbedRenderer fallback. ✅ PASS — MacCatalyst Controls device tests (TabbedPage) completed with 785 run / 759 passed / 0 failed / 26 ignored. 2 files Better than PR for rollout safety because it matches #33082's staged rollout plan and reduces default-path blast radius.
PR PR #36507 Replace iOS/MacCatalyst TabbedPage renderer with layered TabbedViewHandler + TabBarControllerManager; handler registered unconditionally. ⚠️ SKIPPED (Gate: no tests detected) 10 files Original PR; broad default-handler flip remains the main discussion risk.

Cross-Pollination

Model Round New Ideas? Details
maui-expert-reviewer 1 Yes Proposed staged opt-in switch with compatibility-renderer fallback.

Exhausted: No — stopped because Candidate #1 passed the targeted MacCatalyst regression run and is demonstrably safer than the PR's unconditional default flip for the linked issue's rollout requirements.
Selected Fix: Candidate #1 — preserves the new handler for opt-in validation while avoiding a global default behavior change without added test coverage.


📝 Recommended PR Title & Description

Assessment: ✏️ Recommend updating — the winning fix changes the rollout model to default-off opt-in and adds async lifecycle hardening, while the current description says the handler is registered as the default.

Recommended title

[Net11] [iOS/MacCatalyst] TabbedPage: Migrate to handler architecture behind runtime switch

Recommended description

## Description of Change

Replaces the monolithic `TabbedRenderer` (~600 lines, single class that is a `UITabBarController`) with a layered `TabbedViewHandler` architecture for iOS and MacCatalyst.

The new handler is available behind a default-off runtime feature switch so it can be validated without globally changing every existing iOS/MacCatalyst `TabbedPage` app at once. When `RuntimeFeature.IsiOSTabbedViewHandlerEnabled` is not enabled, `TabbedPage` continues to use `Handlers.Compatibility.TabbedRenderer`.

## Issues Fixed

Fixes #33082

> **Note**: The shared Core infrastructure is designed for potential reuse by a future Shell handler, but Shell integration is not part of this PR.

## Motivation

The `TabbedRenderer` is a single class that **is** a `UITabBarController`. It owns all tab management, appearance, lifecycle, reordering, and page lifecycle in one file. This makes it:

- **Hard to maintain** — changes to tab bar appearance risk breaking tab selection logic
- **Not reusable** — other components that may need `UITabBarController` management cannot reuse the renderer internals
- **Inconsistent with handler architecture** — every other control has moved to handlers; `TabbedPage` was still using the renderer on iOS
- **Prone to retain cycles** — the renderer both is the UIKit view controller and owns event subscriptions, requiring careful manual cleanup

## What Changed

### New Files (Core layer — `src/Core/`)

| File | Purpose |
|------|---------|
| `Handlers/TabbedView/TabbedViewHandler.cs` | Cross-platform handler base: `ViewHandler<ITabbedView, PlatformView>`, mapper, and command mapper |
| `Handlers/TabbedView/TabbedViewHandler.iOS.cs` | iOS/MacCatalyst handler with `ITabBarManagerDelegate` implementation, native-selection synchronization, and handler lifecycle wiring |
| `Handlers/TabbedView/ITabbedViewHandler.cs` | Handler interface contract extending `IViewHandler` |
| `Platform/iOS/TabBarControllerManager/TabBarControllerManager.cs` | Shared `UITabBarController` manager with nested `MauiTabBarController`, weak-reference delegate pattern, disabled tab reordering, iOS 18 toolbar-tab handling, MacCatalyst tab bar visibility updates, and disposal state |
| `Platform/iOS/TabBarControllerManager/ITabBarManagerDelegate.cs` | Interface bridging Core and handler callbacks: tab selection, view lifecycle, layout, trait changes, reordering, and current page view controller lookup |
| `Core/ITabbedView.cs` | Marker interface for the tabbed view contract (extends `IView`) |
| `RuntimeFeature.cs` | Adds default-off `RuntimeFeature.IsiOSTabbedViewHandlerEnabled` to stage the new handler rollout |

### New/Updated Files (Controls layer — `src/Controls/`)

| File | Purpose |
|------|---------|
| `TabbedPage/TabbedPage.Mapper.cs` | `RemapForControls()` registration for iOS/MacCatalyst mapper methods and platform view factory |
| `TabbedPage/TabbedPage.iOS.cs` | iOS/MacCatalyst mapper implementations for item source/current page synchronization, tab bar colors, translucency, status bar/home indicator forwarding, platform view factory, cleanup, and async-safe tab icon updates |
| `TabbedPage/TabbedPage.cs` | Implements `ITabbedView`, tracks pending page collection/property changes for incremental native synchronization, and wires/unwires page `PropertyChanged` subscriptions |

### Modified Files

| Area | File | Change |
|------|------|--------|
| Handler registration | `AppHostBuilderExtensions.cs` | Registers `TabbedViewHandler` for iOS/MacCatalyst only when `RuntimeFeature.IsiOSTabbedViewHandlerEnabled` is enabled; otherwise keeps `TabbedRenderer` fallback |
| Public API tracking | `src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt`, `src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt` | Adds the new handler/manager API surface entries |
| Test assets | `src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DynamicFontImageSourceColorShouldApplyOnTabIcon.png` | Updates the MacCatalyst snapshot for the tab icon rendering output |

## Rollout Model

- **Default behavior:** existing iOS/MacCatalyst apps keep using `TabbedRenderer`.
- **Opt-in behavior:** enabling `RuntimeFeature.IsiOSTabbedViewHandlerEnabled` switches `TabbedPage` to the new `TabbedViewHandler`.
- This staged model reduces blast radius while the new handler receives broader validation.

## Lifecycle and Async Safety

Tab icon updates now avoid an unhandled `async void` continuation path. The icon update runs as a handled fire-and-forget task, checks whether the original `TabBarControllerManager` was disposed, and bails out if the handler/page/manager changed while image loading was in flight.

## Platforms

- iOS
- MacCatalyst

🏁 Report — Final Recommendation

Comparative Report — PR #36507

Candidates compared

Rank Candidate Regression result Assessment
1 pr-plus-reviewer ✅ Build passed for Controls.Core on net11.0-maccatalyst26.5; inherits the staged-rollout test evidence from try-fix-1 and adds the expert async lifecycle fix. Best candidate. Keeps the PR's handler architecture, gates the high-blast-radius default flip behind a default-off runtime switch, and fixes the async void tab-icon continuation issue.
2 try-fix-1 ✅ PASS — MacCatalyst Controls device tests with TabbedPage filter: 785 run / 759 passed / 0 failed / 26 ignored. Strong rollout fix: adds the default-off switch and compatibility-renderer fallback. It does not include the later expert reviewer async/lifecycle fix, so it ranks below pr-plus-reviewer.
3 pr ⚠️ Gate skipped — no tests detected in this PR. Implements the handler migration but leaves two expert findings unresolved: unconditional global iOS/MacCatalyst rollout and async void tab item update lifecycle risk.

No candidate had failing regression tests. Per the ranking rule, the skipped raw PR candidate is ranked below candidates with passing validation.

Winning candidate

Winner: pr-plus-reviewer

This is the best single candidate because it combines the PR's handler migration with both expert reviewer fixes: staged opt-in rollout and async lifecycle hardening. It is safer than the raw PR's unconditional default switch and more complete than try-fix-1, which addressed rollout risk but not the async void continuation issue.

Recommended action

Update PR #36507 with the pr-plus-reviewer sandbox diff:

/Users/cloudtest/.copilot/session-state/fe8f4dda-07b2-4a64-ac0e-a6dd6e293ab6/files/pr-plus-reviewer.diff

🧭 Next Steps — review latest findings

No alternative fix was selected for this run. Review the session findings and CI results before merging.

@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.

Expert Review — 2 findings

See inline comments for details.

#if IOS || MACCATALYST
handlersCollection.AddHandler(typeof(NavigationPage), typeof(Handlers.Compatibility.NavigationRenderer));
handlersCollection.AddHandler(typeof(TabbedPage), typeof(Handlers.Compatibility.TabbedRenderer));
handlersCollection.AddHandler<TabbedPage, TabbedViewHandler>();

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-Generated Review (multi-model)

[major] Regression Prevention / Architectural Layer Placement — This unconditionally flips every iOS/MacCatalyst TabbedPage from Handlers.Compatibility.TabbedRenderer to the brand-new TabbedViewHandler for all consumers, with no feature switch/opt-out. The linked issue (#33082) called for a staged rollout behind an AppContext switch disabled by default, but that switch was removed here. Given the size of the new native tab-bar implementation (TabBarControllerManager, MauiTabBarController, ~1300 new lines) and that the only test-asset change in this PR is a single updated snapshot PNG, this is a very high blast-radius change to ship as an unconditional default. Recommend gating behind a RuntimeFeature-style switch (default off) until broader device/UI regression coverage exists, consistent with the linked issue's rollout plan.

}

// Tab bar item creation — ported from TabbedRenderer.SetTabBarItem
async void SetTabBarItem(IPlatformViewHandler renderer, TabBarControllerManager manager)

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-Generated Review (multi-model)

[moderate] Async and Threading SafetySetTabBarItem resumes after await GetIcon(page) as async void, so exceptions in the post-await UIKit work cannot be observed by callers. A concrete lifecycle case is handler teardown while an icon load is in flight: OnHandlerChangingPartial disposes the old TabBarControllerManager, but this continuation can still see the same manager through the old handler and then access currentManager.TraitCollection / create the UITabBarItem on a disposed native controller. Wrap the post-await body in try/catch (or convert this to a fire-and-forget helper with exception handling) and bail out when the captured manager has been disposed.

@kubaflo

kubaflo commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-tabbedpage TabbedPage community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/ios platform/macos macOS / Mac Catalyst s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates 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.

6 participants