Items { get; set; } = new()
+ {
+ new ItemModel { Title = "Item 1" },
+ new ItemModel { Title = "Item 2" },
+ new ItemModel { Title = "Item 3" },
+ new ItemModel { Title = "Item 4" },
+ new ItemModel { Title = "Item 5" },
+ new ItemModel { Title = "Item 6" }
+ };
+
+ void OnPropertyChanged(string name) =>
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+
+ public class ItemModel
+ {
+ public string Title { get; set; } = string.Empty;
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TitleBar/TitleBarControlPage.xaml b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TitleBar/TitleBarControlPage.xaml
new file mode 100644
index 000000000000..d7fa063e73f2
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TitleBar/TitleBarControlPage.xaml
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TitleBar/TitleBarControlPage.xaml.cs b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TitleBar/TitleBarControlPage.xaml.cs
new file mode 100644
index 000000000000..ea76b4e65646
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TitleBar/TitleBarControlPage.xaml.cs
@@ -0,0 +1,133 @@
+namespace Maui.Controls.Sample;
+
+public partial class TitleBarControlPage : ContentPage
+{
+ private TitleBarViewModel _viewModel;
+
+ public TitleBarControlPage()
+ {
+ InitializeComponent();
+
+ _viewModel = new TitleBarViewModel();
+ BindingContext = _viewModel;
+
+ Loaded += MainPage_Loaded;
+ }
+
+ private void MainPage_Loaded(object sender, EventArgs e)
+ {
+ // Setup TitleBar once the page is loaded and the Window is available
+ SetupTitleBar();
+ }
+
+ private void SetupTitleBar()
+ {
+ var window = GetParentWindow();
+ if (window == null)
+ return;
+
+ try
+ {
+ // Create a new TitleBar with the desired properties
+ var titleBar = new Microsoft.Maui.Controls.TitleBar
+ {
+ Title = _viewModel.Title,
+ Subtitle = _viewModel.Subtitle,
+ BackgroundColor = _viewModel.Color,
+ ForegroundColor = _viewModel.ForegroundColor,
+ Icon = _viewModel.Icon,
+ IsVisible = _viewModel.IsVisible,
+ HeightRequest = 60
+ };
+
+ // Set content properties conditionally to avoid null reference issues
+ if (_viewModel.TrailingContent != null)
+ titleBar.TrailingContent = _viewModel.TrailingContent;
+
+ if (_viewModel.LeadingContent != null)
+ titleBar.LeadingContent = _viewModel.LeadingContent;
+
+ if (_viewModel.TitleBarContent != null)
+ titleBar.Content = _viewModel.TitleBarContent;
+
+ titleBar.FlowDirection = _viewModel.FlowDirection;
+
+ // Set up visual states for the TitleBar
+ VisualStateManager.SetVisualStateGroups(titleBar, new VisualStateGroupList
+ {
+ new VisualStateGroup
+ {
+ Name = "TitleActiveStates",
+ States =
+ {
+ new VisualState
+ {
+ Name = "TitleBarTitleActive",
+ Setters = { new Setter { Property = Microsoft.Maui.Controls.TitleBar.ForegroundColorProperty, Value = Colors.White } }
+ },
+ new VisualState
+ {
+ Name = "TitleBarTitleInactive",
+ Setters = { new Setter { Property = Microsoft.Maui.Controls.TitleBar.ForegroundColorProperty, Value = Colors.Black } }
+ }
+ }
+ }
+ });
+
+ // Assign the new TitleBar to the window
+ window.TitleBar = titleBar;
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine($"Error setting up TitleBar: {ex.Message}");
+ }
+ }
+
+ private void OnFlowDirectionCheckBoxChanged(object sender, CheckedChangedEventArgs e)
+ {
+ if (e.Value)
+ {
+ _viewModel.FlowDirection = FlowDirection.RightToLeft;
+ }
+ else
+ {
+ _viewModel.FlowDirection = FlowDirection.LeftToRight;
+ }
+ }
+
+ private void OnResetButtonClicked(object sender, EventArgs e)
+ {
+ _viewModel = new TitleBarViewModel();
+ this.BindingContext = _viewModel;
+
+ FlowDirectionRTLCheckBox.IsChecked = false;
+
+ SetupTitleBar();
+ }
+
+ private void OnTitleBarContentChanged(object sender, CheckedChangedEventArgs e)
+ {
+ if (sender is RadioButton radioButton && e.Value)
+ {
+ switch (radioButton.Value?.ToString())
+ {
+ case "SearchBar":
+ _viewModel.SetSearchBarContent();
+ break;
+
+ case "HorizontalStackLayout":
+ _viewModel.SetHorizontalStackLayoutContent();
+ break;
+
+ case "ProgressBar":
+ _viewModel.SetGridWithProgressBar();
+ break;
+ }
+ }
+ }
+
+ private void OnApplyButtonClicked(object sender, EventArgs e)
+ {
+ SetupTitleBar();
+ }
+}
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TitleBar/TitleBarViewModel.cs b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TitleBar/TitleBarViewModel.cs
new file mode 100644
index 000000000000..c867356fe6e8
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TitleBar/TitleBarViewModel.cs
@@ -0,0 +1,415 @@
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+namespace Maui.Controls.Sample;
+
+public class TitleBarViewModel : INotifyPropertyChanged
+{
+ private IView _titleBarContent;
+ private string _title;
+ private string _subtitle;
+ private IView _trailingContent;
+ private Color _foregroundColor = Colors.Black;
+ private ImageSource _icon;
+
+ public IView TitleBarContent
+ {
+ get => _titleBarContent;
+ set
+ {
+ if (_titleBarContent != value)
+ {
+ _titleBarContent = value;
+ }
+ }
+ }
+
+ private bool _isTitleBarContentVisible = false;
+ public bool IsTitleBarContentVisible
+ {
+ get => _isTitleBarContentVisible;
+ set
+ {
+ if (_isTitleBarContentVisible != value)
+ {
+ _isTitleBarContentVisible = value;
+ IsSearchBarChecked = false;
+ IsHorizontalStackLayoutChecked = false;
+ IsGridWithProgressBarChecked = false;
+
+ if (!_isTitleBarContentVisible)
+ {
+ TitleBarContent = null;
+ }
+ }
+ }
+ }
+
+ private bool _isSearchBarChecked = false;
+ public bool IsSearchBarChecked
+ {
+ get => _isSearchBarChecked;
+ set
+ {
+ if (_isSearchBarChecked != value)
+ {
+ _isSearchBarChecked = value;
+
+ }
+ }
+ }
+
+ private bool _isHorizontalStackLayoutChecked = false;
+ public bool IsHorizontalStackLayoutChecked
+ {
+ get => _isHorizontalStackLayoutChecked;
+ set
+ {
+ if (_isHorizontalStackLayoutChecked != value)
+ {
+ _isHorizontalStackLayoutChecked = value;
+ }
+ }
+ }
+
+ private bool _isGridWithProgressBarChecked = false;
+ public bool IsGridWithProgressBarChecked
+ {
+ get => _isGridWithProgressBarChecked;
+ set
+ {
+ if (_isGridWithProgressBarChecked != value)
+ {
+ _isGridWithProgressBarChecked = value;
+ }
+ }
+ }
+
+ public void SetSearchBarContent()
+ {
+ if (IsTitleBarContentVisible)
+ {
+ TitleBarContent = new SearchBar
+ {
+ Placeholder = "Search",
+ PlaceholderColor = Colors.White,
+ BackgroundColor = Colors.LightGray,
+ MaximumWidthRequest = 300,
+ HorizontalOptions = LayoutOptions.Fill,
+ VerticalOptions = LayoutOptions.Center
+ };
+ }
+ }
+
+ public void SetHorizontalStackLayoutContent()
+ {
+ if (IsTitleBarContentVisible)
+ {
+ TitleBarContent = new HorizontalStackLayout
+ {
+ HorizontalOptions = LayoutOptions.Center,
+ Children =
+ {
+ new Label { Text = "Label 1", TextColor = Colors.White, VerticalOptions = LayoutOptions.Center },
+ new Label { Text = "Label 2", TextColor = Colors.White, VerticalOptions = LayoutOptions.Center }
+ }
+ };
+ }
+ }
+
+ public void SetGridWithProgressBar()
+ {
+ if (IsTitleBarContentVisible)
+ {
+ TitleBarContent = new Grid
+ {
+ Children =
+ {
+ new ProgressBar
+ {
+ Margin=10,
+ Progress = 0.5,
+ BackgroundColor = Colors.LightGray,
+ ProgressColor = Colors.White,
+ HorizontalOptions = LayoutOptions.Fill,
+ VerticalOptions = LayoutOptions.Center
+ }
+ }
+ };
+ }
+ }
+
+ public string Title
+ {
+ get => _title;
+ set
+ {
+ if (_title != value)
+ {
+ _title = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public string Subtitle
+ {
+ get => _subtitle;
+ set
+ {
+ if (_subtitle != value)
+ {
+ _subtitle = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public Color ForegroundColor
+ {
+ get => _foregroundColor;
+ set
+ {
+ if (_foregroundColor != value)
+ {
+ _foregroundColor = value;
+ }
+ }
+ }
+
+ public ImageSource Icon
+ {
+ get => _icon;
+ set
+ {
+ if (_icon != value)
+ {
+ _icon = value;
+ }
+ }
+ }
+
+ private Color _color = Color.FromArgb("#6600ff");
+ public Color Color
+ {
+ get => _color;
+ set { _color = value; }
+ }
+
+ private bool _isRedChecked = false;
+ public bool IsRedChecked
+ {
+ get => _isRedChecked;
+ set
+ {
+ if (_isRedChecked != value)
+ {
+ _isRedChecked = value;
+ if (value && ShowBackgroundColor) // Check if ShowBackgroundColor is true
+ Color = Colors.Red;
+ }
+ }
+ }
+
+ private bool _isOrangeChecked = false;
+ public bool IsOrangeChecked
+ {
+ get => _isOrangeChecked;
+ set
+ {
+ if (_isOrangeChecked != value)
+ {
+ _isOrangeChecked = value;
+ if (value && ShowBackgroundColor)
+ Color = Colors.Orange;
+ }
+ }
+ }
+
+ private bool _isVisible = true;
+ public bool IsVisible
+ {
+ get => _isVisible;
+ set
+ {
+ if (_isVisible != value)
+ {
+ _isVisible = value;
+ }
+ }
+ }
+
+ public FlowDirection _flowDirection = FlowDirection.LeftToRight;
+ public FlowDirection FlowDirection
+ {
+ get => _flowDirection;
+ set
+ {
+ if (_flowDirection != value)
+ {
+ _flowDirection = value;
+ }
+ }
+ }
+
+ private bool _showLeadingContent = false;
+ public bool ShowLeadingContent
+ {
+ get => _showLeadingContent;
+ set
+ {
+ if (_showLeadingContent != value)
+ {
+ _showLeadingContent = value;
+
+ LeadingContent = _showLeadingContent ? new Image
+ {
+ Source = "dotnet_bot.png",
+ HeightRequest = 60,
+ Margin = 10,
+ VerticalOptions = LayoutOptions.Center
+ } : null;
+ }
+ }
+ }
+
+ private IView _leadingContent;
+ public IView LeadingContent
+ {
+ get => _leadingContent;
+ set
+ {
+ if (_leadingContent != value)
+ {
+ _leadingContent = value;
+ }
+ }
+ }
+
+ public IView TrailingContent
+ {
+ get => _trailingContent;
+ set
+ {
+ if (_trailingContent != value)
+ {
+ _trailingContent = value;
+ }
+ }
+ }
+ private bool _showTrailingContent = false;
+ public bool ShowTrailingContent
+ {
+ get => _showTrailingContent;
+ set
+ {
+ if (_showTrailingContent != value)
+ {
+ _showTrailingContent = value;
+
+ TrailingContent = _showTrailingContent ? new ImageButton
+ {
+ Source = "avatar.png",
+ CornerRadius = 5,
+ Margin = 10,
+ HeightRequest = 60,
+ } : null;
+ }
+ }
+ }
+
+ private bool _showTitle = false;
+ public bool ShowTitle
+ {
+ get => _showTitle;
+ set
+ {
+ if (_showTitle != value)
+ {
+ _showTitle = value;
+ Title = _showTitle ? "My MAUI App" : string.Empty;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ private bool _showSubtitle = false;
+ public bool ShowSubtitle
+ {
+ get => _showSubtitle;
+ set
+ {
+ if (_showSubtitle != value)
+ {
+ _showSubtitle = value;
+ Subtitle = _showSubtitle ? "Demo TitleBar Integration" : string.Empty;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ private bool _showForegroundColor = false;
+ public bool ShowForegroundColor
+ {
+ get => _showForegroundColor;
+ set
+ {
+ if (_showForegroundColor != value)
+ {
+ _showForegroundColor = value;
+ ForegroundColor = _showForegroundColor ? Colors.Black : Colors.Black;
+ IsWhiteForegroundChecked = false;
+ }
+ }
+ }
+
+ private bool _isWhiteForegroundChecked = false;
+ public bool IsWhiteForegroundChecked
+ {
+ get => _isWhiteForegroundChecked;
+ set
+ {
+ if (_isWhiteForegroundChecked != value)
+ {
+ _isWhiteForegroundChecked = value;
+ if (value && ShowForegroundColor)
+ ForegroundColor = Colors.White;
+ }
+ }
+ }
+
+ private bool _showIcon = false;
+ public bool ShowIcon
+ {
+ get => _showIcon;
+ set
+ {
+ if (_showIcon != value)
+ {
+ _showIcon = value;
+ Icon = _showIcon ? ImageSource.FromFile("green.png") : null;
+ }
+ }
+ }
+
+ private bool _showBackgroundColor = false;
+ public bool ShowBackgroundColor
+ {
+ get => _showBackgroundColor;
+ set
+ {
+ if (_showBackgroundColor != value)
+ {
+ _showBackgroundColor = value;
+ Color = _showBackgroundColor ? Color.FromArgb("#6600ff") : Color.FromArgb("#6600ff");
+ IsOrangeChecked = false;
+ IsRedChecked = false;
+ }
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewControlPage.xaml b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewControlPage.xaml
new file mode 100644
index 000000000000..674a3fa2f035
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewControlPage.xaml
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewControlPage.xaml.cs b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewControlPage.xaml.cs
new file mode 100644
index 000000000000..28363a3ac476
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewControlPage.xaml.cs
@@ -0,0 +1,58 @@
+using System;
+using Microsoft.Maui.Controls;
+
+namespace Maui.Controls.Sample;
+
+public class TwoPaneViewControlPage : NavigationPage
+{
+ private TwoPaneViewViewModel _viewModel;
+ public TwoPaneViewControlPage()
+ {
+ _viewModel = new TwoPaneViewViewModel();
+ PushAsync(new TwoPaneViewControlMainPage(_viewModel));
+ }
+}
+public partial class TwoPaneViewControlMainPage : ContentPage
+{
+ private TwoPaneViewViewModel _viewModel;
+ public TwoPaneViewControlMainPage(TwoPaneViewViewModel viewModel)
+ {
+ InitializeComponent();
+ _viewModel = viewModel;
+ BindingContext = _viewModel;
+
+ // Subscribe to TwoPaneView mode changes to update the CurrentModeText
+ MyTwoPaneView.ModeChanged += OnTwoPaneViewModeChanged;
+ }
+
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+
+ // Initialize the IsWideMode property with the current TwoPaneView mode
+ _viewModel.IsWideMode = MyTwoPaneView.Mode == Microsoft.Maui.Controls.Foldable.TwoPaneViewMode.Wide;
+ }
+
+ protected override void OnDisappearing()
+ {
+ base.OnDisappearing();
+
+ // Unsubscribe from the event to prevent memory leaks
+ MyTwoPaneView.ModeChanged -= OnTwoPaneViewModeChanged;
+ }
+
+ private void OnTwoPaneViewModeChanged(object sender, EventArgs e)
+ {
+ // Update the ViewModel's IsWideMode property based on the TwoPaneView's current mode
+ if (sender is Microsoft.Maui.Controls.Foldable.TwoPaneView twoPaneView)
+ {
+ _viewModel.IsWideMode = twoPaneView.Mode == Microsoft.Maui.Controls.Foldable.TwoPaneViewMode.Wide;
+ }
+ }
+
+ private async void NavigateToOptionsPage_Clicked(object sender, EventArgs e)
+ {
+ BindingContext = _viewModel = new TwoPaneViewViewModel();
+ await Navigation.PushAsync(new TwoPaneViewOptionsPage(_viewModel));
+ }
+}
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewOptionsPage.xaml b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewOptionsPage.xaml
new file mode 100644
index 000000000000..c305838a8926
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewOptionsPage.xaml
@@ -0,0 +1,165 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewOptionsPage.xaml.cs b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewOptionsPage.xaml.cs
new file mode 100644
index 000000000000..8d3829d10f83
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewOptionsPage.xaml.cs
@@ -0,0 +1,76 @@
+namespace Maui.Controls.Sample;
+
+public partial class TwoPaneViewOptionsPage : ContentPage
+{
+ private TwoPaneViewViewModel _viewModel;
+
+ public TwoPaneViewOptionsPage(TwoPaneViewViewModel viewModel)
+ {
+ InitializeComponent();
+ _viewModel = viewModel;
+ BindingContext = _viewModel;
+ TallModeStepper.Value = _viewModel.MinTallModeHeight;
+ WideModeStepper.Value = _viewModel.MinWideModeWidth;
+ Pane1LengthStepper.Value = ParseLength(_viewModel.Pane1Length);
+ Pane2LengthStepper.Value = ParseLength(_viewModel.Pane2Length);
+
+ TallModeHeightValue.Text = $"{_viewModel.MinTallModeHeight}px";
+ WideModeWidthValue.Text = $"{_viewModel.MinWideModeWidth}px";
+ Pane1LengthValue.Text = _viewModel.Pane1Length.ToString();
+ Pane2LengthValue.Text = _viewModel.Pane2Length.ToString();
+ }
+
+ private void OnFlowDirectionCheckBoxChanged(object sender, CheckedChangedEventArgs e)
+ {
+ if (e.Value)
+ {
+ _viewModel.FlowDirection = FlowDirection.RightToLeft;
+ }
+ else
+ {
+ _viewModel.FlowDirection = FlowDirection.LeftToRight;
+ }
+ }
+
+ private void OnShadowCheckBoxChanged(object sender, CheckedChangedEventArgs e)
+ {
+ _viewModel.IsShadowEnabled = e.Value;
+ }
+
+ private void ApplyButton_Clicked(object sender, EventArgs e)
+ {
+ Navigation.PopAsync();
+ }
+ private void OnTallModeHeightChanged(object sender, ValueChangedEventArgs e)
+ {
+ var value = (int)e.NewValue;
+ _viewModel.MinTallModeHeight = value;
+ TallModeHeightValue.Text = $"{value}px";
+ }
+
+ private void OnWideModeWidthChanged(object sender, ValueChangedEventArgs e)
+ {
+ var value = (int)e.NewValue;
+ _viewModel.MinWideModeWidth = value;
+ WideModeWidthValue.Text = $"{value}px";
+ }
+
+ private void OnPane1LengthChanged(object sender, ValueChangedEventArgs e)
+ {
+ var value = e.NewValue;
+ _viewModel.Pane1Length = new GridLength(value, GridUnitType.Star);
+ Pane1LengthValue.Text = $"{value}";
+ }
+
+ private void OnPane2LengthChanged(object sender, ValueChangedEventArgs e)
+ {
+ var value = e.NewValue;
+ _viewModel.Pane2Length = new GridLength(value, GridUnitType.Star);
+ Pane2LengthValue.Text = $"{value}";
+ }
+
+ private double ParseLength(GridLength length)
+ {
+ return length.IsStar ? length.Value : 1; // Default to 1* if not a star value
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewViewModel.cs b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewViewModel.cs
new file mode 100644
index 000000000000..e1b4b7bde76d
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/TwoPaneView/TwoPaneViewViewModel.cs
@@ -0,0 +1,196 @@
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using Microsoft.Maui.Controls.Foldable;
+namespace Maui.Controls.Sample;
+
+public class TwoPaneViewViewModel : INotifyPropertyChanged
+{
+ public event PropertyChangedEventHandler PropertyChanged;
+ private GridLength _pane1Length = new GridLength(1, GridUnitType.Star);
+ private GridLength _pane2Length = new GridLength(1, GridUnitType.Star);
+ private double _minTallModeHeight = 500;
+ private double _minWideModeWidth = 700;
+ private bool _isShadowEnabled = false;
+ private bool _isVisible = true;
+ private FlowDirection _flowDirection = FlowDirection.LeftToRight;
+ private TwoPaneViewTallModeConfiguration _tallModeConfiguration = TwoPaneViewTallModeConfiguration.TopBottom;
+ private TwoPaneViewWideModeConfiguration _wideModeConfiguration = TwoPaneViewWideModeConfiguration.LeftRight;
+ private TwoPaneViewPriority _panePriority = TwoPaneViewPriority.Pane1;
+
+ public bool IsShadowEnabled
+ {
+ get => _isShadowEnabled;
+ set
+ {
+ if (_isShadowEnabled != value)
+ {
+ _isShadowEnabled = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+ public bool IsVisible
+ {
+ get => _isVisible;
+ set
+ {
+ if (_isVisible != value)
+ {
+ _isVisible = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public FlowDirection FlowDirection
+ {
+ get => _flowDirection;
+ set
+ {
+ if (_flowDirection != value)
+ {
+ _flowDirection = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public GridLength Pane1Length
+ {
+ get => _pane1Length;
+ set
+ {
+ _pane1Length = value;
+ OnPropertyChanged();
+ }
+ }
+ public GridLength Pane2Length
+ {
+ get => _pane2Length;
+ set
+ {
+ _pane2Length = value;
+ OnPropertyChanged();
+ }
+ }
+ public double MinTallModeHeight
+ {
+ get => _minTallModeHeight;
+ set
+ {
+ _minTallModeHeight = value;
+ OnPropertyChanged();
+ }
+ }
+ public double MinWideModeWidth
+ {
+ get => _minWideModeWidth;
+ set
+ {
+ _minWideModeWidth = value;
+ OnPropertyChanged();
+ }
+ }
+ public TwoPaneViewTallModeConfiguration TallModeConfiguration
+ {
+ get => _tallModeConfiguration;
+ set
+ {
+ if (_tallModeConfiguration != value)
+ {
+ _tallModeConfiguration = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(IsTallModeTopBottom));
+ OnPropertyChanged(nameof(IsTallModeSinglePane));
+ }
+ }
+ }
+
+ public TwoPaneViewWideModeConfiguration WideModeConfiguration
+ {
+ get => _wideModeConfiguration;
+ set
+ {
+ if (_wideModeConfiguration != value)
+ {
+ _wideModeConfiguration = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(IsWideModeLeftRight));
+ OnPropertyChanged(nameof(IsWideModeSinglePane));
+ }
+ }
+ }
+
+ public TwoPaneViewPriority PanePriority
+ {
+ get => _panePriority;
+ set
+ {
+ if (_panePriority != value)
+ {
+ _panePriority = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(IsPanePriorityPane1));
+ OnPropertyChanged(nameof(IsPanePriorityPane2));
+ }
+ }
+ }
+
+ // Computed properties for radio button bindings
+ public bool IsTallModeTopBottom
+ {
+ get => TallModeConfiguration == TwoPaneViewTallModeConfiguration.TopBottom;
+ set { if (value) TallModeConfiguration = TwoPaneViewTallModeConfiguration.TopBottom; }
+ }
+ public bool IsTallModeSinglePane
+ {
+ get => TallModeConfiguration == TwoPaneViewTallModeConfiguration.SinglePane;
+ set { if (value) TallModeConfiguration = TwoPaneViewTallModeConfiguration.SinglePane; }
+ }
+
+ public bool IsWideModeLeftRight
+ {
+ get => WideModeConfiguration == TwoPaneViewWideModeConfiguration.LeftRight;
+ set { if (value) WideModeConfiguration = TwoPaneViewWideModeConfiguration.LeftRight; }
+ }
+ public bool IsWideModeSinglePane
+ {
+ get => WideModeConfiguration == TwoPaneViewWideModeConfiguration.SinglePane;
+ set { if (value) WideModeConfiguration = TwoPaneViewWideModeConfiguration.SinglePane; }
+ }
+
+ public bool IsPanePriorityPane1
+ {
+ get => PanePriority == TwoPaneViewPriority.Pane1;
+ set { if (value) PanePriority = TwoPaneViewPriority.Pane1; }
+ }
+ public bool IsPanePriorityPane2
+ {
+ get => PanePriority == TwoPaneViewPriority.Pane2;
+ set { if (value) PanePriority = TwoPaneViewPriority.Pane2; }
+ }
+
+ // Property to track if the current mode is Wide mode
+ // This would typically be set by the TwoPaneView control itself
+ private bool _isWideMode = false;
+ public bool IsWideMode
+ {
+ get => _isWideMode;
+ set
+ {
+ if (_isWideMode != value)
+ {
+ _isWideMode = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(CurrentModeText));
+ }
+ }
+ }
+
+ public string CurrentModeText => IsWideMode ? "Wide Mode" : "Tall Mode";
+
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+}
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewControlPage.xaml b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewControlPage.xaml
new file mode 100644
index 000000000000..c3a63424fcab
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewControlPage.xaml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewControlPage.xaml.cs b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewControlPage.xaml.cs
new file mode 100644
index 000000000000..3cb7e21d748c
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewControlPage.xaml.cs
@@ -0,0 +1,44 @@
+using Microsoft.Maui.Controls;
+namespace Maui.Controls.Sample;
+
+public class WebViewControlPage : NavigationPage
+{
+ private WebViewViewModel _viewModel;
+ public WebViewControlPage()
+ {
+ _viewModel = new WebViewViewModel();
+ BindingContext = _viewModel;
+ PushAsync(new WebViewControlMainPage(_viewModel));
+ }
+}
+public partial class WebViewControlMainPage : ContentPage
+{
+ private WebViewViewModel _viewModel;
+ public WebViewControlMainPage(WebViewViewModel viewModel)
+ {
+ InitializeComponent();
+ _viewModel = viewModel;
+ BindingContext = _viewModel;
+ _viewModel.WebViewReference = WebViewControl;
+ }
+ private async void NavigateToOptionsPage_Clicked(object sender, EventArgs e)
+ {
+ var oldViewModel = _viewModel;
+ _viewModel = new WebViewViewModel();
+ _viewModel.CopyWebViewStateFrom(oldViewModel);
+ BindingContext = _viewModel;
+ await Navigation.PushAsync(new WebViewOptionsPage(_viewModel));
+ }
+ private void OnWebViewNavigating(object sender, WebNavigatingEventArgs e)
+ {
+ _viewModel.OnNavigating(sender, e);
+ }
+ private void OnWebViewNavigated(object sender, WebNavigatedEventArgs e)
+ {
+ _viewModel.OnNavigated(sender, e);
+ }
+ private void OnWebViewProcessTerminated(object sender, EventArgs e)
+ {
+ _viewModel.OnProcessTerminated(sender, e);
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewOptionsPage.xaml b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewOptionsPage.xaml
new file mode 100644
index 000000000000..d879a97d2afb
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewOptionsPage.xaml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewOptionsPage.xaml.cs b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewOptionsPage.xaml.cs
new file mode 100644
index 000000000000..86aae98194eb
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewOptionsPage.xaml.cs
@@ -0,0 +1,200 @@
+using System.Net;
+using Microsoft.Maui.Controls;
+namespace Maui.Controls.Sample;
+
+public partial class WebViewOptionsPage : ContentPage
+{
+ private WebViewViewModel _viewModel;
+ public WebViewOptionsPage(WebViewViewModel viewModel)
+ {
+ InitializeComponent();
+ _viewModel = viewModel;
+ BindingContext = _viewModel;
+ }
+ private async void ApplyButton_Clicked(object sender, EventArgs e)
+ {
+ await Navigation.PopAsync();
+ }
+ private void OnHtmlSourceClicked(object sender, EventArgs e)
+ {
+ _viewModel.Source = new HtmlWebViewSource
+ {
+ Html = @"
+
+
+ HTML WebView Source
+
+
+ WebView Feature Matrix
+ This page demonstrates various capabilities of the .NET MAUI WebView control, such as:
+
+ Rendering HTML content
+ Executing JavaScript
+ Cookie management
+ Back/Forward navigation
+
+ Test Content
+
+ This is a longer body paragraph to help test the EvaluateJavaScript functionality
+ and how it extracts body text. You can use this text to verify substring operations and test scrolling
+ or formatting in the WebView.
+
+
+ Try interacting with navigation buttons, loading multiple pages, or checking cookie behavior.
+
+ Generated for testing WebView features.
+
+ ",
+ };
+ }
+ private void OnMicrosoftUrlClicked(object sender, EventArgs e)
+ {
+ _viewModel.Source = new UrlWebViewSource
+ {
+ Url = "https://www.microsoft.com"
+ };
+ }
+ private void OnGithubUrlClicked(object sender, EventArgs e)
+ {
+ _viewModel.Source = new UrlWebViewSource
+ {
+ Url = "https://github.com/dotnet/maui"
+ };
+ }
+ private void LoadMultiplePages_Clicked(object sender, EventArgs e)
+ {
+ _viewModel.Source = new HtmlWebViewSource
+ {
+ Html = @"
+
+
+
+ Multiple Pages Navigation
+
+
+
+ Welcome to Page 1
+ This is the first page.
+ Go to Page 2 (Microsoft)
+ Go to Page 3 (GitHub)
+
+ "
+ };
+ }
+ private void AddTestCookie_Clicked(object sender, EventArgs e)
+ {
+ _viewModel.AddTestCookies();
+ }
+ private void ClearCookies_Clicked(object sender, EventArgs e)
+ {
+ _viewModel.ClearCookiesForCurrentSource();
+ }
+ private void TestDocumentTitle_Clicked(object sender, EventArgs e)
+ {
+ _viewModel.Source = new HtmlWebViewSource
+ {
+ Html = "WebView Test Page Page with Title This page has a title that can be retrieved via JavaScript.
"
+ };
+ }
+ private void LoadPage1_Clicked(object sender, EventArgs e)
+ {
+ _viewModel.Source = new HtmlWebViewSource
+ {
+ Html = @"
+
+
+ Navigation Test - Page 1
+
+
+
+ Navigation Test - Page 1
+ This is the first page for navigation testing.
+ Go to Page 2
+
+
+ ",
+ };
+ }
+ private void LoadPage2_Clicked(object sender, EventArgs e)
+ {
+ _viewModel.Source = new HtmlWebViewSource
+ {
+ Html = @"
+
+
+ Navigation Test - Page 2
+
+
+
+ Navigation Test - Page 2
+ This is the second page for navigation testing.
+ Go Back
+
+
+ ",
+ };
+ }
+ private void IsVisibleRadio_CheckedChanged(object sender, CheckedChangedEventArgs e)
+ {
+ if (!(sender is RadioButton rb) || !rb.IsChecked)
+ return;
+ _viewModel.IsVisible = rb.Content?.ToString() == "True";
+ }
+ private void ShadowRadio_CheckedChanged(object sender, CheckedChangedEventArgs e)
+ {
+ if (e.Value && BindingContext is WebViewViewModel vm)
+ {
+ var rb = sender as RadioButton;
+ if (rb?.Content?.ToString() == "True")
+ {
+ vm.Shadow = new Shadow { Brush = Brush.Black, Offset = new Point(5, 5), Radius = 5, Opacity = 0.5f };
+ }
+ else if (rb?.Content?.ToString() == "False")
+ {
+ vm.Shadow = null!;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewViewModel.cs b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewViewModel.cs
new file mode 100644
index 000000000000..e38d19e5697f
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/FeatureMatrix/WebView/WebViewViewModel.cs
@@ -0,0 +1,379 @@
+using System;
+using System.ComponentModel;
+using System.Net;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using System.Windows.Input;
+using Microsoft.Maui.Controls;
+namespace Maui.Controls.Sample;
+
+public class WebViewViewModel : INotifyPropertyChanged
+{
+ private WebViewSource _source;
+ private CookieContainer _cookies;
+ private bool _canGoBack;
+ private bool _canGoForward;
+ private bool _isVisible = true;
+ private Shadow _shadow = null;
+ private string _navigatingStatus;
+ private string _navigatedStatus;
+ private string _processTerminatedStatus;
+ private string _jsEvaluationResult;
+ private bool _isEventStatusLabelVisible = false;
+ public bool IsPageLoaded { get; set; }
+ public event PropertyChangedEventHandler PropertyChanged;
+ public WebViewViewModel()
+ {
+ Source = new HtmlWebViewSource
+ {
+ Html = @"
+
+
+ HTML WebView Source
+
+
+ WebView Feature Matrix
+ This page demonstrates various capabilities of the .NET MAUI WebView control, such as:
+
+ Rendering HTML content
+ Executing JavaScript
+ Cookie management
+ Back/Forward navigation
+
+ Test Content
+
+ This is a longer body paragraph to help test the EvaluateJavaScript functionality
+ and how it extracts body text. You can use this text to verify substring operations and test scrolling
+ or formatting in the WebView.
+
+
+ Try interacting with navigation buttons, loading multiple pages, or checking cookie behavior.
+
+ Generated for testing WebView features.
+
+ ",
+ };
+ GoBackCommand = new Command(OnGoBack, () => CanGoBack);
+ GoForwardCommand = new Command(OnGoForward, () => CanGoForward);
+ ReloadCommand = new Command(OnReload);
+ EvaluateJavaScriptCommand = new Command(OnEvaluateJavaScript);
+ }
+ public void CopyWebViewStateFrom(WebViewViewModel oldViewModel)
+ {
+ WebViewReference = oldViewModel.WebViewReference;
+ IsPageLoaded = oldViewModel.IsPageLoaded;
+ CanGoBack = oldViewModel.CanGoBack;
+ CanGoForward = oldViewModel.CanGoForward;
+ JsEvaluationResult = oldViewModel.JsEvaluationResult;
+ }
+ public WebViewSource Source
+ {
+ get => _source;
+ set
+ {
+ if (_source != value)
+ {
+ _source = value;
+ JsEvaluationResult = string.Empty;
+ OnPropertyChanged();
+ }
+ }
+ }
+ public CookieContainer Cookies
+ {
+ get => _cookies;
+ set
+ {
+ if (_cookies != value)
+ {
+ _cookies = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(CookiesDisplay));
+ }
+ }
+ }
+
+ public bool CanGoBack
+ {
+ get => _canGoBack;
+ set
+ {
+ if (_canGoBack != value)
+ {
+ _canGoBack = value;
+ OnPropertyChanged();
+ ((Command)GoBackCommand).ChangeCanExecute();
+ }
+ }
+ }
+ public bool CanGoForward
+ {
+ get => _canGoForward;
+ set
+ {
+ if (_canGoForward != value)
+ {
+ _canGoForward = value;
+ OnPropertyChanged();
+ ((Command)GoForwardCommand).ChangeCanExecute();
+ }
+ }
+ }
+ public bool IsVisible
+ {
+ get => _isVisible;
+ set
+ {
+ if (_isVisible != value)
+ {
+ _isVisible = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+ public string NavigatingStatus
+ {
+ get => _navigatingStatus;
+ set
+ {
+ if (_navigatingStatus != value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ IsEventStatusLabelVisible = true;
+ }
+ _navigatingStatus = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+ public string NavigatedStatus
+ {
+ get => _navigatedStatus;
+ set
+ {
+ if (_navigatedStatus != value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ IsEventStatusLabelVisible = true;
+ }
+ _navigatedStatus = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+ public string ProcessTerminatedStatus
+ {
+ get => _processTerminatedStatus;
+ set
+ {
+ if (_processTerminatedStatus != value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ IsEventStatusLabelVisible = true;
+ }
+ _processTerminatedStatus = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+ public string JsEvaluationResult
+ {
+ get => _jsEvaluationResult;
+ set
+ {
+ if (_jsEvaluationResult != value)
+ {
+ _jsEvaluationResult = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+ public bool IsEventStatusLabelVisible
+ {
+ get => _isEventStatusLabelVisible;
+ set
+ {
+ if (_isEventStatusLabelVisible != value)
+ {
+ _isEventStatusLabelVisible = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+ public Shadow Shadow
+ {
+ get => _shadow;
+ set { if (_shadow != value) { _shadow = value; OnPropertyChanged(); } }
+ }
+ public ICommand GoBackCommand { get; }
+ public ICommand GoForwardCommand { get; }
+ public ICommand ReloadCommand { get; }
+ public ICommand EvaluateJavaScriptCommand { get; }
+ public WebView WebViewReference { get; set; }
+ private void OnGoBack()
+ {
+ WebViewReference?.GoBack();
+ }
+ private void OnGoForward()
+ {
+ WebViewReference?.GoForward();
+ }
+ private void OnReload()
+ {
+ WebViewReference?.Reload();
+ }
+ private async void OnEvaluateJavaScript()
+ {
+ if (WebViewReference != null)
+ {
+ try
+ {
+ var title = await WebViewReference.EvaluateJavaScriptAsync("document.title");
+ if (string.IsNullOrEmpty(title))
+ {
+ var bodyText = await WebViewReference.EvaluateJavaScriptAsync("document.body.textContent.substring(0, 20)");
+ JsEvaluationResult = $"JS Result: {bodyText}... (body content)";
+ }
+ else
+ {
+ JsEvaluationResult = $"JS Result: {title}";
+ }
+ }
+ catch (Exception ex)
+ {
+ JsEvaluationResult = $"JS Error: {ex.Message}";
+ }
+ }
+ }
+ public void AddTestCookies()
+ {
+ var domain = GetCookieDomain();
+ if (string.IsNullOrEmpty(domain))
+ return;
+ var cookieContainer = Cookies ?? new CookieContainer();
+ var uri = new Uri($"https://{domain}");
+ var cookie = new Cookie
+ {
+ Name = "DotNetMAUICookie",
+ Value = "My cookie",
+ Domain = uri.Host,
+ Path = "/",
+ Expires = DateTime.Now.AddDays(1)
+ };
+ try
+ {
+ cookieContainer.Add(uri, cookie);
+ }
+ catch
+ {
+ // Ignore if cookie is malformed
+ }
+ Cookies = cookieContainer;
+ }
+ public void ClearCookiesForCurrentSource()
+ {
+ Cookies = new CookieContainer();
+ }
+ private string GetCookieDomain()
+ {
+ if (Source is UrlWebViewSource urlSource && !string.IsNullOrEmpty(urlSource.Url))
+ {
+ var uri = new Uri(urlSource.Url);
+ var domain = uri.Host;
+ if (domain.StartsWith("www."))
+ domain = domain.Substring(4);
+ return domain;
+ }
+ if (Source is HtmlWebViewSource)
+ return "localhost";
+ return null;
+ }
+ public string CookiesDisplay
+ {
+ get
+ {
+ if (Cookies == null || Cookies.Count == 0)
+ return "No cookies available.";
+ try
+ {
+ var domain = GetDomainFromSource();
+ var uri = new Uri($"https://{domain}");
+ var cookieCollection = Cookies.GetCookies(uri);
+ var visibleCookies = cookieCollection.Cast()
+ .Where(c => !IsSystemCookie(c.Name))
+ .ToList();
+ if (visibleCookies.Count == 0)
+ return $" No displayable cookies for domain: {domain}";
+ var cookieText = string.Join("\n", visibleCookies.Select(c => $"{c.Name} = {c.Value}"));
+ return $"Domain: {domain}\nCount: {visibleCookies.Count}\n{cookieText}";
+ }
+ catch (Exception ex)
+ {
+ return $" Error reading cookies: {ex.Message}";
+ }
+ }
+ }
+ private string GetDomainFromSource()
+ {
+ if (Source is UrlWebViewSource urlSource && !string.IsNullOrEmpty(urlSource.Url))
+ {
+ var uri = new Uri(urlSource.Url);
+ var domain = uri.Host;
+ return domain.StartsWith("www.") ? domain.Substring(4) : domain;
+ }
+ else if (Source is HtmlWebViewSource)
+ {
+ return "localhost";
+ }
+ return "unknown";
+ }
+ private bool IsSystemCookie(string name)
+ {
+ var excluded = new[] { "TestCookie", "SessionId" };
+ return excluded.Contains(name, StringComparer.OrdinalIgnoreCase);
+ }
+ public void OnNavigating(object sender, WebNavigatingEventArgs e)
+ {
+ if (Source is HtmlWebViewSource)
+ {
+ NavigatingStatus = "Navigating to: Embedded HTML";
+ }
+ else if (Source is UrlWebViewSource)
+ {
+ try
+ {
+ var uri = new Uri(e.Url);
+ NavigatingStatus = $"Navigating to: {uri.Host}";
+ }
+ catch
+ {
+ var shortUrl = e.Url?.Length > 40 ? e.Url.Substring(0, 40) + "..." : e.Url;
+ NavigatingStatus = $"Navigating to: {shortUrl}";
+ }
+ }
+ else
+ {
+ NavigatingStatus = "Navigating...";
+ }
+ }
+ public void OnNavigated(object sender, WebNavigatedEventArgs e)
+ {
+ NavigatedStatus = $"Navigated: {e.Result}";
+ if (WebViewReference != null)
+ {
+ CanGoBack = WebViewReference.CanGoBack;
+ CanGoForward = WebViewReference.CanGoForward;
+ }
+ }
+ public void OnProcessTerminated(object sender, EventArgs e)
+ {
+ ProcessTerminatedStatus = "WebView process terminated";
+ }
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/23732Page.xaml b/src/Controls/tests/TestCases.HostApp/Issues/23732Page.xaml
new file mode 100644
index 000000000000..928cce4361fd
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/23732Page.xaml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/23732Page.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/23732Page.xaml.cs
new file mode 100644
index 000000000000..bf7c83c2d056
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/23732Page.xaml.cs
@@ -0,0 +1,68 @@
+using System.Collections.ObjectModel;
+
+namespace Maui.Controls.Sample.Issues
+{
+ public partial class _23732Page : ContentPage
+ {
+ public ObservableCollection Models { get; } = new();
+ public _23732Page(bool isPage4)
+ {
+ InitializeComponent();
+ BindingContext = this;
+ for (int i = 0; i <= 6; i++)
+ {
+ Models.Add(string.Empty);
+ }
+
+ if (isPage4)
+ {
+ var label = new Label
+ {
+ Text = "page4",
+ AutomationId = "label",
+ HorizontalTextAlignment = TextAlignment.Center
+ };
+ (Content as Grid)?.Children.Insert(0, label);
+ }
+ }
+
+ private string _label;
+ public string Label
+ {
+ get => _label;
+ set
+ {
+ if (_label != value)
+ {
+ _label = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+ }
+
+ [Issue(IssueTracker.Github, 23732, "TabBar content not displayed properly", PlatformAffected.Android)]
+ public partial class Issue23732 : TabbedPage
+ {
+ public Issue23732()
+ {
+ for (int i = 1; i <= 5; i++)
+ {
+ Children.Add(CreateNavigationPage($"Page {i}", $"page{i}"));
+ }
+ }
+
+ private NavigationPage CreateNavigationPage(string title, string label)
+ {
+ var mainPage = new _23732Page(label == "page4")
+ {
+ Label = label
+ };
+
+ return new NavigationPage(mainPage)
+ {
+ Title = title
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue17783.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue17783.cs
new file mode 100644
index 000000000000..aeba6c842a4d
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue17783.cs
@@ -0,0 +1,45 @@
+using System.Windows.Input;
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 17783, "Pasting long text when the editor has a max length does nothing", PlatformAffected.All)]
+public partial class Issue17783 : ContentPage
+{
+ public Issue17783()
+ {
+ var stackLayout = new VerticalStackLayout();
+
+ var entry = new Entry
+ {
+ AutomationId = "Entry",
+ MaxLength = 5
+ };
+
+ var editor = new Editor
+ {
+ AutomationId = "Editor",
+ MaxLength = 5
+ };
+
+ var pasteToEntryButton = new Button
+ {
+ Text = "Paste to entry",
+ AutomationId = "PasteToEntryButton"
+ };
+ pasteToEntryButton.Clicked += (s, e) => entry.Text = "Hello, Maui!";
+
+ var pasteToEditorButton = new Button
+ {
+ Text = "Paste to editor",
+ AutomationId = "PasteToEditorButton"
+ };
+ pasteToEditorButton.Clicked += (s, e) => editor.Text = "Hello, Maui!";
+
+ stackLayout.Children.Add(entry);
+ stackLayout.Children.Add(editor);
+ stackLayout.Children.Add(pasteToEntryButton);
+ stackLayout.Children.Add(pasteToEditorButton);
+
+ Content = stackLayout;
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue19997.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue19997.cs
new file mode 100644
index 000000000000..aba690f70326
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue19997.cs
@@ -0,0 +1,45 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 19997, "[Android, iOS, MacOS] Entry ClearButton Color Not Updating on AppThemeBinding Change", PlatformAffected.Android | PlatformAffected.iOS | PlatformAffected.macOS)]
+public class Issue19997 : TestContentPage
+{
+ protected override void Init()
+ {
+ Title = "Issue19997";
+
+ // Create the UITestEntry with app theme binding for TextColor
+ var entry = new UITestEntry
+ {
+ Text = "Hii",
+ IsCursorVisible = false,
+ AutomationId = "EntryWithAppThemeBinding",
+ ClearButtonVisibility = ClearButtonVisibility.WhileEditing
+ };
+
+ // Set up app theme binding for TextColor (Light=Blue, Dark=Red)
+ entry.SetAppThemeColor(Entry.TextColorProperty, Colors.Blue, Colors.Red);
+
+ // Create the button
+ var button = new Button
+ {
+ Text = "Change theme",
+ AutomationId = "ThemeButton"
+ };
+ button.Clicked += Button_Clicked;
+
+ // Create the layout and add controls
+ var layout = new VerticalStackLayout();
+ layout.Children.Add(entry);
+ layout.Children.Add(button);
+
+ Content = layout;
+ }
+
+ void Button_Clicked(object sender, EventArgs e)
+ {
+ if (Application.Current != null)
+ {
+ Application.Current.UserAppTheme = Application.Current.UserAppTheme != AppTheme.Dark ? AppTheme.Dark : AppTheme.Light;
+ }
+ }
+}
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue21375.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue21375.xaml
new file mode 100644
index 000000000000..ce265dd0ca2a
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue21375.xaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue21375.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue21375.xaml.cs
new file mode 100644
index 000000000000..b6bea7f0fca1
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue21375.xaml.cs
@@ -0,0 +1,109 @@
+using System.Collections.ObjectModel;
+using System.Text;
+
+#if ANDROID
+using AndroidX.RecyclerView.Widget;
+#endif
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 21375, "Selected CollectionView item is not announced", PlatformAffected.iOS & PlatformAffected.macOS & PlatformAffected.Android)]
+public partial class Issue21375 : ContentPage
+{
+ public ObservableCollection- Items { get; set; }
+
+ public Issue21375()
+ {
+ InitializeComponent();
+
+ Items = new ObservableCollection
-
+ {
+ new Item { Name = "Item 1", Description = "Description for item 1" },
+ new Item { Name = "Item 2", Description = "Description for item 2" },
+ new Item { Name = "Item 3", Description = "Description for item 3" },
+ new Item { Name = "Item 4", Description = "Description for item 4" },
+ new Item { Name = "Item 5", Description = "Description for item 5" }
+ };
+
+ BindingContext = this;
+ }
+
+ void NoneSelectionMode(object sender, EventArgs e)
+ {
+ collectionView.SelectionMode = SelectionMode.None;
+ }
+
+ void SingleSelectionMode(object sender, EventArgs e)
+ {
+ collectionView.SelectionMode = SelectionMode.Single;
+ }
+
+ void MultipleSelectionMode(object sender, EventArgs e)
+ {
+ collectionView.SelectionMode = SelectionMode.Multiple;
+ }
+
+ void Calculate(object sender, EventArgs e)
+ {
+ var sb = new StringBuilder();
+#if IOS || MACCATALYST
+ if (collectionView.Handler?.PlatformView is UIKit.UIView vc
+ && vc.Subviews is UIKit.UIView[] subviews && subviews.Length > 0
+ && subviews[0] is UIKit.UICollectionView uiCollectionView)
+ {
+ for (int i = 0; i < uiCollectionView.VisibleCells.Length; i++)
+ {
+ var cell = uiCollectionView.VisibleCells[i];
+ sb.AppendLine($"Item{i} Cell: {cell.AccessibilityTraits}");
+ if (cell.ContentView is not null && cell.ContentView.Subviews.Length > 0)
+ {
+ var firstChild = cell.ContentView.Subviews[0];
+ sb.AppendLine($"Item{i} FirstChild: {firstChild.AccessibilityTraits}");
+ }
+ }
+ }
+#elif ANDROID
+ var plat = collectionView.Handler?.PlatformView;
+ if (plat is RecyclerView recyclerView)
+ {
+ var adapter = recyclerView.GetAdapter();
+ var layoutManager = recyclerView.GetLayoutManager();
+ var childCount = layoutManager.ChildCount;
+ for (int i = 0; i < childCount; i++)
+ {
+ var viewHolder = recyclerView.GetChildAt(i);
+ if (viewHolder is null)
+ continue;
+
+ var position = recyclerView.GetChildAdapterPosition(viewHolder);
+ sb.AppendLine($"Item{position} Cell: {viewHolder.Selected}");
+ }
+ }
+#elif WINDOWS
+ var plat = collectionView.Handler?.PlatformView;
+ if (plat is Microsoft.UI.Xaml.Controls.ListView listView)
+ {
+ foreach (var item in listView.Items)
+ {
+ var container = listView.ContainerFromItem(item) as Microsoft.UI.Xaml.Controls.ListViewItem;
+ if (container != null)
+ {
+ sb.AppendLine($"Item: {item} IsSelected: {container.IsSelected}");
+ }
+ }
+ }
+#endif
+ Output.Text = sb.ToString();
+ }
+
+ void ClearSelection(object sender, EventArgs e)
+ {
+ collectionView.SelectedItem = null;
+ }
+
+ public class Item
+ {
+ public string Name { get; set; }
+ public string Description { get; set; }
+ }
+}
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue21640.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue21640.cs
new file mode 100644
index 000000000000..1b99cb46353e
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue21640.cs
@@ -0,0 +1,65 @@
+namespace Maui.Controls.Sample.Issues
+{
+ [Issue(IssueTracker.Github, 21640, "TabbedPage content was not updated", PlatformAffected.Android)]
+ public partial class Issue21640 : TabbedPage
+ {
+ private Page _savedPage;
+ public Issue21640()
+ {
+ var homePage = new ContentPage
+ {
+ Title = "Home",
+ Content = new Button
+ {
+ Text = "Toggle Tab",
+ Command = new Command(ToggleTab),
+ AutomationId = "ToogleTabButton"
+ }
+ };
+
+ var newPage = CreateNewPage();
+ _savedPage = new NavigationPage(newPage) { Title = "Settings" };
+ Children.Add(new NavigationPage(homePage) { Title = "Home" });
+ }
+
+ private async void ToggleTab()
+ {
+ if (Children.Count == 1)
+ {
+ await MainThread.InvokeOnMainThreadAsync(() =>
+ {
+ Children.Add(_savedPage);
+ });
+ }
+ else if (Children.Count == 2)
+ {
+ _savedPage = Children[1];
+ await MainThread.InvokeOnMainThreadAsync(() =>
+ {
+ Children.RemoveAt(1);
+ });
+ }
+ }
+
+ private Page CreateNewPage()
+ {
+ return new ContentPage
+ {
+ Title = "NewPage",
+ Content = new VerticalStackLayout
+ {
+ Children =
+ {
+ new Label
+ {
+ Text = "Welcome to .NET MAUI!",
+ VerticalOptions = LayoutOptions.Center,
+ HorizontalOptions = LayoutOptions.Center,
+ AutomationId = "label"
+ }
+ }
+ }
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue23834.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue23834.cs
new file mode 100644
index 000000000000..10f03ae5562d
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue23834.cs
@@ -0,0 +1,54 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 23834, "Flyout Item misbehavior", PlatformAffected.UWP)]
+public class Issue23834 : TestShell
+{
+ protected override void Init()
+ {
+ var shellContent = new ShellContent()
+ {
+ ContentTemplate = new DataTemplate(typeof(Issue23834SamplePage))
+ };
+
+ this.Items.Add(new FlyoutItem()
+ {
+ Title = "Flyout Item 1",
+ IsVisible = false,
+ Items =
+ {
+ shellContent
+ }
+ });
+
+ this.Items.Add(new FlyoutItem()
+ {
+ Title = "Flyout Item 2",
+ Items =
+ {
+ shellContent
+ }
+ });
+ }
+}
+
+public class Issue23834SamplePage : ContentPage
+{
+ public Issue23834SamplePage()
+ {
+ var layout = new StackLayout();
+ var changeButton = new Button
+ {
+ Text = "Change First Item's IsVisible",
+ AutomationId = "button"
+ };
+
+ changeButton.Clicked += (s, e) =>
+ {
+ Shell.Current.Items[0].IsVisible = true;
+ };
+
+ layout.Children.Add(changeButton);
+
+ Content = layout;
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue27711.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue27711.xaml
new file mode 100644
index 000000000000..33a60887ba2b
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue27711.xaml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Item 1
+ Item 2
+ Item 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue27711.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue27711.xaml.cs
new file mode 100644
index 000000000000..68cf8717cb8f
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue27711.xaml.cs
@@ -0,0 +1,15 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 27711, "FlowDirection = `RightToLeft` doesn't work with CV1 & CV2", PlatformAffected.iOS)]
+public partial class Issue27711 : ContentPage
+{
+ public Issue27711()
+ {
+ InitializeComponent();
+ }
+
+ private void switch_Toggled(object sender, ToggledEventArgs e)
+ {
+ CV.FlowDirection = CV.FlowDirection == FlowDirection.LeftToRight ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue28343.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue28343.cs
index 2e8950507a6a..de60a29ae76a 100644
--- a/src/Controls/tests/TestCases.HostApp/Issues/Issue28343.cs
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue28343.cs
@@ -42,7 +42,20 @@ public Issue28343()
refreshView.Content = CreateContent();
})
}, 0, 2 },
- { refreshView, 0, 3 }
+ {
+ new Button
+ {
+ Text = "Scroll Up",
+ AutomationId = "ScrollToUpButton",
+ Command = new Command(() =>
+ {
+ if (refreshView.Content is CollectionView collectionView)
+ {
+ collectionView.ScrollTo(0, position: ScrollToPosition.Start, animate: false);
+ }
+ })
+ }, 0, 3 },
+ { refreshView, 0, 4 }
};
refreshView.Command = new Command(() =>
@@ -56,7 +69,8 @@ public Issue28343()
grid.RowDefinitions[0].Height = GridLength.Auto;
grid.RowDefinitions[1].Height = GridLength.Auto;
grid.RowDefinitions[2].Height = GridLength.Auto;
- grid.RowDefinitions[3].Height = GridLength.Star;
+ grid.RowDefinitions[3].Height = GridLength.Auto;
+ grid.RowDefinitions[4].Height = GridLength.Star;
}
View CreateContent()
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue28524.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue28524.xaml
new file mode 100644
index 000000000000..364efea4a6e5
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue28524.xaml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Baboon
+ Capuchin Monkey
+ Blue Monkey
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue28524.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue28524.xaml.cs
new file mode 100644
index 000000000000..d3f80d7d0591
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue28524.xaml.cs
@@ -0,0 +1,10 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 28524, "[iOS] CurrentItem does not work when PeekAreaInsets is set", PlatformAffected.iOS)]
+public partial class Issue28524 : ContentPage
+{
+ public Issue28524()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue28716.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue28716.xaml
new file mode 100644
index 000000000000..7bb8d0a5dfa4
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue28716.xaml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue28716.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue28716.xaml.cs
new file mode 100644
index 000000000000..d0f792bfddd1
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue28716.xaml.cs
@@ -0,0 +1,33 @@
+using System.Collections.ObjectModel;
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 28716, "Support for KeepLastItemInView for CV2", PlatformAffected.iOS)]
+public partial class Issue28716 : ContentPage
+{
+ private ObservableCollection _items;
+ public ObservableCollection Items
+ {
+ get => _items;
+ set
+ {
+ if (_items != value)
+ {
+ _items = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public Command AddItemCommand => new(() =>
+ {
+ Items.Add($"Item{_items.Count}");
+ });
+
+ public Issue28716()
+ {
+ InitializeComponent();
+ Items = [.. Enumerable.Range(0, 20).Select(x => $"Item{x}")];
+ BindingContext = this;
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue29297.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue29297.cs
new file mode 100644
index 000000000000..867195f6f518
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue29297.cs
@@ -0,0 +1,87 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 29297, "Crash on shell navigation for Mac Catalyst", PlatformAffected.macOS)]
+public class Issue29297 : Shell
+{
+ public Issue29297()
+ {
+ CurrentItem = new Issue29297_MainPage();
+ }
+
+ public class Issue29297_MainPage : ContentPage
+ {
+ Label label;
+ bool isNavigated;
+ public Issue29297_MainPage()
+ {
+ var stack = new StackLayout();
+ label = new Label();
+ var Button = new Button();
+ Button.Text = "Click to navigate new page";
+ Button.AutomationId = "Button";
+ Button.Clicked += Clicked;
+ stack.Children.Add(Button);
+ stack.Children.Add(label);
+ this.Content = stack;
+ this.Loaded += MainPage_Loaded;
+ }
+
+ private async void Clicked(object sender, EventArgs e)
+ {
+ isNavigated = true;
+ await Navigation.PushAsync(new Issue29297_NewPage());
+ }
+
+ private void MainPage_Loaded(object sender, EventArgs e)
+ {
+ if (isNavigated)
+ {
+ label.Text = $"Successfully navigated back";
+ }
+ }
+ }
+
+ public class Issue29297_NewPage : ContentPage
+ {
+ public Issue29297_NewPage()
+ {
+ var stack = new StackLayout();
+ var Button = new Button();
+ Button.Text = "Click to navigate main page";
+ Button.AutomationId = "Button";
+ Button.Clicked += Clicked;
+ stack.Children.Add(Button);
+ this.Unloaded += NewPage_Unloaded;
+ this.Content = stack;
+ }
+
+ private void Clicked(object sender, EventArgs e)
+ {
+ Shell.Current.GoToAsync("..");
+ }
+
+ private void NewPage_Unloaded(object sender, EventArgs e)
+ {
+ if (sender is not VisualElement senderElement)
+ return;
+
+ var visualTreeElement = (IVisualTreeElement)senderElement;
+
+ Disconnect(visualTreeElement);
+
+ return;
+
+ void Disconnect(IVisualTreeElement element)
+ {
+ if (element is VisualElement visualElement)
+ {
+
+ foreach (IVisualTreeElement childElement in element.GetVisualChildren())
+ Disconnect(childElement);
+
+ visualElement.Handler?.DisconnectHandler();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue29491.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue29491.cs
new file mode 100644
index 000000000000..cd16b0e6a1e2
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue29491.cs
@@ -0,0 +1,93 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 29491, "[CV2][CollectionView] Changing CollectionView's ItemsSource in runtime removes elements' parent seemingly random", PlatformAffected.iOS)]
+public class Issue29491 : ContentPage
+{
+ List m_items =
+ [
+ "Item 1", "Item 2", "Item 3", "Item 4", "Item 5",
+ "Item 6", "Item 7", "Item 8", "Item 9", "Item 10"
+ ];
+
+ public List Items
+ {
+ get => m_items;
+ set
+ {
+ if (Equals(value, m_items))
+ return;
+ m_items = value;
+ OnPropertyChanged(nameof(Items));
+ }
+ }
+
+ public Issue29491()
+ {
+ BindingContext = this;
+
+ var reverseButton = new Button
+ {
+ Text = "Reverse",
+ AutomationId = "Button"
+ };
+ reverseButton.Clicked += Button_OnClicked;
+
+ var collectionView = new CollectionView
+ {
+ ItemTemplate = new DataTemplate(() =>
+ {
+ var stack = new VerticalStackLayout();
+
+ var label = new Label
+ {
+ FontSize = 30
+ };
+ label.SetBinding(Label.TextProperty, ".");
+
+ var parentLabel = new Label { AutomationId = "Label" };
+ parentLabel.SetBinding(Label.TextProperty, new Binding
+ {
+ Source = stack,
+ Path = "Parent",
+ TargetNullValue = "`null`"
+ });
+
+ var grid = new Grid
+ {
+ ColumnDefinitions = new ColumnDefinitionCollection
+ {
+ new ColumnDefinition { Width = GridLength.Auto },
+ new ColumnDefinition { Width = GridLength.Star }
+ }
+ };
+ grid.Add(new Label { Text = "Parent: " });
+ grid.Add(parentLabel, 1, 0);
+
+ stack.Add(label);
+ stack.Add(grid);
+
+ return stack;
+ })
+ };
+ collectionView.SetBinding(ItemsView.ItemsSourceProperty, nameof(Items));
+
+ var mainLayout = new StackLayout
+ {
+ Children =
+ {
+ reverseButton,
+ collectionView
+ }
+ };
+
+ Content = mainLayout;
+ }
+
+ void Button_OnClicked(object sender, EventArgs e)
+ {
+ var reversed = new List(Items);
+ reversed.Reverse();
+ Items = reversed;
+ }
+}
+
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue30350.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue30350.xaml
new file mode 100644
index 000000000000..364ed042ca83
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue30350.xaml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue30350.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue30350.xaml.cs
new file mode 100644
index 000000000000..0b0f68add01a
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue30350.xaml.cs
@@ -0,0 +1,142 @@
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using Microsoft.Maui.Graphics;
+using Microsoft.Maui.Graphics.Platform;
+using IImage = Microsoft.Maui.Graphics.IImage;
+
+namespace Maui.Controls.Sample.Issues
+{
+ [Issue(IssueTracker.Github, 30350, "IImage downsize broken starting from 9.0.80 and not fixed in 9.0.81", PlatformAffected.iOS)]
+ public partial class Issue30350 : TestContentPage
+ {
+ private ImageSource _originalSource;
+ private string _originalSize;
+ private ImageSource _downsizedSource;
+ private string _downsizedImageSize;
+
+ public Issue30350()
+ {
+ InitializeComponent();
+ BindingContext = this;
+ }
+
+ protected override void Init()
+ {
+ // Delay loading to ensure all controls are initialized
+ Dispatcher.Dispatch(async () => await LoadImagesAsync());
+ }
+
+ public ImageSource OriginalSource
+ {
+ get => _originalSource;
+ set
+ {
+ if (Equals(value, _originalSource))
+ return;
+ _originalSource = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public ImageSource DownsizedSource
+ {
+ get => _downsizedSource;
+ set
+ {
+ if (Equals(value, _downsizedSource))
+ return;
+ _downsizedSource = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public string OriginalSize
+ {
+ get => _originalSize;
+ set
+ {
+ if (value == _originalSize)
+ return;
+ _originalSize = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public string DownsizedImageSize
+ {
+ get => _downsizedImageSize;
+ set
+ {
+ if (value == _downsizedImageSize)
+ return;
+ _downsizedImageSize = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private async Task LoadImagesAsync()
+ {
+ try
+ {
+ // Check if StatusLabel is available
+ if (StatusLabel != null)
+ StatusLabel.Text = "Loading images...";
+
+ // Load original image from embedded resource
+ OriginalSource = ImageSource.FromResource("Controls.TestCases.HostApp.Resources.Images.royals.png");
+
+ // Load IImage for processing
+ var assembly = GetType().GetTypeInfo().Assembly;
+ using var stream = assembly.GetManifestResourceStream("Controls.TestCases.HostApp.Resources.Images.royals.png");
+
+ if (stream == null)
+ {
+ if (StatusLabel != null)
+ StatusLabel.Text = "Error: Could not load royals.png resource";
+ return;
+ }
+
+ var originalImage = PlatformImage.FromStream(stream);
+ if (originalImage == null)
+ {
+ if (StatusLabel != null)
+ StatusLabel.Text = "Error: Could not create IImage from stream";
+ return;
+ }
+
+ OriginalSize = $"{originalImage.Width}x{originalImage.Height}";
+
+ // Perform downsize operation - this is where the issue occurs in MAUI 9.0.80+
+ // The downsized image should be flipped/rotated incorrectly on iOS 9.0.80+
+ var downsizedImage = originalImage.Downsize(100);
+ if (downsizedImage == null)
+ {
+ if (StatusLabel != null)
+ StatusLabel.Text = "Error: Downsize operation failed";
+ return;
+ }
+
+ DownsizedImageSize = $"{downsizedImage.Width}x{downsizedImage.Height}";
+
+ // Convert downsized IImage to ImageSource
+ using var downsizedStream = new MemoryStream();
+ await downsizedImage.SaveAsync(downsizedStream, ImageFormat.Png);
+ downsizedStream.Position = 0;
+
+ DownsizedSource = ImageSource.FromStream(() => new MemoryStream(downsizedStream.ToArray()));
+
+ if (StatusLabel != null)
+ StatusLabel.Text = "Images loaded. Compare for flipping/rotation issues in MAUI 9.0.80+";
+ }
+ catch (Exception ex)
+ {
+ if (StatusLabel != null)
+ StatusLabel.Text = $"Error loading images: {ex.Message}";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue30367.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue30367.cs
new file mode 100644
index 000000000000..aa462b42c8cd
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue30367.cs
@@ -0,0 +1,40 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 30367, "SearchBar FlowDirection Property Not Working on Android", PlatformAffected.Android)]
+public class Issue30367 : ContentPage
+{
+ SearchBar ltrSearchBar;
+ SearchBar rtlSearchBar;
+
+ public Issue30367()
+ {
+ Title = "Issue 30367";
+
+ ltrSearchBar = new SearchBar
+ {
+ Placeholder = "Search here...",
+ Text = "Left to Right",
+ BackgroundColor = Colors.LightBlue,
+ FlowDirection = FlowDirection.LeftToRight
+ };
+
+ rtlSearchBar = new SearchBar
+ {
+ Placeholder = "Search here...",
+ Text = "Right to Left",
+ BackgroundColor = Colors.LightBlue,
+ FlowDirection = FlowDirection.RightToLeft
+ };
+
+ Content = new StackLayout
+ {
+ Children =
+ {
+ new Label { Text = "LTR SearchBar:", AutomationId = "SearchBarLabel" },
+ ltrSearchBar,
+ new Label { Text = "RTL SearchBar:" },
+ rtlSearchBar,
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue30426.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue30426.xaml
new file mode 100644
index 000000000000..c796c306d141
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue30426.xaml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue30426.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue30426.xaml.cs
new file mode 100644
index 000000000000..f59cd99ffe52
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue30426.xaml.cs
@@ -0,0 +1,137 @@
+using System.Reflection;
+using Microsoft.Maui.Graphics.Platform;
+using IImage = Microsoft.Maui.Graphics.IImage;
+
+namespace Maui.Controls.Sample.Issues
+{
+ [Issue(IssueTracker.Github, 30426, "IImage Downsize() throws Exception in 9.0.81 when called from background thread on iOS", PlatformAffected.iOS)]
+ public partial class Issue30426 : TestContentPage
+ {
+ private IImage _originalImage;
+
+ public Issue30426()
+ {
+ InitializeComponent();
+ }
+
+ protected override void Init()
+ {
+
+ }
+
+ private async void OnSelectImageClicked(object sender, EventArgs e)
+ {
+ await LoadEmbeddedImageAsync();
+ }
+
+ private async Task LoadEmbeddedImageAsync()
+ {
+ try
+ {
+ var assembly = GetType().GetTypeInfo().Assembly;
+ using (var stream = assembly.GetManifestResourceStream("Controls.TestCases.HostApp.Resources.Images.royals.png"))
+ {
+ _originalImage = PlatformImage.FromStream(stream);
+ using var memoryStream = new MemoryStream();
+ await stream.CopyToAsync(memoryStream);
+
+ FileSizeLabel.Text = $"File Size: {stream.Length / 1024:N0} KB";
+ DimensionsLabel.Text = $"Dimensions: {_originalImage.Width} x {_originalImage.Height}";
+ }
+
+ ProcessImageButton.IsEnabled = true;
+ StatusLabel.Text = "Status: Image loaded successfully";
+ }
+ catch (Exception ex)
+ {
+ ShowError($"Failed to load image: {ex.Message}");
+ }
+ }
+
+ private void OnResizeSliderChanged(object sender, ValueChangedEventArgs e)
+ {
+ var percentage = (int)e.NewValue;
+ ResizeLabel.Text = $"{percentage}%";
+ }
+
+ private async void OnProcessImageClicked(object sender, EventArgs e)
+ {
+ if (_originalImage == null)
+ {
+ ShowError("No image loaded");
+ return;
+ }
+
+ try
+ {
+ StatusLabel.Text = "Status: Processing image...";
+ ErrorLabel.IsVisible = false;
+ ProcessImageButton.IsEnabled = false;
+
+ var resizePercentage = ResizeSlider.Value / 100f;
+ var newWidth = (float)(_originalImage.Width * resizePercentage);
+ var newHeight = (float)(_originalImage.Height * resizePercentage);
+
+ // This should cause the issue on iOS 9.0.81 when called from background thread
+ await Task.Run(() => ProcessImageOnBackgroundThread(newWidth, newHeight));
+
+ }
+ catch (Exception ex)
+ {
+ ShowError($"Image processing failed: {ex.Message}");
+ }
+ finally
+ {
+ ProcessImageButton.IsEnabled = true;
+ }
+ }
+
+ private void ProcessImageOnBackgroundThread(float newWidth, float newHeight)
+ {
+ try
+ {
+ // This call should throw UIKitThreadAccessException on iOS 9.0.81
+ var resizedImage = _originalImage.Downsize(newWidth, newHeight, false);
+
+ MainThread.BeginInvokeOnMainThread(() =>
+ {
+ UpdateImageDisplay(resizedImage, "Background Thread");
+ });
+ }
+ catch (Exception ex)
+ {
+ MainThread.BeginInvokeOnMainThread(() =>
+ {
+ ShowError($"Background thread processing failed: {ex.Message}");
+ });
+ }
+ }
+
+ private async void UpdateImageDisplay(IImage resizedImage, string processingMethod)
+ {
+ try
+ {
+ using var stream = new MemoryStream();
+ await resizedImage.SaveAsync(stream, ImageFormat.Jpeg, 0.8f);
+
+ stream.Position = 0;
+ DisplayImage.Source = ImageSource.FromStream(() => new MemoryStream(stream.ToArray()));
+
+ FileSizeLabel.Text = $"File Size: {stream.Length / 1024:N0} KB";
+ DimensionsLabel.Text = $"Dimensions: {resizedImage.Width} x {resizedImage.Height}";
+ StatusLabel.Text = $"Status: Image processed successfully";
+ }
+ catch (Exception ex)
+ {
+ ShowError($"Failed to update display: {ex.Message}");
+ }
+ }
+
+ private void ShowError(string message)
+ {
+ ErrorLabel.Text = message;
+ ErrorLabel.IsVisible = true;
+ StatusLabel.Text = "Status: Error occurred";
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue30536.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue30536.cs
new file mode 100644
index 000000000000..61d03ad38917
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue30536.cs
@@ -0,0 +1,154 @@
+#if WINDOWS
+using System.Runtime.InteropServices;
+#endif
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 30536, "[Windows] PointerGestureRecognizer behaves incorrectly when multiple windows are open", PlatformAffected.UWP)]
+public class Issue30536 : ContentPage
+{
+ Button newWindowButton;
+ Button closeNewWindowButton;
+ Button minimizeSecondWindowButton;
+ Label pointerEnterCountLabel;
+ Label pointerExitCountLabel;
+ Border theBorder;
+ int enterCount = 0;
+ int exitCount = 0;
+ Window secondWindow;
+ public Issue30536()
+ {
+ InitializeUI();
+ }
+
+ private void InitializeUI()
+ {
+ // Create the VerticalStackLayout
+ var stackLayout = new VerticalStackLayout
+ {
+ Spacing = 5
+ };
+
+ // Create New Window button
+ newWindowButton = new Button
+ {
+ Text = "New Window",
+ AutomationId = "NewWindowButton"
+ };
+ newWindowButton.Clicked += OnNewWindowButton_Clicked;
+
+ closeNewWindowButton = new Button
+ {
+ Text = "Close New Window",
+ AutomationId = "CloseNewWindowButton"
+ };
+ closeNewWindowButton.Clicked += (sender, e) =>
+ {
+ if (secondWindow != null)
+ {
+ Application.Current.CloseWindow(secondWindow);
+ secondWindow = null;
+ }
+ };
+
+ minimizeSecondWindowButton = new Button
+ {
+ Text = "Minimize Second Window",
+ AutomationId = "MinimizeSecondWindowButton"
+ };
+ minimizeSecondWindowButton.Clicked += (sender, e) =>
+ {
+ if (secondWindow != null)
+ {
+ MinimizeWindow(secondWindow);
+ }
+ };
+
+ // Create pointer enter count label
+ pointerEnterCountLabel = new Label
+ {
+ Text = $"Pointer Enter Count: {enterCount}",
+ AutomationId = "PointerEnterCountLabel"
+
+ };
+
+ pointerExitCountLabel = new Label
+ {
+ Text = $"Pointer Exit Count: {exitCount}",
+ AutomationId = "PointerExitCountLabel"
+
+ };
+
+ // Create the border with red background
+ theBorder = new Border
+ {
+ WidthRequest = 500,
+ HeightRequest = 500,
+ BackgroundColor = Colors.Red,
+ Content = new Button
+ {
+ Text = "Tap Me",
+ AutomationId = "BorderButton"
+ }
+ };
+
+ // Create and add PointerGestureRecognizer
+ var pointerGestureRecognizer = new PointerGestureRecognizer();
+ pointerGestureRecognizer.PointerEntered += OnPointerGestureRecognizer_PointerEntered;
+ pointerGestureRecognizer.PointerExited += OnPointerGestureRecognizer_PointerExited;
+ theBorder.GestureRecognizers.Add(pointerGestureRecognizer);
+
+ // Add all elements to the stack layout
+ stackLayout.Children.Add(minimizeSecondWindowButton);
+ stackLayout.Children.Add(newWindowButton);
+ stackLayout.Children.Add(closeNewWindowButton);
+ stackLayout.Children.Add(pointerEnterCountLabel);
+ stackLayout.Children.Add(pointerExitCountLabel);
+ stackLayout.Children.Add(theBorder);
+
+ // Set the content
+ Content = stackLayout;
+ }
+
+#if WINDOWS
+ // Windows API declarations
+ [DllImport("user32.dll")]
+ private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
+
+ // ShowWindow constants
+ private const int SW_MINIMIZE = 6;
+#endif
+
+ private void OnNewWindowButton_Clicked(object sender, EventArgs e)
+ {
+ secondWindow = new Window(new ContentPage());
+ Application.Current.OpenWindow(secondWindow);
+ }
+
+ private void MinimizeWindow(Window window)
+ {
+#if WINDOWS
+ if (window.Handler?.PlatformView is Microsoft.UI.Xaml.Window win)
+ {
+ // Get window handle directly from MAUI's platform view
+ var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(win);
+ if (hwnd != IntPtr.Zero)
+ {
+ ShowWindow(hwnd, SW_MINIMIZE);
+ }
+ }
+#endif
+ }
+ private void OnPointerGestureRecognizer_PointerEntered(object sender, PointerEventArgs e)
+ {
+ theBorder.BackgroundColor = Colors.Lime;
+ enterCount++;
+ pointerEnterCountLabel.Text = $"Pointer Enter Count: {enterCount}";
+ }
+ private void OnPointerGestureRecognizer_PointerExited(object sender, PointerEventArgs e)
+ {
+ theBorder.BackgroundColor = Colors.Red;
+ exitCount++;
+ pointerExitCountLabel.Text = $"Pointer Exit Count: {exitCount}";
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue30575.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue30575.cs
new file mode 100644
index 000000000000..052641a2abf9
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue30575.cs
@@ -0,0 +1,31 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 30575, "FlowDirection RightToLeft causes mirrored content in WebView", PlatformAffected.UWP)]
+public class Issue30575 : ContentPage
+{
+ public Issue30575()
+ {
+ VerticalStackLayout stackLayout = new VerticalStackLayout();
+ WebView webView = new WebView
+ {
+ HeightRequest = 400,
+ WidthRequest = 400,
+ FlowDirection = FlowDirection.RightToLeft,
+ };
+
+ webView.Source = new UrlWebViewSource
+ {
+ Url = "https://github.com/dotnet/maui/issues/30575"
+ };
+
+ Label label = new Label
+ {
+ AutomationId = "WebViewLabel",
+ Text = "The test passes if the content is not mirrored.",
+ };
+
+ stackLayout.Children.Add(webView);
+ stackLayout.Children.Add(label);
+ Content = stackLayout;
+ }
+}
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue30597.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue30597.cs
index 8d9a96f71e1a..4771df13eec2 100644
--- a/src/Controls/tests/TestCases.HostApp/Issues/Issue30597.cs
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue30597.cs
@@ -10,6 +10,7 @@ public Issue30597()
Placeholder = "Placeholder with AppThemeBinding - red/green"
};
searchBar3.SetAppThemeColor(SearchBar.PlaceholderColorProperty, Colors.Red, Colors.Green);
+ this.SetAppThemeColor(BackgroundProperty, Colors.White, Colors.Black);
Content = new StackLayout
{
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue30601.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue30601.cs
new file mode 100644
index 000000000000..acd9c5bf0503
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue30601.cs
@@ -0,0 +1,41 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 30601, "[Android] SearchBar does not update colors on theme change", PlatformAffected.Android)]
+public class Issue30601 : ContentPage
+{
+ public Issue30601()
+ {
+ var searchBar3 = new SearchBar
+ {
+ Placeholder = "Placeholder with AppThemeBinding - red/green"
+ };
+ searchBar3.SetAppThemeColor(SearchBar.PlaceholderColorProperty, Colors.Red, Colors.Green);
+ this.SetAppThemeColor(BackgroundProperty, Colors.White, Colors.Black);
+
+ Content = new StackLayout
+ {
+ Children =
+ {
+ new SearchBar
+ {
+ Placeholder = "Placeholder - system's default"
+ },
+ new SearchBar
+ {
+ PlaceholderColor = Colors.Red,
+ Placeholder = "Placeholder - red"
+ },
+ searchBar3,
+ new Button
+ {
+ Text = "Change Theme",
+ AutomationId = "changeThemeButton",
+ Command= new Command(() =>
+ {
+ Application.Current!.UserAppTheme = Application.Current!.UserAppTheme != AppTheme.Dark ? AppTheme.Dark : AppTheme.Light;
+ })
+ }
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31139.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue31139.xaml
new file mode 100644
index 000000000000..cd5b8a1a72e5
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31139.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31139.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue31139.xaml.cs
new file mode 100644
index 000000000000..2e5d06270ee1
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31139.xaml.cs
@@ -0,0 +1,75 @@
+using System.ComponentModel;
+using System.Diagnostics;
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 31139, "Binding updates from background thread should marshal to UI thread", PlatformAffected.All)]
+public partial class Issue31139 : ContentPage
+{
+ public Issue31139()
+ {
+ InitializeComponent();
+ BindingContext = new Issue31139ViewModel();
+ }
+}
+
+public class Issue31139ViewModel : INotifyPropertyChanged
+{
+ bool flag = true;
+ public Issue31139ViewModel()
+ {
+ Thread t = new Thread(() =>
+ {
+ var stopwatch = new Stopwatch();
+ stopwatch.Restart();
+
+ while (true)
+ {
+ try
+ {
+ if (flag)
+ {
+ Status = "Test";
+ flag = false;
+ }
+ else
+ {
+ Status = "Success";
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex);
+ }
+
+ Thread.Sleep(500);
+ }
+ });
+
+ t.IsBackground = true;
+ t.Start();
+ }
+
+ private string _status = string.Empty;
+
+ public string Status
+ {
+ get => _status;
+ set
+ {
+ if (_status != value)
+ {
+ _status = value;
+ OnPropertyChanged(nameof(Status));
+ }
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31314.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue31314.cs
new file mode 100644
index 000000000000..75ebb6bc46b5
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31314.cs
@@ -0,0 +1,48 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 31314, "LinearGradientBrush can not work", PlatformAffected.Android)]
+public class Issue31314 : ContentPage
+{
+ public Issue31314()
+ {
+ Content = new VerticalStackLayout
+ {
+ Children =
+ {
+ new Label
+ {
+ Text = "Label",
+ AutomationId = "label"
+ },
+ CreateBorder(new GradientStopCollection
+ {
+ new GradientStop(Color.FromArgb("0000FF"), 1.0f),
+ new GradientStop(Color.FromArgb("3fb0fe"), 0.75f),
+ new GradientStop(Color.FromArgb("67f4ed"), 0.5f),
+ new GradientStop(Color.FromArgb("79e800"), 0.22f),
+ }),
+ CreateBorder(new GradientStopCollection
+ {
+ new GradientStop(Color.FromArgb("a7e800"), 0.0f),
+ new GradientStop(Color.FromArgb("79e800"), 0.22f),
+ new GradientStop(Color.FromArgb("67f4ed"), 0.5f),
+ new GradientStop(Color.FromArgb("3fb0fe"), 0.75f),
+ new GradientStop(Color.FromArgb("0000FF"), 1.0f),
+ })
+ }
+ };
+ }
+
+ static Border CreateBorder(GradientStopCollection stops) =>
+ new()
+ {
+ HeightRequest = 100,
+ WidthRequest = 100,
+ Background = new LinearGradientBrush
+ {
+ StartPoint = new Point(0, 0),
+ EndPoint = new Point(0, 1),
+ GradientStops = stops
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31351.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue31351.cs
new file mode 100644
index 000000000000..90aa1596c0bf
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31351.cs
@@ -0,0 +1,282 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Windows.Input;
+using Microsoft.Maui.Controls;
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 31351, "[WinUI] Custom CollectionView does not work on ScrollTo", PlatformAffected.All)]
+public partial class Issue31351 : ContentPage
+{
+ readonly Issue31351CustomCollectionView _customCollectionView;
+ readonly Issue31351StartupPageModel _viewModel;
+
+ public Issue31351()
+ {
+ _viewModel = new Issue31351StartupPageModel();
+ BindingContext = _viewModel;
+
+ var scrollButton = new Button
+ {
+ Text = "Scroll to Mid",
+ AutomationId = "Issue31351ScrollButton"
+ };
+ scrollButton.Clicked += (s, e) =>
+ {
+ _viewModel.Scroll.Execute(null);
+ };
+
+ var scrollButton2 = new Button
+ {
+ Text = "Scroll to Top",
+ AutomationId = "Issue31351TopScrollButton"
+ };
+ scrollButton2.HeightRequest = 50;
+ scrollButton2.Clicked += (s, e) =>
+ {
+ _customCollectionView.ScrollTo(0, position: ScrollToPosition.Center, animate: true);
+ };
+
+ var statusLabel = new Label
+ {
+ Text = "Ready - Tap buttons to test ScrollTo functionality",
+ AutomationId = "Issue31351StatusLabel",
+ BackgroundColor = Colors.LightYellow,
+ Padding = new Thickness(10),
+ HorizontalTextAlignment = TextAlignment.Center
+ };
+
+ _customCollectionView = new Issue31351CustomCollectionView
+ {
+ AutomationId = "Issue31351CollectionView",
+ Margin = 10,
+ BackgroundColor = Colors.LightGray
+ };
+ _customCollectionView.SetBinding(Issue31351CustomCollectionView.CustomItemsSourceProperty,
+ new Binding(nameof(Issue31351StartupPageModel.DisplayItems), BindingMode.TwoWay, source: _viewModel));
+ _customCollectionView.SetBinding(Issue31351CustomCollectionView.CustomSelectedItemProperty,
+ new Binding(nameof(Issue31351StartupPageModel.SelectedDisplayItem), BindingMode.TwoWay, source: _viewModel));
+ _customCollectionView.SetBinding(Issue31351CustomCollectionView.InvalidateCommandProperty,
+ new Binding(nameof(Issue31351StartupPageModel.InvalidateTreeviewCommand), BindingMode.OneWayToSource, source: _viewModel));
+
+
+ _customCollectionView.Scrolled += (sender, e) =>
+ {
+ statusLabel.Text = $"Scrolled: First={e.FirstVisibleItemIndex}, Center={e.CenterItemIndex}, Last={e.LastVisibleItemIndex}";
+ };
+
+
+ var layoutGrid = new Grid();
+ layoutGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
+ layoutGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
+ layoutGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
+ layoutGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
+ layoutGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
+
+ layoutGrid.Add(scrollButton, 0, 0);
+ layoutGrid.Add(scrollButton2, 0, 1);
+ layoutGrid.Add(statusLabel, 0, 2);
+ layoutGrid.Add(_customCollectionView, 0, 3);
+
+ Content = layoutGrid;
+ }
+
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+ _viewModel.OnAppearing.Execute(null);
+ }
+}
+
+internal class Issue31351StartupPageModel : INotifyPropertyChanged
+{
+ public class Issue31351DisplayItem : IIssue31351TreeviewItem
+ {
+ public string Title { get; set; }
+ }
+
+ public List DisplayItems { get; set; } = new();
+
+ Issue31351DisplayItem _displayItem;
+ public Issue31351DisplayItem SelectedDisplayItem
+ {
+ get { return _displayItem; }
+ set { _displayItem = value; OnPropertyChanged("SelectedDisplayItem"); }
+ }
+
+ public Action InvalidateTreeviewCommand { get; set; }
+
+ public class Issue31351DataItem
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ public List data = new();
+
+ public Issue31351StartupPageModel()
+ {
+ #region *// Generate test data
+ for (int i = 0; i < 100; i++)
+ {
+ data.Add(new Issue31351DataItem { Id = i, Name = $"Item {i}" });
+ }
+ #endregion
+ }
+ public event PropertyChangedEventHandler PropertyChanged;
+ public void OnPropertyChanged(string name)
+ {
+ if (this.PropertyChanged != null)
+ this.PropertyChanged(this, new PropertyChangedEventArgs(name));
+ }
+
+ public ICommand OnAppearing => new Command(() =>
+ {
+ DisplayItems.Clear();
+ foreach (var dataItem in data)
+ {
+ DisplayItems.Add(new Issue31351DisplayItem { Title = dataItem.Name });
+ }
+
+ SelectedDisplayItem = DisplayItems[5];
+ InvalidateTreeviewCommand?.Invoke();
+ });
+
+ public ICommand Scroll => new Command(() =>
+ {
+ SelectedDisplayItem = DisplayItems[50];
+ InvalidateTreeviewCommand?.Invoke();
+ });
+}
+
+public interface IIssue31351TreeviewItem
+{
+ string Title { get; set; }
+}
+
+internal class Issue31351CustomCollectionView : CollectionView where T : IIssue31351TreeviewItem
+{
+ #region *// Bindable properties
+
+ #region *// Item source
+ public static readonly BindableProperty CustomItemsSourceProperty = BindableProperty.Create(
+ nameof(CustomItemsSource),
+ typeof(List),
+ typeof(Issue31351CustomCollectionView),
+ null);
+
+ public List CustomItemsSource
+ {
+ get { return (List)GetValue(CustomItemsSourceProperty); }
+ set { SetValue(CustomItemsSourceProperty, value); }
+ }
+ #endregion
+
+ #region *// InvalidateCommand
+ public static BindableProperty InvalidateCommandProperty = BindableProperty.Create(
+ nameof(InvalidateCommand),
+ typeof(Action),
+ typeof(Issue31351CustomCollectionView),
+ null,
+ BindingMode.OneWayToSource);
+
+ public Action InvalidateCommand
+ {
+ get { return (Action)GetValue(InvalidateCommandProperty); }
+ set { SetValue(InvalidateCommandProperty, value); }
+ }
+ #endregion
+
+ #region *// Selected item
+ public static readonly BindableProperty CustomSelectedItemProperty = BindableProperty.Create(
+ nameof(CustomSelectedItem),
+ typeof(IIssue31351TreeviewItem),
+ typeof(Issue31351CustomCollectionView),
+ null);
+
+ public IIssue31351TreeviewItem CustomSelectedItem
+ {
+ get { return (IIssue31351TreeviewItem)GetValue(CustomSelectedItemProperty); }
+ set { SetValue(CustomSelectedItemProperty, value); }
+ }
+ #endregion
+
+ #endregion
+
+ public class Issue31351CollectionViewItem
+ {
+ public string Title { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ return false;
+ if (obj is not Issue31351CollectionViewItem)
+ return false;
+ return ((Issue31351CollectionViewItem)this).Title.Equals(((Issue31351CollectionViewItem)obj).Title, StringComparison.Ordinal);
+ }
+
+ public override int GetHashCode()
+ {
+ return Title?.GetHashCode(StringComparison.Ordinal) ?? 0;
+ }
+ }
+
+ List CollectionViewItems = new();
+
+ public Issue31351CustomCollectionView()
+ {
+ ItemTemplate = new DataTemplate(() =>
+ {
+ var label = new Label();
+ label.SetBinding(Label.TextProperty, nameof(Issue31351CollectionViewItem.Title));
+ label.Padding = new Thickness(10);
+ label.BackgroundColor = Colors.White;
+
+ var border = new Border
+ {
+ Content = label,
+ BackgroundColor = Colors.White,
+ Stroke = Colors.Gray,
+ StrokeThickness = 1,
+ Margin = new Thickness(2)
+ };
+
+ return border;
+ });
+
+ SelectionMode = SelectionMode.Single;
+
+ InvalidateCommand = new Action(() =>
+ {
+ Invalidate();
+ });
+ }
+
+ void Invalidate()
+ {
+ CollectionViewItems.Clear();
+
+ if (CustomItemsSource != null)
+ {
+ foreach (var itemSource in CustomItemsSource)
+ {
+ CollectionViewItems.Add(new Issue31351CollectionViewItem { Title = itemSource.Title });
+ }
+ }
+
+ ItemsSource = CollectionViewItems;
+ if (CustomSelectedItem != null)
+ {
+ var selectedCollectionViewItem = CollectionViewItems.FirstOrDefault(o => o.Title == CustomSelectedItem.Title);
+
+ ScrollTo(selectedCollectionViewItem, position: ScrollToPosition.Center, animate: true);
+ SelectedItem = selectedCollectionViewItem;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31375.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue31375.cs
new file mode 100644
index 000000000000..d813bc4c45d7
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31375.cs
@@ -0,0 +1,60 @@
+using System.Windows.Input;
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 31375, "[Windows] RefreshView Command executes multiple times when IsRefreshing is set to True", PlatformAffected.UWP)]
+public class Issue31375 : ContentPage
+{
+ bool _isLoading = false;
+ Label _textLabel;
+ int count = 0;
+
+ public bool IsLoading
+ {
+ get => _isLoading;
+ set
+ {
+ _isLoading = value;
+ OnPropertyChanged(nameof(IsLoading));
+ }
+ }
+
+ public ICommand RefreshCommand { get; set; }
+ public Issue31375()
+ {
+ // Create UI elements
+ var button = new Button { Text = "Click To Refresh", AutomationId = "RefreshButton" };
+ button.Clicked += Button_Clicked;
+
+ _textLabel = new Label() { AutomationId = "CounterLabel" };
+ _textLabel.Text = count++.ToString();
+
+ // Set BindingContext
+ BindingContext = this;
+
+ // Assign command
+ RefreshCommand = new Command(AddItems);
+ var refreshView = new RefreshView
+ {
+ Margin = 16,
+ Content = _textLabel,
+ };
+ refreshView.SetBinding(RefreshView.IsRefreshingProperty, nameof(IsLoading));
+ refreshView.SetBinding(RefreshView.CommandProperty, nameof(RefreshCommand));
+ Content = new StackLayout
+ {
+ Children = { refreshView, button }
+ };
+ }
+
+ void Button_Clicked(object sender, EventArgs e)
+ {
+ IsLoading = true;
+ }
+
+ void AddItems()
+ {
+ IsLoading = false;
+ _textLabel.Text = count++.ToString();
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31377.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue31377.xaml
new file mode 100644
index 000000000000..e27fb252d7ca
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31377.xaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31377.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue31377.xaml.cs
new file mode 100644
index 000000000000..85fa548f3a94
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31377.xaml.cs
@@ -0,0 +1,36 @@
+using System.Collections.ObjectModel;
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 31377, "TabbedPage overflow 'More' button does not work", PlatformAffected.iOS)]
+public partial class Issue31377 : TabbedPage
+{
+ public Issue31377()
+ {
+ InitializeComponent();
+ BindingContext = new TabbedPageViewModel();
+ }
+
+ public class TabbedPageViewModel
+ {
+ public ObservableCollection ItemsSource { get; } =
+ [
+ new TabbedPageItemSource { Name = "Tab 1", ImageUrl = "dotnet_bot.png" },
+ new TabbedPageItemSource { Name = "Tab 2", ImageUrl = "dotnet_bot.png" },
+ new TabbedPageItemSource { Name = "Tab 3", ImageUrl = "dotnet_bot.png" },
+ new TabbedPageItemSource { Name = "Tab 4", ImageUrl = "dotnet_bot.png" },
+ new TabbedPageItemSource { Name = "Tab 5", ImageUrl = "dotnet_bot.png" },
+ new TabbedPageItemSource { Name = "Tab 6", ImageUrl = "dotnet_bot.png" },
+ new TabbedPageItemSource { Name = "Tab 7", ImageUrl = "dotnet_bot.png" },
+ new TabbedPageItemSource { Name = "Tab 8", ImageUrl = "dotnet_bot.png" },
+ new TabbedPageItemSource { Name = "Tab 9", ImageUrl = "dotnet_bot.png" },
+ new TabbedPageItemSource { Name = "Tab 10", ImageUrl = "dotnet_bot.png" }
+ ];
+ }
+
+ public class TabbedPageItemSource
+ {
+ public string Name { get; set; }
+ public string ImageUrl { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31390.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue31390.cs
new file mode 100644
index 000000000000..8909f0646361
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31390.cs
@@ -0,0 +1,144 @@
+using System.ComponentModel;
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 31390, "System.ArgumentException thrown when setting FlyoutLayoutBehavior dynamically", PlatformAffected.UWP)]
+public class Issue31390 : NavigationPage
+{
+ private Issue31390ViewModel _viewModel;
+ public Issue31390()
+ {
+ _viewModel = new Issue31390ViewModel();
+ PushAsync(new Issue31390FlyoutPage(_viewModel));
+ }
+}
+
+public partial class Issue31390FlyoutPage : FlyoutPage
+{
+ Issue31390ViewModel _viewModel;
+ public Issue31390FlyoutPage(Issue31390ViewModel _viewModel)
+ {
+ _viewModel = new Issue31390ViewModel();
+ BindingContext = _viewModel;
+
+ var flyoutPage = new ContentPage
+ {
+ Title = "Flyout",
+ Content = new StackLayout
+ {
+ Children =
+ {
+ new Label
+ {
+ Text = "This is Flyout",
+ AutomationId = "Issue31390_FlyoutLabel"
+ }
+ }
+ }
+ };
+
+ var detailPage = new ContentPage
+ {
+ Content = new StackLayout
+ {
+ Padding = 16,
+ Spacing = 16,
+ Children =
+ {
+ new Label { Text = "This is Detail Page" }
+ }
+ }
+ };
+
+ var navigationPage = new NavigationPage(detailPage)
+ {
+ Title = "Detail"
+ };
+
+ Flyout = flyoutPage;
+ Detail = navigationPage;
+
+ var ChangeToPopover = new ToolbarItem
+ {
+ Text = "GoToNextPage",
+ AutomationId = "GoToNextPage"
+ };
+ ChangeToPopover.Clicked += NavigateToPopover_Clicked;
+
+ ToolbarItems.Add(ChangeToPopover);
+
+ SetBinding(FlyoutLayoutBehaviorProperty, new Binding(nameof(Issue31390ViewModel.FlyoutLayoutBehavior)));
+ }
+
+ private async void NavigateToPopover_Clicked(object sender, EventArgs e)
+ {
+ BindingContext = _viewModel = new Issue31390ViewModel();
+ await Navigation.PushAsync(new Issue31390SecondPage(_viewModel));
+ }
+}
+
+public class Issue31390SecondPage : ContentPage
+{
+ private readonly Issue31390ViewModel _viewModel;
+
+ public Issue31390SecondPage(Issue31390ViewModel viewModel)
+ {
+ _viewModel = viewModel;
+ BindingContext = _viewModel;
+ ToolbarItems.Add(new ToolbarItem
+ {
+ Text = "Apply",
+ AutomationId = "Apply",
+ Command = new Command(() =>
+ {
+ Navigation.PopAsync();
+ })
+ });
+ var ChangeToPopoverButton = new Button
+ {
+ Text = "Change to Popover",
+ AutomationId = "ChangeToPopover"
+ };
+ ChangeToPopoverButton.Clicked += ChangeToPopoverButton_Clicked;
+
+ Content = new StackLayout
+ {
+ Padding = 16,
+ Children =
+ {
+ ChangeToPopoverButton
+ }
+ };
+ }
+
+ private void ChangeToPopoverButton_Clicked(object sender, EventArgs e)
+ {
+ if (sender is Button button && BindingContext is Issue31390ViewModel vm)
+ {
+
+ vm.FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
+
+ }
+ }
+}
+
+public class Issue31390ViewModel : INotifyPropertyChanged
+{
+ private FlyoutLayoutBehavior _flyoutLayoutBehavior = FlyoutLayoutBehavior.Default;
+ public FlyoutLayoutBehavior FlyoutLayoutBehavior
+ {
+ get => _flyoutLayoutBehavior;
+ set
+ {
+ if (_flyoutLayoutBehavior != value)
+ {
+ _flyoutLayoutBehavior = value;
+ OnPropertyChanged(nameof(FlyoutLayoutBehavior));
+ }
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ protected void OnPropertyChanged(string propertyName) =>
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31520.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue31520.cs
new file mode 100644
index 000000000000..12a1cb73d86e
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31520.cs
@@ -0,0 +1,123 @@
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 31520, "NavigatingFrom is triggered first when using PushAsync", PlatformAffected.Android)]
+public class Issue31520 : NavigationPage
+{
+ public static int count = 0;
+ public static Label statusLabel;
+ public static Issue31520Page2 currentPage2;
+
+ public Issue31520() : base(new Issue31520Page1())
+ {
+
+ }
+}
+
+public class Issue31520Page1 : ContentPage
+{
+ public Issue31520Page1()
+ {
+ SetupPageContent();
+
+ Disappearing += (s, e) =>
+ {
+ Issue31520.count++;
+ };
+
+ NavigatingFrom += (s, e) =>
+ {
+ if (Issue31520.statusLabel is not null)
+ {
+ Issue31520.statusLabel.Text = (Issue31520.count == 0)
+ ? "NavigatingFrom triggered before Disappearing"
+ : "NavigatingFrom triggered after Disappearing";
+
+ Issue31520.currentPage2?.UpdateNavigatingStatusLabel();
+ }
+ };
+ }
+
+ private void SetupPageContent()
+ {
+ Title = "Page 1";
+
+ Issue31520.statusLabel = new Label
+ {
+ Text = "Ready",
+ AutomationId = "statusLabel"
+ };
+
+ var button = new Button
+ {
+ Text = "Push",
+ AutomationId = "PushButton"
+ };
+ button.Clicked += OnCounterClicked;
+
+ Content = new VerticalStackLayout
+ {
+ Padding = new Thickness(30, 0),
+ Spacing = 25,
+ Children =
+ {
+ Issue31520.statusLabel,
+ button
+ }
+ };
+ }
+
+ private void OnCounterClicked(object sender, EventArgs e)
+ {
+ Navigation.PushAsync(new Issue31520Page2());
+ }
+}
+
+public class Issue31520Page2 : ContentPage
+{
+ private Label navigatingStatusLabel;
+
+ public Issue31520Page2()
+ {
+ Issue31520.currentPage2 = this;
+
+ Appearing += (s, e) =>
+ {
+ Issue31520.count++;
+ };
+
+ Title = "Page 2";
+
+ var button = new Button
+ {
+ Text = "Pop",
+ AutomationId = "ChildPageButton"
+ };
+ button.Clicked += OnButtonClicked;
+
+ navigatingStatusLabel = new Label
+ {
+ Text = Issue31520.statusLabel?.Text ?? "Ready",
+ AutomationId = "NavigatingStatusLabel"
+ };
+
+ Content = new StackLayout
+ {
+ Children =
+ {
+ navigatingStatusLabel,
+ button
+ }
+ };
+ }
+
+ public void UpdateNavigatingStatusLabel()
+ {
+ if (navigatingStatusLabel is not null && Issue31520.statusLabel is not null)
+ navigatingStatusLabel.Text = Issue31520.statusLabel.Text;
+ }
+
+ private void OnButtonClicked(object sender, EventArgs e)
+ {
+ Navigation.PopAsync();
+ }
+}
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31535.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue31535.cs
new file mode 100644
index 000000000000..f97bff2767e5
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31535.cs
@@ -0,0 +1,131 @@
+using System.Collections.ObjectModel;
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 31535, "[iOS] Crash occurred on CarouselView2 when deleting last one remaining item with loop as false", PlatformAffected.iOS)]
+public class Issue31535 : ContentPage
+{
+ ObservableCollection _items = new();
+ public ObservableCollection Items
+ {
+ get => _items;
+ set
+ {
+ _items = value;
+ OnPropertyChanged();
+ }
+ }
+ public Issue31535()
+ {
+ // Start with empty collection to test all scenarios
+ Items = new ObservableCollection();
+
+ // Create CarouselView
+ var carousel = new CarouselView2
+ {
+ Loop = false,
+ HeightRequest = 200,
+ ItemsSource = Items,
+ AutomationId = "TestCarouselView",
+ ItemTemplate = new DataTemplate(() =>
+ {
+ var border = new Border
+ {
+ Margin = 10,
+ WidthRequest = 200,
+ BackgroundColor = Colors.Red
+ };
+
+ var label = new Label();
+ label.SetBinding(Label.TextProperty, ".");
+
+ border.Content = label;
+ return border;
+ })
+ };
+
+ // Create Buttons for testing different scenarios
+ var addSingleItemButton = new Button
+ {
+ AutomationId = "AddSingleItemButton",
+ Text = "Add Single Item"
+ };
+
+ var removeSingleItemButton = new Button
+ {
+ AutomationId = "RemoveSingleItemButton",
+ Text = "Remove Single Item"
+ };
+
+ var addMultipleItemsButton = new Button
+ {
+ AutomationId = "AddMultipleItemsButton",
+ Text = "Add Multiple Items"
+ };
+
+ var removeAllItemsButton = new Button
+ {
+ AutomationId = "RemoveAllItemsButton",
+ Text = "Remove All Items"
+ };
+
+ var itemCountLabel = new Label
+ {
+ Text = $"Items Count: {Items.Count}",
+ HorizontalOptions = LayoutOptions.Center
+ };
+
+ // Event handlers
+ addSingleItemButton.Clicked += (s, e) =>
+ {
+ Items.Add($"Item {Items.Count + 1}");
+ itemCountLabel.Text = $"Items Count: {Items.Count}";
+ };
+
+ removeSingleItemButton.Clicked += (s, e) =>
+ {
+ if (Items.Count > 0)
+ {
+ Items.RemoveAt(Items.Count - 1);
+ itemCountLabel.Text = $"Items Count: {Items.Count}";
+ }
+ };
+
+ addMultipleItemsButton.Clicked += (s, e) =>
+ {
+ var currentCount = Items.Count;
+ Items.Add($"Item {currentCount + 1}");
+ Items.Add($"Item {currentCount + 2}");
+ Items.Add($"Item {currentCount + 3}");
+ itemCountLabel.Text = $"Items Count: {Items.Count}";
+ };
+
+ removeAllItemsButton.Clicked += (s, e) =>
+ {
+ Items.Clear();
+ itemCountLabel.Text = $"Items Count: {Items.Count}";
+ };
+
+ Content = new VerticalStackLayout
+ {
+ Spacing = 10,
+ Padding = 20,
+ Children =
+ {
+ new Label
+ {
+ Text = "CarouselView2 Loop=false Test",
+ FontSize = 18,
+ HorizontalOptions = LayoutOptions.Center
+ },
+ itemCountLabel,
+ carousel,
+ addSingleItemButton,
+ removeSingleItemButton,
+ addMultipleItemsButton,
+ removeAllItemsButton
+ }
+ };
+ BindingContext = this;
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31539.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue31539.cs
new file mode 100644
index 000000000000..e71984344b10
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31539.cs
@@ -0,0 +1,70 @@
+using System.Collections.ObjectModel;
+
+namespace Maui.Controls.Sample.Issues;
+
+[Issue(IssueTracker.Github, 31539, "[iOS, macOS] Navigation Page BackButtonTitle Not Updating", PlatformAffected.iOS | PlatformAffected.macOS)]
+
+public class Issue31539 : TestNavigationPage
+{
+ protected override void Init()
+ {
+ Navigation.PushAsync(new Issue31539ContentPage());
+ }
+}
+
+public class Issue31539ContentPage : ContentPage
+{
+ public Issue31539ContentPage()
+ {
+ var layout = new VerticalStackLayout
+ {
+ Padding = 20,
+ Spacing = 12
+ };
+
+ var pushButton = new Button
+ {
+ Text = "Push Second Page",
+ AutomationId = "PushSecondPage"
+ };
+ pushButton.Clicked += OnPushSecondPage;
+
+ var backTitleButton = new Button
+ {
+ Text = "Set BackButtonTitle = 'Back Home'",
+ AutomationId = "SetBackButtonTitle"
+ };
+ backTitleButton.Clicked += OnSetBackButtonTitle;
+
+ layout.Children.Add(pushButton);
+ layout.Children.Add(backTitleButton);
+
+ Content = layout;
+ }
+
+ void OnPushSecondPage(object sender, EventArgs e)
+ {
+ Navigation.PushAsync(new Issue31539SecondContentPage());
+ }
+
+ void OnSetBackButtonTitle(object sender, EventArgs e)
+ {
+ NavigationPage.SetBackButtonTitle(this, "Back Home");
+ }
+}
+
+public class Issue31539SecondContentPage : ContentPage
+{
+ public Issue31539SecondContentPage()
+ {
+ Content = new StackLayout
+ {
+ Padding = 20,
+ Spacing = 12,
+ Children =
+ {
+ new Label { Text = "This is the second page.", AutomationId = "SecondPageLabel" }
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31606.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue31606.xaml
new file mode 100644
index 000000000000..b5aac6c0936b
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31606.xaml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue31606.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue31606.xaml.cs
new file mode 100644
index 000000000000..deeab279448a
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue31606.xaml.cs
@@ -0,0 +1,19 @@
+namespace Maui.Controls.Sample.Issues
+{
+ [Issue(IssueTracker.Github, 31606, "Crash on Windows when SemanticProperties.Description is set for ToolbarItem", PlatformAffected.UWP)]
+ public partial class Issue31606 : NavigationPage
+ {
+ public Issue31606()
+ {
+ Navigation.PushAsync(new Issue31606MainPage());
+ }
+ }
+
+ public partial class Issue31606MainPage : ContentPage
+ {
+ public Issue31606MainPage()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue7045.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue7045.xaml
new file mode 100644
index 000000000000..46ab4816aed1
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue7045.xaml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue7045.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue7045.xaml.cs
new file mode 100644
index 000000000000..3ca7fb8a2712
--- /dev/null
+++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue7045.xaml.cs
@@ -0,0 +1,15 @@
+namespace Maui.Controls.Sample.Issues;
+
+[XamlCompilation(XamlCompilationOptions.Compile)]
+[Issue(IssueTracker.Github, 7045, "Shell BackButtonBehavior binding Command to valid ICommand causes back button to disappear", PlatformAffected.All)]
+public partial class Issue7045 : Shell
+{
+ public Command BackCommand { get; }
+
+ public Issue7045()
+ {
+ InitializeComponent();
+ NavigateButton.Clicked += async (s, e) => await Current.GoToAsync($"//DetialPage"); ;
+ DetailPage.BindingContext = this;
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BackButtonHidden.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BackButtonHidden.png
new file mode 100644
index 000000000000..ec455fcb66c4
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BackButtonHidden.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BackButtonVisible.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BackButtonVisible.png
new file mode 100644
index 000000000000..828aae8669d8
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BackButtonVisible.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgBlue.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgBlue.png
new file mode 100644
index 000000000000..aa143af4ee04
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgBlue.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgLinear.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgLinear.png
new file mode 100644
index 000000000000..d2ecc6037392
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgLinear.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgRadial.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgRadial.png
new file mode 100644
index 000000000000..a7180eaf59f5
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgRadial.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgRed.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgRed.png
new file mode 100644
index 000000000000..2accfc6e0729
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarBgRed.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarTextBlack.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarTextBlack.png
new file mode 100644
index 000000000000..bb9bb1dd6c45
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarTextBlack.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarTextWhite.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarTextWhite.png
new file mode 100644
index 000000000000..80e827560331
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/BarTextWhite.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_PaddingWithContent_Label.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_PaddingWithContent_Label.png
new file mode 100644
index 000000000000..5dfbd3ca7b16
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_PaddingWithContent_Label.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_Shadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_Shadow.png
new file mode 100644
index 000000000000..7fa0bddb3e1a
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithDashArrayAndOffset.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithDashArrayAndOffset.png
new file mode 100644
index 000000000000..d91edfae08a7
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithDashArrayAndOffset.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithPaddingAndContent_Image.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithPaddingAndContent_Image.png
new file mode 100644
index 000000000000..775ba81232a9
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithPaddingAndContent_Image.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithStrokeShape_RoundRectangle.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithStrokeShape_RoundRectangle.png
new file mode 100644
index 000000000000..839fafe66175
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithStrokeShape_RoundRectangle.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithStrokeThickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithStrokeThickness.png
new file mode 100644
index 000000000000..ec2020ddd2a2
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeColorWithStrokeThickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeShapeWithStrokeThickness_Ellipse.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeShapeWithStrokeThickness_Ellipse.png
new file mode 100644
index 000000000000..3c2a884968b4
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Border_StrokeShapeWithStrokeThickness_Ellipse.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Combine_BarBackgroundColor_TextColor_IconColor_Visual.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Combine_BarBackgroundColor_TextColor_IconColor_Visual.png
new file mode 100644
index 000000000000..d68891d612a6
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Combine_BarBackgroundColor_TextColor_IconColor_Visual.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Background_WithRTL.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Background_WithRTL.png
new file mode 100644
index 000000000000..d8d7aa31b9d9
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Background_WithRTL.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_IsVisible_WithTitle.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_IsVisible_WithTitle.png
new file mode 100644
index 000000000000..b33c09789f39
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_IsVisible_WithTitle.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_IsVisible_WithoutTitle.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_IsVisible_WithoutTitle.png
new file mode 100644
index 000000000000..86107c0ac707
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_IsVisible_WithoutTitle.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Padding_WithBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Padding_WithBackgroundColor.png
new file mode 100644
index 000000000000..b36d241ac3ce
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Padding_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Padding_WithRTL.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Padding_WithRTL.png
new file mode 100644
index 000000000000..db5aafea375d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Padding_WithRTL.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Padding_WithTitle.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Padding_WithTitle.png
new file mode 100644
index 000000000000..2884432c3562
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Padding_WithTitle.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Title_WithBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Title_WithBackgroundColor.png
new file mode 100644
index 000000000000..6dbc46bf3605
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Title_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Title_WithBackgroundColorAndPadding.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Title_WithBackgroundColorAndPadding.png
new file mode 100644
index 000000000000..7f7e776e8a82
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_Title_WithBackgroundColorAndPadding.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_zContent.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_zContent.png
new file mode 100644
index 000000000000..4876cfb49ff3
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ContentPage_zContent.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithBackgroundColor.png
new file mode 100644
index 000000000000..b459c6ad6438
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithFlowDirection.png
new file mode 100644
index 000000000000..93d9716c9e58
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithHeightRequest.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithHeightRequest.png
new file mode 100644
index 000000000000..be8d76d29e7c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithHeightRequest.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithShadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithShadow.png
new file mode 100644
index 000000000000..f7321601b827
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithShadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithWidthRequest.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithWidthRequest.png
new file mode 100644
index 000000000000..2b352720260d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DefaultContentWithWidthRequest.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DownSizeImageAppearProperly.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DownSizeImageAppearProperly.png
new file mode 100644
index 000000000000..9077225a21a8
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/DownSizeImageAppearProperly.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..10fd2e63de69
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..38d6f471073a
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..a40bab3e55b0
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..43dc663d10fe
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Ellipse_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/EntryClearButtonColorShouldUpdateOnThemeChange.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/EntryClearButtonColorShouldUpdateOnThemeChange.png
new file mode 100644
index 000000000000..71fc61267c24
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/EntryClearButtonColorShouldUpdateOnThemeChange.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithBackgroundColor.png
new file mode 100644
index 000000000000..b0c87ae6110c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithCardColorChanged.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithCardColorChanged.png
new file mode 100644
index 000000000000..5f71890f2dd1
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithCardColorChanged.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithFlowDirection.png
new file mode 100644
index 000000000000..30ca98f1d4cd
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithIconImageChanged.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithIconImageChanged.png
new file mode 100644
index 000000000000..11089e46e599
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/FirstCustomPageWithIconImageChanged.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection.png
new file mode 100644
index 000000000000..64155c652d2e
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection_With_Height.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection_With_Height.png
new file mode 100644
index 000000000000..df325cce9e3b
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection_With_HeightAndWidth.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection_With_HeightAndWidth.png
new file mode 100644
index 000000000000..ecf7f9f1413d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection_With_Width.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection_With_Width.png
new file mode 100644
index 000000000000..0a27da73c1dc
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_RTLFlowDirection_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_Height.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_Height.png
new file mode 100644
index 000000000000..10d3718f1366
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_HeightAndWidth.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_HeightAndWidth.png
new file mode 100644
index 000000000000..52f39fec60d0
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_RTL.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_RTL.png
new file mode 100644
index 000000000000..774e360faad7
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_RTL.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_Width.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_Width.png
new file mode 100644
index 000000000000..6f7001830f4d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/HorizontalStackLayout_Spacing_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/IconColorDefault.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/IconColorDefault.png
new file mode 100644
index 000000000000..853d8d0e57e0
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/IconColorDefault.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/IconColorRed.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/IconColorRed.png
new file mode 100644
index 000000000000..e754a3a09028
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/IconColorRed.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Issue23834FlyoutMisbehavior.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Issue23834FlyoutMisbehavior.png
new file mode 100644
index 000000000000..ddb55e9a6862
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Issue23834FlyoutMisbehavior.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..bd4b7999a938
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..63df5f6c2b01
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..4e296cbb634e
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..e4540bb12c7c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Line_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/LinearGradientBrushShouldWork.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/LinearGradientBrushShouldWork.png
new file mode 100644
index 000000000000..87637093bdae
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/LinearGradientBrushShouldWork.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/NavBarHidden.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/NavBarHidden.png
new file mode 100644
index 000000000000..9cd32f1ab308
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/NavBarHidden.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/NavBarVisible.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/NavBarVisible.png
new file mode 100644
index 000000000000..4a4fbb3bc4e9
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/NavBarVisible.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..a44457b039bc
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..8f66fe98668c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_Points_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_Points_Thickness.png
new file mode 100644
index 000000000000..9b50d9dcfe87
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_Points_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..273ad71e7fce
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..5b879d92f789
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Path_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetCharacterSpacing_VerifyCharacterSpacingLabel.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetCharacterSpacing_VerifyCharacterSpacingLabel.png
new file mode 100644
index 000000000000..1cf223e849e1
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetCharacterSpacing_VerifyCharacterSpacingLabel.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFlowDirectionRTL_VerifyFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFlowDirectionRTL_VerifyFlowDirection.png
new file mode 100644
index 000000000000..c0a622c6ec94
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFlowDirectionRTL_VerifyFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily.png
new file mode 100644
index 000000000000..f09c82033cf9
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes.png
new file mode 100644
index 000000000000..45f89a14f760
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily.png
new file mode 100644
index 000000000000..c9cc6acaa170
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem.png
new file mode 100644
index 000000000000..5eb2c14b7bb2
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetIsEnabledFalse_VerifyPickerDisabled.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetIsEnabledFalse_VerifyPickerDisabled.png
new file mode 100644
index 000000000000..9909c85a350e
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetIsEnabledFalse_VerifyPickerDisabled.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetSelectedIndex_VerifySelectedIndexAndItem.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetSelectedIndex_VerifySelectedIndexAndItem.png
new file mode 100644
index 000000000000..2da5a44dadbf
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetSelectedIndex_VerifySelectedIndexAndItem.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetSelectedItem_VerifySelectedItemLabel.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetSelectedItem_VerifySelectedItemLabel.png
new file mode 100644
index 000000000000..104e38219e7c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetSelectedItem_VerifySelectedItemLabel.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetShadow_VerifyShadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetShadow_VerifyShadow.png
new file mode 100644
index 000000000000..9334a8e5c42f
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetShadow_VerifyShadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetTextColorRed_VerifyTextColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetTextColorRed_VerifyTextColor.png
new file mode 100644
index 000000000000..bb9a0398983c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetTextColorRed_VerifyTextColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem.png
new file mode 100644
index 000000000000..2f5d38e5713e
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_Validate_VerifyLabels.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_Validate_VerifyLabels.png
new file mode 100644
index 000000000000..8d5855ec78ca
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Picker_Validate_VerifyLabels.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PlaceholderColorShouldChange.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PlaceholderColorShouldChange.png
index 9cf1fcba3ccf..117589ea4104 100644
Binary files a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PlaceholderColorShouldChange.png and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PlaceholderColorShouldChange.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..1b1c7bccc4dd
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..34b7b4111e05
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_Points_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_Points_Thickness.png
new file mode 100644
index 000000000000..b84313c2e345
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_Points_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..44686cb232ce
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..5d8201998d1b
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/PolyLine_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..de44bb3d8a77
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..3c8713b4a7f7
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..866703ea7372
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..ba034bc35e44
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Polygon_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..b08e901a28e0
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..f23b715784cd
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..62b33e926351
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..6e7eb6102e22
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Rectangle_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/RefreshView_SetShadowWithCollectionView_VerifyShadowApplied.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/RefreshView_SetShadowWithCollectionView_VerifyShadowApplied.png
new file mode 100644
index 000000000000..d24fb1ce6bc2
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/RefreshView_SetShadowWithCollectionView_VerifyShadowApplied.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/RefreshView_SetShadow_VerifyShadowApplied.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/RefreshView_SetShadow_VerifyShadowApplied.png
new file mode 100644
index 000000000000..eb91b9376ed0
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/RefreshView_SetShadow_VerifyShadowApplied.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SearchbarColorsShouldUpdate.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SearchbarColorsShouldUpdate.png
new file mode 100644
index 000000000000..f4ef9c4f7943
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SearchbarColorsShouldUpdate.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SecondCustomPageWithBackgroundColorChanged.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SecondCustomPageWithBackgroundColorChanged.png
new file mode 100644
index 000000000000..416c9905d606
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SecondCustomPageWithBackgroundColorChanged.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SecondCustomPageWithFlowDirectionChanged.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SecondCustomPageWithFlowDirectionChanged.png
new file mode 100644
index 000000000000..969ae6e775cb
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SecondCustomPageWithFlowDirectionChanged.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Shape_Polygon_Pentagon.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Shape_Polygon_Pentagon.png
new file mode 100644
index 000000000000..0df26f8b4636
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Shape_Polygon_Pentagon.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Shape_Rectangle_HeightAndWidth.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Shape_Rectangle_HeightAndWidth.png
new file mode 100644
index 000000000000..0e728c4b4457
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Shape_Rectangle_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Shape_Rectangle_XAndYRadius.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Shape_Rectangle_XAndYRadius.png
new file mode 100644
index 000000000000..83690aafbade
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/Shape_Rectangle_XAndYRadius.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ShellBackButtonBehaviorShouldWork.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ShellBackButtonBehaviorShouldWork.png
new file mode 100644
index 000000000000..34c69d10d83d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ShellBackButtonBehaviorShouldWork.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_BackgroundColor_WithGrid.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_BackgroundColor_WithGrid.png
new file mode 100644
index 000000000000..bb289058ff6e
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_BackgroundColor_WithGrid.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_ForegroundColor_WithBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_ForegroundColor_WithBackgroundColor.png
new file mode 100644
index 000000000000..99f286b59033
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_ForegroundColor_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_ForegroundColor_WithGrid.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_ForegroundColor_WithGrid.png
new file mode 100644
index 000000000000..deae85bef404
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_ForegroundColor_WithGrid.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithBackgroundColor.png
new file mode 100644
index 000000000000..e56847cc7cc2
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithForegroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithForegroundColor.png
new file mode 100644
index 000000000000..46acfb916ae5
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithForegroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithSearchBar.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithSearchBar.png
new file mode 100644
index 000000000000..5b3998fed2a7
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithSearchBar.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithTrailingContentAndLeadingContent.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithTrailingContentAndLeadingContent.png
new file mode 100644
index 000000000000..299cd27bd821
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Icon_WithTrailingContentAndLeadingContent.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_IsVisible.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_IsVisible.png
new file mode 100644
index 000000000000..1cc137175d7b
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_Entry.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_Entry.png
new file mode 100644
index 000000000000..601b3f88bc5a
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_Entry.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithBackgroundColor.png
new file mode 100644
index 000000000000..b1f58c210f54
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithGrid.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithGrid.png
new file mode 100644
index 000000000000..bf241aa2e869
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithGrid.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithHorizontalStackLayout.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithHorizontalStackLayout.png
new file mode 100644
index 000000000000..af2d5c88b18b
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithHorizontalStackLayout.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithSearchBar.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithSearchBar.png
new file mode 100644
index 000000000000..1b386650afaf
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TitleAndSubTitle_WithSearchBar.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithBackgroundColor.png
new file mode 100644
index 000000000000..1e700ad3fc7b
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithGrid.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithGrid.png
new file mode 100644
index 000000000000..0b5252ee7c69
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithGrid.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithHorizontalStackLayout.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithHorizontalStackLayout.png
new file mode 100644
index 000000000000..0d5c76204b28
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithHorizontalStackLayout.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithSearchBar.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithSearchBar.png
new file mode 100644
index 000000000000..1cbc40180e2a
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithSearchBar.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithTitleAndSubtitle.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithTitleAndSubtitle.png
new file mode 100644
index 000000000000..2be79d32887f
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_TrailingContentAndLeadingContent_WithTitleAndSubtitle.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Window.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Window.png
new file mode 100644
index 000000000000..2cd446e83a5a
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleBar_Window.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleIcon_Add_Visual.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleIcon_Add_Visual.png
new file mode 100644
index 000000000000..5a8e0325eb74
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleIcon_Add_Visual.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleIcon_AddingTwice_DoesNotDuplicate.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleIcon_AddingTwice_DoesNotDuplicate.png
new file mode 100644
index 000000000000..0c73144c944d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleIcon_AddingTwice_DoesNotDuplicate.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleIcon_And_TitleView_Persist_On_Push_Then_Clear.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleIcon_And_TitleView_Persist_On_Push_Then_Clear.png
new file mode 100644
index 000000000000..3c3b26edfb50
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleIcon_And_TitleView_Persist_On_Push_Then_Clear.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleViewApplied.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleViewApplied.png
new file mode 100644
index 000000000000..322e062cc068
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleViewApplied.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleViewCleared.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleViewCleared.png
new file mode 100644
index 000000000000..0532981eeb6c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TitleViewCleared.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_IsVisible.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_IsVisible.png
new file mode 100644
index 000000000000..cabfd872faf1
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane1Priority.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane1Priority.png
new file mode 100644
index 000000000000..7b29b26dba45
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane1Priority.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane1SizeIncrease.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane1SizeIncrease.png
new file mode 100644
index 000000000000..27427de67f60
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane1SizeIncrease.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane1SizeIncrease_WithTallMode.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane1SizeIncrease_WithTallMode.png
new file mode 100644
index 000000000000..23559a24e1de
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane1SizeIncrease_WithTallMode.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane2Priority.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane2Priority.png
new file mode 100644
index 000000000000..7b45adf20c50
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane2Priority.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane2SizeIncrease.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane2SizeIncrease.png
new file mode 100644
index 000000000000..762a78494e4d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane2SizeIncrease.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane2SizeIncrease_WithTallMode.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane2SizeIncrease_WithTallMode.png
new file mode 100644
index 000000000000..64c8e2e7206e
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_Pane2SizeIncrease_WithTallMode.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_RTLFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_RTLFlowDirection.png
new file mode 100644
index 000000000000..f7eea7618b51
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_RTLFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_TallMode.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_TallMode.png
new file mode 100644
index 000000000000..49c62f6c8d00
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_TallMode.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_WideMode.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_WideMode.png
new file mode 100644
index 000000000000..e2fe688b8aa5
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_WideMode.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_ZIsShadowEnabled.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_ZIsShadowEnabled.png
new file mode 100644
index 000000000000..32459571a1b8
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/TwoPaneView_ZIsShadowEnabled.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_AllProportional.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_AllProportional.png
new file mode 100644
index 000000000000..db4bf25d5c7c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_AllProportional.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_FlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_FlowDirection.png
new file mode 100644
index 000000000000..8cdfa605a681
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_FlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_HeightProportional.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_HeightProportional.png
new file mode 100644
index 000000000000..685c3f81caee
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_HeightProportional.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_LayoutBounds.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_LayoutBounds.png
new file mode 100644
index 000000000000..04a9eda27df3
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_LayoutBounds.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_PositionProportional.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_PositionProportional.png
new file mode 100644
index 000000000000..da9c452f86a3
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_PositionProportional.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_SizeProportional.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_SizeProportional.png
new file mode 100644
index 000000000000..90ef030cd2bb
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_SizeProportional.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_SizeProportionalAndPositionProportional.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_SizeProportionalAndPositionProportional.png
new file mode 100644
index 000000000000..053841f3a6ee
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_SizeProportionalAndPositionProportional.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_SizeProportionalWithMaximumValue.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_SizeProportionalWithMaximumValue.png
new file mode 100644
index 000000000000..586f3ef31eea
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_SizeProportionalWithMaximumValue.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_Visibility.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_Visibility.png
new file mode 100644
index 000000000000..ddf7a51783c4
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_Visibility.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_WidthAndHeight.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_WidthAndHeight.png
new file mode 100644
index 000000000000..8912cf473d30
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_WidthAndHeight.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_WidthProportional.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_WidthProportional.png
new file mode 100644
index 000000000000..c71809fb6b5d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_WidthProportional.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_WidthProportionalAndHeightProportional.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_WidthProportionalAndHeightProportional.png
new file mode 100644
index 000000000000..25771600b740
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_WidthProportionalAndHeightProportional.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_XProportional.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_XProportional.png
new file mode 100644
index 000000000000..cc973d8675a7
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_XProportional.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_XProportionalAndYProportional.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_XProportionalAndYProportional.png
new file mode 100644
index 000000000000..33600b8e0ba5
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_XProportionalAndYProportional.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_YProportional.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_YProportional.png
new file mode 100644
index 000000000000..33fbea7c7302
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyAbsoluteLayout_YProportional.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyBackButtonTitleUpdates.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyBackButtonTitleUpdates.png
new file mode 100644
index 000000000000..80f4d69acdc3
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyBackButtonTitleUpdates.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyClearVisiblityButtonWhenTextColorChanged.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyClearVisiblityButtonWhenTextColorChanged.png
index caf5c55a16ae..f8cdcd5b0189 100644
Binary files a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyClearVisiblityButtonWhenTextColorChanged.png and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyClearVisiblityButtonWhenTextColorChanged.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyCollectionViewContentWithButtonSwipeItem.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyCollectionViewContentWithButtonSwipeItem.png
new file mode 100644
index 000000000000..3a193bfa5a5b
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyCollectionViewContentWithButtonSwipeItem.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyCollectionViewContentWithIconImageSwipeItem.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyCollectionViewContentWithIconImageSwipeItem.png
new file mode 100644
index 000000000000..4db4e44228b2
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyCollectionViewContentWithIconImageSwipeItem.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyCollectionViewContentWithLabelSwipeItem.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyCollectionViewContentWithLabelSwipeItem.png
new file mode 100644
index 000000000000..bca4f785e277
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyCollectionViewContentWithLabelSwipeItem.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyDataTemplateParentIsNotNull.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyDataTemplateParentIsNotNull.png
new file mode 100644
index 000000000000..bc10361e4f3d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyDataTemplateParentIsNotNull.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_BackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_BackgroundColor.png
new file mode 100644
index 000000000000..5f5a2672df99
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_BackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_DetailPageIconImageSource.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_DetailPageIconImageSource.png
new file mode 100644
index 000000000000..fd2e2a7988c0
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_DetailPageIconImageSource.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_DetailPageIconImageSource_FlyoutLayoutBehavior.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_DetailPageIconImageSource_FlyoutLayoutBehavior.png
new file mode 100644
index 000000000000..149372a7a4d8
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_DetailPageIconImageSource_FlyoutLayoutBehavior.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_FlyoutLayoutBehaviorPopover.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_FlyoutLayoutBehaviorPopover.png
new file mode 100644
index 000000000000..545befba6617
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_FlyoutLayoutBehaviorPopover.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_IsEnabled.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_IsEnabled.png
new file mode 100644
index 000000000000..0adba97a37e8
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_IsEnabled.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_IsVisible.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_IsVisible.png
new file mode 100644
index 000000000000..b4d2d1ecf3ac
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_Title.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_Title.png
new file mode 100644
index 000000000000..e1f37bdcd724
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyFlyoutPage_Title.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColor.png
new file mode 100644
index 000000000000..e5b1faa613cb
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColorWhenItemsAdded.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColorWhenItemsAdded.png
new file mode 100644
index 000000000000..5b1cd4601165
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColorWhenItemsAdded.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColorWithFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColorWithFlowDirection.png
new file mode 100644
index 000000000000..4baa73bc1cdf
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColorWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColorWithIndicatorSize.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColorWithIndicatorSize.png
new file mode 100644
index 000000000000..725a41b5810d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorColorWithIndicatorSize.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorHideSingleIsFalse.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorHideSingleIsFalse.png
new file mode 100644
index 000000000000..6384eb02f1ef
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorHideSingleIsFalse.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorHideSingleIsFalseWithSelectedIndicatorColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorHideSingleIsFalseWithSelectedIndicatorColor.png
new file mode 100644
index 000000000000..3ce613fb8c31
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorHideSingleIsFalseWithSelectedIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorHideSingleWithIndicatorSize.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorHideSingleWithIndicatorSize.png
new file mode 100644
index 000000000000..da64627b6901
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorHideSingleWithIndicatorSize.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorSizeWithFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorSizeWithFlowDirection.png
new file mode 100644
index 000000000000..6ed5ba3112ae
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorSizeWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorSizeWithMaximumVisible.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorSizeWithMaximumVisible.png
new file mode 100644
index 000000000000..d070773fe3b5
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorSizeWithMaximumVisible.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_FlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_FlowDirection.png
new file mode 100644
index 000000000000..545cffb7a90c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_FlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_HideSingle.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_HideSingle.png
new file mode 100644
index 000000000000..54b11310cb37
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_HideSingle.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_IsVisible.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_IsVisible.png
new file mode 100644
index 000000000000..8d78659020b0
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_MaximumVisible.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_MaximumVisible.png
new file mode 100644
index 000000000000..1bac6d606f24
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_MaximumVisible.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_Shadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_Shadow.png
new file mode 100644
index 000000000000..3d10a7b9152c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyIndicatorView_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySearchBarFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySearchBarFlowDirection.png
new file mode 100644
index 000000000000..651996c8587c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySearchBarFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColor.png
new file mode 100644
index 000000000000..6e6d89ecf89d
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColorWithFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColorWithFlowDirection.png
new file mode 100644
index 000000000000..dc1e5d1d2af2
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColorWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColorWithIndicatorColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColorWithIndicatorColor.png
new file mode 100644
index 000000000000..08711821f15a
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColorWithIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColorWithIndicatorSize.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColorWithIndicatorSize.png
new file mode 100644
index 000000000000..2a6fb45a50cd
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySelectedIndicatorColorWithIndicatorSize.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedAuto.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedAuto.png
new file mode 100644
index 000000000000..7ab7a61df198
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedAuto.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedCloseSwipeViewButton.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedCloseSwipeViewButton.png
new file mode 100644
index 000000000000..6b161974212a
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedCloseSwipeViewButton.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithButtonSwipeItemsBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithButtonSwipeItemsBackgroundColor.png
new file mode 100644
index 000000000000..46f3858091ac
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithButtonSwipeItemsBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentAndBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentAndBackgroundColor.png
new file mode 100644
index 000000000000..1dd07fa13391
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentAndBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentAndFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentAndFlowDirection.png
new file mode 100644
index 000000000000..b1394ce98491
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentAndFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentAndThreshold.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentAndThreshold.png
new file mode 100644
index 000000000000..6771f92cdb4f
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentAndThreshold.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentChanged.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentChanged.png
new file mode 100644
index 000000000000..e73bb535b9a1
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithCollectionViewContentChanged.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithIconImageSwipeItemsBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithIconImageSwipeItemsBackgroundColor.png
new file mode 100644
index 000000000000..18d364cf1828
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithIconImageSwipeItemsBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndBackgroundColor.png
new file mode 100644
index 000000000000..b87e94a154ca
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndFlowDirection.png
new file mode 100644
index 000000000000..4fd47f9c909e
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndShadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndShadow.png
new file mode 100644
index 000000000000..dd3fa1335190
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndShadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndThreshold.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndThreshold.png
new file mode 100644
index 000000000000..09093ae3ae0a
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentAndThreshold.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentChanged.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentChanged.png
new file mode 100644
index 000000000000..0edc591c83ab
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithImageContentChanged.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndBackgroundColor.png
new file mode 100644
index 000000000000..49c68753e41e
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndFlowDirection.png
new file mode 100644
index 000000000000..582f96106845
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndShadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndShadow.png
new file mode 100644
index 000000000000..20e943f8a761
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndShadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndThreshold.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndThreshold.png
new file mode 100644
index 000000000000..f428914ca39c
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelContentAndThreshold.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelSwipeItemsBackgroundColor.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelSwipeItemsBackgroundColor.png
new file mode 100644
index 000000000000..358660cda8dc
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySwipeViewWithLabelSwipeItemsBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyWebViewWithShadow.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyWebViewWithShadow.png
new file mode 100644
index 000000000000..963f9978eb71
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyWebViewWithShadow.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection.png
new file mode 100644
index 000000000000..0ba81df0cd91
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection_With_Height.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection_With_Height.png
new file mode 100644
index 000000000000..abba4c5ab948
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection_With_HeightAndWidth.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection_With_HeightAndWidth.png
new file mode 100644
index 000000000000..55921e6bc384
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection_With_Width.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection_With_Width.png
new file mode 100644
index 000000000000..84c909d0a2ac
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_RTLFlowDirection_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_Height.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_Height.png
new file mode 100644
index 000000000000..00f6efc66de5
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_HeightAndWidth.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_HeightAndWidth.png
new file mode 100644
index 000000000000..baba65465c78
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_RTL.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_RTL.png
new file mode 100644
index 000000000000..cb54d3dd1f6b
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_RTL.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_Width.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_Width.png
new file mode 100644
index 000000000000..fc76fa19abb4
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerticalStackLayout_Spacing_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/WebViewShouldNotMirrored.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/WebViewShouldNotMirrored.png
new file mode 100644
index 000000000000..627435c5fba1
Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/WebViewShouldNotMirrored.png differ
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AbsoluteLayoutFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AbsoluteLayoutFeatureTests.cs
new file mode 100644
index 000000000000..befe3a5853ba
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/AbsoluteLayoutFeatureTests.cs
@@ -0,0 +1,399 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests;
+
+public class AbsoluteLayoutFeatureTests : UITest
+{
+ public const string AbsoluteLayoutFeatureMatrix = "AbsoluteLayout Feature Matrix";
+ public const string Options = "Options";
+ public const string Apply = "Apply";
+ public const string XEntry = "XEntry";
+ public const string YEntry = "YEntry";
+ public const string WidthEntry = "WidthEntry";
+ public const string HeightEntry = "HeightEntry";
+ public const string LayoutFlagNoneCheckBox = "LayoutFlagNoneCheckBox";
+ public const string LayoutFlagXProportionalCheckBox = "LayoutFlagXProportionalCheckBox";
+ public const string LayoutFlagYProportionalCheckBox = "LayoutFlagYProportionalCheckBox";
+ public const string LayoutFlagWidthProportionalCheckBox = "LayoutFlagWidthProportionalCheckBox";
+ public const string LayoutFlagHeightProportionalCheckBox = "LayoutFlagHeightProportionalCheckBox";
+ public const string LayoutFlagPositionProportionalCheckBox = "LayoutFlagPositionProportionalCheckBox";
+ public const string LayoutFlagSizeProportionalCheckBox = "LayoutFlagSizeProportionalCheckBox";
+ public const string LayoutFlagAllCheckBox = "LayoutFlagAllCheckBox";
+
+ public AbsoluteLayoutFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(AbsoluteLayoutFeatureMatrix);
+ }
+
+ [Test, Order(1)]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_LayoutBounds()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(XEntry);
+ App.ClearText(XEntry);
+ App.EnterText(XEntry, "100");
+ App.WaitForElement(YEntry);
+ App.ClearText(YEntry);
+ App.EnterText(YEntry, "100");
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "100");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "100");
+ App.WaitForElement(LayoutFlagNoneCheckBox);
+ App.Tap(LayoutFlagNoneCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_WidthAndHeight()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "500");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "250");
+ App.WaitForElement(LayoutFlagNoneCheckBox);
+ App.Tap(LayoutFlagNoneCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_XProportional()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(XEntry);
+ App.ClearText(XEntry);
+ App.EnterText(XEntry, "0.5");
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "100");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "100");
+ App.WaitForElement(LayoutFlagXProportionalCheckBox);
+ App.Tap(LayoutFlagXProportionalCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_YProportional()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(YEntry);
+ App.ClearText(YEntry);
+ App.EnterText(YEntry, "0.5");
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "100");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "100");
+ App.WaitForElement(LayoutFlagYProportionalCheckBox);
+ App.Tap(LayoutFlagYProportionalCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_XProportionalAndYProportional()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(XEntry);
+ App.ClearText(XEntry);
+ App.EnterText(XEntry, "0.5");
+ App.WaitForElement(YEntry);
+ App.ClearText(YEntry);
+ App.EnterText(YEntry, "0.5");
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "100");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "100");
+ App.WaitForElement(LayoutFlagXProportionalCheckBox);
+ App.Tap(LayoutFlagXProportionalCheckBox);
+ App.WaitForElement(LayoutFlagYProportionalCheckBox);
+ App.Tap(LayoutFlagYProportionalCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_PositionProportional()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(XEntry);
+ App.ClearText(XEntry);
+ App.EnterText(XEntry, "0.5");
+ App.WaitForElement(YEntry);
+ App.ClearText(YEntry);
+ App.EnterText(YEntry, "0.5");
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "100");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "100");
+ App.WaitForElement(LayoutFlagPositionProportionalCheckBox);
+ App.Tap(LayoutFlagPositionProportionalCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_WidthProportional()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "100");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "0.5");
+ App.WaitForElement(LayoutFlagWidthProportionalCheckBox);
+ App.Tap(LayoutFlagWidthProportionalCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_HeightProportional()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "0.5");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "100");
+ App.WaitForElement(LayoutFlagHeightProportionalCheckBox);
+ App.Tap(LayoutFlagHeightProportionalCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_WidthProportionalAndHeightProportional()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "0.5");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "0.5");
+ App.WaitForElement(LayoutFlagHeightProportionalCheckBox);
+ App.Tap(LayoutFlagHeightProportionalCheckBox);
+ App.WaitForElement(LayoutFlagWidthProportionalCheckBox);
+ App.Tap(LayoutFlagWidthProportionalCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_SizeProportional()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "0.5");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "0.5");
+ App.WaitForElement(LayoutFlagSizeProportionalCheckBox);
+ App.Tap(LayoutFlagSizeProportionalCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_SizeProportionalWithMaximumValue()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "1");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "1");
+ App.WaitForElement(LayoutFlagSizeProportionalCheckBox);
+ App.Tap(LayoutFlagSizeProportionalCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_AllProportional()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(XEntry);
+ App.ClearText(XEntry);
+ App.EnterText(XEntry, "0.5");
+ App.WaitForElement(YEntry);
+ App.ClearText(YEntry);
+ App.EnterText(YEntry, "0.5");
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "0.5");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "0.5");
+ App.WaitForElement(LayoutFlagAllCheckBox);
+ App.Tap(LayoutFlagAllCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_SizeProportionalAndPositionProportional()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(XEntry);
+ App.ClearText(XEntry);
+ App.EnterText(XEntry, "0.5");
+ App.WaitForElement(YEntry);
+ App.ClearText(YEntry);
+ App.EnterText(YEntry, "0.5");
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "0.5");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "0.5");
+ App.WaitForElement(LayoutFlagSizeProportionalCheckBox);
+ App.Tap(LayoutFlagSizeProportionalCheckBox);
+ App.WaitForElement(LayoutFlagPositionProportionalCheckBox);
+ App.Tap(LayoutFlagPositionProportionalCheckBox);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_FlowDirection()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "100");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "100");
+ App.WaitForElement("FlowDirectionRTL");
+ App.Tap("FlowDirectionRTL");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_Visibility()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("IsVisibleFalse");
+ App.Tap("IsVisibleFalse");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+#if TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST // Issue Link: https://github.com/dotnet/maui/issues/31496
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_BackgroundColor()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("BackgroundColorGrayButton");
+ App.Tap("BackgroundColorGrayButton");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void VerifyAbsoluteLayout_Reset_LayoutBounds()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(XEntry);
+ App.ClearText(XEntry);
+ App.EnterText(XEntry, "100");
+ App.WaitForElement(YEntry);
+ App.ClearText(YEntry);
+ App.EnterText(YEntry, "100");
+ App.WaitForElement(HeightEntry);
+ App.ClearText(HeightEntry);
+ App.EnterText(HeightEntry, "100");
+ App.WaitForElement(WidthEntry);
+ App.ClearText(WidthEntry);
+ App.EnterText(WidthEntry, "100");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(XEntry);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/BorderFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/BorderFeatureTests.cs
new file mode 100644
index 000000000000..88841ab229f8
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/BorderFeatureTests.cs
@@ -0,0 +1,457 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests;
+
+public class BorderFeatureTests : UITest
+{
+ public const string BorderFeatureMatrix = "Border Feature Matrix";
+
+ public BorderFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(BorderFeatureMatrix);
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_PaddingWithContent_Label()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PaddingEntry");
+ App.EnterText("PaddingEntry", "10,20,60,10");
+
+ App.WaitForElement("LabelRadioButton");
+ App.Tap("LabelRadioButton");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeColorWithPaddingAndContent_Image()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RedColorButton");
+ App.Tap("RedColorButton");
+
+ App.WaitForElement("PaddingEntry");
+ App.EnterText("PaddingEntry", "10,20,60,10");
+
+ App.WaitForElement("ImageRadioButton");
+ App.Tap("ImageRadioButton");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeColorWithStrokeShape_RoundRectangle()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("BlueColorButton");
+ App.Tap("BlueColorButton");
+
+ App.WaitForElement("RoundRectangleShapeRadio");
+ App.Tap("RoundRectangleShapeRadio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeColorWithStrokeThickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("GreenColorButton");
+ App.Tap("GreenColorButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeShapeWithStrokeThickness_Ellipse()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("EllipseShapeRadio");
+ App.Tap("EllipseShapeRadio");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+
+#if TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST //For more information, see : https://github.com/dotnet/maui/issues/29661 , https://github.com/dotnet/maui/issues/29743
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeShapeWithStrokeLineJoin_Bevel()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolygonShapeRadio");
+ App.Tap("PolygonShapeRadio");
+
+ App.WaitForElement("BevelLineJoinRadio");
+ App.Tap("BevelLineJoinRadio");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeShapeWithDashArray_Path()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,3");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("PathShapeRadio");
+ App.Tap("PathShapeRadio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeThicknessWithDashArray()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,3");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+#if WINDOWS
+ VerifyScreenshot(cropTop: 100);
+#else
+ VerifyScreenshot();
+#endif
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeDashArrayWithDashOffset()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,3");
+
+ App.WaitForElement("DashOffsetEntry");
+ App.EnterText("DashOffsetEntry", "2");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+#if WINDOWS
+ VerifyScreenshot(cropTop: 100);
+#else
+ VerifyScreenshot();
+#endif
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeColorWithStrokeLineJoin_Round()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RectangleShapeRadio");
+ App.Tap("RectangleShapeRadio");
+
+ App.WaitForElement("RoundLineJoinRadio");
+ App.Tap("RoundLineJoinRadio");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+#if TEST_FAILS_ON_WINDOWS // For more information, see : https://github.com/dotnet/maui/issues/29741
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeDashArrayWithStrokeLineCap_Round()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,3");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("RoundLineCapRadio");
+ App.Tap("RoundLineCapRadio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeDashArrayWithDashOffsetAndStrokeLineCapRound()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,3");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("RoundLineCapRadio");
+ App.Tap("RoundLineCapRadio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeDashArrayWithStrokeLineCap_Square()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,3");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("SquareLineCapRadio");
+ App.Tap("SquareLineCapRadio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeDashArrayWithEllipseShapeAndStrokeLineCap_Square()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,3");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("EllipseShapeRadio");
+ App.Tap("EllipseShapeRadio");
+
+ App.WaitForElement("SquareLineCapRadio");
+ App.Tap("SquareLineCapRadio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_PolygonShapeWithStrokeLineCap_Round()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,3");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "15");
+
+ App.WaitForElement("PolygonShapeRadio");
+ App.Tap("PolygonShapeRadio");
+
+ App.WaitForElement("RoundLineCapRadio");
+ App.Tap("RoundLineCapRadio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+#endif
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeDashArrayWithStrokeColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,3");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "10");
+
+ App.WaitForElement("RedColorButton");
+ App.Tap("RedColorButton");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeThicknessWithStrokeLineJoin_Bevel()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("BevelLineJoinRadio");
+ App.Tap("BevelLineJoinRadio");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "15");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_PolygonShapeWithStrokeLineJoin_Bevel()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RectangleShapeRadio");
+ App.Tap("RectangleShapeRadio");
+
+ App.WaitForElement("BevelLineJoinRadio");
+ App.Tap("BevelLineJoinRadio");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "15");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+#endif
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_Shadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("OffsetXEntry");
+ App.EnterText("OffsetXEntry", "10");
+ App.WaitForElement("OffsetYEntry");
+ App.EnterText("OffsetYEntry", "10");
+ App.WaitForElement("OpacityEntry");
+ App.EnterText("OpacityEntry", "0.8");
+ App.WaitForElement("RadiusEntry");
+ App.EnterText("RadiusEntry", "10");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+#if WINDOWS
+ VerifyScreenshot(cropTop: 100);
+#else
+ VerifyScreenshot();
+#endif
+ }
+
+#if TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST // For more information, see : https://github.com/dotnet/maui/issues/29898
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void Border_StrokeColorWithDashArrayAndOffset()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,3");
+
+ App.WaitForElement("DashOffsetEntry");
+ App.EnterText("DashOffsetEntry", "2");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "15");
+
+ App.WaitForElement("BlackColorButton");
+ App.Tap("BlackColorButton");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ VerifyScreenshot();
+ }
+#endif
+
+}
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentPageFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentPageFeatureTests.cs
new file mode 100644
index 000000000000..9b991de09f6f
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentPageFeatureTests.cs
@@ -0,0 +1,243 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests
+{
+ [Category(UITestCategories.Page)]
+ public class ContentPageFeatureTests : UITest
+ {
+ public const string ContentPageFeatureMatrix = "ContentPage Feature Matrix";
+
+ public ContentPageFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(ContentPageFeatureMatrix);
+ }
+
+ [Test]
+ public void ContentPage_zContent()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("KeyboardTestLabel");
+ App.Tap("KeyboardTestLabel");
+
+ App.WaitForElement("ContentButton");
+ App.Tap("ContentButton");
+
+ VerifyScreenshot();
+
+ App.WaitForElement("ResetContentButton");
+ App.Tap("ResetContentButton");
+ }
+
+ [Test]
+ public void ContentPage_IsVisible_WithTitle()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("VisibilityCheckBox");
+ App.Tap("VisibilityCheckBox");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void ContentPage_IsVisible_WithoutTitle()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("TitleEntry");
+ App.Tap("TitleEntry");
+ App.ClearText("TitleEntry");
+
+ App.WaitForElement("VisibilityCheckBox");
+ App.Tap("VisibilityCheckBox");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void ContentPage_Padding_WithBackgroundColor()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("PaddingButton");
+ App.Tap("PaddingButton");
+
+ App.WaitForElement("BackgroundButton");
+ App.Tap("BackgroundButton");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void ContentPage_Title_WithBackgroundColor()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "New Title");
+
+ App.WaitForElement("BackgroundButton");
+ App.Tap("BackgroundButton");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void ContentPage_Title_WithBackgroundColorAndPadding()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "New Title");
+
+ App.WaitForElement("BackgroundButton");
+ App.Tap("BackgroundButton");
+
+ App.WaitForElement("PaddingButton");
+ App.Tap("PaddingButton");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void ContentPage_Background_WithRTL()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("BackgroundButton");
+ App.Tap("BackgroundButton");
+
+ App.WaitForElement("FlowDirectionButton");
+ App.Tap("FlowDirectionButton");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void ContentPage_Padding_WithRTL()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("PaddingButton");
+ App.Tap("PaddingButton");
+
+ App.WaitForElement("FlowDirectionButton");
+ App.Tap("FlowDirectionButton");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void ContentPage_Padding_WithTitle()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("PaddingButton");
+ App.Tap("PaddingButton");
+
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "New Title");
+
+ VerifyScreenshot();
+ }
+
+#if ANDROID || IOS
+ [Test]
+ public void ContentPage_HideSoftinput_WithRTLAndPadding()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("IsBusyLabel");
+ App.Tap("IsBusyLabel");
+
+ App.WaitForElement("FlowDirectionButton");
+ App.Tap("FlowDirectionButton");
+
+ App.WaitForElement("PaddingButton");
+ App.Tap("PaddingButton");
+
+ App.WaitForElement("HideSoftInputCheckBox");
+ App.Tap("HideSoftInputCheckBox");
+
+ App.WaitForElement("TestEntry");
+ App.Tap("TestEntry");
+
+ App.WaitForElement("KeyboardTestLabel");
+ App.Tap("KeyboardTestLabel");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void ContentPage_HideSoftinput_WithPaddingAndBackground()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("BackgroundButton");
+ App.Tap("BackgroundButton");
+
+ App.WaitForElement("PaddingButton");
+ App.Tap("PaddingButton");
+
+ App.WaitForElement("HideSoftInputCheckBox");
+ App.Tap("HideSoftInputCheckBox");
+
+ App.WaitForElement("TestEntry");
+ App.Tap("TestEntry");
+
+ App.WaitForElement("KeyboardTestLabel");
+ App.Tap("KeyboardTestLabel");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void ContentPage_Title_WithPaddingAndHideSoftInput()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "New Title");
+
+ App.WaitForElement("PaddingButton");
+ App.Tap("PaddingButton");
+
+ App.WaitForElement("HideSoftInputCheckBox");
+ App.Tap("HideSoftInputCheckBox");
+
+ App.WaitForElement("TestEntry");
+ App.Tap("TestEntry");
+
+ App.WaitForElement("KeyboardTestLabel");
+ App.Tap("KeyboardTestLabel");
+
+ VerifyScreenshot();
+ }
+#endif
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentViewFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentViewFeatureTests.cs
new file mode 100644
index 000000000000..f001048fa6d5
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ContentViewFeatureTests.cs
@@ -0,0 +1,340 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests;
+
+[Category(UITestCategories.ViewBaseTests)]
+public class ContentViewFeatureTests : UITest
+{
+ public const string ContentViewFeatureMatrix = "ContentView Feature Matrix";
+
+ public ContentViewFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(ContentViewFeatureMatrix);
+ }
+
+ [Test]
+ public void ContentViewWithDefaultLayoutContent()
+ {
+ App.WaitForElement("This is Default Page");
+ App.WaitForElement("Change Text");
+ App.Tap("Change Text");
+ App.WaitForElement("Text Changed after Button Click!");
+ }
+
+ [Test]
+ public void ContentViewWithFirstCustomPage()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FirstPageRadioButton");
+ App.Tap("FirstPageRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("First ContentView Page");
+ }
+
+ [Test]
+ public void ContentViewWithFirstCustomPageAndControlTemplate()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FirstPageRadioButton");
+ App.Tap("FirstPageRadioButton");
+ App.WaitForElement("ControlTemplateYesRadioButton");
+ App.Tap("ControlTemplateYesRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("First ContentView Page");
+ App.WaitForElement("First Control Template Applied");
+ }
+
+ [Test]
+ public void ContentViewWithSecondCustomPage()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("SecondPageRadioButton");
+ App.Tap("SecondPageRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Second Custom Title");
+ }
+
+ [Test]
+ public void ContentViewWithSecondCustomPageAndControlTemplate()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("SecondPageRadioButton");
+ App.Tap("SecondPageRadioButton");
+ App.WaitForElement("ControlTemplateYesRadioButton");
+ App.Tap("ControlTemplateYesRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Second Custom Title");
+ App.WaitForElement("Second Control Template Applied");
+ }
+
+ [Test]
+ public void DefaultContentWithIsEnabled()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("EnabledFalseRadioButton");
+ App.Tap("EnabledFalseRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("This is Default Page");
+ App.WaitForElement("Change Text");
+ App.Tap("Change Text");
+ App.WaitForNoElement("Text Changed after Button Click!");
+ }
+
+ [Test]
+ public void DefaultContentWithBackgroundColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("BgSkyBlueRadioButton");
+ App.Tap("BgSkyBlueRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("This is Default Page");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void DefaultContentWithHeightRequest()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("Height600RadioButton");
+ App.Tap("Height600RadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("This is Default Page");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void DefaultContentWithWidthRequest()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("Width50RadioButton");
+ App.Tap("Width50RadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("This is Default Page");
+ VerifyScreenshot();
+ }
+
+#if TEST_FAILS_ON_WINDOWS // related issue link: https://github.com/dotnet/maui/issues/29812
+ [Test]
+ public void DefaultContentWithShadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("This is Default Page");
+ VerifyScreenshot();
+ }
+#endif
+
+ [Test]
+ public void DefaultContentWithIsVisible()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("VisibleFalseRadioButton");
+ App.Tap("VisibleFalseRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForNoElement("This is Default Page");
+ }
+
+ [Test]
+ public void DefaultContentWithFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FlowDirectionRightToLeft");
+ App.Tap("FlowDirectionRightToLeft");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("This is Default Page");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void FirstCustomPageWithIsEnable()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FirstPageRadioButton");
+ App.Tap("FirstPageRadioButton");
+ App.WaitForElement("EnabledTrueRadioButton");
+ App.Tap("EnabledTrueRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("First ContentView Page");
+ App.WaitForElement("Change Text");
+ App.Tap("Change Text");
+ App.WaitForElement("Success");
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FirstPageRadioButton");
+ App.Tap("FirstPageRadioButton");
+ App.WaitForElement("EnabledFalseRadioButton");
+ App.Tap("EnabledFalseRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("First ContentView Page");
+ App.WaitForElement("Change Text");
+ App.Tap("Change Text");
+ App.WaitForElement("Failed");
+ }
+
+ [Test]
+ public void FirstCustomPageWithBackgroundColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FirstPageRadioButton");
+ App.Tap("FirstPageRadioButton");
+ App.WaitForElement("BgSkyBlueRadioButton");
+ App.Tap("BgSkyBlueRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("First ContentView Page");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void FirstCustomPageWithIsVisible()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FirstPageRadioButton");
+ App.Tap("FirstPageRadioButton");
+ App.WaitForElement("VisibleFalseRadioButton");
+ App.Tap("VisibleFalseRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForNoElement("First ContentView Page");
+ }
+
+ [Test]
+ public void FirstCustomPageWithFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FirstPageRadioButton");
+ App.Tap("FirstPageRadioButton");
+ App.WaitForElement("FlowDirectionRightToLeft");
+ App.Tap("FlowDirectionRightToLeft");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("First ContentView Page");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void FirstCustomPageWithCardTitleSetValues()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FirstPageRadioButton");
+ App.Tap("FirstPageRadioButton");
+ App.WaitForElement("CardTitleRadioButtonSecond");
+ App.Tap("CardTitleRadioButtonSecond");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Test Content View");
+ }
+
+ [Test]
+ public void FirstCustomPageWithIconImageChanged()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FirstPageRadioButton");
+ App.Tap("FirstPageRadioButton");
+ App.WaitForElement("IconImageSourceRadioButtonSecond");
+ App.Tap("IconImageSourceRadioButtonSecond");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("First ContentView Page");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void FirstCustomPageWithCardColorChanged()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FirstPageRadioButton");
+ App.Tap("FirstPageRadioButton");
+ App.WaitForElement("CardColorRadioButtonRed");
+ App.Tap("CardColorRadioButtonRed");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("First ContentView Page");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void SecondCustomPageWithBackgroundColorChanged()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("SecondPageRadioButton");
+ App.Tap("SecondPageRadioButton");
+ App.WaitForElement("BgLightGreenRadioButton");
+ App.Tap("BgLightGreenRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Second Custom Title");
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void SecondCustomPageWithIsVisibleChanged()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("SecondPageRadioButton");
+ App.Tap("SecondPageRadioButton");
+ App.WaitForElement("VisibleFalseRadioButton");
+ App.Tap("VisibleFalseRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForNoElement("Second Custom Title");
+ }
+
+ [Test]
+ public void SecondCustomPageWithFlowDirectionChanged()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("SecondPageRadioButton");
+ App.Tap("SecondPageRadioButton");
+ App.WaitForElement("FlowDirectionRightToLeft");
+ App.Tap("FlowDirectionRightToLeft");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Second Custom Title");
+ VerifyScreenshot();
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/FlyoutPageFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/FlyoutPageFeatureTests.cs
new file mode 100644
index 000000000000..6a59d939a035
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/FlyoutPageFeatureTests.cs
@@ -0,0 +1,417 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests;
+
+public class FlyoutPageFeatureTests : UITest
+{
+ public const string FlyoutPageFeatureMatrix = "Flyout Feature Matrix";
+ public const string Options = "Options";
+ public const string Apply = "Apply";
+ public const string FlowDirectionRTL = "FlowDirectionRTL";
+ public const string IsEnabledFalse = "IsEnabledFalse";
+ public const string IsVisibleFalse = "IsVisibleFalse";
+ public const string IsPresentedTrue = "IsPresentedTrue";
+ public const string IsGestureEnabledTrue = "IsGestureEnabledTrue";
+ public const string IsGestureEnabledFalse = "IsGestureEnabledFalse";
+ public const string TitleEntry = "TitleEntry";
+ public const string FlyoutLayoutBehaviorSplit = "FlyoutLayoutBehaviorSplit";
+ public const string FlyoutLayoutBehaviorSplitOnPortrait = "FlyoutLayoutBehaviorSplitOnPortrait";
+ public const string SetDetail1Button = "SetDetail1Button";
+ public const string SetFlyout1Button = "SetFlyout1Button";
+ public const string FlyoutLayoutBehaviorPopover = "FlyoutLayoutBehaviorPopover";
+
+ public FlyoutPageFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(FlyoutPageFeatureMatrix);
+ }
+
+ [Test, Order(1)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_NavigationEvents()
+ {
+ App.WaitForElement("SetDetail1Button");
+ App.Tap("SetDetail1Button");
+ App.WaitForElement("BackToOriginalDetailButton1");
+ App.Tap("BackToOriginalDetailButton1");
+ App.WaitForElement("NavigatedToLabel");
+ Assert.That(App.FindElement("NavigatedToLabel").GetText(), Is.EqualTo("NavigatedTo: Detail 1"));
+ Assert.That(App.FindElement("NavigatingFromLabel").GetText(), Is.EqualTo("NavigatingFrom: Detail 1"));
+ Assert.That(App.FindElement("NavigatedFromLabel").GetText(), Is.EqualTo("NavigatedFrom: Detail 1"));
+ }
+
+#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_WINDOWS // Issue Link: https://github.com/dotnet/maui/issues/31374, https://github.com/dotnet/maui/issues/31372
+ [Test, Order(2)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_IsPresented()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IsPresentedTrue);
+ App.Tap(IsPresentedTrue);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement("Flyout Item 1");
+ App.WaitForElement("Flyout Item 2");
+ App.Tap("CloseFlyoutButton");
+ }
+#endif
+
+#if TEST_FAILS_ON_WINDOWS // In windows default set as Split FlyoutLayoutBehavior
+ [Test, Order(3)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_IsGestureEnabled()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IsGestureEnabledTrue);
+ App.Tap(IsGestureEnabledTrue);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+
+ var detail = App.FindElement("DetailPageLabel").GetRect();
+ var startX = detail.X + 5;
+ var endX = detail.X + (detail.Width * 0.5);
+ var y = detail.Y + (detail.Height / 2);
+ bool flyoutOpened = false;
+ for (int i = 0; i < 3 && !flyoutOpened; i++)
+ {
+ App.DragCoordinates((float)startX, (float)y, (float)endX, (float)y);
+ try
+ {
+ App.WaitForElement("Flyout Item 1", timeout: TimeSpan.FromSeconds(2));
+ flyoutOpened = true;
+ }
+ catch (Exception)
+ {
+ // not found yet, will retry
+ }
+ }
+ Assert.That(flyoutOpened, Is.True, "Flyout did not open after multiple drag attempts");
+ App.Tap("CloseFlyoutButton");
+ }
+
+ [Test, Order(4)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_IsGestureEnabledFalse()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IsGestureEnabledFalse);
+ App.Tap(IsGestureEnabledFalse);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+
+ var detail = App.FindElement("DetailPageLabel").GetRect();
+ var startX = detail.X + 5;
+ var endX = detail.X + (detail.Width * 0.5);
+ var y = detail.Y + (detail.Height / 2);
+ App.DragCoordinates((float)startX, (float)y, (float)endX, (float)y);
+ App.WaitForNoElement("Flyout Item 1");
+ App.WaitForNoElement("Flyout Item 2");
+ }
+#endif
+
+#if TEST_FAILS_ON_WINDOWS // Issue Link: https://github.com/dotnet/maui/issues/31390
+ [Test, Order(5)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_IsGestureEnabled_FlyoutBehaviorPopover()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IsGestureEnabledTrue);
+ App.Tap(IsGestureEnabledTrue);
+ App.WaitForElement(FlyoutLayoutBehaviorPopover);
+ App.Tap(FlyoutLayoutBehaviorPopover);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+
+ var detail = App.FindElement("DetailPageLabel").GetRect();
+ var startX = detail.X + 5;
+ var endX = detail.X + (detail.Width * 0.5);
+ var y = detail.Y + (detail.Height / 2);
+ bool flyoutOpened = false;
+ for (int i = 0; i < 3 && !flyoutOpened; i++)
+ {
+ App.DragCoordinates((float)startX, (float)y, (float)endX, (float)y);
+ try
+ {
+ App.WaitForElement("Flyout Item 1", timeout: TimeSpan.FromSeconds(2));
+ flyoutOpened = true;
+ }
+ catch (Exception)
+ {
+ // not found yet, will retry
+ }
+ }
+ Assert.That(flyoutOpened, Is.True, "Flyout did not open after multiple drag attempts");
+ App.Tap("CloseFlyoutButton");
+ }
+
+ [Test, Order(6)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_IsGestureEnabledFalse_FlyoutBehaviorPopover()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IsGestureEnabledFalse);
+ App.Tap(IsGestureEnabledFalse);
+ App.WaitForElement(FlyoutLayoutBehaviorPopover);
+ App.Tap(FlyoutLayoutBehaviorPopover);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+
+ var detail = App.FindElement("DetailPageLabel").GetRect();
+ var startX = detail.X + 5;
+ var endX = detail.X + (detail.Width * 0.5);
+ var y = detail.Y + (detail.Height / 2);
+ App.DragCoordinates((float)startX, (float)y, (float)endX, (float)y);
+ App.WaitForNoElement("Flyout Item 1");
+ App.WaitForNoElement("Flyout Item 2");
+ }
+#endif
+
+ [Test, Order(7)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_IsEnabled()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IsEnabledFalse);
+ App.Tap(IsEnabledFalse);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+#if TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST // Issue Link: https://github.com/dotnet/maui/issues/26726
+ [Test, Order(8)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_IsFlowDirectionRTL()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(FlowDirectionRTL);
+ App.Tap(FlowDirectionRTL);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_WINDOWS // Issue Link: https://github.com/dotnet/maui/issues/31374, https://github.com/dotnet/maui/issues/31372
+ [Test, Order(9)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_IsFlowDirectionRTLWithIsPresented()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(FlowDirectionRTL);
+ App.Tap(FlowDirectionRTL);
+ App.WaitForElement(IsPresentedTrue);
+ App.Tap(IsPresentedTrue);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+#endif
+
+#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_WINDOWS // Orientation not supported in Catalyst and Windows , Android Issue Link: https://github.com/dotnet/maui/issues/31374
+ [Test, Order(10)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_IsPresented_OrientationLandscape()
+ {
+ App.SetOrientationLandscape();
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IsPresentedTrue);
+ App.Tap(IsPresentedTrue);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement("Flyout Item 1");
+ App.WaitForElement("Flyout Item 2");
+ App.Tap("CloseFlyoutButton");
+ App.SetOrientationPortrait();
+ }
+#endif
+
+ [Test, Order(11)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_Title()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(TitleEntry);
+ App.EnterText(TitleEntry, "New Title");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST// FlyoutLayoutBehavior is not changed in mobile platforms, Issue Link: https://github.com/dotnet/maui/issues/16245
+ [Test, Order(12)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_FlyoutLayoutBehavior_Split()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(FlyoutLayoutBehaviorSplit);
+ App.Tap(FlyoutLayoutBehaviorSplit);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+#if TEST_FAILS_ON_WINDOWS // Issue Link: https://github.com/dotnet/maui/issues/31390
+ [Test, Order(13)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_FlyoutLayoutBehavior_SplitOnPortrait()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(FlyoutLayoutBehaviorSplitOnPortrait);
+ App.Tap(FlyoutLayoutBehaviorSplitOnPortrait);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+#endif
+
+#if TEST_FAILS_ON_WINDOWS // Issue Link: https://github.com/dotnet/maui/issues/31390
+ [Test, Order(14)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_FlyoutLayoutBehaviorPopover()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(FlyoutLayoutBehaviorPopover);
+ App.Tap(FlyoutLayoutBehaviorPopover);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+
+#if TEST_FAILS_ON_WINDOWS // Issue Link: https://github.com/dotnet/maui/issues/20088
+ [Test, Order(15)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_Detail()
+ {
+ App.WaitForElement(SetDetail1Button);
+ App.Tap(SetDetail1Button);
+ App.WaitForElement("Detail 1 - Content");
+ App.WaitForElement("BackToOriginalDetailButton1");
+ App.Tap("BackToOriginalDetailButton1");
+ }
+
+ [Test, Order(16)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_Flyout()
+ {
+ App.WaitForElement(SetFlyout1Button);
+ App.Tap(SetFlyout1Button);
+ App.WaitForElement("OpenFlyoutButton");
+ App.Tap("OpenFlyoutButton");
+ App.WaitForElement("Flyout 1 - Item 1");
+ App.WaitForElement("Flyout 1 - Item 2");
+ App.WaitForElement("BackToOriginalFlyoutButton1");
+ App.Tap("BackToOriginalFlyoutButton1");
+ }
+#endif
+
+#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_WINDOWS // Android Issue Link: https://github.com/dotnet/maui/issues/22116 , https://github.com/dotnet/maui/issues/15211
+ // Windows Issue Link: https://github.com/dotnet/maui/issues/15211#issuecomment-1562587775 , https://github.com/dotnet/maui/issues/31390
+ [Test, Order(17)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_DetailPageIconImageSource()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("IconFontIconButton");
+ App.Tap("IconFontIconButton");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(18)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_DetailPageIconImageSource_FlyoutLayoutBehavior()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("IconFontIconButton");
+ App.Tap("IconFontIconButton");
+ App.WaitForElement(FlyoutLayoutBehaviorPopover);
+ App.Tap(FlyoutLayoutBehaviorPopover);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+
+#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_WINDOWS // Issue Link: https://github.com/dotnet/maui/issues/31390, https://github.com/dotnet/maui/issues/31374
+ [Test, Order(19)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_FlyoutLayoutBehaviorPopover_IsPresented()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(FlyoutLayoutBehaviorPopover);
+ App.Tap(FlyoutLayoutBehaviorPopover);
+ App.WaitForElement(IsPresentedTrue);
+ App.Tap(IsPresentedTrue);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement("Flyout Item 1");
+ App.WaitForElement("Flyout Item 2");
+ App.WaitForElement("CloseFlyoutButton");
+ App.Tap("CloseFlyoutButton");
+ }
+#endif
+
+ [Test, Order(20)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyDynamicFlyoutPage()
+ {
+ App.WaitForElement("GoToNewPageButton");
+ App.Tap("GoToNewPageButton");
+ App.WaitForElement("This is the detail of the new FlyoutPage");
+ App.WaitForElement("CloseNewFlyoutPageButton");
+ App.Tap("CloseNewFlyoutPageButton");
+ }
+
+ [Test, Order(21)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_BackgroundColor()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("BackgroundColorLightYellowButton");
+ App.Tap("BackgroundColorLightYellowButton");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(22)]
+ [Category(UITestCategories.FlyoutPage)]
+ public void VerifyFlyoutPage_IsVisible()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IsVisibleFalse);
+ App.Tap(IsVisibleFalse);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/IndicatorViewFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/IndicatorViewFeatureTests.cs
new file mode 100644
index 000000000000..3befa9415c46
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/IndicatorViewFeatureTests.cs
@@ -0,0 +1,676 @@
+using Microsoft.Maui.Controls.Shapes;
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+
+namespace Microsoft.Maui.TestCases.Tests;
+
+public class IndicatorViewFeatureTests : UITest
+{
+ private const string IndicatorViewFeatureMatrix = "IndicatorView Feature Matrix";
+ public const string Options = "Options";
+ public const string Apply = "Apply";
+ public const string IndicatorColorBrownButton = "IndicatorColorBrownButton";
+ public const string IndicatorColorGreenButton = "IndicatorColorGreenButton";
+ public const string SelectedIndicatorColorGrayButton = "SelectedIndicatorColorGrayButton";
+ public const string SelectedIndicatorColorOrangeButton = "SelectedIndicatorColorOrangeButton";
+ public const string SelectedIndicatorColorPurpleButton = "SelectedIndicatorColorPurpleButton";
+ public const string IndicatorShapeSquareRadioButton = "IndicatorShapeSquareRadioButton";
+ public const string HideSingleTrueRadioButton = "HideSingleTrueRadioButton";
+ public const string HideSingleFalseRadioButton = "HideSingleFalseRadioButton";
+ public const string FlowDirectionRightToLeftRadioButton = "FlowDirectionRTLRadioButton";
+ public const string IsEnabledFalseRadioButton = "IsEnabledFalseRadioButton";
+ public const string IsVisibleFalseRadioButton = "IsVisibleFalseRadioButton";
+ public const string PositionEntry = "PositionEntry";
+ public const string AddItemButton = "AddItemButton";
+ public const string RemoveItemButton = "RemoveItemButton";
+ public const string MaximumVisibleStepper = "MaximumVisibleStepper";
+ public const string ShadowTrueRadioButton = "ShadowTrueRadioButton";
+ public const string CountLabel = "CountLabel";
+ public const string PositionLabel = "PositionLabel";
+ public const string IndicatorSizeStepper = "IndicatorSizeStepper";
+ public const string PositionStepper = "PositionStepper";
+ public const string IconTemplateButton = "IconTemplateButton";
+
+ public IndicatorViewFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(IndicatorViewFeatureMatrix);
+ }
+
+ [Test, Order(1)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorColor()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IndicatorColorGreenButton);
+ App.Tap(IndicatorColorGreenButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(2)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifySelectedIndicatorColor()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(SelectedIndicatorColorPurpleButton);
+ App.Tap(SelectedIndicatorColorPurpleButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(3)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorView_Count()
+ {
+ App.WaitForElement(Options);
+ Assert.That(App.FindElement(CountLabel).GetText(), Is.EqualTo("Count: 5"));
+ App.WaitForElement(AddItemButton);
+ App.Tap(AddItemButton);
+ Assert.That(App.FindElement(CountLabel).GetText(), Is.EqualTo("Count: 6"));
+ App.WaitForElement(RemoveItemButton);
+ App.Tap(RemoveItemButton);
+ Assert.That(App.FindElement(CountLabel).GetText(), Is.EqualTo("Count: 5"));
+ }
+
+#if TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_WINDOWS // Issue Link: https://github.com/dotnet/maui/issues/29312, https://github.com/dotnet/maui/issues/15443
+ [Test, Order(4)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorView_Position()
+ {
+ App.WaitForElement(Options);
+ Assert.That(App.FindElement(PositionLabel).GetText(), Is.EqualTo("Position: 0"));
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ IncreasePositionStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ Assert.That(App.FindElement(PositionLabel).GetText(), Is.EqualTo("Position: 1"));
+ }
+
+ [Test, Order(13)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifySelectedIndicatorColorWhenItemsChanged()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(SelectedIndicatorColorOrangeButton);
+ App.Tap(SelectedIndicatorColorOrangeButton);
+ IncreasePositionStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(18)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifySelectedIndicatorColorWithPosition()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(SelectedIndicatorColorPurpleButton);
+ App.Tap(SelectedIndicatorColorPurpleButton);
+ IncreasePositionStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(29)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorShapeWithPosition()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IndicatorShapeSquareRadioButton);
+ App.Tap(IndicatorShapeSquareRadioButton);
+ IncreasePositionStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+
+#if TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST // Issue Link: https://github.com/dotnet/maui/issues/31064
+ [Test, Order(5)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifySelectedIndicatorSize()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ IncreaseIndicatorSizeStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+
+#if TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST // Issue Link: https://github.com/dotnet/maui/issues/31065
+ [Test, Order(6)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorShape()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IndicatorShapeSquareRadioButton);
+ App.Tap(IndicatorShapeSquareRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(16)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorColorWithIndicatorShape()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IndicatorColorBrownButton);
+ App.Tap(IndicatorColorBrownButton);
+ App.WaitForElement(IndicatorShapeSquareRadioButton);
+ App.Tap(IndicatorShapeSquareRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(17)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifySelectedIndicatorColorWithIndicatorShape()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(SelectedIndicatorColorOrangeButton);
+ App.Tap(SelectedIndicatorColorOrangeButton);
+ App.WaitForElement(IndicatorShapeSquareRadioButton);
+ App.Tap(IndicatorShapeSquareRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(21)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorSizeWithIndicatorShape()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ IncreaseIndicatorSizeStepper();
+ App.WaitForElement(IndicatorShapeSquareRadioButton);
+ App.Tap(IndicatorShapeSquareRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(26)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorShapeWithFlowDirection()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IndicatorShapeSquareRadioButton);
+ App.Tap(IndicatorShapeSquareRadioButton);
+ App.WaitForElement(FlowDirectionRightToLeftRadioButton);
+ App.Tap(FlowDirectionRightToLeftRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(27)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorShapeWithHideSingle()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HideSingleTrueRadioButton);
+ App.Tap(HideSingleTrueRadioButton);
+ App.WaitForElement(IndicatorShapeSquareRadioButton);
+ App.Tap(IndicatorShapeSquareRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ for (int i = 0; i < 4; i++)
+ {
+ App.WaitForElement(RemoveItemButton);
+ App.Tap(RemoveItemButton);
+ }
+ VerifyScreenshot();
+ }
+
+ [Test, Order(28)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorShapeWithMaximumVisible()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IndicatorShapeSquareRadioButton);
+ App.Tap(IndicatorShapeSquareRadioButton);
+ DecreaseMaximumVisibleStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#if TEST_FAILS_ON_WINDOWS // Issue Link: https://github.com/dotnet/maui/issues/29812
+ [Test, Order(30)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorShapeWithShadow()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IndicatorShapeSquareRadioButton);
+ App.Tap(IndicatorShapeSquareRadioButton);
+ App.WaitForElement(ShadowTrueRadioButton);
+ App.Tap(ShadowTrueRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+#endif
+
+ [Test, Order(7)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorView_HideSingle()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HideSingleTrueRadioButton);
+ App.Tap(HideSingleTrueRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ for (int i = 0; i < 4; i++)
+ {
+ App.WaitForElement(RemoveItemButton);
+ App.Tap(RemoveItemButton);
+ }
+ VerifyScreenshot();
+ }
+
+ [Test, Order(8)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorView_MaximumVisible()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ DecreaseMaximumVisibleStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(9)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorView_FlowDirection()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(FlowDirectionRightToLeftRadioButton);
+ App.Tap(FlowDirectionRightToLeftRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(10)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorView_IsVisible()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IsVisibleFalseRadioButton);
+ App.Tap(IsVisibleFalseRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+#if TEST_FAILS_ON_WINDOWS // https://github.com/dotnet/maui/issues/29812
+ [Test, Order(11)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorView_Shadow()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(ShadowTrueRadioButton);
+ App.Tap(ShadowTrueRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+
+ [Test, Order(12)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorColorWhenItemsAdded()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IndicatorColorBrownButton);
+ App.Tap(IndicatorColorBrownButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement(AddItemButton);
+ App.Tap(AddItemButton);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(14)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorColorWithIndicatorSize()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IndicatorColorBrownButton);
+ App.Tap(IndicatorColorBrownButton);
+ IncreaseIndicatorSizeStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(15)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifySelectedIndicatorColorWithIndicatorSize()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(SelectedIndicatorColorOrangeButton);
+ App.Tap(SelectedIndicatorColorOrangeButton);
+ IncreaseIndicatorSizeStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(19)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifySelectedIndicatorColorWithFlowDirection()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(SelectedIndicatorColorOrangeButton);
+ App.Tap(SelectedIndicatorColorOrangeButton);
+ App.WaitForElement(FlowDirectionRightToLeftRadioButton);
+ App.Tap(FlowDirectionRightToLeftRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(20)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorColorWithFlowDirection()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IndicatorColorGreenButton);
+ App.Tap(IndicatorColorGreenButton);
+ App.WaitForElement(FlowDirectionRightToLeftRadioButton);
+ App.Tap(FlowDirectionRightToLeftRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(22)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorHideSingleWithIndicatorSize()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HideSingleTrueRadioButton);
+ App.Tap(HideSingleTrueRadioButton);
+ IncreaseIndicatorSizeStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ for (int i = 0; i < 4; i++)
+ {
+ App.WaitForElement(RemoveItemButton);
+ App.Tap(RemoveItemButton);
+ }
+ VerifyScreenshot();
+ }
+
+#if TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_IOS && TEST_FAILS_ON_WINDOWS //Issue Link: https://github.com/dotnet/maui/issues/31140 , https://github.com/dotnet/maui/issues/29812
+ [Test, Order(23)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorSizeWithShadow()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ IncreaseIndicatorSizeStepper();
+ App.WaitForElement(ShadowTrueRadioButton);
+ App.Tap(ShadowTrueRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+
+ [Test, Order(24)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorSizeWithFlowDirection()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ IncreaseIndicatorSizeStepper();
+ App.WaitForElement(FlowDirectionRightToLeftRadioButton);
+ App.Tap(FlowDirectionRightToLeftRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(25)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorSizeWithMaximumVisible()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ IncreaseIndicatorSizeStepper();
+ DecreaseMaximumVisibleStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(31)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifySelectedIndicatorColorWithIndicatorColor()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(SelectedIndicatorColorOrangeButton);
+ App.Tap(SelectedIndicatorColorOrangeButton);
+ App.WaitForElement(IndicatorColorGreenButton);
+ App.Tap(IndicatorColorGreenButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(32)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorHideSingleIsFalse()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HideSingleFalseRadioButton);
+ App.Tap(HideSingleFalseRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ for (int i = 0; i < 4; i++)
+ {
+ App.WaitForElement(RemoveItemButton);
+ App.Tap(RemoveItemButton);
+ }
+ VerifyScreenshot();
+ }
+
+ [Test, Order(33)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorHideSingleIsFalseWithSelectedIndicatorColor()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HideSingleFalseRadioButton);
+ App.Tap(HideSingleFalseRadioButton);
+ App.WaitForElement(SelectedIndicatorColorOrangeButton);
+ App.Tap(SelectedIndicatorColorOrangeButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ for (int i = 0; i < 4; i++)
+ {
+ App.WaitForElement(RemoveItemButton);
+ App.Tap(RemoveItemButton);
+ }
+ VerifyScreenshot();
+ }
+
+#if TEST_FAILS_ON_WINDOWS && TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST
+// Issue Link: https://github.com/dotnet/maui/issues/31128
+// Issue Link: https://github.com/dotnet/maui/issues/31141
+// Issue Link: https://github.com/dotnet/maui/issues/31145
+ [Test, Order(34)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorTemplate()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IconTemplateButton);
+ App.Tap(IconTemplateButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(35)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorTemplateWithFlowDirection()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IconTemplateButton);
+ App.Tap(IconTemplateButton);
+ App.WaitForElement(FlowDirectionRightToLeftRadioButton);
+ App.Tap(FlowDirectionRightToLeftRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(36)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorTemplateWithMaximumVisible()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IconTemplateButton);
+ App.Tap(IconTemplateButton);
+ DecreaseMaximumVisibleStepper();
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(37)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorTemplateWithShadow()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IconTemplateButton);
+ App.Tap(IconTemplateButton);
+ App.WaitForElement(ShadowTrueRadioButton);
+ App.Tap(ShadowTrueRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(38)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorTemplateWithIsVisible()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IconTemplateButton);
+ App.Tap(IconTemplateButton);
+ App.WaitForElement(IsVisibleFalseRadioButton);
+ App.Tap(IsVisibleFalseRadioButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(39)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorTemplateWithSelectedIndicatorColor()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IconTemplateButton);
+ App.Tap(IconTemplateButton);
+ App.WaitForElement(SelectedIndicatorColorOrangeButton);
+ App.Tap(SelectedIndicatorColorOrangeButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+
+ [Test, Order(40)]
+ [Category(UITestCategories.IndicatorView)]
+ public void VerifyIndicatorTemplateWithIndicatorColor()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(IconTemplateButton);
+ App.Tap(IconTemplateButton);
+ App.WaitForElement(IndicatorColorGreenButton);
+ App.Tap(IndicatorColorGreenButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ VerifyScreenshot();
+ }
+#endif
+
+ public void IncreasePositionStepper()
+ {
+ ChangeStepper(PositionStepper, true);
+ }
+ public void DecreaseMaximumVisibleStepper()
+ {
+ ChangeStepper(MaximumVisibleStepper, false);
+ }
+ public void IncreaseIndicatorSizeStepper()
+ {
+ ChangeStepper(IndicatorSizeStepper, true);
+ }
+ private void ChangeStepper(string stepperAutomationId, bool increase)
+ {
+#if WINDOWS
+ if (increase)
+ App.IncreaseStepper(stepperAutomationId);
+ else
+ App.DecreaseStepper(stepperAutomationId);
+#else
+ App.WaitForElement(stepperAutomationId);
+ if (increase)
+ App.IncreaseStepper(stepperAutomationId);
+ else
+ App.DecreaseStepper(stepperAutomationId);
+#endif
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/NavigationPageFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/NavigationPageFeatureTests.cs
new file mode 100644
index 000000000000..82746acd2668
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/NavigationPageFeatureTests.cs
@@ -0,0 +1,503 @@
+using System.Linq;
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests
+{
+ [Category(UITestCategories.Navigation)]
+ public class NavigationPageFeatureTests : UITest
+ {
+ public const string NavigationPageFeatureMatrix = "NavigationPage Feature Matrix";
+
+ public NavigationPageFeatureTests(TestDevice device) : base(device) { }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(NavigationPageFeatureMatrix);
+ }
+
+ [Test, Order(1)]
+ public void EntryPoints_AreVisible()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ApplyButton");
+ App.WaitForElement("PushPageButton");
+ App.WaitForElement("PopToRootButton");
+
+ App.WaitForElement("HasNavigationBarCheckBox");
+ App.WaitForElement("HasBackButtonCheckBox");
+ App.WaitForElement("BackButtonTitleEntry");
+
+ App.WaitForElement("BarBackgroundColorBlueButton");
+ App.WaitForElement("BarTextColorWhiteButton");
+ App.WaitForElement("BarBackgroundLinearButton");
+ App.WaitForElement("BarBackgroundRadialButton");
+ App.WaitForElement("BarBackgroundClearButton");
+ App.WaitForElement("IconColorRedButton");
+ App.WaitForElement("IconColorPurpleButton");
+ App.WaitForElement("IconColorDefaultButton");
+ App.WaitForElement("TitleIconButton");
+ App.WaitForElement("TitleViewButton");
+ }
+
+ [Test, Order(0)]
+ public void Defaults_AreCorrect_OnLoad()
+ {
+ App.WaitForElement("CurrentPageLabel");
+ Assert.That(App.FindElement("CurrentPageLabel").GetText(), Is.EqualTo("Sample Page"));
+ App.WaitForElement("RootPageLabel");
+ Assert.That(App.FindElement("RootPageLabel").GetText(), Is.EqualTo("Sample Page"));
+
+ // Last event should be the initial NavigatedTo on root
+ App.WaitForElement("LastNavigationEventLabel");
+ Assert.That(App.FindElement("LastNavigationEventLabel").GetText(), Does.Contain("NavigatedTo: Sample Page"));
+
+ // From/PreFrom not yet
+ App.WaitForElement("NavigatedFromStatusLabel");
+ Assert.That(App.FindElement("NavigatedFromStatusLabel").GetText(), Is.EqualTo("Not yet"));
+ App.WaitForElement("NavigatingFromStatusLabel");
+ Assert.That(App.FindElement("NavigatingFromStatusLabel").GetText(), Is.EqualTo("Not yet"));
+
+ // To params should indicate a single-item stack on load
+ App.WaitForElement("NavigatedToParamsLabel");
+ var toParams = App.FindElement("NavigatedToParamsLabel").GetText();
+ Assert.That(toParams, Does.Contain("StackCount=1"));
+
+ // Default back button title
+ App.WaitForElement("BackButtonTitleEntry");
+ Assert.That(App.FindElement("BackButtonTitleEntry").GetText(), Is.EqualTo("Back"));
+ }
+
+ [Test, Order(2)]
+ public void Events_AreRaised_WithExpectedPages_On_Push_And_Pop()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton");
+ App.WaitForElement("PopPageButton");
+
+ // Pop back to root
+ App.Tap("PopPageButton");
+ App.WaitForElement("CurrentPageLabel");
+
+ // Verify statuses reflect raised pages
+ App.WaitForElement("NavigatedFromStatusLabel");
+ Assert.That(App.FindElement("NavigatedFromStatusLabel").GetText(), Does.Contain("Page 2"));
+ App.WaitForElement("NavigatingFromStatusLabel");
+ Assert.That(App.FindElement("NavigatingFromStatusLabel").GetText(), Does.Contain("Page 2"));
+ App.WaitForElement("NavigatedToStatusLabel");
+ Assert.That(App.FindElement("NavigatedToStatusLabel").GetText(), Does.Contain("Sample Page"));
+
+ // Verify parameter labels include the expected titles and keys
+ var toParams = App.FindElement("NavigatedToParamsLabel").GetText();
+ Assert.That(toParams, Does.Contain("PreviousPageTitle=Page 2"));
+ var fromParams = App.FindElement("NavigatedFromParamsLabel").GetText();
+ Assert.That(fromParams, Does.Contain("DestinationTitle=Sample Page"));
+ var preParams = App.FindElement("NavigatingFromParamsLabel").GetText();
+ Assert.That(preParams, Does.Contain("Requested=Pop"));
+ }
+
+ [Test, Order(3)]
+ public void PopToRoot_FromPage3_ReturnsToRoot()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton"); // to Page 2
+ App.WaitForElement("PushPage3Button");
+ App.Tap("PushPage3Button"); // to Page 3
+
+ // Pop to root using the in-page button
+ App.WaitForElement("PopToRootPageButton");
+ App.Tap("PopToRootPageButton");
+ App.WaitForElement("CurrentPageLabel");
+ Assert.That(App.FindElement("CurrentPageLabel").GetText(), Is.EqualTo("Sample Page"));
+ }
+
+ // BackButtonTitle does not applicable for Android and Windows Platforms
+#if TEST_FAILS_ON_IOS && TESTS_FAIL_ON_MACCATALYST// Issue Link: https://github.com/dotnet/maui/issues/31539
+#if IOS || MACCATALYST
+ [Test,Order(19)]
+ public void BackButtonTitle_AppliesOnNextPage_Visual()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("BackButtonTitleEntry");
+ App.ClearText("BackButtonTitleEntry");
+ App.EnterText("BackButtonTitleEntry", "My Back");
+ App.PressEnter();
+ App.Tap("ApplyButton");
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton");
+ // Validate visually on page 2 (back button title)
+ VerifyScreenshot();
+ }
+#endif
+#endif
+
+ [Test, Order(5)]
+ public void ToggleHasBackButton_HidesBackArrow_Visual()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ Exception? exception = null;
+ App.WaitForElement("HasBackButtonCheckBox");
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton");
+ // Screenshot: Back arrow visible
+ VerifyScreenshotOrSetException(ref exception, "BackButtonVisible");
+ App.WaitForElement("PopPageButton");
+ App.Tap("PopPageButton");
+ App.WaitForElement("HasBackButtonCheckBox");
+ App.Tap("HasBackButtonCheckBox");
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton");
+ // Screenshot: Back arrow hidden
+ VerifyScreenshotOrSetException(ref exception, "BackButtonHidden");
+ if (exception != null)
+ throw exception;
+ }
+
+ [Test, Order(6)]
+ public void ToggleHasNavigationBar_HidesBar_Visual()
+ {
+ App.WaitForElement("PopToRootPageButton");
+ App.Tap("PopToRootPageButton");
+
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ Exception? exception = null;
+ App.WaitForElement("HasNavigationBarCheckBox");
+ App.Tap("HasNavigationBarCheckBox");
+ // Screenshot: Navigation bar hidden
+ VerifyScreenshotOrSetException(ref exception, "NavBarHidden");
+ App.Tap("HasNavigationBarCheckBox");
+ // Screenshot: Navigation bar visible again
+ VerifyScreenshotOrSetException(ref exception, "NavBarVisible");
+ if (exception != null)
+ throw exception;
+ }
+
+ [Test, Order(7)]
+ public void SetBarBackgroundColor_Visual()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ Exception? exception = null;
+ App.WaitForElement("BarBackgroundColorBlueButton");
+ App.Tap("BarBackgroundColorBlueButton");
+ // Screenshot: Blue bar background
+ VerifyScreenshotOrSetException(ref exception, "BarBgBlue");
+ App.WaitForElement("BarBackgroundColorRedButton");
+ App.Tap("BarBackgroundColorRedButton");
+ // Screenshot: Red bar background
+ VerifyScreenshotOrSetException(ref exception, "BarBgRed");
+ if (exception != null)
+ throw exception;
+ }
+
+ [Test, Order(8)]
+ public void SetBarTextColor_Visual()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ Exception? exception = null;
+ App.WaitForElement("BarTextColorWhiteButton");
+ App.Tap("BarTextColorWhiteButton");
+ // Screenshot: White bar text color
+ VerifyScreenshotOrSetException(ref exception, "BarTextWhite");
+ App.WaitForElement("BarTextColorBlackButton");
+ App.Tap("BarTextColorBlackButton");
+ // Screenshot: Black bar text color
+ VerifyScreenshotOrSetException(ref exception, "BarTextBlack");
+ if (exception != null)
+ throw exception;
+ }
+
+ [Test, Order(9)]
+ public void SetBarBackground_Linear_Radial_Clear_Visual()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ Exception? exception = null;
+ App.WaitForElement("BarBackgroundLinearButton");
+ App.Tap("BarBackgroundLinearButton");
+ // Screenshot: Linear gradient applied
+ VerifyScreenshotOrSetException(ref exception, "BarBgLinear");
+
+ App.WaitForElement("BarBackgroundRadialButton");
+ App.Tap("BarBackgroundRadialButton");
+ // Screenshot: Radial gradient applied
+ VerifyScreenshotOrSetException(ref exception, "BarBgRadial");
+
+ App.WaitForElement("BarBackgroundClearButton");
+ App.Tap("BarBackgroundClearButton");
+ if (exception != null)
+ throw exception;
+ }
+
+ [Test, Order(10)]
+ public void SetIconColor_Red_Purple_Default_Visual()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ Exception? exception = null;
+ App.WaitForElement("IconColorRedButton");
+ App.Tap("IconColorRedButton");
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton");
+ // Screenshot: Red icon color on pushed page
+ VerifyScreenshotOrSetException(ref exception, "IconColorRed");
+ App.WaitForElement("PopPageButton");
+ App.Tap("PopPageButton");
+
+ App.WaitForElement("IconColorDefaultButton");
+ App.Tap("IconColorDefaultButton");
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton");
+ // Screenshot: Default icon color on pushed page
+ VerifyScreenshotOrSetException(ref exception, "IconColorDefault");
+ if (exception != null)
+ throw exception;
+ }
+
+ [Test, Order(11)]
+ public void TitleIcon_Add_Visual()
+ {
+ App.WaitForElement("PopToRootPageButton");
+ App.Tap("PopToRootPageButton");
+
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("TitleIconButton");
+ App.Tap("TitleIconButton");
+ // Screenshot: Title icon applied on current page
+ VerifyScreenshot();
+ }
+
+#if TEST_FAILS_ON_ANDROID //Issue Link: https://github.com/dotnet/maui/issues/31445
+ [Test, Order(12)]
+ public void TitleIcon_AddingTwice_DoesNotDuplicate()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("TitleIconButton");
+ App.Tap("TitleIconButton");
+ App.WaitForElement("TitleIconButton");
+ App.Tap("TitleIconButton");
+ App.WaitForElement("TitleIconButton");
+ App.Tap("TitleIconButton");
+ VerifyScreenshot();
+ }
+#endif
+
+ [Test, Order(13)]
+ public void Combine_BarBackgroundColor_TextColor_IconColor_Visual()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+ // Set bar background color and text color
+ App.WaitForElement("BarBackgroundColorBlueButton");
+ App.Tap("BarBackgroundColorBlueButton");
+ App.WaitForElement("BarTextColorWhiteButton");
+ App.Tap("BarTextColorWhiteButton");
+ // Set icon color
+ App.WaitForElement("IconColorRedButton");
+ App.Tap("IconColorRedButton");
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton");
+ // Screenshot: Combined bar background, text color and icon color on pushed page
+ VerifyScreenshot();
+ }
+
+ [Test, Order(14)]
+ public void TitleIcon_And_TitleView_Persist_On_Push_Then_Clear()
+ {
+ App.WaitForElement("PopToRootPageButton");
+ App.Tap("PopToRootPageButton");
+
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+ // Add both title icon and custom title view
+ App.WaitForElement("TitleIconButton");
+ App.Tap("TitleIconButton");
+ App.WaitForElement("TitleViewButton");
+ App.Tap("TitleViewButton");
+ App.WaitForElement("BackButtonTitleEntry");
+ App.ClearText("BackButtonTitleEntry");
+ App.EnterText("BackButtonTitleEntry", "My Back");
+ App.PressEnter();
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+ // Push and verify they persist
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton");
+ // Screenshot: Title icon and custom title view present on pushed page
+ VerifyScreenshot();
+ }
+
+ [Test, Order(15)]
+ public void EventParams_Update_On_Push_And_Pop()
+ {
+ App.WaitForElement("PopToRootPageButton");
+ App.Tap("PopToRootPageButton");
+
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+ // Push to Page 2
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton");
+ // Pop back to root (labels live on root page)
+ App.WaitForElement("PopPageButton");
+ App.Tap("PopPageButton");
+ // Validate param label contains expected keys after navigation sequence
+ App.WaitForElement("NavigationEventParamsLabel");
+ var text = App.FindElement("NavigationEventParamsLabel").GetText();
+ Assert.That(text, Does.Match("PreviousPageTitle|BeforeCount"));
+ }
+
+ [Test, Order(16)]
+ public void Combine_AllFeatures_Then_Push_Pop_Verify_AllEventsAndParams()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+ // Combine several features
+ App.WaitForElement("BarBackgroundColorBlueButton");
+ App.Tap("BarBackgroundColorBlueButton");
+ App.WaitForElement("BarTextColorWhiteButton");
+ App.Tap("BarTextColorWhiteButton");
+ App.WaitForElement("BarBackgroundLinearButton");
+ App.Tap("BarBackgroundLinearButton");
+ App.WaitForElement("IconColorPurpleButton");
+ App.Tap("IconColorPurpleButton");
+ App.WaitForElement("BackButtonTitleEntry");
+ App.ClearText("BackButtonTitleEntry");
+ App.EnterText("BackButtonTitleEntry", "TestBack");
+ App.PressEnter();
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+ App.WaitForElement("TitleIconButton");
+ App.Tap("TitleIconButton");
+ App.WaitForElement("TitleViewButton");
+ App.Tap("TitleViewButton");
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ // Push to Page 2
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton");
+ App.WaitForElement("PopPageButton"); // we are on Page 2
+
+ // Pop back to root so we can read root labels
+ App.Tap("PopPageButton");
+ App.WaitForElement("CurrentPageLabel");
+
+ // Ensure all three events reported and include expected page names/keys
+ App.WaitForElement("NavigatedFromStatusLabel");
+ var fromStatus = App.FindElement("NavigatedFromStatusLabel").GetText();
+ Assert.That(fromStatus, Does.Contain("Page 2"), "NavigatedFrom should be raised on Page 2");
+
+ App.WaitForElement("NavigatingFromStatusLabel");
+ var preFromStatus = App.FindElement("NavigatingFromStatusLabel").GetText();
+ Assert.That(preFromStatus, Does.Contain("Page 2"), "NavigatingFrom should be raised on Page 2");
+
+ App.WaitForElement("NavigatedToStatusLabel");
+ var toStatus = App.FindElement("NavigatedToStatusLabel").GetText();
+ Assert.That(toStatus, Does.Contain("Sample Page"), "NavigatedTo should be raised on Sample Page after pop");
+
+ // Params validations
+ var toParams = App.FindElement("NavigatedToParamsLabel").GetText();
+ Assert.That(toParams, Does.Contain("PreviousPageTitle=Page 2"));
+
+ var fromParams = App.FindElement("NavigatedFromParamsLabel").GetText();
+ Assert.That(fromParams, Does.Contain("DestinationTitle=Sample Page"));
+ Assert.That(fromParams, Does.Contain("Type=Pop"));
+
+ var preParams = App.FindElement("NavigatingFromParamsLabel").GetText();
+ Assert.That(preParams, Does.Contain("Requested=Pop"));
+ }
+
+ [Test, Order(17)]
+ public void Combine_AllFeatures_PushToPage3_PopToRoot_Verify_AllEventsAndParams()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+ // Ensure some non-defaults are set
+ App.WaitForElement("BarBackgroundColorRedButton");
+ App.Tap("BarBackgroundColorRedButton");
+ App.WaitForElement("BarTextColorBlackButton");
+ App.Tap("BarTextColorBlackButton");
+ App.WaitForElement("IconColorRedButton");
+ App.Tap("IconColorRedButton");
+
+ // Go to Page 3
+ App.WaitForElement("PushPageButton");
+ App.Tap("PushPageButton"); // Page 2
+ App.WaitForElement("PushPage3Button");
+ App.Tap("PushPage3Button"); // Page 3
+ App.WaitForElement("PopToRootPageButton");
+
+ // Pop to root
+ App.Tap("PopToRootPageButton");
+ App.WaitForElement("CurrentPageLabel");
+
+ // Validate event labels reference Page 3 and Sample Page appropriately
+ var fromStatus = App.FindElement("NavigatedFromStatusLabel").GetText();
+ Assert.That(fromStatus, Does.Contain("Page 3"), "NavigatedFrom should be raised on Page 3");
+
+ var preFromStatus = App.FindElement("NavigatingFromStatusLabel").GetText();
+ Assert.That(preFromStatus, Does.Contain("Page 3"), "NavigatingFrom should be raised on Page 3");
+
+ var toStatus = App.FindElement("NavigatedToStatusLabel").GetText();
+ Assert.That(toStatus, Does.Contain("Sample Page"), "NavigatedTo should be raised on Sample Page after PopToRoot");
+
+ // Params validations for PopToRoot flow
+ var toParams = App.FindElement("NavigatedToParamsLabel").GetText();
+ Assert.That(toParams, Does.Contain("PreviousPageTitle=Page 3"));
+
+ var fromParams = App.FindElement("NavigatedFromParamsLabel").GetText();
+ Assert.That(fromParams, Does.Contain("DestinationTitle=Sample Page"));
+ Assert.That(fromParams, Does.Contain("Type=PopToRoot"));
+
+ var preParams = App.FindElement("NavigatingFromParamsLabel").GetText();
+ Assert.That(preParams, Does.Contain("Requested=PopToRoot"));
+ }
+
+ [Test, Order(18)]
+ public void TitleView_Add_Visual()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ Exception? exception = null;
+ App.WaitForElement("TitleViewButton");
+ App.Tap("TitleViewButton");
+ // Screenshot: TitleView applied
+ VerifyScreenshotOrSetException(ref exception, "TitleViewApplied");
+ App.WaitForElement("TitleViewClearButton");
+ App.Tap("TitleViewClearButton");
+ // Screenshot: TitleView cleared
+ VerifyScreenshotOrSetException(ref exception, "TitleViewCleared");
+ if (exception != null)
+ throw exception;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs
new file mode 100644
index 000000000000..510dd025bd9a
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs
@@ -0,0 +1,513 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests
+{
+ public class PickerFeatureTests : UITest
+ {
+ public const string PickerFeatureMatrix = "Picker Feature Matrix";
+
+ public PickerFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(PickerFeatureMatrix);
+ }
+
+ public void VerifyPickerScreenshot()
+ {
+#if WINDOWS
+ VerifyScreenshot(cropTop: 100);
+#else
+ VerifyScreenshot();
+#endif
+ }
+
+ [Test, Order(1)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_Validate_VerifyLabels()
+ {
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+#if TEST_FAILS_ON_CATALYST
+
+ [Test, Order(2)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_TapPicker_TakeScreenshot()
+ {
+ App.WaitForElement("Picker");
+ App.Tap("Picker");
+ VerifyPickerScreenshot();
+
+#if IOS
+ App.WaitForElement("Done");
+ App.Tap("Done");
+#elif WINDOWS
+ App.Tap("Option 2 - Second option");
+#endif
+ }
+#endif
+
+#if TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST
+
+ [Test, Order(3)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SelectItem_VerifySelectedItem()
+ {
+#if ANDROID
+ App.WaitForElement("Cancel");
+ App.Tap("Cancel");
+#endif
+ App.WaitForElement("Picker");
+ App.Tap("Picker");
+ App.WaitForElement("Option 3 - Third option");
+ App.Tap("Option 3 - Third option");
+ VerifyPickerScreenshot();
+ }
+#endif
+
+ [Test, Order(4)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetSelectedIndex_VerifySelectedIndexAndItem()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("SelectedIndexEntry");
+ App.ClearText("SelectedIndexEntry");
+ App.EnterText("SelectedIndexEntry", "1");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ Assert.That(App.FindElement("SelectedIndexLabel").GetText(), Is.EqualTo("1"));
+ VerifyPickerScreenshot();
+ }
+
+ [Test, Order(5)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetSelectedItem_VerifySelectedItemLabel()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("SelectedItemEntry");
+ App.ClearText("SelectedItemEntry");
+ App.EnterText("SelectedItemEntry", "Option 4 - Fourth option");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ Assert.That(App.FindElement("SelectedItemLabel").GetText(), Is.EqualTo("Option 4 - Fourth option"));
+ VerifyPickerScreenshot();
+ }
+
+#if TEST_FAILS_ON_WINDOWS // Issue Link - https://github.com/dotnet/maui/issues/30464
+
+ [Test, Order(6)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetCharacterSpacing_VerifyCharacterSpacingLabel()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CharacterSpacingEntry");
+ App.ClearText("CharacterSpacingEntry");
+ App.EnterText("CharacterSpacingEntry", "5");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+#endif
+
+#if TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_IOS && TEST_FAILS_ON_WINDOWS // Issue Link - https://github.com/dotnet/maui/issues/30463, https://github.com/dotnet/maui/issues/30464
+
+ [Test, Order(7)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetCharacterSpacingAndTitle_VerifyBoth()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "Custom Title");
+ App.WaitForElement("CharacterSpacingEntry");
+ App.ClearText("CharacterSpacingEntry");
+ App.EnterText("CharacterSpacingEntry", "5");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+#endif
+
+ [Test, Order(8)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FontSizeEntry");
+ App.ClearText("FontSizeEntry");
+ App.EnterText("FontSizeEntry", "24");
+ App.PressEnter();
+ App.WaitForElement("FontAttributesBold");
+ App.Tap("FontAttributesBold");
+ App.WaitForElement("SelectedIndexEntry");
+ App.ClearText("SelectedIndexEntry");
+ App.EnterText("SelectedIndexEntry", "1");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+ [Test, Order(9)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FontSizeEntry");
+ App.ClearText("FontSizeEntry");
+ App.EnterText("FontSizeEntry", "18");
+ App.PressEnter();
+ App.WaitForElement("FontFamilyDokdoButton");
+ App.Tap("FontFamilyDokdoButton");
+ App.WaitForElement("SelectedIndexEntry");
+ App.ClearText("SelectedIndexEntry");
+ App.EnterText("SelectedIndexEntry", "1");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+ [Test, Order(10)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetFlowDirectionRTL_VerifyFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FlowDirectionRTL");
+ App.Tap("FlowDirectionRTL");
+ App.WaitForElement("SelectedIndexEntry");
+ App.ClearText("SelectedIndexEntry");
+ App.EnterText("SelectedIndexEntry", "1");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+#if TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_IOS // Issue Link - https://github.com/dotnet/maui/issues/30463
+
+ [Test, Order(11)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetFlowDirectionRTLAndTitle_VerifyFlowDirectionAndTitle()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FlowDirectionRTL");
+ App.Tap("FlowDirectionRTL");
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "RTL Title");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+#endif
+
+ [Test, Order(12)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FontAttributesItalic");
+ App.Tap("FontAttributesItalic");
+ App.WaitForElement("FontFamilyDokdoButton");
+ App.Tap("FontFamilyDokdoButton");
+ App.WaitForElement("SelectedIndexEntry");
+ App.ClearText("SelectedIndexEntry");
+ App.EnterText("SelectedIndexEntry", "2");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+ [Test, Order(13)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetIsEnabledFalse_VerifyPickerDisabled()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IsEnabledFalseRadio");
+ App.Tap("IsEnabledFalseRadio");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ App.Tap("Picker");
+ VerifyPickerScreenshot();
+ }
+
+ [Test, Order(14)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetIsVisibleFalse_VerifyPickerHidden()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IsVisibleFalseRadio");
+ App.Tap("IsVisibleFalseRadio");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForNoElement("Picker");
+ }
+
+ [Test, Order(15)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("HorizontalTextAlignmentEnd");
+ App.Tap("HorizontalTextAlignmentEnd");
+ App.WaitForElement("SelectedItemEntry");
+ App.ClearText("SelectedItemEntry");
+ App.EnterText("SelectedItemEntry", "Option 2 - Second option");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+#if TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_IOS // Issue Link - https://github.com/dotnet/maui/issues/30463
+
+ [Test, Order(16)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetHorizontalTextAlignmentEndAndTitle_VerifyTitleAlignment()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("HorizontalTextAlignmentEnd");
+ App.Tap("HorizontalTextAlignmentEnd");
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "Aligned Title");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+#endif
+
+ [Test, Order(17)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("VerticalTextAlignmentEnd");
+ App.Tap("VerticalTextAlignmentEnd");
+ App.WaitForElement("SelectedItemEntry");
+ App.ClearText("SelectedItemEntry");
+ App.EnterText("SelectedItemEntry", "Option 3 - Third option");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+#if TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_IOS // Issue Link - https://github.com/dotnet/maui/issues/30463
+
+ [Test, Order(18)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetVerticalTextAlignmentEndAndTitle_VerifyTitleAlignment()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("VerticalTextAlignmentEnd");
+ App.Tap("VerticalTextAlignmentEnd");
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "Aligned Title");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+#endif
+
+#if TEST_FAILS_ON_WINDOWS // Issue Link - https://github.com/dotnet/maui/issues/29812
+
+ [Test, Order(19)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetShadow_VerifyShadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ShadowTrueButton");
+ App.Tap("ShadowTrueButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+#endif
+
+ [Test, Order(20)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetTextColorRed_VerifyTextColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("TextColorRedButton");
+ App.Tap("TextColorRedButton");
+ App.WaitForElement("SelectedIndexEntry");
+ App.ClearText("SelectedIndexEntry");
+ App.EnterText("SelectedIndexEntry", "2");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+#if TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_IOS // Issue Link - https://github.com/dotnet/maui/issues/30463
+
+ [Test, Order(21)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetTitle_VerifyTitleLabel()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "Choose Option");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+ [Test, Order(22)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetTitleColorOrange_VerifyTitleColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("TitleColorOrangeButton");
+ App.Tap("TitleColorOrangeButton");
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "Choose Option");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+ [Test, Order(23)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetTitleWithFontSize_VerifyTitleAndFontSize()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "Styled Title");
+ App.WaitForElement("FontSizeEntry");
+ App.ClearText("FontSizeEntry");
+ App.EnterText("FontSizeEntry", "22");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+ [Test, Order(24)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetTitleWithFontAttributeBold_VerifyTitleAndFontAttribute()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "Styled Title");
+ App.WaitForElement("FontAttributesBold");
+ App.Tap("FontAttributesBold");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+
+ [Test, Order(25)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetTitleWithFontFamilyDokdo_VerifyTitleAndFontFamily()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "Styled Title");
+ App.WaitForElement("FontFamilyDokdoButton");
+ App.Tap("FontFamilyDokdoButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+#endif
+
+#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_IOS && TEST_FAILS_ON_WINDOWS // Issue Link - https://github.com/dotnet/maui/issues/4818
+
+ [Test, Order(26)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SetItemDisplayBindingName_VerifyItemDisplay()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ItemDisplayNameButton");
+ App.Tap("ItemDisplayNameButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ VerifyPickerScreenshot();
+ }
+#endif
+
+ [Test, Order(27)]
+ [Category(UITestCategories.Picker)]
+ public void Picker_SelectedIndexChanged_VerifyEventTriggered()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("SelectedIndexEntry");
+ App.ClearText("SelectedIndexEntry");
+ App.EnterText("SelectedIndexEntry", "2");
+ App.PressEnter();
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("Picker");
+ Assert.That(App.FindElement("SelectedIndexChangedStatusLabel").GetText(), Is.EqualTo("Triggered"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/RefreshViewFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/RefreshViewFeatureTests.cs
new file mode 100644
index 000000000000..2923368e055b
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/RefreshViewFeatureTests.cs
@@ -0,0 +1,223 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests;
+
+public class RefreshViewFeatureTests : UITest
+{
+ public const string RefreshViewFeatureMatrix = "RefreshView Feature Matrix";
+
+ public RefreshViewFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(RefreshViewFeatureMatrix);
+ }
+
+ [Test, Order(1)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_ValidateDefaultValues_VerifyLabels()
+ {
+ App.WaitForElement("Options");
+ Assert.That(App.FindElement("IsRefreshingValueLabel").GetText(), Is.EqualTo("False"));
+ Assert.That(App.FindElement("IsEnabledValueLabel").GetText(), Is.EqualTo("True"));
+ Assert.That(App.FindElement("IsVisibleValueLabel").GetText(), Is.EqualTo("True"));
+ Assert.That(App.FindElement("RefreshStatusLabel").GetText(), Is.EqualTo("None"));
+ }
+
+#if TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_WINDOWS // In Appium PullToRefresh is not supported on Catalyst and Windows
+
+ [Test, Order(2)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_InsideScrollView_VerifyScrollAndRefresh()
+ {
+ App.WaitForElement("RefreshView");
+ App.WaitForElement("ScrollViewContentButton");
+ App.Tap("ScrollViewContentButton");
+ App.WaitForElement("RefreshView");
+ App.ScrollUp("RefreshView");
+ Assert.That(App.FindElement("RefreshStatusLabel").GetText(), Is.Not.EqualTo("None"));
+ }
+
+ [Test, Order(3)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_InsideCollectionView_VerifyRefresh()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("RefreshView");
+ App.WaitForElement("CollectionViewContentButton");
+ App.Tap("CollectionViewContentButton");
+ App.WaitForElement("RefreshView");
+ App.ScrollUp("RefreshView");
+ Assert.That(App.FindElement("RefreshStatusLabel").GetText(), Is.Not.EqualTo("None"));
+ }
+
+ [Test, Order(4)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_SetCommandParameterTrue_VerifyCommandParameter()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CommandRedButton");
+ App.Tap("CommandRedButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("RefreshView");
+ App.ScrollUp("RefreshView");
+ Assert.That(App.FindElement("RefreshStatusLabel").GetText(), Is.Not.EqualTo("None"));
+ }
+
+ [Test, Order(5)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_SetIsEnabled_VerifyEnabledState()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IsEnabledFalseButton");
+ App.Tap("IsEnabledFalseButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("RefreshView");
+ App.ScrollUp("RefreshView");
+ Assert.That(App.FindElement("RefreshStatusLabel").GetText(), Is.EqualTo("None"));
+ }
+
+ [Test, Order(6)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_SetRefreshColorBlue_VerifyColorChange()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("RefreshColorBlueRadio");
+ App.Tap("RefreshColorBlueRadio");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("RefreshView");
+ App.WaitForElement("CollectionViewContentButton");
+ App.Tap("CollectionViewContentButton");
+ App.WaitForElement("RefreshView");
+ App.ScrollUp("RefreshView");
+ Assert.That(App.FindElement("RefreshStatusLabel").GetText(), Is.Not.EqualTo("None"));
+ }
+
+ [Test, Order(7)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_SetFlowDirectionRightToLeft_VerifyFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FlowDirectionRTL");
+ App.Tap("FlowDirectionRTL");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("RefreshView");
+ App.ScrollUp("RefreshView");
+ Assert.That(App.FindElement("RefreshStatusLabel").GetText(), Is.Not.EqualTo("None"));
+ }
+#endif
+
+ [Test, Order(8)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_SetIsVisible_VerifyVisibilityState()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IsVisibleFalseButton");
+ App.Tap("IsVisibleFalseButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForNoElement("RefreshView");
+ }
+
+#if TEST_FAILS_ON_WINDOWS // Issue Link - https://github.com/dotnet/maui/issues/30535
+
+ [Test, Order(9)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_SetIsRefreshingAndScrollView_VerifyStatusChanges()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IsRefreshingTrueRadioButton");
+ App.Tap("IsRefreshingTrueRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("RefreshView");
+ App.WaitForElement("ScrollViewContentButton");
+ App.Tap("ScrollViewContentButton");
+ Assert.That(App.FindElement("IsRefreshingValueLabel").GetText(), Is.EqualTo("True"));
+ }
+
+ [Test, Order(10)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_SetIsRefreshingAndCollectionView_VerifyStatusChanges()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IsRefreshingTrueRadioButton");
+ App.Tap("IsRefreshingTrueRadioButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("RefreshView");
+ App.WaitForElement("CollectionViewContentButton");
+ App.Tap("CollectionViewContentButton");
+ Assert.That(App.FindElement("IsRefreshingValueLabel").GetText(), Is.EqualTo("True"));
+ }
+
+ [Test, Order(11)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_SetRefreshColorRedAndIsRefreshing_VerifyColorChange()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IsRefreshingTrueRadioButton");
+ App.Tap("IsRefreshingTrueRadioButton");
+ App.WaitForElement("RefreshColorRedRadio");
+ App.Tap("RefreshColorRedRadio");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("RefreshView");
+ Assert.That(App.FindElement("IsRefreshingValueLabel").GetText(), Is.EqualTo("True"));
+ }
+#endif
+
+#if TEST_FAILS_ON_WINDOWS // Issue Link - https://github.com/dotnet/maui/issues/29812
+
+ [Test, Order(12)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_SetShadow_VerifyShadowApplied()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ShadowTrueButton");
+ App.Tap("ShadowTrueButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("RefreshView");
+ VerifyScreenshot();
+ }
+
+ [Test, Order(13)]
+ [Category(UITestCategories.RefreshView)]
+ public void RefreshView_SetShadowWithCollectionView_VerifyShadowApplied()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ShadowTrueButton");
+ App.Tap("ShadowTrueButton");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("RefreshView");
+ App.WaitForElement("CollectionViewContentButton");
+ App.Tap("CollectionViewContentButton");
+ VerifyScreenshot();
+ }
+#endif
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/SearchBarFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/SearchBarFeatureTests.cs
index 3a0d3e52a2ef..2cb2ff4f8f7f 100644
--- a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/SearchBarFeatureTests.cs
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/SearchBarFeatureTests.cs
@@ -36,18 +36,19 @@ public void SearchBar_InitialState_VerifyVisualState()
}
#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_WINDOWS // Issue Link - https://github.com/dotnet/maui/issues/14061
- [Test, Order(2)]
- [Category(UITestCategories.SearchBar)]
- public void SearchBar_SearchButtonClicked_VerifyEventTriggered()
- {
- App.WaitForElement("SearchBar");
- App.ClearText("SearchBar");
- App.EnterText("SearchBar", "Test Search");
- App.PressEnter();
- App.WaitForElement("SearchButtonPressedLabel");
- var labelText = App.WaitForElement("SearchButtonPressedLabel").GetText();
- Assert.That(labelText, Is.EqualTo("Yes"));
- }
+
+ [Test, Order(2)]
+ [Category(UITestCategories.SearchBar)]
+ public void SearchBar_SearchButtonClicked_VerifyEventTriggered()
+ {
+ App.WaitForElement("SearchBar");
+ App.ClearText("SearchBar");
+ App.EnterText("SearchBar", "Test Search");
+ App.PressEnter();
+ App.WaitForElement("SearchButtonPressedLabel");
+ var labelText = App.WaitForElement("SearchButtonPressedLabel").GetText();
+ Assert.That(labelText, Is.EqualTo("Yes"));
+ }
[Test, Order(3)]
[Category(UITestCategories.SearchBar)]
@@ -106,7 +107,6 @@ public void SearchBar_SetFlowDirection_VerifyVisualState()
App.WaitForElementTillPageNavigationSettled("SearchBar");
App.ClearText("SearchBar");
App.EnterText("SearchBar", "Search Text");
- App.DismissKeyboard();
VerifyScreenshotWithPlatformCropping();
}
#endif
@@ -464,8 +464,6 @@ public void SearchBar_SetKeyboardAndText_VerifyVisualState()
App.WaitForElementTillPageNavigationSettled("SearchBar");
App.Tap("SearchBar");
VerifyScreenshotWithPlatformCropping();
- App.EnterText("SearchBar", "1234567890");
- App.DismissKeyboard();
}
#endif
@@ -483,7 +481,6 @@ public void SearchBar_SetMaxLengthAndText()
App.WaitForElementTillPageNavigationSettled("SearchBar");
App.ClearText("SearchBar");
App.EnterText("SearchBar", "SearchText");
- App.DismissKeyboard();
App.WaitForElement("SearchBar");
var text = string.Empty;
#if ANDROID
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ShapesFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ShapesFeatureTests.cs
new file mode 100644
index 000000000000..83b306176adb
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/ShapesFeatureTests.cs
@@ -0,0 +1,871 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+
+namespace Microsoft.Maui.TestCases.Tests;
+
+public class ShapesFeatureTests : UITest
+{
+ public const string ShapesFeatureMatrix = "Shapes Feature Matrix";
+
+ public ShapesFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(ShapesFeatureMatrix);
+ }
+
+ public void VerifyShapeScreenshot()
+ {
+#if WINDOWS
+ VerifyScreenshot(cropTop: 100);
+#else
+ VerifyScreenshot();
+#endif
+ }
+
+#if TEST_FAILS_ON_WINDOWS //For more information see: https://github.com/dotnet/maui/issues/29812
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Rectangle_FillColorWithStrokeColor_Shadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("FillColorBlueRadioButton");
+ App.Tap("FillColorBlueRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Ellipse_FillColorWithStrokeColor_Shadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("EllipseRadioButton");
+ App.Tap("EllipseRadioButton");
+
+ App.WaitForElement("FillColorGreenRadioButton");
+ App.Tap("FillColorGreenRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Line_FillColorWithStrokeColor_Shadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("LineRadioButton");
+ App.Tap("LineRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+
+ App.WaitForElement("X1Entry");
+ App.Tap("X1Entry");
+ App.ClearText("X1Entry");
+ App.EnterText("X1Entry", "50");
+
+ App.WaitForElement("Y1Entry");
+ App.Tap("Y1Entry");
+ App.ClearText("Y1Entry");
+ App.EnterText("Y1Entry", "50");
+
+ App.WaitForElement("X2Entry");
+ App.Tap("X2Entry");
+ App.ClearText("X2Entry");
+ App.EnterText("X2Entry", "200");
+
+ App.WaitForElement("Y2Entry");
+ App.Tap("Y2Entry");
+ App.ClearText("Y2Entry");
+ App.EnterText("Y2Entry", "150");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Polygon_FillColorWithStrokeColor_Shadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolygonRadioButton");
+ App.Tap("PolygonRadioButton");
+
+ App.WaitForElement("FillColorBlueRadioButton");
+ App.Tap("FillColorBlueRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void PolyLine_FillColorWithStrokeColor_Shadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolyLineRadioButton");
+ App.Tap("PolyLineRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Path_FillColorWithStrokeColor_Shadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PathRadioButton");
+ App.Tap("PathRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+#endif
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Rectangle_DashArray_DashOffset_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeDashOffsetEntry");
+ App.Tap("StrokeDashOffsetEntry");
+ App.ClearText("StrokeDashOffsetEntry");
+ App.EnterText("StrokeDashOffsetEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Ellipse_DashArray_DashOffset_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("EllipseRadioButton");
+ App.Tap("EllipseRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeDashOffsetEntry");
+ App.Tap("StrokeDashOffsetEntry");
+ App.ClearText("StrokeDashOffsetEntry");
+ App.EnterText("StrokeDashOffsetEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void PolyLine_DashArray_DashOffset_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolyLineRadioButton");
+ App.Tap("PolyLineRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeDashOffsetEntry");
+ App.Tap("StrokeDashOffsetEntry");
+ App.ClearText("StrokeDashOffsetEntry");
+ App.EnterText("StrokeDashOffsetEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Polygon_DashArray_DashOffset_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolygonRadioButton");
+ App.Tap("PolygonRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeDashOffsetEntry");
+ App.Tap("StrokeDashOffsetEntry");
+ App.ClearText("StrokeDashOffsetEntry");
+ App.EnterText("StrokeDashOffsetEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Path_DashArray_DashOffset_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PathRadioButton");
+ App.Tap("PathRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeDashOffsetEntry");
+ App.Tap("StrokeDashOffsetEntry");
+ App.ClearText("StrokeDashOffsetEntry");
+ App.EnterText("StrokeDashOffsetEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Line_DashArray_DashOffset_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("LineRadioButton");
+ App.Tap("LineRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeDashOffsetEntry");
+ App.Tap("StrokeDashOffsetEntry");
+ App.ClearText("StrokeDashOffsetEntry");
+ App.EnterText("StrokeDashOffsetEntry", "5");
+
+ App.WaitForElement("X1Entry");
+ App.Tap("X1Entry");
+ App.ClearText("X1Entry");
+ App.EnterText("X1Entry", "50");
+
+ App.WaitForElement("Y1Entry");
+ App.Tap("Y1Entry");
+ App.ClearText("Y1Entry");
+ App.EnterText("Y1Entry", "50");
+
+ App.WaitForElement("X2Entry");
+ App.Tap("X2Entry");
+ App.ClearText("X2Entry");
+ App.EnterText("X2Entry", "200");
+
+ App.WaitForElement("Y2Entry");
+ App.Tap("Y2Entry");
+ App.ClearText("Y2Entry");
+ App.EnterText("Y2Entry", "150");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Path_Points_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PathRadioButton");
+ App.Tap("PathRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "4");
+
+ App.WaitForElement("PathDataEntry");
+ App.Tap("PathDataEntry");
+ App.ClearText("PathDataEntry");
+ App.EnterText("PathDataEntry", "M 20,100 Q 40,60 60,100 T 100,100 T 140,100 T 180,100 T 220,100 T 260,100");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void PolyLine_Points_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolyLineRadioButton");
+ App.Tap("PolyLineRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "4");
+
+ App.WaitForElement("PolyLinePointsEntry");
+ App.Tap("PolyLinePointsEntry");
+ App.ClearText("PolyLinePointsEntry");
+ App.EnterText("PolyLinePointsEntry", "0,0 10,30 15,0 18,60 23,30 35,30 40,0 43,60 48,30 100,30");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Shape_Polygon_Pentagon()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolygonRadioButton");
+ App.Tap("PolygonRadioButton");
+
+ App.WaitForElement("FillColorBlueRadioButton");
+ App.Tap("FillColorBlueRadioButton");
+
+ App.WaitForElement("PolygonPointsEntry");
+ App.Tap("PolygonPointsEntry");
+ App.ClearText("PolygonPointsEntry");
+ App.EnterText("PolygonPointsEntry", "150,50 195,90 175,140 125,140 105,90");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Shape_Rectangle_XAndYRadius()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("RadiusXEntry");
+ App.Tap("RadiusXEntry");
+ App.ClearText("RadiusXEntry");
+ App.EnterText("RadiusXEntry", "50");
+
+ App.WaitForElement("RadiusYEntry");
+ App.Tap("RadiusYEntry");
+ App.ClearText("RadiusYEntry");
+ App.EnterText("RadiusYEntry", "10");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Shape_Rectangle_HeightAndWidth()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RectangleHeightEntry");
+ App.Tap("RectangleHeightEntry");
+ App.ClearText("RectangleHeightEntry");
+ App.EnterText("RectangleHeightEntry", "100");
+
+ App.WaitForElement("RectangleWidthEntry");
+ App.Tap("RectangleWidthEntry");
+ App.ClearText("RectangleWidthEntry");
+ App.EnterText("RectangleWidthEntry", "200");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Rectangle_StrokeColor_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Ellipse_StrokeColor_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("EllipseRadioButton");
+ App.Tap("EllipseRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("FillColorBlueRadioButton");
+ App.Tap("FillColorBlueRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Line_StrokeColor_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("LineRadioButton");
+ App.Tap("LineRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("X1Entry");
+ App.Tap("X1Entry");
+ App.ClearText("X1Entry");
+ App.EnterText("X1Entry", "50");
+
+ App.WaitForElement("Y1Entry");
+ App.Tap("Y1Entry");
+ App.ClearText("Y1Entry");
+ App.EnterText("Y1Entry", "50");
+
+ App.WaitForElement("X2Entry");
+ App.Tap("X2Entry");
+ App.ClearText("X2Entry");
+ App.EnterText("X2Entry", "200");
+
+ App.WaitForElement("Y2Entry");
+ App.Tap("Y2Entry");
+ App.ClearText("Y2Entry");
+ App.EnterText("Y2Entry", "150");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Polygon_StrokeColor_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolygonRadioButton");
+ App.Tap("PolygonRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("FillColorGreenRadioButton");
+ App.Tap("FillColorGreenRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void PolyLine_StrokeColor_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolyLineRadioButton");
+ App.Tap("PolyLineRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Path_StrokeColor_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PathRadioButton");
+ App.Tap("PathRadioButton");
+
+ App.WaitForElement("FillColorGreenRadioButton");
+ App.Tap("FillColorGreenRadioButton");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Rectangle_StrokeColor_DashArray_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Ellipse_StrokeColor_DashArray_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("EllipseRadioButton");
+ App.Tap("EllipseRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Line_StrokeColor_DashArray_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("LineRadioButton");
+ App.Tap("LineRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("X1Entry");
+ App.Tap("X1Entry");
+ App.ClearText("X1Entry");
+ App.EnterText("X1Entry", "50");
+
+ App.WaitForElement("Y1Entry");
+ App.Tap("Y1Entry");
+ App.ClearText("Y1Entry");
+ App.EnterText("Y1Entry", "50");
+
+ App.WaitForElement("X2Entry");
+ App.Tap("X2Entry");
+ App.ClearText("X2Entry");
+ App.EnterText("X2Entry", "200");
+
+ App.WaitForElement("Y2Entry");
+ App.Tap("Y2Entry");
+ App.ClearText("Y2Entry");
+ App.EnterText("Y2Entry", "150");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Polygon_StrokeColor_DashArray_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolygonRadioButton");
+ App.Tap("PolygonRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void PolyLine_StrokeColor_DashArray_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PolyLineRadioButton");
+ App.Tap("PolyLineRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+ [Test]
+ [Category(UITestCategories.Shape)]
+ public void Path_StrokeColor_DashArray_Thickness()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("PathRadioButton");
+ App.Tap("PathRadioButton");
+
+ App.WaitForElement("StrokeColorRedRadioButton");
+ App.Tap("StrokeColorRedRadioButton");
+
+ App.WaitForElement("StrokeDashArrayEntry");
+ App.Tap("StrokeDashArrayEntry");
+ App.ClearText("StrokeDashArrayEntry");
+ App.EnterText("StrokeDashArrayEntry", "5,2");
+
+ App.WaitForElement("StrokeThicknessEntry");
+ App.Tap("StrokeThicknessEntry");
+ App.ClearText("StrokeThicknessEntry");
+ App.EnterText("StrokeThicknessEntry", "5");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyShapeScreenshot();
+ }
+
+}
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/StackLayoutFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/StackLayoutFeatureTests.cs
new file mode 100644
index 000000000000..7699d6fd661e
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/StackLayoutFeatureTests.cs
@@ -0,0 +1,446 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests;
+
+[Category(UITestCategories.Layout)]
+public class StackLayoutFeatureTests : UITest
+{
+ public const string StackLayoutFeatureMatrix = "StackLayout Feature Matrix";
+
+ public StackLayoutFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(StackLayoutFeatureMatrix);
+ }
+
+ [Test]
+ public void HorizontalStackLayout_IsVisible()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("CheckBoxIsVisible");
+ App.Tap("CheckBoxIsVisible");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ App.WaitForNoElement("LabelSpacing");
+ }
+
+ [Test]
+ public void VerticalStackLayout_IsVisible()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RadioVertical");
+ App.Tap("RadioVertical");
+
+ App.WaitForElement("CheckBoxIsVisible");
+ App.Tap("CheckBoxIsVisible");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ App.WaitForNoElement("LabelSpacing");
+ }
+
+ [Test]
+ public void HorizontalStackLayout_RTLFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("CheckBoxIsRtl");
+ App.Tap("CheckBoxIsRtl");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void VerticalStackLayout_RTLFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RadioVertical");
+ App.Tap("RadioVertical");
+
+ App.WaitForElement("CheckBoxIsRtl");
+ App.Tap("CheckBoxIsRtl");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void VerticalStackLayout_Spacing_With_RTL()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RadioVertical");
+ App.Tap("RadioVertical");
+
+ App.WaitForElement("EntrySpacing");
+ App.ClearText("EntrySpacing");
+ App.EnterText("EntrySpacing", "20");
+
+ App.WaitForElement("CheckBoxIsRtl");
+ App.Tap("CheckBoxIsRtl");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void HorizontalStackLayout_Spacing_With_RTL()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("EntrySpacing");
+ App.ClearText("EntrySpacing");
+ App.EnterText("EntrySpacing", "20");
+
+ App.WaitForElement("CheckBoxIsRtl");
+ App.Tap("CheckBoxIsRtl");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void HorizontalStackLayout_Spacing_With_Height()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("EntrySpacing");
+ App.ClearText("EntrySpacing");
+ App.EnterText("EntrySpacing", "30");
+
+ App.WaitForElement("EntryHeight");
+ App.ClearText("EntryHeight");
+ App.EnterText("EntryHeight", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void HorizontalStackLayout_Spacing_With_Width()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("EntrySpacing");
+ App.ClearText("EntrySpacing");
+ App.EnterText("EntrySpacing", "30");
+
+ App.WaitForElement("EntryWidth");
+ App.ClearText("EntryWidth");
+ App.EnterText("EntryWidth", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void HorizontalStackLayout_RTLFlowDirection_With_Height()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("CheckBoxIsRtl");
+ App.Tap("CheckBoxIsRtl");
+
+ App.WaitForElement("EntryHeight");
+ App.ClearText("EntryHeight");
+ App.EnterText("EntryHeight", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void HorizontalStackLayout_RTLFlowDirection_With_Width()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("CheckBoxIsRtl");
+ App.Tap("CheckBoxIsRtl");
+
+ App.WaitForElement("EntryWidth");
+ App.ClearText("EntryWidth");
+ App.EnterText("EntryWidth", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void VerticalStackLayout_Spacing_With_Width()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RadioVertical");
+ App.Tap("RadioVertical");
+
+ App.WaitForElement("EntrySpacing");
+ App.ClearText("EntrySpacing");
+ App.EnterText("EntrySpacing", "30");
+
+ App.WaitForElement("EntryWidth");
+ App.ClearText("EntryWidth");
+ App.EnterText("EntryWidth", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void VerticalStackLayout_Spacing_With_Height()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RadioVertical");
+ App.Tap("RadioVertical");
+
+ App.WaitForElement("EntrySpacing");
+ App.ClearText("EntrySpacing");
+ App.EnterText("EntrySpacing", "30");
+
+ App.WaitForElement("EntryHeight");
+ App.ClearText("EntryHeight");
+ App.EnterText("EntryHeight", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void VerticalStackLayout_RTLFlowDirection_With_Width()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RadioVertical");
+ App.Tap("RadioVertical");
+
+ App.WaitForElement("CheckBoxIsRtl");
+ App.Tap("CheckBoxIsRtl");
+
+ App.WaitForElement("EntryWidth");
+ App.ClearText("EntryWidth");
+ App.EnterText("EntryWidth", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void VerticalStackLayout_RTLFlowDirection_With_Height()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RadioVertical");
+ App.Tap("RadioVertical");
+
+ App.WaitForElement("CheckBoxIsRtl");
+ App.Tap("CheckBoxIsRtl");
+
+ App.WaitForElement("EntryHeight");
+ App.ClearText("EntryHeight");
+ App.EnterText("EntryHeight", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void VerticalStackLayout_RTLFlowDirection_With_HeightAndWidth()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RadioVertical");
+ App.Tap("RadioVertical");
+
+ App.WaitForElement("CheckBoxIsRtl");
+ App.Tap("CheckBoxIsRtl");
+
+ App.WaitForElement("EntryHeight");
+ App.ClearText("EntryHeight");
+ App.EnterText("EntryHeight", "50");
+
+ App.WaitForElement("EntryWidth");
+ App.ClearText("EntryWidth");
+ App.EnterText("EntryWidth", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void HorizontalStackLayout_RTLFlowDirection_With_HeightAndWidth()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("CheckBoxIsRtl");
+ App.Tap("CheckBoxIsRtl");
+
+ App.WaitForElement("EntryHeight");
+ App.ClearText("EntryHeight");
+ App.EnterText("EntryHeight", "50");
+
+ App.WaitForElement("EntryWidth");
+ App.ClearText("EntryWidth");
+ App.EnterText("EntryWidth", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void VerticalStackLayout_Spacing_With_HeightAndWidth()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RadioVertical");
+ App.Tap("RadioVertical");
+
+ App.WaitForElement("EntrySpacing");
+ App.ClearText("EntrySpacing");
+ App.EnterText("EntrySpacing", "30");
+
+ App.WaitForElement("EntryHeight");
+ App.ClearText("EntryHeight");
+ App.EnterText("EntryHeight", "50");
+
+ App.WaitForElement("EntryWidth");
+ App.ClearText("EntryWidth");
+ App.EnterText("EntryWidth", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ public void HorizontalStackLayout_Spacing_With_HeightAndWidth()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("EntrySpacing");
+ App.ClearText("EntrySpacing");
+ App.EnterText("EntrySpacing", "30");
+
+ App.WaitForElement("EntryHeight");
+ App.ClearText("EntryHeight");
+ App.EnterText("EntryHeight", "50");
+
+ App.WaitForElement("EntryWidth");
+ App.ClearText("EntryWidth");
+ App.EnterText("EntryWidth", "50");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+#if ANDROID || IOS
+ [Test]
+ public void HorizontalStackLayout_Spacing_WithLandscape()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("EntrySpacing");
+ App.ClearText("EntrySpacing");
+ App.EnterText("EntrySpacing", "30");
+
+ App.SetOrientationLandscape();
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+#if ANDROID
+ VerifyScreenshot(cropLeft: 125);
+#else
+ VerifyScreenshot();
+#endif
+ }
+
+ [Test]
+ public void VerticalStackLayout_Spacing_WithLandscape()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("RadioVertical");
+ App.Tap("RadioVertical");
+
+ App.WaitForElement("EntrySpacing");
+ App.ClearText("EntrySpacing");
+ App.EnterText("EntrySpacing", "30");
+
+ App.SetOrientationLandscape();
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+#if ANDROID
+ VerifyScreenshot(cropLeft: 125);
+#else
+ VerifyScreenshot();
+#endif
+ }
+#endif
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/SwipeViewFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/SwipeViewFeatureTests.cs
new file mode 100644
index 000000000000..048fb253db2a
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/SwipeViewFeatureTests.cs
@@ -0,0 +1,834 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+namespace Microsoft.Maui.TestCases.Tests;
+
+[Category(UITestCategories.SwipeView)]
+public class SwipeViewFeatureTests : UITest
+{
+ public const string SwipeViewFeatureMatrix = "SwipeView Feature Matrix";
+
+ public SwipeViewFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(SwipeViewFeatureMatrix);
+ }
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/30949 && https://github.com/dotnet/maui/issues/30947
+ [Test, Order(1)]
+ public void VerifySwipeViewWhenLabelSwipeItemAndEvents()
+ {
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ App.WaitForElement("Label");
+ App.Tap("Label");
+ Assert.That(App.WaitForElement("EventInvokedLabel").GetText(), Is.EqualTo("Label Invoked"));
+ Assert.That(App.WaitForElement("SwipeStartedLabel").GetText(), Is.EqualTo("Swipe Started: Right"));
+ Assert.That(App.WaitForElement("SwipeChangingLabel").GetText(), Is.EqualTo("Swipe Changing: Right"));
+ Assert.That(App.WaitForElement("SwipeEndedLabel").GetText(), Is.EqualTo("Swipe Ended: Right, IsOpen: Open"));
+ }
+
+ [Test, Order(2)]
+ public void VerifySwipeViewWhenImageSwipeItemAndEvents()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IconImageSourceSwipeItem");
+ App.Tap("IconImageSourceSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ App.WaitForElement("Icon");
+ App.Tap("Icon");
+ Assert.That(App.WaitForElement("EventInvokedLabel").GetText(), Is.EqualTo("Icon Invoked"));
+ Assert.That(App.WaitForElement("SwipeStartedLabel").GetText(), Is.EqualTo("Swipe Started: Right"));
+ Assert.That(App.WaitForElement("SwipeChangingLabel").GetText(), Is.EqualTo("Swipe Changing: Right"));
+ Assert.That(App.WaitForElement("SwipeEndedLabel").GetText(), Is.EqualTo("Swipe Ended: Right, IsOpen: Open"));
+ }
+
+#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_WINDOWS //In Android, Buttton SwipeItem is not Invoked & On Windows, related issue link: https://github.com/dotnet/maui/issues/27436
+ [Test, Order(3)]
+ public void VerifySwipeViewWhenButtonSwipeItemAndEvents()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ButtonSwipeItem");
+ App.Tap("ButtonSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ App.WaitForElement("Click Me");
+ App.Tap("Click Me");
+ Assert.That(App.WaitForElement("EventInvokedLabel").GetText(), Is.EqualTo("Button Clicked"));
+ Assert.That(App.WaitForElement("SwipeStartedLabel").GetText(), Is.EqualTo("Swipe Started: Right"));
+ Assert.That(App.WaitForElement("SwipeChangingLabel").GetText(), Is.EqualTo("Swipe Changing: Right"));
+ Assert.That(App.WaitForElement("SwipeEndedLabel").GetText(), Is.EqualTo("Swipe Ended: Right, IsOpen: Open"));
+ }
+#endif
+#endif
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/14777
+ [Test, Order(4)]
+ public void VerifySwipeViewWhenLabelContentAndProgrammaticActions()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.WaitForElement("OpenLeft");
+ App.Tap("OpenLeft");
+ App.WaitForElement("Label");
+ App.Tap("OpenRight");
+ App.WaitForElement("Label");
+ App.Tap("OpenTop");
+ App.WaitForElement("Label");
+ App.Tap("OpenBottom");
+ App.WaitForElement("Label");
+ App.Tap("CloseSwipeViewButton");
+ App.WaitForNoElement("Label");
+ }
+
+ [Test, Order(5)]
+ public void VerifySwipeViewWithImageContentAndProgrammaticActions()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewImage");
+ App.WaitForElement("OpenLeft");
+ App.Tap("OpenLeft");
+ App.WaitForElement("Label");
+ App.Tap("OpenRight");
+ App.WaitForElement("Label");
+ App.Tap("OpenTop");
+ App.WaitForElement("Label");
+ App.Tap("OpenBottom");
+ App.WaitForElement("Label");
+ App.WaitForElement("CloseSwipeViewButton");
+ App.Tap("CloseSwipeViewButton");
+ App.WaitForNoElement("Label");
+ }
+
+ [Test, Order(6)]
+ public void VerifySwipeViewWithCollectionViewContentAndProgrammaticActions()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewCollectionItem");
+ App.WaitForElement("OpenLeft");
+ App.Tap("OpenLeft");
+ App.WaitForNoElement("Label");
+ App.Tap("OpenRight");
+ App.WaitForNoElement("Label");
+ App.SwipeLeftToRight("Item 4");
+ App.WaitForElement("Label");
+ App.WaitForElement("CloseSwipeViewButton");
+ App.Tap("CloseSwipeViewButton");
+ App.WaitForElement("Label");
+ }
+#endif
+
+ [Test]
+ public void VerifySwipeViewWithImageContentChanged()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithCollectionViewContentChanged()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ VerifySwipeViewScreenshot();
+ }
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/30947
+ [Test]
+ public void VerifySwipeViewWithLabelContentAndThreshold()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ThresholdEntry");
+ App.ClearText("ThresholdEntry");
+ App.EnterText("ThresholdEntry", "30");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewLabel");
+ App.SwipeLeftToRight("SwipeViewLabel");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithImageContentAndThreshold()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("ThresholdEntry");
+ App.ClearText("ThresholdEntry");
+ App.EnterText("ThresholdEntry", "30");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewImage");
+ App.SwipeLeftToRight("SwipeViewImage");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithCollectionViewContentAndThreshold()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("ThresholdEntry");
+ App.ClearText("ThresholdEntry");
+ App.EnterText("ThresholdEntry", "30");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ App.SwipeLeftToRight("Item 4");
+ VerifySwipeViewScreenshot();
+ }
+#endif
+
+ [Test]
+ public void VerifySwipeViewWithLabelContentAndBackgroundColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("LightGreenBackground");
+ App.Tap("LightGreenBackground");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithImageContentAndBackgroundColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("LightGreenBackground");
+ App.Tap("LightGreenBackground");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithCollectionViewContentAndBackgroundColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("LightPinkBackground");
+ App.Tap("LightPinkBackground");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithLabelContentAndFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("FlowDirectionRightToLeft");
+ App.Tap("FlowDirectionRightToLeft");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithImageContentAndFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("FlowDirectionRightToLeft");
+ App.Tap("FlowDirectionRightToLeft");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithCollectionViewContentAndFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("FlowDirectionRightToLeft");
+ App.Tap("FlowDirectionRightToLeft");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ VerifySwipeViewScreenshot();
+ }
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/29812
+ [Test]
+ public void VerifySwipeViewWithLabelContentAndShadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithImageContentAndShadow()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControlLabel");
+ VerifySwipeViewScreenshot();
+ }
+#endif
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/30947
+ [Test]
+ public void VerifySwipeViewWithLabelContentAndIsEnabledFalse()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IsEnabledFalse");
+ App.Tap("IsEnabledFalse");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ App.WaitForNoElement("Label");
+ }
+
+ [Test]
+ public void VerifySwipeViewWithImageContentAndIsEnabledFalse()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("IsEnabledFalse");
+ App.Tap("IsEnabledFalse");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewImage");
+ App.SwipeLeftToRight("SwipeViewImage");
+ App.WaitForNoElement("Label");
+ }
+
+ [Test]
+ public void VerifySwipeViewWithCollectionViewContentAndIsEnabledFalse()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("IsEnabledFalse");
+ App.Tap("IsEnabledFalse");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewCollectionItem");
+ App.SwipeLeftToRight("SwipeViewCollectionItem");
+ App.WaitForNoElement("Label");
+ }
+#endif
+
+ [Test]
+ public void VerifySwipeViewWithLabelContentAndIsVisibleFalse()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IsVisibleFalse");
+ App.Tap("IsVisibleFalse");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForNoElement("SwipeViewControl");
+ }
+
+ [Test]
+ public void VerifySwipeViewWithImageContentAndIsVisibleFalse()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("IsVisibleFalse");
+ App.Tap("IsVisibleFalse");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForNoElement("SwipeViewImage");
+ }
+
+ [Test]
+ public void VerifySwipeViewWithCollectionViewContentAndIsVisibleFalse()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("IsVisibleFalse");
+ App.Tap("IsVisibleFalse");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForNoElement("SwipeViewCollectionItem");
+ }
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/30947
+ [Test]
+ public void VerifySwipeViewWithLabelContentSwipeMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ExecuteSwipeMode");
+ App.Tap("ExecuteSwipeMode");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ Assert.That(App.WaitForElement("EventInvokedLabel").GetText(), Is.EqualTo("Label Invoked"));
+ }
+
+ [Test]
+ public void VerifySwipeViewWithImageContentSwipeMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("ExecuteSwipeMode");
+ App.Tap("ExecuteSwipeMode");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewImage");
+ App.SwipeLeftToRight("SwipeViewImage");
+ Assert.That(App.WaitForElement("EventInvokedLabel").GetText(), Is.EqualTo("Label Invoked"));
+ }
+
+ [Test]
+ public void VerifySwipeViewWithCollectionViewContentSwipeMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("ExecuteSwipeMode");
+ App.Tap("ExecuteSwipeMode");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewCollectionItem");
+ App.SwipeLeftToRight("SwipeViewCollectionItem");
+ Assert.That(App.WaitForElement("EventInvokedLabel").GetText(), Is.EqualTo("Label Invoked"));
+ }
+
+ [Test]
+ public void VerifyLabelWithSwipeRevealAndSwipeBehaviorOnInvokedAuto()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ App.WaitForElement("Label");
+ App.Tap("Label");
+ App.WaitForNoElement("Label");
+ }
+
+ [Test]
+ public void VerifyImageWithSwipeRevealAndSwipeBehaviorOnInvokedAuto()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("IconImageSourceSwipeItem");
+ App.Tap("IconImageSourceSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewImage");
+ App.SwipeLeftToRight("SwipeViewImage");
+ bool iconDismissed = true;
+ for (int i = 0; i < 3 && !iconDismissed; i++)
+ {
+ try
+ {
+ App.WaitForElement("Icon");
+ App.Tap("Icon");
+ App.WaitForNoElement("Icon");
+ iconDismissed = false;
+ break;
+ }
+ catch (Exception)
+ {
+ // retry
+ }
+
+ Assert.That(iconDismissed, Is.True, "Icon did not disappear after 3 attempts.");
+ }
+
+ }
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/27436
+ [Test]
+ public void VerifyCollectionViewWithSwipeRevealAndSwipeBehaviorOnInvokedAuto()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("ButtonSwipeItem");
+ App.Tap("ButtonSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewCollectionItem");
+ App.SwipeLeftToRight("Item 3");
+ App.WaitForElement("Click Me");
+ App.Tap("Click Me");
+ App.WaitForNoElement("Click Me");
+ }
+#endif
+
+ [Test]
+ public void VerifySwipeModeRevealWithSwipeBehaviorOnInvokedRemainOpen()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("RemainOpenSwipeBehavior");
+ App.Tap("RemainOpenSwipeBehavior");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ App.WaitForElement("Label");
+ App.Tap("Label");
+ App.WaitForElement("Label");
+ }
+
+ [Test]
+ public void VerifySwipeModeRevealWithSwipeBehaviorOnInvokedCloseSwipeViewButton()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CloseSwipeBehavior");
+ App.Tap("CloseSwipeBehavior");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ App.WaitForElement("Label");
+ App.Tap("Label");
+ App.WaitForNoElement("Label");
+ }
+
+ [Test]
+ public void VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedAuto()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ExecuteSwipeMode");
+ App.Tap("ExecuteSwipeMode");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ Assert.That(App.WaitForElement("EventInvokedLabel").GetText(), Is.EqualTo("Label Invoked"));
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedRemainOpen()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ExecuteSwipeMode");
+ App.Tap("ExecuteSwipeMode");
+ App.WaitForElement("RemainOpenSwipeBehavior");
+ App.Tap("RemainOpenSwipeBehavior");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ App.WaitForElement("Label");
+ App.Tap("Label");
+ App.WaitForElement("Label");
+ }
+
+ [Test]
+ public void VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedCloseSwipeViewButton()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ExecuteSwipeMode");
+ App.Tap("ExecuteSwipeMode");
+ App.WaitForElement("CloseSwipeBehavior");
+ App.Tap("CloseSwipeBehavior");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ Assert.That(App.WaitForElement("EventInvokedLabel").GetText(), Is.EqualTo("Label Invoked"));
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithLabelSwipeItemsBackgroundColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("YellowSwipeItemBackground");
+ App.Tap("YellowSwipeItemBackground");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifySwipeViewWithIconImageSwipeItemsBackgroundColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IconImageSourceSwipeItem");
+ App.Tap("IconImageSourceSwipeItem");
+ App.WaitForElement("YellowSwipeItemBackground");
+ App.Tap("YellowSwipeItemBackground");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ VerifySwipeViewScreenshot();
+ }
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/27436
+ [Test]
+ public void VerifySwipeViewWithButtonSwipeItemsBackgroundColor()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ButtonSwipeItem");
+ App.Tap("ButtonSwipeItem");
+ App.WaitForElement("YellowSwipeItemBackground");
+ App.Tap("YellowSwipeItemBackground");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ VerifySwipeViewScreenshot();
+ }
+#endif
+
+ [Test]
+ public void VerifySwipeViewWithIconImageSwipeItemChanged()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("IconImageSourceSwipeItem");
+ App.Tap("IconImageSourceSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ App.WaitForElement("Icon");
+ }
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/27436
+ [Test]
+ public void VerifySwipeViewWithButtonSwipeItemChanged()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ButtonSwipeItem");
+ App.Tap("ButtonSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ App.WaitForElement("Click Me");
+ }
+#endif
+
+ [Test]
+ public void VerifyCollectionViewContentWithLabelSwipeItem()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("LabelSwipeItem");
+ App.Tap("LabelSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewCollectionItem");
+ App.SwipeLeftToRight("Item 3");
+ App.SwipeLeftToRight("Item 6");
+ App.WaitForElement("Label");
+ VerifySwipeViewScreenshot();
+ }
+
+ [Test]
+ public void VerifyCollectionViewContentWithIconImageSwipeItem()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("IconImageSourceSwipeItem");
+ App.Tap("IconImageSourceSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewCollectionItem");
+ App.SwipeLeftToRight("Item 2");
+ App.SwipeLeftToRight("Item 4");
+ App.WaitForElement("Icon");
+ VerifySwipeViewScreenshot();
+ }
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/27436
+ [Test]
+ public void VerifyCollectionViewContentWithButtonSwipeItem()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("CollectionViewContent");
+ App.Tap("CollectionViewContent");
+ App.WaitForElement("ButtonSwipeItem");
+ App.Tap("ButtonSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewCollectionItem");
+ App.SwipeLeftToRight("Item 1");
+ App.SwipeLeftToRight("Item 5");
+ App.WaitForElement("Click Me");
+ VerifySwipeViewScreenshot();
+ }
+#endif
+
+ [Test]
+ public void VerifyImageContentWithLabelSwipeItem()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("LabelSwipeItem");
+ App.Tap("LabelSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewImage");
+ App.SwipeLeftToRight("SwipeViewImage");
+ App.WaitForElement("Label");
+ }
+
+ [Test]
+ public void VerifyImageContentWithIconImageSwipeItem()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("IconImageSourceSwipeItem");
+ App.Tap("IconImageSourceSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewImage");
+ App.SwipeLeftToRight("SwipeViewImage");
+ App.WaitForElement("Icon");
+ }
+
+#if TEST_FAILS_ON_WINDOWS //related issue link: https://github.com/dotnet/maui/issues/27436
+ [Test]
+ public void VerifyImageContentWithButtonSwipeItem()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ImageContent");
+ App.Tap("ImageContent");
+ App.WaitForElement("ButtonSwipeItem");
+ App.Tap("ButtonSwipeItem");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewImage");
+ App.SwipeLeftToRight("SwipeViewImage");
+ App.WaitForElement("Click Me");
+ }
+#endif
+
+ [Test]
+ public void VerifyThresholdWithSwipeMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+ App.WaitForElement("ThresholdEntry");
+ App.ClearText("ThresholdEntry");
+ App.EnterText("ThresholdEntry", "20");
+ App.WaitForElement("ExecuteSwipeMode");
+ App.Tap("ExecuteSwipeMode");
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+ App.WaitForElement("SwipeViewControl");
+ App.SwipeLeftToRight("SwipeViewControl");
+ Assert.That(App.WaitForElement("SwipeStartedLabel").GetText(), Is.EqualTo("Swipe Started: Right"));
+ }
+#endif
+
+ private void VerifySwipeViewScreenshot()
+ {
+#if WINDOWS
+ VerifyScreenshot(cropTop: 100);
+#else
+ VerifyScreenshot();
+#endif
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/TitleBarFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/TitleBarFeatureTests.cs
new file mode 100644
index 000000000000..06ffe26bef07
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/TitleBarFeatureTests.cs
@@ -0,0 +1,584 @@
+// This feature test is applicable only on desktop platforms (Windows and Mac).
+#if MACCATALYST || WINDOWS
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests;
+
+public class TitleBarFeatureTests : UITest
+{
+ public const string TitleBarFeatureMatrix = "TitleBar Feature Matrix";
+
+ public TitleBarFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(TitleBarFeatureMatrix);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_Window()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowLeadingContentCheckBox");
+ App.Tap("ShowLeadingContentCheckBox");
+
+ App.WaitForElement("ShowTrailingContentCheckBox");
+ App.Tap("ShowTrailingContentCheckBox");
+
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+
+ App.WaitForElement("ShowIconCheckBox");
+ App.Tap("ShowIconCheckBox");
+
+ App.WaitForElement("ShowBackgroundColorCheckBox");
+ App.Tap("ShowBackgroundColorCheckBox");
+
+ App.WaitForElement("OrangeRadioButton");
+ App.Tap("OrangeRadioButton");
+
+ App.WaitForElement("ShowForegroundColorCheckBox");
+ App.Tap("ShowForegroundColorCheckBox");
+ App.WaitForElement("WhiteForegroundRadioButton");
+ App.Tap("WhiteForegroundRadioButton");
+
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+
+ App.WaitForElement("ProgressBarRadioButton");
+ App.Tap("ProgressBarRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_Icon_WithTrailingContentAndLeadingContent()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowIconCheckBox");
+ App.Tap("ShowIconCheckBox");
+
+ App.WaitForElement("ShowLeadingContentCheckBox");
+ App.Tap("ShowLeadingContentCheckBox");
+ App.WaitForElement("ShowTrailingContentCheckBox");
+ App.Tap("ShowTrailingContentCheckBox");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_Icon_WithBackgroundColor()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowIconCheckBox");
+ App.Tap("ShowIconCheckBox");
+
+ App.WaitForElement("ShowBackgroundColorCheckBox");
+ App.Tap("ShowBackgroundColorCheckBox");
+ App.WaitForElement("RedRadioButton");
+ App.Tap("RedRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_Icon_WithSearchBar()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowIconCheckBox");
+ App.Tap("ShowIconCheckBox");
+
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("SearchBarRadioButton");
+ App.Tap("SearchBarRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_Icon_WithForegroundColor()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowIconCheckBox");
+ App.Tap("ShowIconCheckBox");
+
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+
+ App.WaitForElement("ShowForegroundColorCheckBox");
+ App.Tap("ShowForegroundColorCheckBox");
+ App.WaitForElement("WhiteForegroundRadioButton");
+ App.Tap("WhiteForegroundRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_ForegroundColor_WithBackgroundColor()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+
+ App.WaitForElement("ShowForegroundColorCheckBox");
+ App.Tap("ShowForegroundColorCheckBox");
+ App.WaitForElement("WhiteForegroundRadioButton");
+ App.Tap("WhiteForegroundRadioButton");
+
+ App.WaitForElement("ShowBackgroundColorCheckBox");
+ App.Tap("ShowBackgroundColorCheckBox");
+ App.WaitForElement("RedRadioButton");
+ App.Tap("RedRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_ForegroundColor_WithGrid()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+
+ App.WaitForElement("ShowForegroundColorCheckBox");
+ App.Tap("ShowForegroundColorCheckBox");
+ App.WaitForElement("WhiteForegroundRadioButton");
+ App.Tap("WhiteForegroundRadioButton");
+
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("ProgressBarRadioButton");
+ App.Tap("ProgressBarRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_TrailingContentAndLeadingContent_WithHorizontalStackLayout()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowLeadingContentCheckBox");
+ App.Tap("ShowLeadingContentCheckBox");
+ App.WaitForElement("ShowTrailingContentCheckBox");
+ App.Tap("ShowTrailingContentCheckBox");
+
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("HorizontalStackLayoutRadioButton");
+ App.Tap("HorizontalStackLayoutRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_TrailingContentAndLeadingContent_WithGrid()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowLeadingContentCheckBox");
+ App.Tap("ShowLeadingContentCheckBox");
+ App.WaitForElement("ShowTrailingContentCheckBox");
+ App.Tap("ShowTrailingContentCheckBox");
+
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("ProgressBarRadioButton");
+ App.Tap("ProgressBarRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_TrailingContentAndLeadingContent_WithTitleAndSubtitle()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowLeadingContentCheckBox");
+ App.Tap("ShowLeadingContentCheckBox");
+ App.WaitForElement("ShowTrailingContentCheckBox");
+ App.Tap("ShowTrailingContentCheckBox");
+
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_TrailingContentAndLeadingContent_WithBackgroundColor()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowLeadingContentCheckBox");
+ App.Tap("ShowLeadingContentCheckBox");
+ App.WaitForElement("ShowTrailingContentCheckBox");
+ App.Tap("ShowTrailingContentCheckBox");
+
+ App.WaitForElement("ShowBackgroundColorCheckBox");
+ App.Tap("ShowBackgroundColorCheckBox");
+ App.WaitForElement("OrangeRadioButton");
+ App.Tap("OrangeRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_TrailingContentAndLeadingContent_WithSearchBar()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowLeadingContentCheckBox");
+ App.Tap("ShowLeadingContentCheckBox");
+ App.WaitForElement("ShowTrailingContentCheckBox");
+ App.Tap("ShowTrailingContentCheckBox");
+
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("SearchBarRadioButton");
+ App.Tap("SearchBarRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_TitleAndSubTitle_WithBackgroundColor()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+
+ App.WaitForElement("ShowBackgroundColorCheckBox");
+ App.Tap("ShowBackgroundColorCheckBox");
+ App.WaitForElement("OrangeRadioButton");
+ App.Tap("OrangeRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_TitleAndSubTitle_WithHorizontalStackLayout()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("HorizontalStackLayoutRadioButton");
+ App.Tap("HorizontalStackLayoutRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_TitleAndSubTitle_WithGrid()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("ProgressBarRadioButton");
+ App.Tap("ProgressBarRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_TitleAndSubTitle_WithSearchBar()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("SearchBarRadioButton");
+ App.Tap("SearchBarRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_BackgroundColor_WithGrid()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowBackgroundColorCheckBox");
+ App.Tap("ShowBackgroundColorCheckBox");
+ App.WaitForElement("RedRadioButton");
+ App.Tap("RedRadioButton");
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("ProgressBarRadioButton");
+ App.Tap("ProgressBarRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_IsVisible()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowTitleBarCheckBox");
+ App.Tap("ShowTitleBarCheckBox");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+
+#if TEST_FAILS_ON_WINDOWS && TEST_FAILS_ON_MACCATALYST //For more information see: https://github.com/dotnet/maui/issues/30399
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_RTL_WithTrailingContentAndLeadingContent()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowLeadingContentCheckBox");
+ App.Tap("ShowLeadingContentCheckBox");
+ App.WaitForElement("ShowTrailingContentCheckBox");
+ App.Tap("ShowTrailingContentCheckBox");
+ App.WaitForElement("FlowDirectionRTLCheckBox");
+ App.Tap("FlowDirectionRTLCheckBox");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar:true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_RTL_WithTitleAndSubTitle()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("FlowDirectionRTLCheckBox");
+ App.Tap("FlowDirectionRTLCheckBox");
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar:true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_RTL_WithSearchBar()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("FlowDirectionRTLCheckBox");
+ App.Tap("FlowDirectionRTLCheckBox");
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("SearchBarRadioButton");
+ App.Tap("SearchBarRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar:true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_RTL_WithHorizontalStackLayout()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("FlowDirectionRTLCheckBox");
+ App.Tap("FlowDirectionRTLCheckBox");
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("HorizontalStackLayoutRadioButton");
+ App.Tap("HorizontalStackLayoutRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar:true);
+ }
+
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_RTL_WithGridWithProgressBar()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("FlowDirectionRTLCheckBox");
+ App.Tap("FlowDirectionRTLCheckBox");
+ App.WaitForElement("IsTitleBarContentVisibleCheckBox");
+ App.Tap("IsTitleBarContentVisibleCheckBox");
+ App.WaitForElement("ProgressBarRadioButton");
+ App.Tap("ProgressBarRadioButton");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar:true);
+ }
+#endif
+ [Test]
+ [Category(UITestCategories.TitleView)]
+ public void TitleBar_TitleAndSubTitle_Entry()
+ {
+ App.WaitForElement("ResetButton");
+ App.Tap("ResetButton");
+
+ App.WaitForElement("ShowTitleCheckBox");
+ App.Tap("ShowTitleCheckBox");
+ App.WaitForElement("TitleEntry");
+ App.Tap("TitleEntry");
+ App.ClearText("TitleEntry");
+ App.EnterText("TitleEntry", "Custom Title");
+
+ App.WaitForElement("ShowSubtitleCheckBox");
+ App.Tap("ShowSubtitleCheckBox");
+ App.WaitForElement("SubtitleEntry");
+ App.Tap("SubtitleEntry");
+ App.ClearText("SubtitleEntry");
+ App.EnterText("SubtitleEntry", "Custom Subtitle");
+
+ App.WaitForElement("ApplyButton");
+ App.Tap("ApplyButton");
+
+ VerifyScreenshot(includeTitleBar: true);
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/TwoPaneViewFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/TwoPaneViewFeatureTests.cs
new file mode 100644
index 000000000000..a27bdde77fc1
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/TwoPaneViewFeatureTests.cs
@@ -0,0 +1,516 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+
+namespace Microsoft.Maui.TestCases.Tests
+{
+ public class TwoPaneViewFeatureTests : UITest
+ {
+ public const string TwoPaneViewFeatureMatrix = "TwoPaneView Feature Matrix";
+
+ public TwoPaneViewFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(TwoPaneViewFeatureMatrix);
+ }
+
+ // The test cases below are divided based on platform-specific UI behaviors and layout logic.
+ //
+ // For MACCATALYST and WINDOWS:
+ // - Increase WideModeStepper to switch to Tall Mode (Pane1 above Pane2)
+ // - Use Y position to validate layout changes
+ //
+ // For ANDROID and IOS:
+ // - Decrease WideModeStepper to switch to Wide Mode (Pane1 beside Pane2)
+ // - Use X position to validate layout changes
+ // - Extra checks for RTL and shadow are included
+ //
+ // Common tests:
+ // - FlowDirection, visibility, shadow, and pane size changes are tested on all platforms
+ // with minor differences in interactions.
+
+#if MACCATALYST || WINDOWS
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_RTLFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("FlowDirectionRTLCheckBox");
+ App.Tap("FlowDirectionRTLCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_WideMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_IsTall_UsingRect()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.IncreaseStepper("WideModeStepper");
+ App.IncreaseStepper("WideModeStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ var pane1Y = App.WaitForElement("Pane1Label").GetRect().Y;
+ var pane2Y = App.WaitForElement("Pane2Label").GetRect().Y;
+
+ Assert.That(pane2Y, Is.GreaterThan(pane1Y), "Pane2 should be below Pane1 in Tall mode");
+
+ Assert.That(App.WaitForElement("CurrentModeLabel").GetText(), Is.EqualTo("Tall Mode"), "CurrentModeLabel should display 'Tall Mode'");
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Wide_UsingRect()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ var pane1Y = App.WaitForElement("Pane1Label").GetRect().X;
+ var pane2Y = App.WaitForElement("Pane2Label").GetRect().X;
+
+ Assert.That(pane2Y, Is.GreaterThan(pane1Y), "Pane2 should be to the right of Pane1 in Wide mode");
+
+ Assert.That(App.WaitForElement("CurrentModeLabel").GetText(), Is.EqualTo("Wide Mode"));
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_IsWideWithRTL_UsingRect()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.DecreaseStepper("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+
+ App.WaitForElement("FlowDirectionRTLCheckBox");
+ App.Tap("FlowDirectionRTLCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ var pane1X = App.WaitForElement("Pane1Label").GetRect().X;
+ var pane2X = App.WaitForElement("Pane2Label").GetRect().X;
+
+ Assert.That(pane1X, Is.GreaterThan(pane2X), "Pane1 should be to the right of Pane2 in RTL Wide mode");
+
+ Assert.That(App.WaitForElement("CurrentModeLabel").GetText(), Is.EqualTo("Wide Mode"), "CurrentModeLabel should display 'Wide Mode'");
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_TallMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.IncreaseStepper("WideModeStepper");
+ App.IncreaseStepper("WideModeStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Pane1Priority()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("TallModeSinglePaneRadio");
+ App.Tap("TallModeSinglePaneRadio");
+
+ App.WaitForElement("WideModeSinglePaneRadio");
+ App.Tap("WideModeSinglePaneRadio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Pane2Priority()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("TallModeSinglePaneRadio");
+ App.Tap("TallModeSinglePaneRadio");
+
+ App.WaitForElement("WideModeSinglePaneRadio");
+ App.Tap("WideModeSinglePaneRadio");
+
+ App.WaitForElement("PanePriorityPane2Radio");
+ App.Tap("PanePriorityPane2Radio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Pane1SizeIncrease_WithTallMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.IncreaseStepper("Pane1LengthStepper");
+ App.IncreaseStepper("Pane1LengthStepper");
+
+ App.IncreaseStepper("WideModeStepper");
+ App.IncreaseStepper("WideModeStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Pane2SizeIncrease_WithTallMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.IncreaseStepper("Pane2LengthStepper");
+ App.IncreaseStepper("Pane2LengthStepper");
+
+ App.IncreaseStepper("WideModeStepper");
+ App.IncreaseStepper("WideModeStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+#endif
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_IsVisible()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("VisibilityCheckBox");
+ App.Tap("VisibilityCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_ZIsShadowEnabled()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Pane1SizeIncrease()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("Pane1LengthLabel");
+ App.IncreaseStepper("Pane1LengthStepper");
+ App.WaitForElement("Pane1LengthLabel");
+ App.IncreaseStepper("Pane1LengthStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Pane2SizeIncrease()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("Pane2LengthLabel");
+ App.IncreaseStepper("Pane2LengthStepper");
+ App.WaitForElement("Pane2LengthLabel");
+ App.IncreaseStepper("Pane2LengthStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+#if ANDROID || IOS
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_IsTall_UsingRect()
+ {
+ var pane1Y = App.WaitForElement("Pane1Label").GetRect().Y;
+ var pane2Y = App.WaitForElement("Pane2Label").GetRect().Y;
+
+ Assert.That(pane2Y, Is.GreaterThan(pane1Y), "Pane2 should be below Pane1 in Tall mode");
+
+ Assert.That(App.WaitForElement("CurrentModeLabel").GetText(), Is.EqualTo("Tall Mode"), "CurrentModeLabel should display 'Tall Mode'");
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_IsWide_UsingRect()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ var pane1X = App.WaitForElement("Pane1Label").GetRect().X;
+ var pane2X = App.WaitForElement("Pane2Label").GetRect().X;
+
+ Assert.That(pane2X, Is.GreaterThan(pane1X), "Pane2 should be to the right of Pane1 in Wide mode");
+
+ Assert.That(App.WaitForElement("CurrentModeLabel").GetText(), Is.EqualTo("Wide Mode"), "CurrentModeLabel should display 'Wide Mode'");
+
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_IsWideWithRTL_UsingRect()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+
+ App.WaitForElement("FlowDirectionRTLCheckBox");
+ App.Tap("FlowDirectionRTLCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ var pane1X = App.WaitForElement("Pane1Label").GetRect().X;
+ var pane2X = App.WaitForElement("Pane2Label").GetRect().X;
+
+ Assert.That(pane1X, Is.GreaterThan(pane2X), "Pane1 should be to the right of Pane2 in RTL Wide mode");
+
+ Assert.That(App.WaitForElement("CurrentModeLabel").GetText(), Is.EqualTo("Wide Mode"), "CurrentModeLabel should display 'Wide Mode'");
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_TallMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_WideMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Pane1SizeIncrease_WithWideMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("Pane1LengthStepper");
+ App.IncreaseStepper("Pane1LengthStepper");
+ App.WaitForElement("Pane1LengthStepper");
+ App.IncreaseStepper("Pane1LengthStepper");
+
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Pane2SizeIncrease_WithWideMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("Pane2LengthStepper");
+ App.IncreaseStepper("Pane2LengthStepper");
+ App.WaitForElement("Pane2LengthStepper");
+ App.IncreaseStepper("Pane2LengthStepper");
+
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_ShadowWithWideMode()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("ShadowCheckBox");
+ App.Tap("ShadowCheckBox");
+
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_RTLFlowDirection()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+ App.WaitForElement("WideModeStepper");
+ App.DecreaseStepper("WideModeStepper");
+
+ App.WaitForElement("FlowDirectionRTLCheckBox");
+ App.Tap("FlowDirectionRTLCheckBox");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Pane1Priority()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("TallModeSinglePaneRadio");
+ App.Tap("TallModeSinglePaneRadio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+
+ [Test]
+ [Category(UITestCategories.Layout)]
+ public void TwoPaneView_Pane2Priority()
+ {
+ App.WaitForElement("Options");
+ App.Tap("Options");
+
+ App.WaitForElement("TallModeSinglePaneRadio");
+ App.Tap("TallModeSinglePaneRadio");
+
+ App.WaitForElement("PanePriorityPane2Radio");
+ App.Tap("PanePriorityPane2Radio");
+
+ App.WaitForElement("Apply");
+ App.Tap("Apply");
+
+ VerifyScreenshot();
+ }
+#endif
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/WebViewFeatureTests.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/WebViewFeatureTests.cs
new file mode 100644
index 000000000000..0ddd2bb7d7e6
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/WebViewFeatureTests.cs
@@ -0,0 +1,324 @@
+using Microsoft.Maui.Controls;
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+namespace Microsoft.Maui.TestCases.Tests;
+
+public class WebViewFeatureTests : UITest
+{
+ public const string WebViewFeatureMatrix = "WebView Feature Matrix";
+ public const string Options = "Options";
+ public const string Apply = "Apply";
+ public const string WebViewControl = "WebViewControl";
+ public const string HtmlSourceButton = "HtmlSourceButton";
+ public const string GithubUrlButton = "GithubUrlButton";
+ public const string EvaluateJSButton = "EvaluateJSButton";
+ public const string GoBackButton = "GoBackButton";
+ public const string CanGoBackLabel = "CanGoBackLabel";
+ public const string CanGoForwardLabel = "CanGoForwardLabel";
+ public const string NavigatingStatusLabel = "NavigatingStatusLabel";
+ public const string NavigatedStatusLabel = "NavigatedStatusLabel";
+ public const string JSResultLabel = "JSResultLabel";
+ public const string AddTestCookieButton = "AddTestCookieButton";
+ public const string ClearCookiesButton = "ClearCookiesButton";
+ public const string CookieStatusMainLabel = "CookieStatusMainLabel";
+ public WebViewFeatureTests(TestDevice device)
+ : base(device)
+ {
+ }
+ protected override void FixtureSetup()
+ {
+ base.FixtureSetup();
+ App.NavigateToGallery(WebViewFeatureMatrix);
+ }
+
+ [Test, Order(1)]
+ [Category(UITestCategories.WebView)]
+ public void WebView_ValidateDefaultValues_VerifyInitialState()
+ {
+ App.WaitForElement(Options);
+ Assert.That(App.FindElement(CanGoBackLabel).GetText(), Is.EqualTo("False"));
+ Assert.That(App.FindElement(CanGoForwardLabel).GetText(), Is.EqualTo("False"));
+ }
+
+#if TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_IOS // Issue Link: https://github.com/dotnet/maui/issues/30381
+ [Test, Order(2)]
+ [Category(UITestCategories.WebView)]
+ public void WebView_VerifyCanGoBackForward()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("HtmlSourceButton");
+ App.Tap("HtmlSourceButton");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("MicrosoftUrlButton");
+ App.Tap("MicrosoftUrlButton");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("GithubUrlButton");
+ App.Tap("GithubUrlButton");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement(CanGoBackLabel, timeout: TimeSpan.FromSeconds(3));
+ Assert.That(App.FindElement(CanGoBackLabel).GetText(), Is.EqualTo("True"));
+ App.WaitForElement(GoBackButton);
+ App.Tap(GoBackButton);
+ Thread.Sleep(2000); // Allow time to update the state
+ App.WaitForElement(CanGoForwardLabel, timeout: TimeSpan.FromSeconds(5));
+ Assert.That(App.FindElement(CanGoForwardLabel).GetText(), Is.EqualTo("True"));
+ }
+#endif
+
+ [Test, Order(3)]
+ [Category(UITestCategories.WebView)]
+ public void WebView_SetHtmlSource_VerifyJavaScript()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HtmlSourceButton);
+ App.Tap(HtmlSourceButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement(EvaluateJSButton);
+ App.Tap(EvaluateJSButton);
+ App.WaitForElement(JSResultLabel);
+ var jsResult = App.FindElement(JSResultLabel).GetText();
+ Assert.That(jsResult, Is.EqualTo("JS Result: HTML WebView Source"));
+ }
+
+ [Test, Order(4)]
+ [Category(UITestCategories.WebView)]
+ public void WebView_SetUrlSource_VerifyNavigatingEvent()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(GithubUrlButton);
+ App.Tap(GithubUrlButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElementTillPageNavigationSettled(Options);
+ var navigatingText = App.FindElement(NavigatingStatusLabel).GetText();
+ Assert.That(navigatingText, Is.Not.Null.And.Not.Empty);
+ }
+
+ [Test, Order(5)]
+ [Category(UITestCategories.WebView)]
+ public void WebView_SetUrlSource_VerifyNavigatedEvent()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(GithubUrlButton);
+ App.Tap(GithubUrlButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElementTillPageNavigationSettled(Options);
+ var navigatedText = App.FindElement(NavigatedStatusLabel).GetText();
+ Assert.That(navigatedText, Is.EqualTo("Navigated: Success"));
+ }
+
+ [Test, Order(6)]
+ [Category(UITestCategories.WebView)]
+ public void WebView_SetHtmlSource_VerifyNavigatingEvent()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HtmlSourceButton);
+ App.Tap(HtmlSourceButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElementTillPageNavigationSettled(Options);
+ var navigatingText = App.FindElement(NavigatingStatusLabel).GetText();
+ Assert.That(navigatingText, Is.Not.Null.And.Not.Empty);
+ }
+
+ [Test, Order(7)]
+ [Category(UITestCategories.WebView)]
+ public void WebView_SetHtmlSource_VerifyNavigatedEvent()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HtmlSourceButton);
+ App.Tap(HtmlSourceButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElementTillPageNavigationSettled(Options);
+ var navigatedText = App.FindElement(NavigatedStatusLabel).GetText();
+ Assert.That(navigatedText, Is.EqualTo("Navigated: Success"));
+ }
+
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebView_TestCookieManagement_VerifyAddCookie()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(AddTestCookieButton);
+ App.Tap(AddTestCookieButton);
+ App.WaitForElement(HtmlSourceButton);
+ App.Tap(HtmlSourceButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElementTillPageNavigationSettled(Options);
+ var cookiesStatusText = App.FindElement(CookieStatusMainLabel).GetText();
+ Assert.That(cookiesStatusText, Does.Contain("Domain: localhost").And.Contain("Count: 1").And.Contain("DotNetMAUICookie = My cookie"));
+ }
+
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebView_TestCookieManagement_VerifyAddCookieWithUrlSource()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(GithubUrlButton);
+ App.Tap(GithubUrlButton);
+ App.WaitForElement(AddTestCookieButton);
+ App.Tap(AddTestCookieButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElementTillPageNavigationSettled(Options);
+ var cookiesStatusText = App.FindElement(CookieStatusMainLabel).GetText();
+ Assert.That(cookiesStatusText, Does.Contain("Domain: github.com").And.Contain("Count: 1").And.Contain("DotNetMAUICookie = My cookie"));
+ }
+
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebView_TestCookieManagement_VerifyAddCookieAndEvaluateJavaScript()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(AddTestCookieButton);
+ App.Tap(AddTestCookieButton);
+ App.WaitForElement(HtmlSourceButton);
+ App.Tap(HtmlSourceButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElementTillPageNavigationSettled(Options);
+ App.WaitForElement(EvaluateJSButton);
+ App.Tap(EvaluateJSButton);
+ App.WaitForElement(JSResultLabel);
+ var jsResult = App.FindElement(JSResultLabel).GetText();
+ Assert.That(jsResult, Is.EqualTo("JS Result: HTML WebView Source"));
+ var cookiesStatusText = App.FindElement(CookieStatusMainLabel).GetText();
+ Assert.That(cookiesStatusText, Does.Contain("Domain: localhost").And.Contain("Count: 1").And.Contain("DotNetMAUICookie = My cookie"));
+ }
+
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebView_TestClearCookies_VerifyCookiesCleared()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(ClearCookiesButton);
+ App.Tap(ClearCookiesButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElementTillPageNavigationSettled(Options);
+ var clearCookiesText = App.FindElement(CookieStatusMainLabel).GetText();
+ Assert.That(clearCookiesText, Is.EqualTo("No cookies available."));
+ }
+
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebView_TestReloadMethod_VerifyReloadFunctionality()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(GithubUrlButton);
+ App.Tap(GithubUrlButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement("ReloadButton");
+ App.Tap("ReloadButton");
+ var navigatedText = App.FindElement(NavigatedStatusLabel).GetText();
+ Assert.That(navigatedText, Is.EqualTo("Navigated: Success"));
+ }
+
+#if TEST_FAILS_ON_IOS && TEST_FAILS_ON_CATALYST // Issue Link: https://github.com/dotnet/maui/issues/30515
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebView_VerifyReloadFunctionalityForHtmlWebViewSource()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(HtmlSourceButton);
+ App.Tap(HtmlSourceButton);
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement("ReloadButton");
+ App.Tap("ReloadButton");
+ var navigatedText = App.FindElement(NavigatedStatusLabel).GetText();
+ Assert.That(navigatedText, Is.EqualTo("Navigated: Success"));
+ }
+#endif
+
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebView_TestEvaluateJavaScriptAsync_VerifyJavaScriptExecution()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("LoadPage1Button");
+ App.Tap("LoadPage1Button");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement(EvaluateJSButton);
+ App.Tap(EvaluateJSButton);
+ App.WaitForElement(JSResultLabel);
+ var jsResult = App.FindElement(JSResultLabel).GetText();
+ Assert.That(jsResult, Is.EqualTo("JS Result: Navigation Test - Page 1"));
+ }
+
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebView_TestEvaluateJavaScriptAsync_VerifyJavaScriptExecutionWithMultiplePages()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("LoadMultiplePagesButton");
+ App.Tap("LoadMultiplePagesButton");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElement(EvaluateJSButton);
+ App.Tap(EvaluateJSButton);
+ App.WaitForElement(JSResultLabel);
+ var jsResult = App.FindElement(JSResultLabel).GetText();
+ Assert.That(jsResult, Is.EqualTo("JS Result: Multiple Pages Navigation"));
+ }
+
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebView_SetIsVisibleFalse_VerifyWebViewHidden()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement(GithubUrlButton);
+ App.Tap(GithubUrlButton);
+ App.WaitForElement("IsVisibleFalse");
+ App.Tap("IsVisibleFalse");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElementTillPageNavigationSettled(Options);
+ App.WaitForNoElement(WebViewControl);
+ }
+
+#if TEST_FAILS_ON_WINDOWS // Issue Link: https://github.com/dotnet/maui/issues/29812
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void VerifyWebViewWithShadow()
+ {
+ App.WaitForElement(Options);
+ App.Tap(Options);
+ App.WaitForElement("ShadowTrue");
+ App.Tap("ShadowTrue");
+ App.WaitForElement(Apply);
+ App.Tap(Apply);
+ App.WaitForElementTillPageNavigationSettled(Options, timeout: TimeSpan.FromSeconds(3));
+ VerifyScreenshot();
+ }
+#endif
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue15154.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue15154.cs
index eb7a45124209..bbdd0873f20d 100644
--- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue15154.cs
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue15154.cs
@@ -20,7 +20,11 @@ public void ShouldFlyoutTextWrapsInLandscape()
App.WaitForElement("OpenFlyoutButton");
App.Tap("OpenFlyoutButton");
App.SetOrientationLandscape();
+#if ANDROID
+ VerifyScreenshot(cropLeft: 125);
+#else
VerifyScreenshot();
+#endif
}
}
#endif
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue17783.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue17783.cs
new file mode 100644
index 000000000000..efaa3d13e0f1
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue17783.cs
@@ -0,0 +1,30 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues
+{
+ public class Issue17783 : _IssuesUITest
+ {
+ public Issue17783(TestDevice testDevice) : base(testDevice)
+ {
+ }
+
+ public override string Issue => "Pasting long text when the editor has a max length does nothing";
+
+ [Test]
+ [Category(UITestCategories.Editor)]
+ [Category(UITestCategories.Entry)]
+ public void TextShouldBeCut()
+ {
+ App.WaitForElement("PasteToEntryButton");
+ App.Click("PasteToEntryButton");
+ App.Click("PasteToEditorButton");
+ var entryText = App.FindElement("Entry").GetText();
+ var editorText = App.FindElement("Editor").GetText();
+
+ Assert.That(entryText, Is.EqualTo("Hello"));
+ Assert.That(editorText, Is.EqualTo("Hello"));
+ }
+ }
+}
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue19997.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue19997.cs
new file mode 100644
index 000000000000..98c66ca27944
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue19997.cs
@@ -0,0 +1,34 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue19997 : _IssuesUITest
+{
+ public Issue19997(TestDevice device) : base(device)
+ {
+ }
+#if IOS
+ private const int CropBottomValue = 1550;
+#elif ANDROID
+ private const int CropBottomValue = 1150;
+#elif WINDOWS
+ private const int CropBottomValue = 400;
+#else
+ private const int CropBottomValue = 360;
+#endif
+ public override string Issue => "[Android, iOS, MacOS] Entry ClearButton Color Not Updating on AppThemeBinding Change";
+
+ [Test]
+ [Category(UITestCategories.Entry)]
+ public void EntryClearButtonColorShouldUpdateOnThemeChange()
+ {
+ App.WaitForElement("EntryWithAppThemeBinding");
+ App.Tap("EntryWithAppThemeBinding");
+ App.Tap("ThemeButton");
+#if WINDOWS // On Windows, the clear button isn't visible when Entry loses focus, so manually focused to check its icon color.
+ App.Tap("EntryWithAppThemeBinding");
+#endif
+ VerifyScreenshot(cropBottom: CropBottomValue);
+ }
+}
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21375.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21375.cs
new file mode 100644
index 000000000000..a17699e69028
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21375.cs
@@ -0,0 +1,51 @@
+#if !IOS && !MACCATALYST // Test excluded for iOS/macCatalyst as the accessibility implementation was reverted in PR-https://github.com/dotnet/maui/pull/29827
+
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue21375 : _IssuesUITest
+{
+ public Issue21375(TestDevice device) : base(device) { }
+
+ public override string Issue => "Selected CollectionView item is not announced";
+
+ [Test]
+ [Category(UITestCategories.CollectionView)]
+ public void SelectedItemsShowSelected()
+ {
+ var collectionView = App.WaitForElement("collectionView");
+
+ App.Tap("Item 1");
+ App.WaitForElement("calculateButton").Tap();
+
+ VerifyScreenshot(TestContext.CurrentContext.Test.MethodName + "_single");
+
+ App.WaitForElement("multipleButton").Tap();
+ App.Tap("Item 2");
+ App.Tap("Item 3");
+ App.WaitForElement("calculateButton").Tap();
+
+ VerifyScreenshot(TestContext.CurrentContext.Test.MethodName + "_multiple");
+
+ App.WaitForElement("noneButton").Tap();
+ App.WaitForElement("calculateButton").Tap();
+ VerifyScreenshot(TestContext.CurrentContext.Test.MethodName + "_none");
+
+ App.WaitForElement("singleButton").Tap();
+ App.WaitForElement("calculateButton").Tap();
+
+#if !WINDOWS // Windows clears out the selected items when we switch back
+ VerifyScreenshot(TestContext.CurrentContext.Test.MethodName + "_single");
+
+ App.WaitForElement("multipleButton").Tap();
+ App.WaitForElement("calculateButton").Tap();
+
+ VerifyScreenshot(TestContext.CurrentContext.Test.MethodName + "_multiple");
+#endif
+
+ }
+}
+#endif
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21640.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21640.cs
new file mode 100644
index 000000000000..2682e0360a34
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21640.cs
@@ -0,0 +1,43 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues
+{
+ public class Issue21640 : _IssuesUITest
+ {
+ public Issue21640(TestDevice testDevice) : base(testDevice)
+ {
+ }
+ public override string Issue => "TabbedPage content was not updated";
+
+ [Test]
+ [Category(UITestCategories.TabbedPage)]
+ public void TabbedPageContentUpdatesCorrectly()
+ {
+#if ANDROID
+ string tab1Title = "HOME";
+ string tab2Title = "SETTINGS";
+#else
+ string tab1Title = "Home";
+ string tab2Title = "Settings";
+#endif
+ string toggleTabButtonId = "ToogleTabButton";
+ App.WaitForElement(toggleTabButtonId);
+ App.Tap(toggleTabButtonId);
+ App.Tap(tab2Title);
+ App.WaitForElement("label");
+
+ // The issue occurs when repeatedly removing and re-adding the tab while navigating between tabs.
+ for (int i = 0; i < 3; i++)
+ {
+ App.Tap(tab1Title);
+ App.WaitForElement(toggleTabButtonId);
+ App.Tap(toggleTabButtonId); // Removes the tab
+ App.Tap(toggleTabButtonId); // Re-adds the tab
+ App.Tap(tab2Title);
+ App.WaitForElement("label");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22306.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22306.cs
index b416f91f2f95..358b4dc73c6d 100644
--- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22306.cs
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22306.cs
@@ -32,7 +32,12 @@ public void ButtonsLayoutResolveWhenParentSizeChanges()
App.SetOrientationLandscape();
WaitForAllElements();
+#if ANDROID
+ VerifyScreenshot(TestContext.CurrentContext.Test.MethodName + "SizeButtonsDownLandscape", cropLeft: 125);
+#else
VerifyScreenshot(TestContext.CurrentContext.Test.MethodName + "SizeButtonsDownLandscape");
+#endif
+
changeBoundsButton.Click();
WaitForAllElements();
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22606.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22606.cs
index 70b4100b0874..0621826310d2 100644
--- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22606.cs
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22606.cs
@@ -29,7 +29,11 @@ public void BorderBackgroundSizeUpdatesWhenRotatingScreen()
App.WaitForElement("SetHeightTo200");
App.Tap("SetHeightTo200");
App.SetOrientationLandscape();
+#if ANDROID
+ VerifyScreenshot(cropLeft: 125);
+#else
VerifyScreenshot();
+#endif
}
#endif
}
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue23732.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue23732.cs
new file mode 100644
index 000000000000..460da44854cf
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue23732.cs
@@ -0,0 +1,29 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues
+{
+ public class Issue23732 : _IssuesUITest
+ {
+ public Issue23732(TestDevice testDevice) : base(testDevice)
+ {
+ }
+ public override string Issue => "TabBar content not displayed properly";
+
+ [Test]
+ [Category(UITestCategories.TabbedPage)]
+ public void TabbedPageTabContentUpdated()
+ {
+#if ANDROID
+ string pageTitle = "PAGE 4";
+#else
+ string pageTitle = "Page 4";
+#endif
+ App.WaitForElement(pageTitle);
+ App.Tap(pageTitle);
+ var label = App.WaitForElement("label");
+ Assert.That(label.GetText(), Is.EqualTo("page4"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue23834.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue23834.cs
new file mode 100644
index 000000000000..bb91513ff49b
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue23834.cs
@@ -0,0 +1,21 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+public class Issue23834 : _IssuesUITest
+{
+ public Issue23834(TestDevice device) : base(device) { }
+
+ public override string Issue => "Flyout Item misbehavior";
+
+ [Test]
+ [Category(UITestCategories.FlyoutPage)]
+ public void Issue23834FlyoutMisbehavior()
+ {
+ App.WaitForElement("button");
+ App.Tap("button");
+ App.ShowFlyout();
+ VerifyScreenshot();
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26662.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26662.cs
index 227dbd29e99b..f440c18db6f2 100644
--- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26662.cs
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26662.cs
@@ -1,6 +1,3 @@
-// FontImageSource color is not applied to the Tab Icon on Windows for the Tabbedpage
-// Issue: https://github.com/dotnet/maui/issues/26752
-#if TEST_FAILS_ON_WINDOWS
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;
@@ -31,4 +28,3 @@ public void DynamicFontImageSourceColorShouldApplyOnTabIcon()
}
}
}
-#endif
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue27711.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue27711.cs
new file mode 100644
index 000000000000..cdaa7b00eb81
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue27711.cs
@@ -0,0 +1,25 @@
+#if ANDROID || IOS
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue27711 : _IssuesUITest
+{
+ public Issue27711(TestDevice testDevice) : base(testDevice)
+ {
+ }
+
+ public override string Issue => "FlowDirection = `RightToLeft` doesn't work with CV1 & CV2";
+
+ [Test]
+ [Category(UITestCategories.CollectionView)]
+ public void RightToLeftFlowDirectionShouldWork()
+ {
+ App.WaitForElement("switch");
+ App.Click("switch");
+ VerifyScreenshot();
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28343.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28343.cs
index 81930e97b467..b6fde14e4fd5 100644
--- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28343.cs
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28343.cs
@@ -22,7 +22,10 @@ public void ProgressSpinnerNotDisabledOnStartup()
App.WaitForElement("RefreshNotTriggered");
App.WaitForElement("ListItem0");
App.ScrollUp("CollectionView");
+ Thread.Sleep(1000);
App.WaitForElement("RefreshNotTriggered");
+ App.WaitForElement("ScrollToUpButton");
+ App.Tap("ScrollToUpButton");
VerifyScreenshot("Issue28343_ProgressSpinnerDisabled");
}
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28523.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28523.cs
index d0fb4a0c5b4f..8b43aca3bfa8 100644
--- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28523.cs
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28523.cs
@@ -20,7 +20,11 @@ public void CarouselViewItemShouldScaleProperly()
App.WaitForElement("Baboon");
App.SetOrientationLandscape();
App.WaitForElement("Baboon");
+#if ANDROID
+ VerifyScreenshot(cropLeft: 125);
+#else
VerifyScreenshot();
+#endif
}
[TearDown]
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28524.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28524.cs
new file mode 100644
index 000000000000..1ceb0129ad8f
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28524.cs
@@ -0,0 +1,24 @@
+#if ANDROID || IOS
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue28524 : _IssuesUITest
+{
+ public Issue28524(TestDevice device) : base(device) { }
+
+ public override string Issue => "[iOS] CurrentItem does not work when PeekAreaInsets is set";
+
+ [Test]
+ [Category(UITestCategories.CarouselView)]
+ public void CurrentItemShouldWork()
+ {
+ App.WaitForElement("CarouselView");
+ App.ScrollRight("CarouselView", ScrollStrategy.Gesture, 0.8, 500);
+ App.ScrollRight("CarouselView", ScrollStrategy.Gesture, 0.8, 500);
+ App.WaitForElement("Blue Monkey");
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28716.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28716.cs
new file mode 100644
index 000000000000..333ea7c0baf5
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28716.cs
@@ -0,0 +1,24 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+public class Issue28716 : _IssuesUITest
+{
+ public Issue28716(TestDevice testDevice) : base(testDevice)
+ {
+ }
+
+ public override string Issue => "Support for KeepLastItemInView for CV2";
+
+ [Test]
+ [Category(UITestCategories.CollectionView)]
+ public void KeepLastItemInViewShouldWork()
+ {
+ App.WaitForElement("AddItemButton");
+ App.Click("AddItemButton");
+ App.WaitForElement("Item20cv1");
+ App.WaitForElement("Item20cv2");
+ App.WaitForElement("Item20cv3");
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue29297.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue29297.cs
new file mode 100644
index 000000000000..da5f7ee20001
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue29297.cs
@@ -0,0 +1,26 @@
+#if TEST_FAILS_ON_ANDROID // Loaded event is not triggered when navigating back to previous page - https://github.com/dotnet/maui/issues/29414
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+public class Issue29297 : _IssuesUITest
+{
+ public Issue29297(TestDevice testDevice) : base(testDevice)
+ {
+ }
+
+ public override string Issue => "Crash on shell navigation for Mac Catalyst";
+
+ [Test]
+ [Category(UITestCategories.Shell)]
+ public void Shell_Issue29297()
+ {
+ App.WaitForElement("Button");
+ App.Click("Button");
+ App.WaitForElement("Button");
+ App.Click("Button");
+ App.WaitForElement("Successfully navigated back");
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue29491.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue29491.cs
new file mode 100644
index 000000000000..a826fcd2745e
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue29491.cs
@@ -0,0 +1,22 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+public class Issue29491 : _IssuesUITest
+{
+ public Issue29491(TestDevice testDevice) : base(testDevice)
+ {
+ }
+
+ public override string Issue => "[CV2][CollectionView] Changing CollectionView's ItemsSource in runtime removes elements' parent seemingly random";
+
+ [Test]
+ [Category(UITestCategories.CollectionView)]
+ public void VerifyDataTemplateParentIsNotNull()
+ {
+ App.WaitForElement("Button");
+ App.Tap("Button");
+ VerifyScreenshot();
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30350.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30350.cs
new file mode 100644
index 000000000000..24024de4b296
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30350.cs
@@ -0,0 +1,23 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues
+{
+ public class Issue30350 : _IssuesUITest
+ {
+ public Issue30350(TestDevice device) : base(device)
+ {
+ }
+
+ public override string Issue => "IImage downsize broken starting from 9.0.80 and not fixed in 9.0.81";
+
+ [Test]
+ [Category(UITestCategories.Image)]
+ public void DownSizeImageAppearProperly()
+ {
+ App.WaitForElement("WaitForStubControl");
+ VerifyScreenshot();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30367.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30367.cs
new file mode 100644
index 000000000000..cafe4ad8d9e0
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30367.cs
@@ -0,0 +1,22 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue30367 : _IssuesUITest
+{
+ public override string Issue => "SearchBar FlowDirection Property Not Working on Android";
+
+ public Issue30367(TestDevice device)
+ : base(device)
+ { }
+
+ [Test]
+ [Category(UITestCategories.SearchBar)]
+ public void VerifySearchBarFlowDirection()
+ {
+ App.WaitForElement("SearchBarLabel");
+ VerifyScreenshot();
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30426.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30426.cs
new file mode 100644
index 000000000000..51f79dc53576
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30426.cs
@@ -0,0 +1,30 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues
+{
+ public class Issue30426 : _IssuesUITest
+ {
+ public Issue30426(TestDevice device) : base(device)
+ {
+ }
+
+ public override string Issue => "IImage Downsize() throws Exception in 9.0.81 when called from background thread on iOS";
+
+ [Test]
+ [Category(UITestCategories.Image)]
+ public void LoadTestImageButtonShouldLoadImageWithoutException()
+ {
+ App.WaitForElement("WaitForStubControl");
+ App.WaitForElement("LoadImageButton");
+ App.Tap("LoadImageButton");
+ App.WaitForElement("StatusLabel");
+ Assert.That(App.WaitForElement("StatusLabel").GetText(), Is.EqualTo("Status: Image loaded successfully"));
+ App.WaitForElement("ProcessImageButton");
+ App.Tap("ProcessImageButton");
+ App.WaitForElement("StatusLabel");
+ Assert.That(App.WaitForElement("StatusLabel").GetText(), Is.EqualTo("Status: Image processed successfully"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30536.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30536.cs
new file mode 100644
index 000000000000..f823ac32e66e
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30536.cs
@@ -0,0 +1,33 @@
+#if WINDOWS
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+public class Issue30536 : _IssuesUITest
+{
+ public Issue30536(TestDevice device) : base(device) { }
+
+ public override string Issue => "[Windows] PointerGestureRecognizer behaves incorrectly when multiple windows are open";
+
+ [Test]
+ [Category(UITestCategories.Gestures)]
+ public void PointerGesturesShouldWorkProperlyOnMultiWindows()
+ {
+ App.WaitForElement("NewWindowButton");
+ App.Tap("NewWindowButton");
+ App.WaitForElement("MinimizeSecondWindowButton");
+ App.Tap("MinimizeSecondWindowButton");
+ App.WaitForElement("BorderButton");
+ App.Tap("BorderButton");
+ var pointerEnterCount = App.FindElement("PointerEnterCountLabel");
+ Assert.That(pointerEnterCount.GetText(), Is.EqualTo("Pointer Enter Count: 1"));
+
+ var pointerExitCount = App.FindElement("PointerExitCountLabel");
+ Assert.That(pointerExitCount.GetText(), Is.EqualTo("Pointer Exit Count: 0"));
+ //once verified that pointer enter and exit counts are correct, close the newly created window
+ App.WaitForElement("CloseNewWindowButton");
+ App.Tap("CloseNewWindowButton");
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30575.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30575.cs
new file mode 100644
index 000000000000..f1bbf2c00220
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30575.cs
@@ -0,0 +1,21 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue30575 : _IssuesUITest
+{
+ public Issue30575(TestDevice device) : base(device) { }
+
+ public override string Issue => "FlowDirection RightToLeft causes mirrored content in WebView";
+
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebViewShouldNotMirrored()
+ {
+ App.WaitForElement("WebViewLabel");
+ Thread.Sleep(3000);
+ VerifyScreenshot();
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30601.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30601.cs
new file mode 100644
index 000000000000..1b892162da00
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30601.cs
@@ -0,0 +1,21 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue30601 : _IssuesUITest
+{
+ public Issue30601(TestDevice testDevice) : base(testDevice) { }
+
+ public override string Issue => "[Android] SearchBar does not update colors on theme change";
+
+ [Test]
+ [Category(UITestCategories.SearchBar)]
+ public void SearchbarColorsShouldUpdate()
+ {
+ App.WaitForElement("changeThemeButton");
+ App.Tap("changeThemeButton");
+ VerifyScreenshot();
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31139.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31139.cs
new file mode 100644
index 000000000000..0be996086bdc
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31139.cs
@@ -0,0 +1,21 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues
+{
+ public class Issue31139 : _IssuesUITest
+ {
+ public Issue31139(TestDevice device) : base(device) { }
+
+ public override string Issue => "Binding updates from background thread should marshal to UI thread";
+
+ [Test]
+ [Category(UITestCategories.Dispatcher)]
+ public void BindableUpdatesFromBackgroundThreadDoNotCrashAndPropagate()
+ {
+ App.WaitForElement("StatusLabel");
+ Assert.That(App.WaitForTextToBePresentInElement(automationId: "StatusLabel", text: "Success", timeout: TimeSpan.FromSeconds(3)), Is.True);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31314.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31314.cs
new file mode 100644
index 000000000000..e13adc4afc2d
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31314.cs
@@ -0,0 +1,20 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue31314 : _IssuesUITest
+{
+ public Issue31314(TestDevice testDevice) : base(testDevice) { }
+
+ public override string Issue => "LinearGradientBrush can not work";
+
+ [Test]
+ [Category(UITestCategories.Border)]
+ public void LinearGradientBrushShouldWork()
+ {
+ App.WaitForElement("Label");
+ VerifyScreenshot();
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31351.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31351.cs
new file mode 100644
index 000000000000..3e7e507b2e04
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31351.cs
@@ -0,0 +1,29 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue31351 : _IssuesUITest
+{
+ public Issue31351(TestDevice testDevice) : base(testDevice)
+ {
+ }
+
+ public override string Issue => "[WinUI] Custom CollectionView does not work on ScrollTo";
+
+ [Test]
+ [Category(UITestCategories.CollectionView)]
+ public void CustomCollectionViewShouldScroll()
+ {
+ App.WaitForElement("Issue31351CollectionView");
+ App.WaitForElement("Issue31351ScrollButton");
+ App.Tap("Issue31351ScrollButton");
+ var MidItemRect = App.WaitForElement("Item 50").GetRect();
+ Assert.That(MidItemRect.X, Is.GreaterThanOrEqualTo(0));
+ App.WaitForElement("Issue31351TopScrollButton");
+ App.Tap("Issue31351TopScrollButton");
+ var TopItemRect = App.WaitForElement("Item 1").GetRect();
+ Assert.That(TopItemRect.X, Is.GreaterThanOrEqualTo(0));
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31375.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31375.cs
new file mode 100644
index 000000000000..342241edccf9
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31375.cs
@@ -0,0 +1,25 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues
+{
+ public class Issue31375 : _IssuesUITest
+ {
+ public Issue31375(TestDevice device) : base(device)
+ {
+ }
+
+ public override string Issue => "[Windows] RefreshView Command executes multiple times when IsRefreshing is set to True";
+
+ [Test]
+ [Category(UITestCategories.RefreshView)]
+ public void VerifyRefreshViewCommandExecution()
+ {
+ App.WaitForElement("CounterLabel");
+ App.Tap("RefreshButton");
+ App.Tap("RefreshButton");
+ Assert.That(App.FindElement("CounterLabel").GetText(), Is.EqualTo("2"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31377.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31377.cs
new file mode 100644
index 000000000000..e73263cc6055
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31377.cs
@@ -0,0 +1,23 @@
+#if TEST_FAILS_ON_WINDOWS && TEST_FAILS_ON_ANDROID //The more page works differently on these platforms
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue31377 : _IssuesUITest
+{
+ public Issue31377(TestDevice testDevice) : base(testDevice) { }
+
+ public override string Issue => "TabbedPage overflow 'More' button does not work";
+
+ [Test]
+ [Category(UITestCategories.TabbedPage)]
+ public void Issue31377TestsOverflowMoreButton()
+ {
+ App.WaitForElement("More");
+ App.Tap("More");
+ App.WaitForElement("Tab 10");
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31390.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31390.cs
new file mode 100644
index 000000000000..58ec610b34a4
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31390.cs
@@ -0,0 +1,27 @@
+#if TEST_FAILS_ON_ANDROID // https://github.com/dotnet/maui/issues/22116
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue31390 : _IssuesUITest
+{
+ public Issue31390(TestDevice testDevice) : base(testDevice)
+ {
+ }
+ public override string Issue => "System.ArgumentException thrown when setting FlyoutLayoutBehavior dynamically";
+
+ [Test]
+ [Category(UITestCategories.FlyoutPage)]
+ public void EnsureFlyoutLayoutBehaviorChanges()
+ {
+ App.WaitForElement("GoToNextPage");
+ App.Tap("GoToNextPage");
+ App.Tap("ChangeToPopover");
+ App.Tap("Apply");
+ App.TapFlyoutPageIcon("Flyout");
+ App.WaitForElement("Issue31390_FlyoutLabel");
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31520.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31520.cs
new file mode 100644
index 000000000000..04f9d793c76e
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31520.cs
@@ -0,0 +1,23 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue31520 : _IssuesUITest
+{
+ public Issue31520(TestDevice testDevice) : base(testDevice)
+ {
+ }
+ public override string Issue => "NavigatingFrom is triggered first when using PushAsync";
+
+ [Test]
+ [Category(UITestCategories.Navigation)]
+ public void NavigatingFromTriggeredFirst()
+ {
+ App.WaitForElement("PushButton");
+ App.Tap("PushButton");
+ var label = App.WaitForElement("NavigatingStatusLabel");
+ Assert.That(label.GetText(), Is.EqualTo("NavigatingFrom triggered before Disappearing"));
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31535.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31535.cs
new file mode 100644
index 000000000000..418f98180909
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31535.cs
@@ -0,0 +1,25 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue31535 : _IssuesUITest
+{
+ public Issue31535(TestDevice device) : base(device) { }
+
+ public override string Issue => "[iOS] Crash occurred on CarouselView2 when deleting last one remaining item with loop as false";
+
+ [Test]
+ [Category(UITestCategories.CarouselView)]
+ public void CarouselView2ShouldNotCrashOnRemovingItems()
+ {
+ App.WaitForElement("AddSingleItemButton");
+ App.Tap("AddSingleItemButton");
+ //remove one single item, crash should not occured
+ App.Tap("RemoveSingleItemButton");
+ App.Tap("AddMultipleItemsButton");
+ App.Tap("RemoveAllItemsButton");
+ App.WaitForElement("TestCarouselView");
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31539.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31539.cs
new file mode 100644
index 000000000000..633a798b1ba9
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31539.cs
@@ -0,0 +1,27 @@
+# if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_WINDOWS // BackButtonTitle is only applicable for iOS and macOS
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues
+{
+ public class Issue31539 : _IssuesUITest
+ {
+ public Issue31539(TestDevice device) : base(device) { }
+
+ public override string Issue => "[iOS, macOS] Navigation Page BackButtonTitle Not Updating";
+ [Test]
+ [Category(UITestCategories.Navigation)]
+ public void VerifyBackButtonTitleUpdates()
+ {
+ App.WaitForElement("PushSecondPage");
+ App.Tap("PushSecondPage");
+ App.TapBackArrow();
+ App.Tap("SetBackButtonTitle");
+ App.Tap("PushSecondPage");
+ App.WaitForElement("SecondPageLabel");
+ VerifyScreenshot();
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31606.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31606.cs
new file mode 100644
index 000000000000..dac723116f4d
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31606.cs
@@ -0,0 +1,19 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue31606 : _IssuesUITest
+{
+ public Issue31606(TestDevice testDevice) : base(testDevice) { }
+
+ public override string Issue => "Crash on Windows when SemanticProperties.Description is set for ToolbarItem";
+
+ [Test]
+ [Category(UITestCategories.Accessibility)]
+ public void SettingSemanticPropertiesDescriptionDoesNotCrash()
+ {
+ App.WaitForElement("TestStatus");
+ }
+}
\ No newline at end of file
diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue7045.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue7045.cs
new file mode 100644
index 000000000000..08fa227960e7
--- /dev/null
+++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue7045.cs
@@ -0,0 +1,24 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.TestCases.Tests.Issues;
+
+public class Issue7045 : _IssuesUITest
+{
+ public Issue7045(TestDevice testDevice) : base(testDevice)
+ {
+ }
+
+ public override string Issue => "Shell BackButtonBehavior binding Command to valid ICommand causes back button to disappear";
+
+ [Test]
+ [Category(UITestCategories.Shell)]
+ public void ShellBackButtonBehaviorShouldWork()
+ {
+ App.WaitForElement("NavigateButton");
+ App.Click("NavigateButton");
+ App.WaitForElement("DetailPageLabel");
+ VerifyScreenshot();
+ }
+}
diff --git a/src/Controls/tests/TestCases.Shared.Tests/UITest.cs b/src/Controls/tests/TestCases.Shared.Tests/UITest.cs
index 687c937f064f..8aa4c7428c47 100644
--- a/src/Controls/tests/TestCases.Shared.Tests/UITest.cs
+++ b/src/Controls/tests/TestCases.Shared.Tests/UITest.cs
@@ -126,6 +126,8 @@ public void VerifyScreenshotOrSetException(
ref Exception? exception,
string? name = null,
TimeSpan? retryDelay = null,
+ int cropLeft = 0,
+ int cropRight = 0,
int cropTop = 0,
int cropBottom = 0,
double tolerance = 0.0
@@ -136,7 +138,7 @@ public void VerifyScreenshotOrSetException(
{
try
{
- VerifyScreenshot(name, retryDelay, cropTop, cropBottom, tolerance
+ VerifyScreenshot(name, retryDelay, cropLeft, cropRight, cropTop, cropBottom, tolerance
#if MACUITEST || WINTEST
, includeTitleBar
#endif
@@ -153,6 +155,8 @@ public void VerifyScreenshotOrSetException(
///
/// Optional name for the screenshot. If not provided, a default name will be used.
/// Optional delay between retry attempts when verification fails.
+ /// Number of pixels to crop from the left of the screenshot.
+ /// Number of pixels to crop from the right of the screenshot.
/// Number of pixels to crop from the top of the screenshot.
/// Number of pixels to crop from the bottom of the screenshot.
/// Tolerance level for image comparison as a percentage from 0 to 100.
@@ -181,6 +185,8 @@ public void VerifyScreenshotOrSetException(
public void VerifyScreenshot(
string? name = null,
TimeSpan? retryDelay = null,
+ int cropLeft = 0,
+ int cropRight = 0,
int cropTop = 0,
int cropBottom = 0,
double tolerance = 0.0 // Add tolerance parameter (0.05 = 5%)
@@ -327,15 +333,23 @@ but both can happen.
_ => 0,
};
+ // Cropping from the left or right can be applied for any platform using the user-specified crop values.
+ // The default values are set based on the platform, but the final cropping is determined by the parameters passed in.
+ // This allows cropping of UI elements (such as navigation bars or home indicators) for any platform as needed.
+ int cropFromLeft = 0;
+ int cropFromRight = 0;
+
+ cropFromLeft = cropLeft > 0 ? cropLeft : cropFromLeft;
+ cropFromRight = cropRight > 0 ? cropRight : cropFromRight;
cropFromTop = cropTop > 0 ? cropTop : cropFromTop;
cropFromBottom = cropBottom > 0 ? cropBottom : cropFromBottom;
- if (cropFromTop > 0 || cropFromBottom > 0)
+ if (cropFromLeft > 0 || cropFromRight > 0 || cropFromTop > 0 || cropFromBottom > 0)
{
IImageEditor imageEditor = _imageEditorFactory.CreateImageEditor(actualImage);
(int width, int height) = imageEditor.GetSize();
- imageEditor.Crop(0, cropFromTop, width, height - cropFromTop - cropFromBottom);
+ imageEditor.Crop(cropFromLeft, cropFromTop, width - cropFromLeft - cropFromRight, height - cropFromTop - cropFromBottom);
actualImage = imageEditor.GetUpdatedImage();
}
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BackButtonHidden.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BackButtonHidden.png
new file mode 100644
index 000000000000..68d6641352f7
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BackButtonHidden.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BackButtonVisible.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BackButtonVisible.png
new file mode 100644
index 000000000000..bc8e41568ec5
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BackButtonVisible.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgBlue.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgBlue.png
new file mode 100644
index 000000000000..8fd8249661a5
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgBlue.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgLinear.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgLinear.png
new file mode 100644
index 000000000000..eeb8c0bffcb1
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgLinear.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgRadial.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgRadial.png
new file mode 100644
index 000000000000..128370e2bc06
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgRadial.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgRed.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgRed.png
new file mode 100644
index 000000000000..64c151b69eb0
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarBgRed.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarTextBlack.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarTextBlack.png
new file mode 100644
index 000000000000..ca9850566de7
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarTextBlack.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarTextWhite.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarTextWhite.png
new file mode 100644
index 000000000000..766120f4d674
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/BarTextWhite.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_PaddingWithContent_Label.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_PaddingWithContent_Label.png
new file mode 100644
index 000000000000..71728c8e38dc
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_PaddingWithContent_Label.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_PolygonShapeWithStrokeLineJoin_Bevel.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_PolygonShapeWithStrokeLineJoin_Bevel.png
new file mode 100644
index 000000000000..411260056b7a
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_PolygonShapeWithStrokeLineJoin_Bevel.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_Shadow.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_Shadow.png
new file mode 100644
index 000000000000..1cbc28131e69
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithDashArrayAndOffset.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithDashArrayAndOffset.png
new file mode 100644
index 000000000000..6b83e20a4773
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithDashArrayAndOffset.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithPaddingAndContent_Image.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithPaddingAndContent_Image.png
new file mode 100644
index 000000000000..c2a4860193e2
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithPaddingAndContent_Image.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithStrokeLineJoin_Round.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithStrokeLineJoin_Round.png
new file mode 100644
index 000000000000..690dc84c30c7
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithStrokeLineJoin_Round.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithStrokeShape_RoundRectangle.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithStrokeShape_RoundRectangle.png
new file mode 100644
index 000000000000..4c6498e510c8
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithStrokeShape_RoundRectangle.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithStrokeThickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithStrokeThickness.png
new file mode 100644
index 000000000000..a8ab56f92356
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeColorWithStrokeThickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeDashArrayWithDashOffset.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeDashArrayWithDashOffset.png
new file mode 100644
index 000000000000..dbf2de2b93f0
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeDashArrayWithDashOffset.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeDashArrayWithStrokeColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeDashArrayWithStrokeColor.png
new file mode 100644
index 000000000000..c6f289746446
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeDashArrayWithStrokeColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeShapeWithDashArray_Path.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeShapeWithDashArray_Path.png
new file mode 100644
index 000000000000..52562caca14f
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeShapeWithDashArray_Path.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeShapeWithStrokeLineJoin_Bevel.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeShapeWithStrokeLineJoin_Bevel.png
new file mode 100644
index 000000000000..c65259a6f036
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeShapeWithStrokeLineJoin_Bevel.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeShapeWithStrokeThickness_Ellipse.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeShapeWithStrokeThickness_Ellipse.png
new file mode 100644
index 000000000000..94c5f3c92789
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeShapeWithStrokeThickness_Ellipse.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeThicknessWithDashArray.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeThicknessWithDashArray.png
new file mode 100644
index 000000000000..8b35657fb90f
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeThicknessWithDashArray.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeThicknessWithStrokeLineJoin_Bevel.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeThicknessWithStrokeLineJoin_Bevel.png
new file mode 100644
index 000000000000..bb7dfc4ed10a
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Border_StrokeThicknessWithStrokeLineJoin_Bevel.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Combine_BarBackgroundColor_TextColor_IconColor_Visual.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Combine_BarBackgroundColor_TextColor_IconColor_Visual.png
new file mode 100644
index 000000000000..3b511116b451
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Combine_BarBackgroundColor_TextColor_IconColor_Visual.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Background_WithRTL.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Background_WithRTL.png
new file mode 100644
index 000000000000..c4df5c5796df
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Background_WithRTL.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_IsVisible_WithTitle.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_IsVisible_WithTitle.png
new file mode 100644
index 000000000000..8cbf5d885e89
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_IsVisible_WithTitle.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_IsVisible_WithoutTitle.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_IsVisible_WithoutTitle.png
new file mode 100644
index 000000000000..8bd444a66b21
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_IsVisible_WithoutTitle.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Padding_WithBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Padding_WithBackgroundColor.png
new file mode 100644
index 000000000000..4c5d6a5baa6e
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Padding_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Padding_WithRTL.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Padding_WithRTL.png
new file mode 100644
index 000000000000..80b4404aa84a
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Padding_WithRTL.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Padding_WithTitle.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Padding_WithTitle.png
new file mode 100644
index 000000000000..497282a43f0c
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Padding_WithTitle.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Title_WithBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Title_WithBackgroundColor.png
new file mode 100644
index 000000000000..89be24462fc4
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Title_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Title_WithBackgroundColorAndPadding.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Title_WithBackgroundColorAndPadding.png
new file mode 100644
index 000000000000..d9bcde16db7e
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_Title_WithBackgroundColorAndPadding.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_zContent.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_zContent.png
new file mode 100644
index 000000000000..19ee76d23c63
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ContentPage_zContent.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithBackgroundColor.png
new file mode 100644
index 000000000000..30c66ecc587d
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithFlowDirection.png
new file mode 100644
index 000000000000..0b725e1a8074
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithHeightRequest.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithHeightRequest.png
new file mode 100644
index 000000000000..1a9cae479746
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithHeightRequest.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithWidthRequest.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithWidthRequest.png
new file mode 100644
index 000000000000..e2a23e5155d9
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DefaultContentWithWidthRequest.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DownSizeImageAppearProperly.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DownSizeImageAppearProperly.png
new file mode 100644
index 000000000000..4c2597ff9952
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DownSizeImageAppearProperly.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DynamicFontImageSourceColorShouldApplyOnTabIcon.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DynamicFontImageSourceColorShouldApplyOnTabIcon.png
new file mode 100644
index 000000000000..e02d4f1d3237
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/DynamicFontImageSourceColorShouldApplyOnTabIcon.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Ellipse_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Ellipse_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..7ac4cdf8c0c9
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Ellipse_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Ellipse_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Ellipse_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..736716318aec
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Ellipse_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Ellipse_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Ellipse_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..98847468b4aa
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Ellipse_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/EntryClearButtonColorShouldUpdateOnThemeChange.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/EntryClearButtonColorShouldUpdateOnThemeChange.png
new file mode 100644
index 000000000000..7e05cd60da58
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/EntryClearButtonColorShouldUpdateOnThemeChange.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithBackgroundColor.png
new file mode 100644
index 000000000000..d63e1bb4d431
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithCardColorChanged.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithCardColorChanged.png
new file mode 100644
index 000000000000..e657938ad627
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithCardColorChanged.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithFlowDirection.png
new file mode 100644
index 000000000000..5e573c5c8123
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithIconImageChanged.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithIconImageChanged.png
new file mode 100644
index 000000000000..e1cb596ddc5c
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FirstCustomPageWithIconImageChanged.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FontImageSourceColorShouldApplyOnTabIcon.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FontImageSourceColorShouldApplyOnTabIcon.png
new file mode 100644
index 000000000000..1c9b3664c1d3
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/FontImageSourceColorShouldApplyOnTabIcon.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection.png
new file mode 100644
index 000000000000..58ed65e50275
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection_With_Height.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection_With_Height.png
new file mode 100644
index 000000000000..c04592068180
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection_With_HeightAndWidth.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection_With_HeightAndWidth.png
new file mode 100644
index 000000000000..2bc8653fffbf
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection_With_Width.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection_With_Width.png
new file mode 100644
index 000000000000..ec37ea3ce5a2
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_RTLFlowDirection_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_Height.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_Height.png
new file mode 100644
index 000000000000..db934f647476
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_HeightAndWidth.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_HeightAndWidth.png
new file mode 100644
index 000000000000..3cdd54d68eec
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_RTL.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_RTL.png
new file mode 100644
index 000000000000..a21ebf08e446
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_RTL.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_Width.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_Width.png
new file mode 100644
index 000000000000..5fabfe634408
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/HorizontalStackLayout_Spacing_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/IconColorDefault.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/IconColorDefault.png
new file mode 100644
index 000000000000..4aa38949a484
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/IconColorDefault.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/IconColorRed.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/IconColorRed.png
new file mode 100644
index 000000000000..7ab110459627
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/IconColorRed.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue23834FlyoutMisbehavior.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue23834FlyoutMisbehavior.png
new file mode 100644
index 000000000000..6d44dab294cf
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue23834FlyoutMisbehavior.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue24414Test_4.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue24414Test_4.png
index 12b1e3f77595..f126c18a2e5a 100644
Binary files a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue24414Test_4.png and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue24414Test_4.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue24414Test_5.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue24414Test_5.png
index dd3e12c0ba7c..b92a3b3e3a17 100644
Binary files a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue24414Test_5.png and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue24414Test_5.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue28343_ProgressSpinnerDisabled.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue28343_ProgressSpinnerDisabled.png
index 7fd3a49e9c72..339486195ed8 100644
Binary files a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue28343_ProgressSpinnerDisabled.png and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue28343_ProgressSpinnerDisabled.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Line_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Line_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..8e7e28842374
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Line_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Line_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Line_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..c11650b09115
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Line_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Line_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Line_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..575f4733fcf4
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Line_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/LinearGradientBrushShouldWork.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/LinearGradientBrushShouldWork.png
new file mode 100644
index 000000000000..5f964537c0c4
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/LinearGradientBrushShouldWork.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/NavBarHidden.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/NavBarHidden.png
new file mode 100644
index 000000000000..4f0856ca09ac
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/NavBarHidden.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/NavBarVisible.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/NavBarVisible.png
new file mode 100644
index 000000000000..a5b251ff50c3
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/NavBarVisible.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..a38d97ef9e6c
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_Points_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_Points_Thickness.png
new file mode 100644
index 000000000000..132468ac4e42
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_Points_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..0341ccb86663
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..625e6b36b5a8
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Path_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SelectItem_VerifySelectedItem.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SelectItem_VerifySelectedItem.png
new file mode 100644
index 000000000000..7dcafc6c35db
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SelectItem_VerifySelectedItem.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFlowDirectionRTLAndTitle_VerifyFlowDirectionAndTitle.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFlowDirectionRTLAndTitle_VerifyFlowDirectionAndTitle.png
new file mode 100644
index 000000000000..1173266b0244
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFlowDirectionRTLAndTitle_VerifyFlowDirectionAndTitle.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFlowDirectionRTL_VerifyFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFlowDirectionRTL_VerifyFlowDirection.png
new file mode 100644
index 000000000000..152cdbb5aade
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFlowDirectionRTL_VerifyFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily.png
new file mode 100644
index 000000000000..b90fadb407ad
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes.png
new file mode 100644
index 000000000000..c68c23ababfb
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily.png
new file mode 100644
index 000000000000..3f475aa887af
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem.png
new file mode 100644
index 000000000000..39740a40a34b
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetHorizontalTextAlignmentEndAndTitle_VerifyTitleAlignment.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetHorizontalTextAlignmentEndAndTitle_VerifyTitleAlignment.png
new file mode 100644
index 000000000000..f13e01e3c120
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetHorizontalTextAlignmentEndAndTitle_VerifyTitleAlignment.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetIsEnabledFalse_VerifyPickerDisabled.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetIsEnabledFalse_VerifyPickerDisabled.png
new file mode 100644
index 000000000000..a9d7718cf094
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetIsEnabledFalse_VerifyPickerDisabled.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetSelectedIndex_VerifySelectedIndexAndItem.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetSelectedIndex_VerifySelectedIndexAndItem.png
new file mode 100644
index 000000000000..c449d8a44e0e
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetSelectedIndex_VerifySelectedIndexAndItem.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetSelectedItem_VerifySelectedItemLabel.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetSelectedItem_VerifySelectedItemLabel.png
new file mode 100644
index 000000000000..19b076d496af
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetSelectedItem_VerifySelectedItemLabel.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTextColorRed_VerifyTextColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTextColorRed_VerifyTextColor.png
new file mode 100644
index 000000000000..6d0fe67a71a2
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTextColorRed_VerifyTextColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleColorOrange_VerifyTitleColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleColorOrange_VerifyTitleColor.png
new file mode 100644
index 000000000000..c55e9f4ecc23
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleColorOrange_VerifyTitleColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleWithFontAttributeBold_VerifyTitleAndFontAttribute.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleWithFontAttributeBold_VerifyTitleAndFontAttribute.png
new file mode 100644
index 000000000000..2c7f37a4812e
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleWithFontAttributeBold_VerifyTitleAndFontAttribute.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleWithFontFamilyDokdo_VerifyTitleAndFontFamily.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleWithFontFamilyDokdo_VerifyTitleAndFontFamily.png
new file mode 100644
index 000000000000..d54391459ae9
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleWithFontFamilyDokdo_VerifyTitleAndFontFamily.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleWithFontSize_VerifyTitleAndFontSize.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleWithFontSize_VerifyTitleAndFontSize.png
new file mode 100644
index 000000000000..d4f58c63f2b7
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitleWithFontSize_VerifyTitleAndFontSize.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitle_VerifyTitleLabel.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitle_VerifyTitleLabel.png
new file mode 100644
index 000000000000..17516161b29b
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetTitle_VerifyTitleLabel.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem.png
new file mode 100644
index 000000000000..4b75eb789599
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetVerticalTextAlignmentEndAndTitle_VerifyTitleAlignment.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetVerticalTextAlignmentEndAndTitle_VerifyTitleAlignment.png
new file mode 100644
index 000000000000..3fd580f50cfc
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_SetVerticalTextAlignmentEndAndTitle_VerifyTitleAlignment.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_TapPicker_TakeScreenshot.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_TapPicker_TakeScreenshot.png
new file mode 100644
index 000000000000..07ad907cc186
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_TapPicker_TakeScreenshot.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_Validate_VerifyLabels.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_Validate_VerifyLabels.png
new file mode 100644
index 000000000000..fd83fc468c6a
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Picker_Validate_VerifyLabels.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PlaceholderColorShouldChange.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PlaceholderColorShouldChange.png
index c1b39131dbd4..b79711069da8 100644
Binary files a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PlaceholderColorShouldChange.png and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PlaceholderColorShouldChange.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..8ccee3b88c09
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_Points_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_Points_Thickness.png
new file mode 100644
index 000000000000..d011d9c6f274
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_Points_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..8a0f7dd66910
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..63fd7cb8c193
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/PolyLine_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Polygon_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Polygon_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..72694fc8f67d
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Polygon_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Polygon_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Polygon_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..6b08ad202bb9
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Polygon_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Polygon_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Polygon_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..796d46308bbc
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Polygon_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Rectangle_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Rectangle_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..30c00f09e319
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Rectangle_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Rectangle_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Rectangle_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..8d36807caac1
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Rectangle_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Rectangle_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Rectangle_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..6a6af666baaf
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Rectangle_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SearchbarColorsShouldUpdate.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SearchbarColorsShouldUpdate.png
new file mode 100644
index 000000000000..df6bf62b627f
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SearchbarColorsShouldUpdate.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SecondCustomPageWithBackgroundColorChanged.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SecondCustomPageWithBackgroundColorChanged.png
new file mode 100644
index 000000000000..879d2310d45e
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SecondCustomPageWithBackgroundColorChanged.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SecondCustomPageWithFlowDirectionChanged.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SecondCustomPageWithFlowDirectionChanged.png
new file mode 100644
index 000000000000..e5ac404df7fd
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SecondCustomPageWithFlowDirectionChanged.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SelectedItemsShowSelected_multiple.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SelectedItemsShowSelected_multiple.png
new file mode 100644
index 000000000000..a5042cb11c30
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SelectedItemsShowSelected_multiple.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SelectedItemsShowSelected_none.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SelectedItemsShowSelected_none.png
new file mode 100644
index 000000000000..7c51e889dcb8
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SelectedItemsShowSelected_none.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SelectedItemsShowSelected_single.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SelectedItemsShowSelected_single.png
new file mode 100644
index 000000000000..ca7c6ad59a38
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SelectedItemsShowSelected_single.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Shape_Polygon_Pentagon.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Shape_Polygon_Pentagon.png
new file mode 100644
index 000000000000..e9b4675e1d50
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Shape_Polygon_Pentagon.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Shape_Rectangle_HeightAndWidth.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Shape_Rectangle_HeightAndWidth.png
new file mode 100644
index 000000000000..03b92a10bc3f
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Shape_Rectangle_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Shape_Rectangle_XAndYRadius.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Shape_Rectangle_XAndYRadius.png
new file mode 100644
index 000000000000..8cb4001a67cc
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Shape_Rectangle_XAndYRadius.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ShellBackButtonBehaviorShouldWork.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ShellBackButtonBehaviorShouldWork.png
new file mode 100644
index 000000000000..debc9a21f5e1
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ShellBackButtonBehaviorShouldWork.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_BackgroundColor_WithGrid.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_BackgroundColor_WithGrid.png
new file mode 100644
index 000000000000..61326ca38eae
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_BackgroundColor_WithGrid.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_ForegroundColor_WithBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_ForegroundColor_WithBackgroundColor.png
new file mode 100644
index 000000000000..ac868d72ce49
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_ForegroundColor_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_ForegroundColor_WithGrid.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_ForegroundColor_WithGrid.png
new file mode 100644
index 000000000000..d094b1b2e28b
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_ForegroundColor_WithGrid.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithBackgroundColor.png
new file mode 100644
index 000000000000..58254c1be202
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithForegroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithForegroundColor.png
new file mode 100644
index 000000000000..fa6182e0c9bc
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithForegroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithSearchBar.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithSearchBar.png
new file mode 100644
index 000000000000..adcd91940b49
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithSearchBar.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithTrailingContentAndLeadingContent.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithTrailingContentAndLeadingContent.png
new file mode 100644
index 000000000000..e27a046dd92b
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Icon_WithTrailingContentAndLeadingContent.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_IsVisible.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_IsVisible.png
new file mode 100644
index 000000000000..dcbc95c4c2ab
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_Entry.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_Entry.png
new file mode 100644
index 000000000000..df90abcf2e73
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_Entry.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithBackgroundColor.png
new file mode 100644
index 000000000000..c08922abca48
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithGrid.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithGrid.png
new file mode 100644
index 000000000000..4489cd1e1a93
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithGrid.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithHorizontalStackLayout.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithHorizontalStackLayout.png
new file mode 100644
index 000000000000..891d84105dac
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithHorizontalStackLayout.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithSearchBar.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithSearchBar.png
new file mode 100644
index 000000000000..c9f58b8a4246
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TitleAndSubTitle_WithSearchBar.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithBackgroundColor.png
new file mode 100644
index 000000000000..f90014bf5a1b
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithGrid.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithGrid.png
new file mode 100644
index 000000000000..052b4306332d
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithGrid.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithHorizontalStackLayout.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithHorizontalStackLayout.png
new file mode 100644
index 000000000000..b17dfd894cd9
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithHorizontalStackLayout.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithSearchBar.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithSearchBar.png
new file mode 100644
index 000000000000..6083042982ac
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithSearchBar.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithTitleAndSubtitle.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithTitleAndSubtitle.png
new file mode 100644
index 000000000000..08d73ed9fab4
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_TrailingContentAndLeadingContent_WithTitleAndSubtitle.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Window.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Window.png
new file mode 100644
index 000000000000..5f724da15022
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleBar_Window.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleIcon_Add_Visual.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleIcon_Add_Visual.png
new file mode 100644
index 000000000000..ea67bfef4518
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleIcon_Add_Visual.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleIcon_AddingTwice_DoesNotDuplicate.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleIcon_AddingTwice_DoesNotDuplicate.png
new file mode 100644
index 000000000000..3d000499b48c
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleIcon_AddingTwice_DoesNotDuplicate.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleIcon_And_TitleView_Persist_On_Push_Then_Clear.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleIcon_And_TitleView_Persist_On_Push_Then_Clear.png
new file mode 100644
index 000000000000..ec195f3e0a2f
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleIcon_And_TitleView_Persist_On_Push_Then_Clear.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleViewApplied.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleViewApplied.png
new file mode 100644
index 000000000000..9e10a350c3a0
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleViewApplied.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleViewCleared.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleViewCleared.png
new file mode 100644
index 000000000000..ef2163d7b847
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TitleViewCleared.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_IsVisible.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_IsVisible.png
new file mode 100644
index 000000000000..a17cadc71df9
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane1Priority.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane1Priority.png
new file mode 100644
index 000000000000..ce25f59a6d1e
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane1Priority.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane1SizeIncrease.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane1SizeIncrease.png
new file mode 100644
index 000000000000..97a71532aaa8
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane1SizeIncrease.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane1SizeIncrease_WithTallMode.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane1SizeIncrease_WithTallMode.png
new file mode 100644
index 000000000000..5d9d791d1149
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane1SizeIncrease_WithTallMode.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane2Priority.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane2Priority.png
new file mode 100644
index 000000000000..f0b085a20a08
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane2Priority.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane2SizeIncrease.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane2SizeIncrease.png
new file mode 100644
index 000000000000..47b9e7f1e94c
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane2SizeIncrease.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane2SizeIncrease_WithTallMode.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane2SizeIncrease_WithTallMode.png
new file mode 100644
index 000000000000..e9b243d3df0a
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_Pane2SizeIncrease_WithTallMode.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_RTLFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_RTLFlowDirection.png
new file mode 100644
index 000000000000..6c6e78f02720
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_RTLFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_TallMode.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_TallMode.png
new file mode 100644
index 000000000000..547508b3eede
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_TallMode.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_WideMode.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_WideMode.png
new file mode 100644
index 000000000000..47a819cea165
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_WideMode.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_ZIsShadowEnabled.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_ZIsShadowEnabled.png
new file mode 100644
index 000000000000..157483c6f9d0
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/TwoPaneView_ZIsShadowEnabled.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_AllProportional.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_AllProportional.png
new file mode 100644
index 000000000000..bf77fe10e7aa
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_AllProportional.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_BackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_BackgroundColor.png
new file mode 100644
index 000000000000..947a995d6f11
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_BackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_FlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_FlowDirection.png
new file mode 100644
index 000000000000..9ca45d103e44
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_FlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_HeightProportional.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_HeightProportional.png
new file mode 100644
index 000000000000..ffaa5695cf64
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_HeightProportional.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_LayoutBounds.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_LayoutBounds.png
new file mode 100644
index 000000000000..ce6ab6bd7c33
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_LayoutBounds.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_PositionProportional.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_PositionProportional.png
new file mode 100644
index 000000000000..76c29c92e772
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_PositionProportional.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_Reset_LayoutBounds.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_Reset_LayoutBounds.png
new file mode 100644
index 000000000000..8a77aadd05d4
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_Reset_LayoutBounds.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_SizeProportional.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_SizeProportional.png
new file mode 100644
index 000000000000..5f97d4549263
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_SizeProportional.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_SizeProportionalAndPositionProportional.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_SizeProportionalAndPositionProportional.png
new file mode 100644
index 000000000000..44381fc0ce7e
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_SizeProportionalAndPositionProportional.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_SizeProportionalWithMaximumValue.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_SizeProportionalWithMaximumValue.png
new file mode 100644
index 000000000000..ca7efed43824
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_SizeProportionalWithMaximumValue.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_Visibility.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_Visibility.png
new file mode 100644
index 000000000000..e38dcd1d03af
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_Visibility.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_WidthAndHeight.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_WidthAndHeight.png
new file mode 100644
index 000000000000..62649cce8fde
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_WidthAndHeight.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_WidthProportional.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_WidthProportional.png
new file mode 100644
index 000000000000..89a57c915b96
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_WidthProportional.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_WidthProportionalAndHeightProportional.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_WidthProportionalAndHeightProportional.png
new file mode 100644
index 000000000000..fabf16b48ac5
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_WidthProportionalAndHeightProportional.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_XProportional.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_XProportional.png
new file mode 100644
index 000000000000..12f7e5270744
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_XProportional.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_XProportionalAndYProportional.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_XProportionalAndYProportional.png
new file mode 100644
index 000000000000..0180be25a951
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_XProportionalAndYProportional.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_YProportional.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_YProportional.png
new file mode 100644
index 000000000000..4e10eed07183
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyAbsoluteLayout_YProportional.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyDataTemplateParentIsNotNull.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyDataTemplateParentIsNotNull.png
new file mode 100644
index 000000000000..ded903c9b9f8
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyDataTemplateParentIsNotNull.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_BackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_BackgroundColor.png
new file mode 100644
index 000000000000..f678d82122ea
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_BackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_FlyoutLayoutBehavior_Split.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_FlyoutLayoutBehavior_Split.png
new file mode 100644
index 000000000000..b0835557f06a
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_FlyoutLayoutBehavior_Split.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_IsEnabled.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_IsEnabled.png
new file mode 100644
index 000000000000..bd603a505f29
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_IsEnabled.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_IsFlowDirectionRTL.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_IsFlowDirectionRTL.png
new file mode 100644
index 000000000000..99280438d986
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_IsFlowDirectionRTL.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_IsVisible.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_IsVisible.png
new file mode 100644
index 000000000000..714b12b21e28
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_Title.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_Title.png
new file mode 100644
index 000000000000..036a2635ca9d
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyFlyoutPage_Title.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColor.png
new file mode 100644
index 000000000000..9b179caac6e9
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWhenItemsAdded.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWhenItemsAdded.png
new file mode 100644
index 000000000000..193cce016177
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWhenItemsAdded.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWithFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWithFlowDirection.png
new file mode 100644
index 000000000000..f1dff83c9c90
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWithIndicatorShape.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWithIndicatorShape.png
new file mode 100644
index 000000000000..8c97fe493aca
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWithIndicatorShape.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWithIndicatorSize.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWithIndicatorSize.png
new file mode 100644
index 000000000000..bfdaaccc49d2
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorColorWithIndicatorSize.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorHideSingleIsFalse.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorHideSingleIsFalse.png
new file mode 100644
index 000000000000..92718b34eddb
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorHideSingleIsFalse.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorHideSingleIsFalseWithSelectedIndicatorColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorHideSingleIsFalseWithSelectedIndicatorColor.png
new file mode 100644
index 000000000000..369cb64b6de0
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorHideSingleIsFalseWithSelectedIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorHideSingleWithIndicatorSize.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorHideSingleWithIndicatorSize.png
new file mode 100644
index 000000000000..d676c1a00c05
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorHideSingleWithIndicatorSize.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShape.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShape.png
new file mode 100644
index 000000000000..281ef9b529ba
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShape.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShapeWithFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShapeWithFlowDirection.png
new file mode 100644
index 000000000000..98964a730bc0
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShapeWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShapeWithHideSingle.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShapeWithHideSingle.png
new file mode 100644
index 000000000000..4a7b2990ce65
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShapeWithHideSingle.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShapeWithMaximumVisible.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShapeWithMaximumVisible.png
new file mode 100644
index 000000000000..68530d815ef3
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorShapeWithMaximumVisible.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorSizeWithFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorSizeWithFlowDirection.png
new file mode 100644
index 000000000000..a4a4f75a0269
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorSizeWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorSizeWithIndicatorShape.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorSizeWithIndicatorShape.png
new file mode 100644
index 000000000000..a768502e215f
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorSizeWithIndicatorShape.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorSizeWithMaximumVisible.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorSizeWithMaximumVisible.png
new file mode 100644
index 000000000000..b08317373417
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorSizeWithMaximumVisible.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_FlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_FlowDirection.png
new file mode 100644
index 000000000000..9dc7fcbd88d8
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_FlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_HideSingle.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_HideSingle.png
new file mode 100644
index 000000000000..ead4ccbb3093
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_HideSingle.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_IsVisible.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_IsVisible.png
new file mode 100644
index 000000000000..b5e5ea7e1f7a
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_MaximumVisible.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_MaximumVisible.png
new file mode 100644
index 000000000000..577b435c2c85
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyIndicatorView_MaximumVisible.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySearchBarFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySearchBarFlowDirection.png
new file mode 100644
index 000000000000..f864a9007b3f
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySearchBarFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColor.png
new file mode 100644
index 000000000000..a9f2668639e4
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithFlowDirection.png
new file mode 100644
index 000000000000..83dbcf22cdde
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithIndicatorColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithIndicatorColor.png
new file mode 100644
index 000000000000..3e094838a780
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithIndicatorShape.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithIndicatorShape.png
new file mode 100644
index 000000000000..3253ca21164f
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithIndicatorShape.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithIndicatorSize.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithIndicatorSize.png
new file mode 100644
index 000000000000..02f1ca5fc1b1
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorColorWithIndicatorSize.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorSize.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorSize.png
new file mode 100644
index 000000000000..b482f930060a
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySelectedIndicatorSize.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithCollectionViewContentAndBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithCollectionViewContentAndBackgroundColor.png
new file mode 100644
index 000000000000..3f389fc49ceb
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithCollectionViewContentAndBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithCollectionViewContentAndFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithCollectionViewContentAndFlowDirection.png
new file mode 100644
index 000000000000..ba272f524be6
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithCollectionViewContentAndFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithCollectionViewContentChanged.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithCollectionViewContentChanged.png
new file mode 100644
index 000000000000..1f5438c34912
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithCollectionViewContentChanged.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithImageContentAndBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithImageContentAndBackgroundColor.png
new file mode 100644
index 000000000000..0e58ac6387b9
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithImageContentAndBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithImageContentAndFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithImageContentAndFlowDirection.png
new file mode 100644
index 000000000000..5572e65ca04a
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithImageContentAndFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithImageContentChanged.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithImageContentChanged.png
new file mode 100644
index 000000000000..2eab0fe237ab
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithImageContentChanged.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithLabelContentAndBackgroundColor.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithLabelContentAndBackgroundColor.png
new file mode 100644
index 000000000000..a6678ecf58f5
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithLabelContentAndBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithLabelContentAndFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithLabelContentAndFlowDirection.png
new file mode 100644
index 000000000000..0b09a589a211
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySwipeViewWithLabelContentAndFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection.png
new file mode 100644
index 000000000000..8ac2e806c098
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection_With_Height.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection_With_Height.png
new file mode 100644
index 000000000000..1842e78015f8
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection_With_HeightAndWidth.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection_With_HeightAndWidth.png
new file mode 100644
index 000000000000..4f591d3c6960
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection_With_Width.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection_With_Width.png
new file mode 100644
index 000000000000..9e3088140e01
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_RTLFlowDirection_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_Height.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_Height.png
new file mode 100644
index 000000000000..f4f44301ae96
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_HeightAndWidth.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_HeightAndWidth.png
new file mode 100644
index 000000000000..31daebab418b
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_RTL.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_RTL.png
new file mode 100644
index 000000000000..0d63d2a23f08
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_RTL.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_Width.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_Width.png
new file mode 100644
index 000000000000..e68a645feb51
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerticalStackLayout_Spacing_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/WebViewShouldNotMirrored.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/WebViewShouldNotMirrored.png
new file mode 100644
index 000000000000..bf6c65012972
Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/WebViewShouldNotMirrored.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BackButtonHidden.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BackButtonHidden.png
new file mode 100644
index 000000000000..275dcb1d0849
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BackButtonHidden.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BackButtonVisible.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BackButtonVisible.png
new file mode 100644
index 000000000000..46aba0bb0397
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BackButtonVisible.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgBlue.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgBlue.png
new file mode 100644
index 000000000000..a8fe73ec5eaa
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgBlue.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgLinear.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgLinear.png
new file mode 100644
index 000000000000..1b8021c5e985
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgLinear.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgRadial.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgRadial.png
new file mode 100644
index 000000000000..935f266e49f8
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgRadial.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgRed.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgRed.png
new file mode 100644
index 000000000000..90482bdadb5a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarBgRed.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarTextBlack.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarTextBlack.png
new file mode 100644
index 000000000000..fce97e7bb71a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarTextBlack.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarTextWhite.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarTextWhite.png
new file mode 100644
index 000000000000..ceb4403e8822
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BarTextWhite.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_PaddingWithContent_Label.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_PaddingWithContent_Label.png
new file mode 100644
index 000000000000..e898c404d397
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_PaddingWithContent_Label.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_PolygonShapeWithStrokeLineCap_Round.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_PolygonShapeWithStrokeLineCap_Round.png
new file mode 100644
index 000000000000..183318248f2c
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_PolygonShapeWithStrokeLineCap_Round.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_Shadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_Shadow.png
new file mode 100644
index 000000000000..0787eda6f9d6
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithDashArrayAndOffset.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithDashArrayAndOffset.png
new file mode 100644
index 000000000000..9169de07277e
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithDashArrayAndOffset.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithPaddingAndContent_Image.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithPaddingAndContent_Image.png
new file mode 100644
index 000000000000..98c41cb8f2a3
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithPaddingAndContent_Image.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithStrokeShape_RoundRectangle.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithStrokeShape_RoundRectangle.png
new file mode 100644
index 000000000000..31e9c4367962
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithStrokeShape_RoundRectangle.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithStrokeThickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithStrokeThickness.png
new file mode 100644
index 000000000000..ab0056651039
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeColorWithStrokeThickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeDashArrayWithDashOffsetAndStrokeLineCapRound.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeDashArrayWithDashOffsetAndStrokeLineCapRound.png
new file mode 100644
index 000000000000..93aaac12b105
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeDashArrayWithDashOffsetAndStrokeLineCapRound.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeShapeWithStrokeThickness_Ellipse.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeShapeWithStrokeThickness_Ellipse.png
new file mode 100644
index 000000000000..9c573041d664
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Border_StrokeShapeWithStrokeThickness_Ellipse.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Combine_BarBackgroundColor_TextColor_IconColor_Visual.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Combine_BarBackgroundColor_TextColor_IconColor_Visual.png
new file mode 100644
index 000000000000..7992256b6459
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Combine_BarBackgroundColor_TextColor_IconColor_Visual.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Background_WithRTL.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Background_WithRTL.png
new file mode 100644
index 000000000000..09dd3cacbd10
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Background_WithRTL.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_HideSoftinput_WithPaddingAndBackground.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_HideSoftinput_WithPaddingAndBackground.png
new file mode 100644
index 000000000000..3dbd77474c98
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_HideSoftinput_WithPaddingAndBackground.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_HideSoftinput_WithRTLAndPadding.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_HideSoftinput_WithRTLAndPadding.png
new file mode 100644
index 000000000000..5348ef45c49d
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_HideSoftinput_WithRTLAndPadding.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_IsVisible_WithTitle.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_IsVisible_WithTitle.png
new file mode 100644
index 000000000000..fb9259374554
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_IsVisible_WithTitle.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_IsVisible_WithoutTitle.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_IsVisible_WithoutTitle.png
new file mode 100644
index 000000000000..62f6973d1e7c
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_IsVisible_WithoutTitle.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Padding_WithBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Padding_WithBackgroundColor.png
new file mode 100644
index 000000000000..31587315d46e
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Padding_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Padding_WithRTL.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Padding_WithRTL.png
new file mode 100644
index 000000000000..4f29d81792c7
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Padding_WithRTL.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Padding_WithTitle.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Padding_WithTitle.png
new file mode 100644
index 000000000000..45b7d3beb006
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Padding_WithTitle.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithBackgroundColor.png
new file mode 100644
index 000000000000..2b48fd8eee73
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithBackgroundColorAnPadding.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithBackgroundColorAnPadding.png
new file mode 100644
index 000000000000..c0c3b78e4baf
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithBackgroundColorAnPadding.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithBackgroundColorAndPadding.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithBackgroundColorAndPadding.png
new file mode 100644
index 000000000000..9a303f89091b
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithBackgroundColorAndPadding.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithPaddingAndHideSoftInput.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithPaddingAndHideSoftInput.png
new file mode 100644
index 000000000000..ca6ea8c3f4e4
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_Title_WithPaddingAndHideSoftInput.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_zContent.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_zContent.png
new file mode 100644
index 000000000000..586016cc4665
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ContentPage_zContent.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithBackgroundColor.png
new file mode 100644
index 000000000000..bebe7629bcd0
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithFlowDirection.png
new file mode 100644
index 000000000000..57dd5480461b
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithHeightRequest.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithHeightRequest.png
new file mode 100644
index 000000000000..ea72512123ea
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithHeightRequest.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithShadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithShadow.png
new file mode 100644
index 000000000000..0ad8e7c1b0db
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithShadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithWidthRequest.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithWidthRequest.png
new file mode 100644
index 000000000000..63184e1ac617
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DefaultContentWithWidthRequest.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DownSizeImageAppearProperly.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DownSizeImageAppearProperly.png
new file mode 100644
index 000000000000..79d08e141924
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/DownSizeImageAppearProperly.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..bdf91dc0721c
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..17d60c733d2e
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..ee0c235b2f5a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..06d62e653e47
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Ellipse_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/EntryClearButtonColorShouldUpdateOnThemeChange.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/EntryClearButtonColorShouldUpdateOnThemeChange.png
new file mode 100644
index 000000000000..5723dcdc4e4f
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/EntryClearButtonColorShouldUpdateOnThemeChange.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithBackgroundColor.png
new file mode 100644
index 000000000000..aebd0a0557b0
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithCardColorChanged.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithCardColorChanged.png
new file mode 100644
index 000000000000..5474a6e9bd3d
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithCardColorChanged.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithFlowDirection.png
new file mode 100644
index 000000000000..0d8abc2dba98
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithIconImageChanged.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithIconImageChanged.png
new file mode 100644
index 000000000000..f6b9528418e7
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/FirstCustomPageWithIconImageChanged.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection.png
new file mode 100644
index 000000000000..31b55e873133
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection_With_Height.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection_With_Height.png
new file mode 100644
index 000000000000..d1409500d7aa
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection_With_HeightAndWidth.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection_With_HeightAndWidth.png
new file mode 100644
index 000000000000..11a21f9627a1
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection_With_Width.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection_With_Width.png
new file mode 100644
index 000000000000..ab6e122cc031
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_RTLFlowDirection_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_WithLandscape.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_WithLandscape.png
new file mode 100644
index 000000000000..5cf132193032
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_WithLandscape.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_WithLandspace.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_WithLandspace.png
new file mode 100644
index 000000000000..dd8be254bade
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_WithLandspace.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_Height.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_Height.png
new file mode 100644
index 000000000000..50961a23bb93
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_HeightAndWidth.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_HeightAndWidth.png
new file mode 100644
index 000000000000..62088f9760ca
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_RTL.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_RTL.png
new file mode 100644
index 000000000000..64848a2557c9
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_RTL.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_Width.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_Width.png
new file mode 100644
index 000000000000..8412f2bae4cc
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/HorizontalStackLayout_Spacing_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/IconColorDefault.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/IconColorDefault.png
new file mode 100644
index 000000000000..0e3ef9e44a6b
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/IconColorDefault.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/IconColorRed.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/IconColorRed.png
new file mode 100644
index 000000000000..25b615f1b79b
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/IconColorRed.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue23834FlyoutMisbehavior.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue23834FlyoutMisbehavior.png
new file mode 100644
index 000000000000..19c683cd87f9
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue23834FlyoutMisbehavior.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue28343_ProgressSpinnerDisabled.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue28343_ProgressSpinnerDisabled.png
index f1cef54b42c4..78cab0c11e16 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue28343_ProgressSpinnerDisabled.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue28343_ProgressSpinnerDisabled.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..be6557ab5abd
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..91a5bd12c029
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..99db3717e1cd
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..c931827e35eb
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Line_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/LinearGradientBrushShouldWork.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/LinearGradientBrushShouldWork.png
new file mode 100644
index 000000000000..cc9a36a1697a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/LinearGradientBrushShouldWork.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/NavBarHidden.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/NavBarHidden.png
new file mode 100644
index 000000000000..ae195286051a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/NavBarHidden.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/NavBarVisible.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/NavBarVisible.png
new file mode 100644
index 000000000000..d35f477f41a2
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/NavBarVisible.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PageShouldNotScroll.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PageShouldNotScroll.png
index 20a088003f6a..99824db0acb0 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PageShouldNotScroll.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PageShouldNotScroll.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..41d42ffadc2d
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..577389cd2e16
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_Points_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_Points_Thickness.png
new file mode 100644
index 000000000000..4a68aac87ec4
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_Points_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..79f12513decf
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..ab91a0e0b3b3
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Path_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PickerNewKeyboardIsAboveKeyboard_Entry7.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PickerNewKeyboardIsAboveKeyboard_Entry7.png
index f6a2ba16e58c..70eb442b2ad0 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PickerNewKeyboardIsAboveKeyboard_Entry7.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PickerNewKeyboardIsAboveKeyboard_Entry7.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetCharacterSpacing_VerifyCharacterSpacingLabel.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetCharacterSpacing_VerifyCharacterSpacingLabel.png
new file mode 100644
index 000000000000..bf7fe12fdea9
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetCharacterSpacing_VerifyCharacterSpacingLabel.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFlowDirectionRTL_VerifyFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFlowDirectionRTL_VerifyFlowDirection.png
new file mode 100644
index 000000000000..0df5476a67ae
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFlowDirectionRTL_VerifyFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily.png
new file mode 100644
index 000000000000..b3687aac5f77
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes.png
new file mode 100644
index 000000000000..7c968f74647e
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily.png
new file mode 100644
index 000000000000..2ab36ed86b78
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem.png
new file mode 100644
index 000000000000..e44915fa33f6
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetIsEnabledFalse_VerifyPickerDisabled.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetIsEnabledFalse_VerifyPickerDisabled.png
new file mode 100644
index 000000000000..0376586ded22
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetIsEnabledFalse_VerifyPickerDisabled.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetSelectedIndex_VerifySelectedIndexAndItem.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetSelectedIndex_VerifySelectedIndexAndItem.png
new file mode 100644
index 000000000000..ae334acf51c5
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetSelectedIndex_VerifySelectedIndexAndItem.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetSelectedItem_VerifySelectedItemLabel.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetSelectedItem_VerifySelectedItemLabel.png
new file mode 100644
index 000000000000..5fb1ff882e4d
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetSelectedItem_VerifySelectedItemLabel.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetShadow_VerifyShadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetShadow_VerifyShadow.png
new file mode 100644
index 000000000000..1cec547211ef
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetShadow_VerifyShadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetTextColorRed_VerifyTextColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetTextColorRed_VerifyTextColor.png
new file mode 100644
index 000000000000..aafb1990fc64
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetTextColorRed_VerifyTextColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem.png
new file mode 100644
index 000000000000..c8cc7658ad91
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_TapPicker_TakeScreenshot.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_TapPicker_TakeScreenshot.png
new file mode 100644
index 000000000000..63cb70566611
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_TapPicker_TakeScreenshot.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_Validate_VerifyLabels.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_Validate_VerifyLabels.png
new file mode 100644
index 000000000000..470de3e5454f
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Picker_Validate_VerifyLabels.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..93902f4ca168
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..2ae6030abc20
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_Points_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_Points_Thickness.png
new file mode 100644
index 000000000000..487c7f289ce3
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_Points_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..8afba23d6b47
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..157bf5507f47
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/PolyLine_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..80b0b8ac48e8
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..663dbdb7c720
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..fff8a36b0d61
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..e21096b58c8a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Polygon_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_DashArray_DashOffset_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_DashArray_DashOffset_Thickness.png
new file mode 100644
index 000000000000..87956fe0b2d9
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_DashArray_DashOffset_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_FillColorWithStrokeColor_Shadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_FillColorWithStrokeColor_Shadow.png
new file mode 100644
index 000000000000..0c37b2e493a2
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_FillColorWithStrokeColor_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_StrokeColor_DashArray_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_StrokeColor_DashArray_Thickness.png
new file mode 100644
index 000000000000..55e22e5be653
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_StrokeColor_DashArray_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_StrokeColor_Thickness.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_StrokeColor_Thickness.png
new file mode 100644
index 000000000000..274b4b3e827a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Rectangle_StrokeColor_Thickness.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RefreshView_SetShadowWithCollectionView_VerifyShadowApplied.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RefreshView_SetShadowWithCollectionView_VerifyShadowApplied.png
new file mode 100644
index 000000000000..a471ed5e9512
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RefreshView_SetShadowWithCollectionView_VerifyShadowApplied.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RefreshView_SetShadow_VerifyShadowApplied.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RefreshView_SetShadow_VerifyShadowApplied.png
new file mode 100644
index 000000000000..23e1f14c7484
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RefreshView_SetShadow_VerifyShadowApplied.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RightToLeftFlowDirectionShouldWork.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RightToLeftFlowDirectionShouldWork.png
new file mode 100644
index 000000000000..8118ea02e5ec
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RightToLeftFlowDirectionShouldWork.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetCancelButtonAndTextColor_VerifyVisualState.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetCancelButtonAndTextColor_VerifyVisualState.png
index 94ccef85eb02..11a0e1929e50 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetCancelButtonAndTextColor_VerifyVisualState.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetCancelButtonAndTextColor_VerifyVisualState.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFlowDirection_VerifyVisualState.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFlowDirection_VerifyVisualState.png
index a198efe333de..1bc49d75d917 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFlowDirection_VerifyVisualState.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFlowDirection_VerifyVisualState.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontFamilyAndFontSize_VerifyVisualState.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontFamilyAndFontSize_VerifyVisualState.png
index 975fd6a6b075..c177f3507ede 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontFamilyAndFontSize_VerifyVisualState.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontFamilyAndFontSize_VerifyVisualState.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontFamilyAndText_VerifyVisualState.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontFamilyAndText_VerifyVisualState.png
index e92e58568d51..ca50aa48dae9 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontFamilyAndText_VerifyVisualState.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontFamilyAndText_VerifyVisualState.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontSizeAndText_VerifyVisualState.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontSizeAndText_VerifyVisualState.png
index 11e04607e137..4f30472c92c1 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontSizeAndText_VerifyVisualState.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetFontSizeAndText_VerifyVisualState.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetHorizontalTextAlignmentAndText_VerifyVisualState.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetHorizontalTextAlignmentAndText_VerifyVisualState.png
index 32361eef3a69..1440996ac236 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetHorizontalTextAlignmentAndText_VerifyVisualState.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetHorizontalTextAlignmentAndText_VerifyVisualState.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetShadow_VerifyVisualState.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetShadow_VerifyVisualState.png
index 7f3e55ece2f3..36d358275d7c 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetShadow_VerifyVisualState.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchBar_SetShadow_VerifyVisualState.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchbarColorsShouldUpdate.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchbarColorsShouldUpdate.png
new file mode 100644
index 000000000000..4300b3756f63
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchbarColorsShouldUpdate.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SecondCustomPageWithBackgroundColorChanged.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SecondCustomPageWithBackgroundColorChanged.png
new file mode 100644
index 000000000000..2288c640e429
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SecondCustomPageWithBackgroundColorChanged.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SecondCustomPageWithFlowDirectionChanged.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SecondCustomPageWithFlowDirectionChanged.png
new file mode 100644
index 000000000000..bf7a80346f76
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SecondCustomPageWithFlowDirectionChanged.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowAddClip.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowAddClip.png
index 7e857aaa8d2a..451240246401 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowAddClip.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowAddClip.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowRemoveClip.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowRemoveClip.png
index 2be73b534c7b..30ebdd709e87 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowRemoveClip.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowRemoveClip.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_AddClip_VerifyShadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_AddClip_VerifyShadow.png
index 87f93da31763..f7bef7a7961f 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_AddClip_VerifyShadow.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_AddClip_VerifyShadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_ChangeFlowDirection_RTL_VerifyScreenshot.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_ChangeFlowDirection_RTL_VerifyScreenshot.png
index 38c02ae9484c..8c80b5e17945 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_ChangeFlowDirection_RTL_VerifyScreenshot.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_ChangeFlowDirection_RTL_VerifyScreenshot.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetEnabledStateToFalse_VerifyScreenshot.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetEnabledStateToFalse_VerifyScreenshot.png
index c8b6befc8d58..82de865a3fc5 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetEnabledStateToFalse_VerifyScreenshot.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetEnabledStateToFalse_VerifyScreenshot.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOffset_PositiveValues.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOffset_PositiveValues.png
index 3bc683915cce..83e52d091378 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOffset_PositiveValues.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOffset_PositiveValues.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOffset_Zero.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOffset_Zero.png
index 63761fe7dde7..be2a30fa197e 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOffset_Zero.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOffset_Zero.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOpacity.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOpacity.png
index 58226acfd196..452e1944ffa0 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOpacity.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOpacity.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOpacity_Zero.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOpacity_Zero.png
index e2a0fad09a61..190b6d76692a 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOpacity_Zero.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetOpacity_Zero.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetRadius.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetRadius.png
index 97e30bc07e18..194707b609be 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetRadius.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetRadius.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetRadius_Zero.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetRadius_Zero.png
index 537df2f30600..65684c1bdaf6 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetRadius_Zero.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetRadius_Zero.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetVisibilityToFalse_VerifyScreenshot.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetVisibilityToFalse_VerifyScreenshot.png
index 9931f585c792..b18a64ccd696 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetVisibilityToFalse_VerifyScreenshot.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shadow_SetVisibilityToFalse_VerifyScreenshot.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shape_Polygon_Pentagon.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shape_Polygon_Pentagon.png
new file mode 100644
index 000000000000..77f2734c7a2c
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shape_Polygon_Pentagon.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shape_Rectangle_HeightAndWidth.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shape_Rectangle_HeightAndWidth.png
new file mode 100644
index 000000000000..b73980427723
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shape_Rectangle_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shape_Rectangle_XAndYRadius.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shape_Rectangle_XAndYRadius.png
new file mode 100644
index 000000000000..2f37405b9724
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Shape_Rectangle_XAndYRadius.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShellBackButtonBehaviorShouldWork.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShellBackButtonBehaviorShouldWork.png
new file mode 100644
index 000000000000..93d748936279
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShellBackButtonBehaviorShouldWork.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleIcon_Add_Visual.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleIcon_Add_Visual.png
new file mode 100644
index 000000000000..e622d8c891e0
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleIcon_Add_Visual.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleIcon_AddingTwice_DoesNotDuplicate.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleIcon_AddingTwice_DoesNotDuplicate.png
new file mode 100644
index 000000000000..3b9cb2f097a0
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleIcon_AddingTwice_DoesNotDuplicate.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleIcon_And_TitleView_Persist_On_Push_Then_Clear.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleIcon_And_TitleView_Persist_On_Push_Then_Clear.png
new file mode 100644
index 000000000000..6376a9b52a46
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleIcon_And_TitleView_Persist_On_Push_Then_Clear.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleViewApplied.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleViewApplied.png
new file mode 100644
index 000000000000..8942fa36dcb9
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleViewApplied.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleViewCleared.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleViewCleared.png
new file mode 100644
index 000000000000..fbdf845e64d5
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TitleViewCleared.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_IsVisible.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_IsVisible.png
new file mode 100644
index 000000000000..5582337bf72f
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane1Priority.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane1Priority.png
new file mode 100644
index 000000000000..da1388e385a1
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane1Priority.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane1SizeIncrease.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane1SizeIncrease.png
new file mode 100644
index 000000000000..5718627a9d47
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane1SizeIncrease.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane1SizeIncrease_WithWideMode.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane1SizeIncrease_WithWideMode.png
new file mode 100644
index 000000000000..3e92381f0779
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane1SizeIncrease_WithWideMode.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane2Priority.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane2Priority.png
new file mode 100644
index 000000000000..f7700339c7e1
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane2Priority.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane2SizeIncrease.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane2SizeIncrease.png
new file mode 100644
index 000000000000..1ba1f4429e14
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane2SizeIncrease.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane2SizeIncrease_WithWideMode.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane2SizeIncrease_WithWideMode.png
new file mode 100644
index 000000000000..e3761c79cecb
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_Pane2SizeIncrease_WithWideMode.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_RTLFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_RTLFlowDirection.png
new file mode 100644
index 000000000000..20abc0e1a9ac
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_RTLFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_ShadowWithWideMode.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_ShadowWithWideMode.png
new file mode 100644
index 000000000000..a89990a3c4f4
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_ShadowWithWideMode.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_TallMode.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_TallMode.png
new file mode 100644
index 000000000000..1cc20a4eeb11
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_TallMode.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_WideMode.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_WideMode.png
new file mode 100644
index 000000000000..7e849a59900b
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_WideMode.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_ZIsShadowEnabled.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_ZIsShadowEnabled.png
new file mode 100644
index 000000000000..238a730a46e4
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/TwoPaneView_ZIsShadowEnabled.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ValidateEntryClearButtonVisibilityBehavior.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ValidateEntryClearButtonVisibilityBehavior.png
index 3ed29868cddc..95ab55257a45 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ValidateEntryClearButtonVisibilityBehavior.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ValidateEntryClearButtonVisibilityBehavior.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_AllProportional.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_AllProportional.png
new file mode 100644
index 000000000000..8f31c57a9028
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_AllProportional.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_FlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_FlowDirection.png
new file mode 100644
index 000000000000..ad400d3b5fb9
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_FlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_HeightProportional.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_HeightProportional.png
new file mode 100644
index 000000000000..9453cebeef6f
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_HeightProportional.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_LayoutBounds.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_LayoutBounds.png
new file mode 100644
index 000000000000..61bea170346e
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_LayoutBounds.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_PositionProportional.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_PositionProportional.png
new file mode 100644
index 000000000000..f71c796c040c
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_PositionProportional.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_SizeProportional.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_SizeProportional.png
new file mode 100644
index 000000000000..01a6064e725e
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_SizeProportional.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_SizeProportionalAndPositionProportional.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_SizeProportionalAndPositionProportional.png
new file mode 100644
index 000000000000..444817b2617a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_SizeProportionalAndPositionProportional.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_SizeProportionalWithMaximumValue.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_SizeProportionalWithMaximumValue.png
new file mode 100644
index 000000000000..6fbe149cf12b
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_SizeProportionalWithMaximumValue.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_Visibility.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_Visibility.png
new file mode 100644
index 000000000000..4ef5db96cbba
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_Visibility.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_WidthAndHeight.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_WidthAndHeight.png
new file mode 100644
index 000000000000..89499c7c2d42
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_WidthAndHeight.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_WidthProportional.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_WidthProportional.png
new file mode 100644
index 000000000000..57ee95c82436
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_WidthProportional.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_WidthProportionalAndHeightProportional.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_WidthProportionalAndHeightProportional.png
new file mode 100644
index 000000000000..72f776a8c7db
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_WidthProportionalAndHeightProportional.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_XProportional.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_XProportional.png
new file mode 100644
index 000000000000..c27624cce31d
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_XProportional.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_XProportionalAndYProportional.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_XProportionalAndYProportional.png
new file mode 100644
index 000000000000..68b1f27b4cc0
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_XProportionalAndYProportional.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_YProportional.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_YProportional.png
new file mode 100644
index 000000000000..f04ad0f97570
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyAbsoluteLayout_YProportional.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyBackButtonTitleUpdates.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyBackButtonTitleUpdates.png
new file mode 100644
index 000000000000..7b1970350a00
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyBackButtonTitleUpdates.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyClearVisiblityButtonWhenTextColorChanged.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyClearVisiblityButtonWhenTextColorChanged.png
index f4c1863b853f..3399eb244c1e 100644
Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyClearVisiblityButtonWhenTextColorChanged.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyClearVisiblityButtonWhenTextColorChanged.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCollectionViewContentWithButtonSwipeItem.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCollectionViewContentWithButtonSwipeItem.png
new file mode 100644
index 000000000000..f80cbf9742bd
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCollectionViewContentWithButtonSwipeItem.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCollectionViewContentWithIconImageSwipeItem.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCollectionViewContentWithIconImageSwipeItem.png
new file mode 100644
index 000000000000..e2496441beb5
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCollectionViewContentWithIconImageSwipeItem.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCollectionViewContentWithLabelSwipeItem.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCollectionViewContentWithLabelSwipeItem.png
new file mode 100644
index 000000000000..6036795b5d34
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCollectionViewContentWithLabelSwipeItem.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyDataTemplateParentIsNotNull.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyDataTemplateParentIsNotNull.png
new file mode 100644
index 000000000000..788c38b197a5
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyDataTemplateParentIsNotNull.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_BackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_BackgroundColor.png
new file mode 100644
index 000000000000..11c40ffbba17
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_BackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_DetailPageIconImageSource.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_DetailPageIconImageSource.png
new file mode 100644
index 000000000000..57cfff5c0109
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_DetailPageIconImageSource.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_DetailPageIconImageSource_FlyoutLayoutBehavior.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_DetailPageIconImageSource_FlyoutLayoutBehavior.png
new file mode 100644
index 000000000000..7c8860473383
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_DetailPageIconImageSource_FlyoutLayoutBehavior.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_FlyoutLayoutBehaviorPopover.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_FlyoutLayoutBehaviorPopover.png
new file mode 100644
index 000000000000..ca3ebd16206d
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_FlyoutLayoutBehaviorPopover.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_IsEnabled.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_IsEnabled.png
new file mode 100644
index 000000000000..9cf09660298d
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_IsEnabled.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_IsVisible.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_IsVisible.png
new file mode 100644
index 000000000000..20736061760a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_Title.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_Title.png
new file mode 100644
index 000000000000..6df4eb4e30a0
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyFlyoutPage_Title.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColor.png
new file mode 100644
index 000000000000..e87aa65935a0
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColorWhenItemsAdded.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColorWhenItemsAdded.png
new file mode 100644
index 000000000000..f886224c23fc
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColorWhenItemsAdded.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColorWithFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColorWithFlowDirection.png
new file mode 100644
index 000000000000..dae98004484a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColorWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColorWithIndicatorSize.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColorWithIndicatorSize.png
new file mode 100644
index 000000000000..5551e58234cf
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorColorWithIndicatorSize.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorHideSingleIsFalse.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorHideSingleIsFalse.png
new file mode 100644
index 000000000000..e6244cfea2af
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorHideSingleIsFalse.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorHideSingleIsFalseWithSelectedIndicatorColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorHideSingleIsFalseWithSelectedIndicatorColor.png
new file mode 100644
index 000000000000..b78af4aa26db
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorHideSingleIsFalseWithSelectedIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorHideSingleWithIndicatorSize.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorHideSingleWithIndicatorSize.png
new file mode 100644
index 000000000000..a2896a69e93c
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorHideSingleWithIndicatorSize.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorSizeWithFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorSizeWithFlowDirection.png
new file mode 100644
index 000000000000..7cca2225ee79
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorSizeWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorSizeWithMaximumVisible.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorSizeWithMaximumVisible.png
new file mode 100644
index 000000000000..a667e093b91f
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorSizeWithMaximumVisible.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_FlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_FlowDirection.png
new file mode 100644
index 000000000000..67f0f9d42801
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_FlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_HideSingle.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_HideSingle.png
new file mode 100644
index 000000000000..baf4a6a6f787
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_HideSingle.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_IsVisible.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_IsVisible.png
new file mode 100644
index 000000000000..b8e8b2e3fe4d
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_IsVisible.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_MaximumVisible.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_MaximumVisible.png
new file mode 100644
index 000000000000..3eebde4f04f5
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_MaximumVisible.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_Shadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_Shadow.png
new file mode 100644
index 000000000000..536d102ae636
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyIndicatorView_Shadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySearchBarFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySearchBarFlowDirection.png
new file mode 100644
index 000000000000..219e81d16253
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySearchBarFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColor.png
new file mode 100644
index 000000000000..e14fee440b56
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColorWithFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColorWithFlowDirection.png
new file mode 100644
index 000000000000..972d73c934bd
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColorWithFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColorWithIndicatorColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColorWithIndicatorColor.png
new file mode 100644
index 000000000000..0c8243175a28
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColorWithIndicatorColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColorWithIndicatorSize.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColorWithIndicatorSize.png
new file mode 100644
index 000000000000..7f1eac81679f
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySelectedIndicatorColorWithIndicatorSize.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedAuto.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedAuto.png
new file mode 100644
index 000000000000..fba9d6941381
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedAuto.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedCloseSwipeViewButton.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedCloseSwipeViewButton.png
new file mode 100644
index 000000000000..7d5cf2c221b9
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeModeExecuteWithSwipeBehaviorOnInvokedCloseSwipeViewButton.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithButtonSwipeItemsBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithButtonSwipeItemsBackgroundColor.png
new file mode 100644
index 000000000000..ecb3e9bb97b1
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithButtonSwipeItemsBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentAndBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentAndBackgroundColor.png
new file mode 100644
index 000000000000..d4ca0b9aae37
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentAndBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentAndFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentAndFlowDirection.png
new file mode 100644
index 000000000000..5576647e858b
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentAndFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentAndThreshold.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentAndThreshold.png
new file mode 100644
index 000000000000..ce0ab9257f5a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentAndThreshold.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentChanged.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentChanged.png
new file mode 100644
index 000000000000..db76015ead95
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithCollectionViewContentChanged.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithIconImageSwipeItemsBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithIconImageSwipeItemsBackgroundColor.png
new file mode 100644
index 000000000000..7c82520dca3a
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithIconImageSwipeItemsBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndBackgroundColor.png
new file mode 100644
index 000000000000..14300513eb63
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndFlowDirection.png
new file mode 100644
index 000000000000..503d8ddc4908
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndShadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndShadow.png
new file mode 100644
index 000000000000..246859981a6e
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndShadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndThreshold.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndThreshold.png
new file mode 100644
index 000000000000..2d68618d3796
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentAndThreshold.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentChanged.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentChanged.png
new file mode 100644
index 000000000000..616966ee980d
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithImageContentChanged.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndBackgroundColor.png
new file mode 100644
index 000000000000..9b9de94456fb
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndFlowDirection.png
new file mode 100644
index 000000000000..5bade603121c
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndShadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndShadow.png
new file mode 100644
index 000000000000..59cb4a430998
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndShadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndThreshold.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndThreshold.png
new file mode 100644
index 000000000000..e8ce0b679d62
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelContentAndThreshold.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelSwipeItemsBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelSwipeItemsBackgroundColor.png
new file mode 100644
index 000000000000..9507c2941f5e
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifySwipeViewWithLabelSwipeItemsBackgroundColor.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyWebViewWithShadow.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyWebViewWithShadow.png
new file mode 100644
index 000000000000..ef5a02d7ed2e
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyWebViewWithShadow.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection.png
new file mode 100644
index 000000000000..3de43aa8a5ef
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection_With_Height.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection_With_Height.png
new file mode 100644
index 000000000000..8b05df1a5fae
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection_With_HeightAndWidth.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection_With_HeightAndWidth.png
new file mode 100644
index 000000000000..e73e87ae7998
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection_With_Width.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection_With_Width.png
new file mode 100644
index 000000000000..9ff7d82b7c0e
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_RTLFlowDirection_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_WithLandscape.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_WithLandscape.png
new file mode 100644
index 000000000000..5f30b271431b
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_WithLandscape.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_WithLandspace.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_WithLandspace.png
new file mode 100644
index 000000000000..5dccc02e5341
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_WithLandspace.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_Height.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_Height.png
new file mode 100644
index 000000000000..a82aa6fcce7b
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_Height.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_HeightAndWidth.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_HeightAndWidth.png
new file mode 100644
index 000000000000..eb29eb4ea558
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_HeightAndWidth.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_RTL.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_RTL.png
new file mode 100644
index 000000000000..1315a16a38a5
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_RTL.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_Width.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_Width.png
new file mode 100644
index 000000000000..4f04ee5d97f3
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerticalStackLayout_Spacing_With_Width.png differ
diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/WebViewShouldNotMirrored.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/WebViewShouldNotMirrored.png
new file mode 100644
index 000000000000..2601c2ffb60b
Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/WebViewShouldNotMirrored.png differ
diff --git a/src/Core/AndroidNative/build/reports/problems/problems-report.html b/src/Core/AndroidNative/build/reports/problems/problems-report.html
new file mode 100644
index 000000000000..28c86c49448d
--- /dev/null
+++ b/src/Core/AndroidNative/build/reports/problems/problems-report.html
@@ -0,0 +1,663 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Gradle Configuration Cache
+
+
+
+
+
+
+ Loading...
+
+
+
+
+
+
+
diff --git a/src/Core/src/Core/Extensions/ITextInputExtensions.cs b/src/Core/src/Core/Extensions/ITextInputExtensions.cs
index f7fb3d190906..1a708f78aa86 100644
--- a/src/Core/src/Core/Extensions/ITextInputExtensions.cs
+++ b/src/Core/src/Core/Extensions/ITextInputExtensions.cs
@@ -42,7 +42,13 @@ public static bool TextWithinMaxLength(this ITextInput textInput, string? text,
var newLength = currLength + addLength - remLength;
- return newLength <= textInput.MaxLength;
+ var shouldChange = newLength <= textInput.MaxLength;
+
+ // cut text when user is pasting a text longer that maxlength
+ if(!shouldChange && !string.IsNullOrWhiteSpace(replacementString) && replacementString!.Length >= textInput.MaxLength)
+ textInput.Text = replacementString!.Substring(0, textInput.MaxLength);
+
+ return shouldChange;
}
#endif
diff --git a/src/Core/src/Core/IPlatformApplication.cs b/src/Core/src/Core/IPlatformApplication.cs
index c3d1d785d688..08608854e28e 100644
--- a/src/Core/src/Core/IPlatformApplication.cs
+++ b/src/Core/src/Core/IPlatformApplication.cs
@@ -1,33 +1,99 @@
using System;
-namespace Microsoft.Maui
+namespace Microsoft.Maui;
+
+///
+/// Represents the platform-specific application instance that hosts a .NET MAUI application.
+///
+///
+/// This interface provides access to platform-specific services and the main application instance.
+/// Each platform (Android, iOS, Windows, etc.) provides its own implementation of this interface.
+/// Use the IPlatformApplication.Current property to access the current platform application instance.
+///
+public interface IPlatformApplication
{
- ///
- /// IPlatformApplication.
- /// Hosts the platform application.
- ///
- public interface IPlatformApplication
- {
#if !NETSTANDARD2_0
- ///
- /// Gets the current IPlatformApplication.
- /// This must be set in each implementation manually, as we can't
- /// have a true static be used in the implementation.
- ///
- public static IPlatformApplication? Current { get; set; }
+ ///
+ /// Gets or sets the current platform application instance.
+ ///
+ ///
+ /// The current instance, or if not set.
+ ///
+ ///
+ ///
+ /// This property provides access to the platform-specific application instance and its services.
+ /// It must be manually set by each platform implementation during application startup.
+ ///
+ ///
+ /// Common usage scenarios:
+ ///
+ ///
+ /// Accessing platform services: IPlatformApplication.Current?.Services
+ /// Getting the application instance: IPlatformApplication.Current?.Application
+ /// Platform-specific operations requiring the native application context
+ ///
+ ///
+ /// Always check for before using this property, especially during application startup
+ /// or in unit tests where the platform application may not be initialized.
+ ///
+ ///
+ ///
+ ///
+ /// // Accessing a service from the platform application
+ /// var platformApp = IPlatformApplication.Current;
+ /// if (platformApp != null)
+ /// {
+ /// var myService = platformApp.Services.GetService<IMyService>();
+ /// // Use the service...
+ /// }
+ ///
+ ///
+ public static IPlatformApplication? Current { get; set; }
#endif
- ///
- /// Gets the Service Provider.
- /// .
- ///
- public IServiceProvider Services { get; }
+ ///
+ /// Gets the dependency injection service provider for the platform application.
+ ///
+ ///
+ /// An instance containing platform-specific and application services.
+ ///
+ ///
+ /// Use this service provider to resolve services that have been registered with the platform's
+ /// dependency injection container. This includes both framework services and custom services
+ /// registered during application configuration.
+ ///
+ ///
+ ///
+ /// // Getting a service from the platform application
+ /// var logger = platformApp.Services.GetService<ILogger>();
+ /// var httpClient = platformApp.Services.GetRequiredService<HttpClient>();
+ ///
+ ///
+ public IServiceProvider Services { get; }
- ///
- /// Gets the Application.
- /// .
- ///
- public IApplication Application { get; }
- }
+ ///
+ /// Gets the .NET MAUI application instance.
+ ///
+ ///
+ /// An instance representing the current MAUI application.
+ ///
+ ///
+ /// This property provides access to the main MAUI application instance, which contains
+ /// application-level configuration, the main page, and application lifecycle methods.
+ /// Use this to access application-wide properties and methods.
+ ///
+ ///
+ ///
+ /// // Accessing the main page from the application
+ /// var mainPage = platformApp.Application.MainPage;
+ ///
+ /// // Triggering application lifecycle events
+ /// if (platformApp.Application is Application app)
+ /// {
+ /// app.OnStart();
+ /// }
+ ///
+ ///
+ public IApplication Application { get; }
}
diff --git a/src/Core/src/Fonts/FontManager.Windows.cs b/src/Core/src/Fonts/FontManager.Windows.cs
index 7740dce42339..a6bb095a788a 100644
--- a/src/Core/src/Fonts/FontManager.Windows.cs
+++ b/src/Core/src/Fonts/FontManager.Windows.cs
@@ -162,6 +162,12 @@ IEnumerable GetAllFontPossibilities(string fontFamily)
if (fontFile == null)
return null;
+ // Under Native AOT, observed crashes when invoking Win2D CanvasFontSet -> GetPropertyValues
+ // This lookup is an optimization; returning null should just cause callers to use the
+ // PostScript name already embedded in the file path.
+#if USE_NATIVE_AOT
+ return null;
+#else
try
{
var fontUri = new Uri(fontFile, UriKind.RelativeOrAbsolute);
@@ -196,6 +202,7 @@ IEnumerable GetAllFontPossibilities(string fontFamily)
return null;
}
+#endif
}
}
}
\ No newline at end of file
diff --git a/src/Core/src/Graphics/MauiDrawable.Android.cs b/src/Core/src/Graphics/MauiDrawable.Android.cs
index 8243069637fa..ff86649d457c 100644
--- a/src/Core/src/Graphics/MauiDrawable.Android.cs
+++ b/src/Core/src/Graphics/MauiDrawable.Android.cs
@@ -660,7 +660,7 @@ static GradientData GetGradientPaintData(GradientPaint gradientPaint)
var data = new GradientData(orderStops.Length);
int count = 0;
- foreach (var orderStop in orderStops)
+ foreach (var orderStop in orderStops.OrderBy(s => s.Offset))
{
data.Colors[count] = orderStop.Color.ToPlatform().ToArgb();
data.Offsets[count] = orderStop.Offset;
diff --git a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs
index 843d962dc3ea..aaf1a2ec7eda 100644
--- a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs
+++ b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs
@@ -14,28 +14,10 @@ public partial class EditorHandler : ViewHandler
protected override MauiTextView CreatePlatformView()
{
var platformEditor = new MauiTextView();
-
-#if !MACCATALYST
- var accessoryView = new MauiDoneAccessoryView();
- accessoryView.SetDataContext(this);
- accessoryView.SetDoneClicked(OnDoneClicked);
- platformEditor.InputAccessoryView = accessoryView;
-#endif
-
+ platformEditor.AddMauiDoneAccessoryView(this);
return platformEditor;
}
-#if !MACCATALYST
- static void OnDoneClicked(object sender)
- {
- if (sender is IEditorHandler handler)
- {
- handler.PlatformView.ResignFirstResponder();
- handler.VirtualView.Completed();
- }
- }
-#endif
-
public override void SetVirtualView(IView view)
{
base.SetVirtualView(view);
diff --git a/src/Core/src/Handlers/Entry/EntryHandler.Android.cs b/src/Core/src/Handlers/Entry/EntryHandler.Android.cs
index 62b62d270df0..89cf47582001 100644
--- a/src/Core/src/Handlers/Entry/EntryHandler.Android.cs
+++ b/src/Core/src/Handlers/Entry/EntryHandler.Android.cs
@@ -73,8 +73,15 @@ public static void MapBackground(IEntryHandler handler, IEntry entry) =>
public static void MapText(IEntryHandler handler, IEntry entry) =>
handler.PlatformView?.UpdateText(entry);
- public static void MapTextColor(IEntryHandler handler, IEntry entry) =>
+ public static void MapTextColor(IEntryHandler handler, IEntry entry)
+ {
handler.PlatformView?.UpdateTextColor(entry);
+ if (handler is EntryHandler platformHandler && platformHandler._clearButtonVisible)
+ {
+ // Update the clear button color to match the text color
+ handler.PlatformView?.UpdateClearButtonColor(entry.TextColor, platformHandler.GetClearButtonDrawable());
+ }
+ }
public static void MapIsPassword(IEntryHandler handler, IEntry entry)
{
@@ -246,10 +253,7 @@ internal void ShowClearButton()
var drawable = GetClearButtonDrawable();
- if (VirtualView?.TextColor is not null)
- drawable?.SetColorFilter(VirtualView.TextColor.ToPlatform(), FilterMode.SrcIn);
- else
- drawable?.ClearColorFilter();
+ PlatformView.UpdateClearButtonColor(VirtualView.TextColor, drawable);
if (PlatformView.LayoutDirection == LayoutDirection.Rtl)
PlatformView.SetCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
diff --git a/src/Core/src/Handlers/Entry/EntryHandler.iOS.cs b/src/Core/src/Handlers/Entry/EntryHandler.iOS.cs
index 20c31183773a..e6e2030716c8 100644
--- a/src/Core/src/Handlers/Entry/EntryHandler.iOS.cs
+++ b/src/Core/src/Handlers/Entry/EntryHandler.iOS.cs
@@ -11,13 +11,18 @@ public partial class EntryHandler : ViewHandler
{
readonly MauiTextFieldProxy _proxy = new();
- protected override MauiTextField CreatePlatformView() =>
- new MauiTextField
+ protected override MauiTextField CreatePlatformView()
+ {
+ var platformEntry = new MauiTextField
{
BorderStyle = UITextBorderStyle.RoundedRect,
ClipsToBounds = true
};
+ platformEntry.AddMauiDoneAccessoryView(this);
+ return platformEntry;
+ }
+
public override void SetVirtualView(IView view)
{
base.SetVirtualView(view);
@@ -43,8 +48,14 @@ public static void MapText(IEntryHandler handler, IEntry entry)
MapFormatting(handler, entry);
}
- public static void MapTextColor(IEntryHandler handler, IEntry entry) =>
+ public static void MapTextColor(IEntryHandler handler, IEntry entry)
+ {
handler.PlatformView?.UpdateTextColor(entry);
+ if (entry.ClearButtonVisibility == ClearButtonVisibility.WhileEditing)
+ {
+ handler.PlatformView?.UpdateClearButtonColor(entry);
+ }
+ }
public static void MapIsPassword(IEntryHandler handler, IEntry entry) =>
handler.PlatformView?.UpdateIsPassword(entry);
diff --git a/src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Windows.cs b/src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Windows.cs
index 61e4e385d3d9..c2009378abbe 100644
--- a/src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Windows.cs
+++ b/src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Windows.cs
@@ -100,6 +100,12 @@ private void OnWebMessageReceived(WebView2 sender, CoreWebView2WebMessageReceive
MessageReceived(args.TryGetWebMessageAsString());
}
+ internal static void MapFlowDirection(IHybridWebViewHandler handler, IHybridWebView hybridWebView)
+ {
+ // Explicitly do nothing here to override the base ViewHandler.MapFlowDirection behavior
+ // This prevents the WebView2.FlowDirection from being set, avoiding content mirroring
+ }
+
private async void OnWebResourceRequested(CoreWebView2 sender, CoreWebView2WebResourceRequestedEventArgs eventArgs)
{
var url = eventArgs.Request.Uri;
diff --git a/src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.cs b/src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.cs
index ff8e6d2187c3..d68054ea92f5 100644
--- a/src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.cs
+++ b/src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.cs
@@ -71,6 +71,9 @@ public partial class HybridWebViewHandler : IHybridWebViewHandler
public static IPropertyMapper Mapper = new PropertyMapper(ViewHandler.ViewMapper)
{
+#if WINDOWS
+ [nameof(IView.FlowDirection)] = MapFlowDirection,
+#endif
};
public static CommandMapper CommandMapper = new(ViewCommandMapper)
diff --git a/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Windows.cs b/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Windows.cs
index b74c67d250d0..9d04e95741b3 100644
--- a/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Windows.cs
+++ b/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Windows.cs
@@ -166,8 +166,10 @@ void OnRefresh(object sender, RefreshRequestedEventArgs args)
// Store the deferral to complete the refresh later
_refreshCompletionDeferral = args.GetDeferral();
- // Update the virtual view to indicate that a refresh is in progress
- VirtualView.IsRefreshing = true;
+ if (VirtualView != null && !VirtualView.IsRefreshing)
+ {
+ VirtualView.IsRefreshing = true;
+ }
}
void CompleteRefresh()
diff --git a/src/Core/src/Handlers/SearchBar/SearchBarHandler.Android.cs b/src/Core/src/Handlers/SearchBar/SearchBarHandler.Android.cs
index ace12cca000f..44658b3527b3 100644
--- a/src/Core/src/Handlers/SearchBar/SearchBarHandler.Android.cs
+++ b/src/Core/src/Handlers/SearchBar/SearchBarHandler.Android.cs
@@ -4,6 +4,7 @@
using Android.Widget;
using AndroidX.AppCompat.Widget;
using static AndroidX.AppCompat.Widget.SearchView;
+using AView = Android.Views.View;
using SearchView = AndroidX.AppCompat.Widget.SearchView;
namespace Microsoft.Maui.Handlers
@@ -68,6 +69,25 @@ public static void MapPlaceholderColor(ISearchBarHandler handler, ISearchBar sea
handler.PlatformView?.UpdatePlaceholderColor(searchBar, DefaultPlaceholderTextColors, handler.QueryEditor);
}
+ internal static void MapFlowDirection(ISearchBarHandler handler, ISearchBar searchBar)
+ {
+ if (searchBar.FlowDirection == FlowDirection.MatchParent && searchBar.Parent != null && searchBar.Parent is IView parentView)
+ {
+ // When FlowDirection is MatchParent, respect the parent's FlowDirection
+ if (handler.PlatformView is AView platformView)
+ Microsoft.Maui.Platform.ViewExtensions.UpdateFlowDirection(platformView, parentView);
+
+ if (handler.QueryEditor is TextView textView)
+ Microsoft.Maui.Platform.TextViewExtensions.UpdateFlowDirection(textView, parentView);
+ }
+ else
+ {
+ // Otherwise, use the SearchBar's own FlowDirection
+ handler.PlatformView?.UpdateFlowDirection(searchBar);
+ handler.QueryEditor?.UpdateFlowDirection(searchBar);
+ }
+ }
+
public static void MapFont(ISearchBarHandler handler, ISearchBar searchBar)
{
var fontManager = handler.GetRequiredService();
@@ -92,6 +112,7 @@ public static void MapCharacterSpacing(ISearchBarHandler handler, ISearchBar sea
public static void MapTextColor(ISearchBarHandler handler, ISearchBar searchBar)
{
handler.QueryEditor?.UpdateTextColor(searchBar);
+ handler.PlatformView?.UpdateTextColor(searchBar);
}
public static void MapIsTextPredictionEnabled(ISearchBarHandler handler, ISearchBar searchBar)
diff --git a/src/Core/src/Handlers/SearchBar/SearchBarHandler.cs b/src/Core/src/Handlers/SearchBar/SearchBarHandler.cs
index 38b6db79d41b..2fc4011bb310 100644
--- a/src/Core/src/Handlers/SearchBar/SearchBarHandler.cs
+++ b/src/Core/src/Handlers/SearchBar/SearchBarHandler.cs
@@ -36,7 +36,10 @@ public partial class SearchBarHandler : ISearchBarHandler
[nameof(ISearchBar.CancelButtonColor)] = MapCancelButtonColor,
[nameof(ISearchBar.SearchIconColor)] = MapSearchIconColor,
[nameof(ISearchBar.Keyboard)] = MapKeyboard,
- [nameof(ISearchBar.ReturnType)] = MapReturnType
+ [nameof(ISearchBar.ReturnType)] = MapReturnType,
+#if ANDROID
+ [nameof(ISearchBar.FlowDirection)] = MapFlowDirection,
+#endif
};
public static CommandMapper CommandMapper = new(ViewCommandMapper)
diff --git a/src/Core/src/Handlers/View/ViewHandler.Windows.cs b/src/Core/src/Handlers/View/ViewHandler.Windows.cs
index 43d57d93a98f..d0c0db2885a4 100644
--- a/src/Core/src/Handlers/View/ViewHandler.Windows.cs
+++ b/src/Core/src/Handlers/View/ViewHandler.Windows.cs
@@ -6,185 +6,232 @@
using Microsoft.UI.Xaml.Input;
using PlatformView = Microsoft.UI.Xaml.FrameworkElement;
-namespace Microsoft.Maui.Handlers
+namespace Microsoft.Maui.Handlers;
+
+public partial class ViewHandler
{
- public partial class ViewHandler
+ readonly static ConditionalWeakTable FocusManagerMapping = new();
+
+ static ViewHandler()
{
- readonly static ConditionalWeakTable FocusManagerMapping = new();
+ FocusManager.GotFocus += FocusManager_GotFocus;
+ FocusManager.LostFocus += FocusManager_LostFocus;
+ }
- static ViewHandler()
+ partial void ConnectingHandler(PlatformView? platformView)
+ {
+ if (platformView is not null)
{
- FocusManager.GotFocus += FocusManager_GotFocus;
- FocusManager.LostFocus += FocusManager_LostFocus;
+ FocusManagerMapping.Add(platformView, this);
}
+ }
- partial void ConnectingHandler(PlatformView? platformView)
- {
- if (platformView is not null)
- {
- FocusManagerMapping.Add(platformView, this);
- }
- }
+ partial void DisconnectingHandler(PlatformView platformView)
+ {
+ FocusManagerMapping.Remove(platformView);
+ UpdateIsFocused(false);
+ }
- partial void DisconnectingHandler(PlatformView platformView)
- {
- FocusManagerMapping.Remove(platformView);
- UpdateIsFocused(false);
- }
+ static partial void MappingFrame(IViewHandler handler, IView view)
+ {
+ // Both Clip and Shadow depend on the Control size.
+ handler.ToPlatform().UpdateClip(view);
+ handler.ToPlatform().UpdateShadow(view);
+ }
- static partial void MappingFrame(IViewHandler handler, IView view)
- {
- // Both Clip and Shadow depend on the Control size.
- handler.ToPlatform().UpdateClip(view);
- handler.ToPlatform().UpdateShadow(view);
- }
+ public static void MapTranslationX(IViewHandler handler, IView view)
+ {
+ // When a handler is connected, all properties are initialized using this method. So we can skip other properties.
+ handler.ToPlatform().UpdateTransformation(view);
+ }
- public static void MapTranslationX(IViewHandler handler, IView view)
+ public static void MapTranslationY(IViewHandler handler, IView view)
+ {
+ if (view.IsConnectingHandler())
{
- handler.ToPlatform().UpdateTransformation(view);
+ return;
}
- public static void MapTranslationY(IViewHandler handler, IView view)
- {
- handler.ToPlatform().UpdateTransformation(view);
- }
+ handler.ToPlatform().UpdateTransformation(view);
+ }
- public static void MapScale(IViewHandler handler, IView view)
+ public static void MapScale(IViewHandler handler, IView view)
+ {
+ if (view.IsConnectingHandler())
{
- handler.ToPlatform().UpdateTransformation(view);
+ return;
}
- public static void MapScaleX(IViewHandler handler, IView view)
+ handler.ToPlatform().UpdateTransformation(view);
+ }
+
+ public static void MapScaleX(IViewHandler handler, IView view)
+ {
+ if (view.IsConnectingHandler())
{
- handler.ToPlatform().UpdateTransformation(view);
+ return;
}
- public static void MapScaleY(IViewHandler handler, IView view)
+ handler.ToPlatform().UpdateTransformation(view);
+ }
+
+ public static void MapScaleY(IViewHandler handler, IView view)
+ {
+ if (view.IsConnectingHandler())
{
- handler.ToPlatform().UpdateTransformation(view);
+ return;
}
- public static void MapRotation(IViewHandler handler, IView view)
+ handler.ToPlatform().UpdateTransformation(view);
+ }
+
+ public static void MapRotation(IViewHandler handler, IView view)
+ {
+ if (view.IsConnectingHandler())
{
- handler.ToPlatform().UpdateTransformation(view);
+ return;
}
- public static void MapRotationX(IViewHandler handler, IView view)
+ handler.ToPlatform().UpdateTransformation(view);
+ }
+
+ public static void MapRotationX(IViewHandler handler, IView view)
+ {
+ if (view.IsConnectingHandler())
{
- handler.ToPlatform().UpdateTransformation(view);
+ return;
}
- public static void MapRotationY(IViewHandler handler, IView view)
+ handler.ToPlatform().UpdateTransformation(view);
+ }
+
+ public static void MapRotationY(IViewHandler handler, IView view)
+ {
+ if (view.IsConnectingHandler())
{
- handler.ToPlatform().UpdateTransformation(view);
+ return;
}
- public static void MapAnchorX(IViewHandler handler, IView view)
+ handler.ToPlatform().UpdateTransformation(view);
+ }
+
+ public static void MapAnchorX(IViewHandler handler, IView view)
+ {
+ if (view.IsConnectingHandler())
{
- handler.ToPlatform().UpdateTransformation(view);
+ return;
}
- public static void MapAnchorY(IViewHandler handler, IView view)
+ handler.ToPlatform().UpdateTransformation(view);
+ }
+
+ public static void MapAnchorY(IViewHandler handler, IView view)
+ {
+ if (view.IsConnectingHandler())
{
- handler.ToPlatform().UpdateTransformation(view);
+ return;
}
- public static void MapToolbar(IViewHandler handler, IView view)
+ handler.ToPlatform().UpdateTransformation(view);
+ }
+
+ public static void MapToolbar(IViewHandler handler, IView view)
+ {
+ if (view is IToolbarElement tb)
{
- if (view is IToolbarElement tb)
- {
- MapToolbar(handler, tb);
- }
+ MapToolbar(handler, tb);
}
+ }
- internal static void MapToolbar(IElementHandler handler, IToolbarElement toolbarElement)
- {
- _ = handler.MauiContext ?? throw new InvalidOperationException($"{nameof(handler.MauiContext)} null");
+ internal static void MapToolbar(IElementHandler handler, IToolbarElement toolbarElement)
+ {
+ _ = handler.MauiContext ?? throw new InvalidOperationException($"{nameof(handler.MauiContext)} null");
- if (toolbarElement.Toolbar != null)
- {
- var toolBar = toolbarElement.Toolbar.ToPlatform(handler.MauiContext);
- handler.MauiContext.GetNavigationRootManager().SetToolbar(toolBar);
- }
+ if (toolbarElement.Toolbar != null)
+ {
+ var toolBar = toolbarElement.Toolbar.ToPlatform(handler.MauiContext);
+ handler.MauiContext.GetNavigationRootManager().SetToolbar(toolBar);
}
+ }
- public static void MapContextFlyout(IViewHandler handler, IView view)
+ public static void MapContextFlyout(IViewHandler handler, IView view)
+ {
+ if (view is IContextFlyoutElement contextFlyoutContainer)
{
- if (view is IContextFlyoutElement contextFlyoutContainer)
+ if (handler.IsConnectingHandler() && contextFlyoutContainer.ContextFlyout is null)
{
- if (handler.IsConnectingHandler() && contextFlyoutContainer.ContextFlyout is null)
- return;
-
- MapContextFlyout(handler, contextFlyoutContainer);
+ return;
}
+
+ MapContextFlyout(handler, contextFlyoutContainer);
}
+ }
- internal static void MapContextFlyout(IElementHandler handler, IContextFlyoutElement contextFlyoutContainer)
- {
- _ = handler.MauiContext ?? throw new InvalidOperationException($"The handler's {nameof(handler.MauiContext)} cannot be null.");
+ internal static void MapContextFlyout(IElementHandler handler, IContextFlyoutElement contextFlyoutContainer)
+ {
+ _ = handler.MauiContext ?? throw new InvalidOperationException($"The handler's {nameof(handler.MauiContext)} cannot be null.");
- if (handler.PlatformView is Microsoft.UI.Xaml.UIElement uiElement)
+ if (handler.PlatformView is Microsoft.UI.Xaml.UIElement uiElement)
+ {
+ if (contextFlyoutContainer.ContextFlyout != null)
{
- if (contextFlyoutContainer.ContextFlyout != null)
- {
- var contextFlyoutHandler = contextFlyoutContainer.ContextFlyout.ToHandler(handler.MauiContext);
- var contextFlyoutPlatformView = contextFlyoutHandler.PlatformView;
+ var contextFlyoutHandler = contextFlyoutContainer.ContextFlyout.ToHandler(handler.MauiContext);
+ var contextFlyoutPlatformView = contextFlyoutHandler.PlatformView;
- if (contextFlyoutPlatformView is FlyoutBase flyoutBase)
- {
- uiElement.ContextFlyout = flyoutBase;
- }
- }
- else
+ if (contextFlyoutPlatformView is FlyoutBase flyoutBase)
{
- uiElement.ClearValue(UIElement.ContextFlyoutProperty);
+ uiElement.ContextFlyout = flyoutBase;
}
}
+ else
+ {
+ uiElement.ClearValue(UIElement.ContextFlyoutProperty);
+ }
}
+ }
- static void FocusManager_GotFocus(object? sender, FocusManagerGotFocusEventArgs e)
+ internal virtual bool PreventGestureBubbling
+ => this switch
+ {
+ ButtonHandler => true,
+ DatePickerHandler => true,
+ StepperHandler => true,
+ SliderHandler => true,
+ SwitchHandler => true,
+ TimePickerHandler => true,
+ ImageButtonHandler => true,
+ RadioButtonHandler => true,
+ _ => false,
+ };
+
+ static void FocusManager_GotFocus(object? sender, FocusManagerGotFocusEventArgs e)
+ {
+ if (e.NewFocusedElement is PlatformView platformView && FocusManagerMapping.TryGetValue(platformView, out ViewHandler? handler))
{
- if (e.NewFocusedElement is PlatformView platformView && FocusManagerMapping.TryGetValue(platformView, out ViewHandler? handler))
- {
- handler.UpdateIsFocused(true);
- }
+ handler.UpdateIsFocused(true);
}
+ }
- static void FocusManager_LostFocus(object? sender, FocusManagerLostFocusEventArgs e)
+ static void FocusManager_LostFocus(object? sender, FocusManagerLostFocusEventArgs e)
+ {
+ if (e.OldFocusedElement is PlatformView platformView && FocusManagerMapping.TryGetValue(platformView, out ViewHandler? handler))
{
- if (e.OldFocusedElement is PlatformView platformView && FocusManagerMapping.TryGetValue(platformView, out ViewHandler? handler))
- {
- handler.UpdateIsFocused(false);
- }
+ handler.UpdateIsFocused(false);
}
+ }
- private protected void UpdateIsFocused(bool isFocused)
+ private protected void UpdateIsFocused(bool isFocused)
+ {
+ if (VirtualView is not { } virtualView)
{
- if (VirtualView is not { } virtualView)
- {
- return;
- }
+ return;
+ }
- bool updateIsFocused = (isFocused && !virtualView.IsFocused) || (!isFocused && virtualView.IsFocused);
+ bool updateIsFocused = (isFocused && !virtualView.IsFocused) || (!isFocused && virtualView.IsFocused);
- if (updateIsFocused)
- {
- virtualView.IsFocused = isFocused;
- }
+ if (updateIsFocused)
+ {
+ virtualView.IsFocused = isFocused;
}
-
- internal virtual bool PreventGestureBubbling
- => this switch
- {
- ButtonHandler => true,
- DatePickerHandler => true,
- StepperHandler => true,
- SliderHandler => true,
- SwitchHandler => true,
- TimePickerHandler => true,
- ImageButtonHandler => true,
- RadioButtonHandler => true,
- _ => false,
- };
}
}
diff --git a/src/Core/src/Handlers/WebView/WebViewHandler.Windows.cs b/src/Core/src/Handlers/WebView/WebViewHandler.Windows.cs
index 76443edbfe28..2316ab18417f 100644
--- a/src/Core/src/Handlers/WebView/WebViewHandler.Windows.cs
+++ b/src/Core/src/Handlers/WebView/WebViewHandler.Windows.cs
@@ -320,6 +320,12 @@ public static void MapEvaluateJavaScriptAsync(IWebViewHandler handler, IWebView
}
}
+ internal static void MapFlowDirection(IWebViewHandler handler, IWebView webView)
+ {
+ // Explicitly do nothing here to override the base ViewHandler.MapFlowDirection behavior
+ // This prevents the WebView2.FlowDirection from being set, avoiding content mirroring
+ }
+
class WebView2Proxy
{
WeakReference? _window;
diff --git a/src/Core/src/Handlers/WebView/WebViewHandler.cs b/src/Core/src/Handlers/WebView/WebViewHandler.cs
index acd2be502103..b4dbad5fad5c 100644
--- a/src/Core/src/Handlers/WebView/WebViewHandler.cs
+++ b/src/Core/src/Handlers/WebView/WebViewHandler.cs
@@ -24,6 +24,9 @@ public partial class WebViewHandler : IWebViewHandler
{
[nameof(IWebView.Source)] = MapSource,
[nameof(IWebView.UserAgent)] = MapUserAgent,
+#if WINDOWS
+ [nameof(IView.FlowDirection)] = MapFlowDirection,
+#endif
#if __ANDROID__
[nameof(WebViewClient)] = MapWebViewClient,
[nameof(WebChromeClient)] = MapWebChromeClient,
diff --git a/src/Core/src/Platform/Android/EditTextExtensions.cs b/src/Core/src/Platform/Android/EditTextExtensions.cs
index e9f319b31a3d..5be958658882 100644
--- a/src/Core/src/Platform/Android/EditTextExtensions.cs
+++ b/src/Core/src/Platform/Android/EditTextExtensions.cs
@@ -223,6 +223,18 @@ public static void UpdateClearButtonVisibility(this EditText editText, IEntry en
}
}
+ internal static void UpdateClearButtonColor(this EditText editText, Graphics.Color textColor, Drawable? clearButtonDrawable)
+ {
+ if (textColor is not null)
+ {
+ clearButtonDrawable?.SetColorFilter(textColor.ToPlatform(), FilterMode.SrcIn);
+ }
+ else
+ {
+ clearButtonDrawable?.ClearColorFilter();
+ }
+ }
+
public static void UpdateReturnType(this EditText editText, IEntry entry)
{
editText.ImeOptions = entry.ReturnType.ToPlatform();
diff --git a/src/Core/src/Platform/Android/SearchViewExtensions.cs b/src/Core/src/Platform/Android/SearchViewExtensions.cs
index ed9f2863289c..1a6e78424256 100644
--- a/src/Core/src/Platform/Android/SearchViewExtensions.cs
+++ b/src/Core/src/Platform/Android/SearchViewExtensions.cs
@@ -1,9 +1,15 @@
-using Android.Content;
+using System;
+using Android.Content;
using Android.Content.Res;
+using Android.Graphics;
+using Android.Graphics.Drawables;
using Android.Text;
+using Android.Util;
using Android.Views.InputMethods;
using Android.Widget;
+using static Android.Content.Res.Resources;
using SearchView = AndroidX.AppCompat.Widget.SearchView;
+using AAttribute = Android.Resource.Attribute;
namespace Microsoft.Maui.Platform
{
@@ -23,22 +29,36 @@ public static void UpdatePlaceholderColor(this SearchView searchView, ISearchBar
{
editText ??= searchView.GetFirstChildOfType();
- if (editText == null)
+ if (editText is null)
return;
- var placeholderTextColor = searchBar.PlaceholderColor;
-
- if (placeholderTextColor == null)
- {
- editText.SetHintTextColor(defaultPlaceholderColor);
- }
- else
+ if (searchBar?.PlaceholderColor is Graphics.Color placeholderTextColor)
{
if (PlatformInterop.CreateEditTextColorStateList(editText.HintTextColors, placeholderTextColor.ToPlatform()) is ColorStateList c)
{
editText.SetHintTextColor(c);
}
}
+ else if (TryGetDefaultStateColor(searchView, AAttribute.TextColorHint, out var color))
+ {
+ editText.SetHintTextColor(color);
+
+ var searchMagIconImage = searchView.FindViewById(Resource.Id.search_mag_icon);
+ searchMagIconImage?.Drawable?.SetTint(color);
+ }
+ }
+
+ internal static void UpdateTextColor(this SearchView searchView, ITextStyle entry)
+ {
+ if (TryGetDefaultStateColor(searchView, AAttribute.TextColorPrimary, out var color) &&
+ searchView.GetFirstChildOfType() is EditText editText)
+ {
+ if (entry.TextColor is null)
+ editText.SetTextColor(color);
+
+ var searchMagIconImage = searchView.FindViewById(Resource.Id.search_mag_icon);
+ searchMagIconImage?.Drawable?.SetTint(color);
+ }
}
public static void UpdateFont(this SearchView searchView, ISearchBar searchBar, IFontManager fontManager, EditText? editText = null)
@@ -110,12 +130,12 @@ public static void UpdateCancelButtonColor(this SearchView searchView, ISearchBa
{
var image = searchView.FindViewById(searchCloseButtonIdentifier);
- if (image != null && image.Drawable != null)
+ if (image is not null && image.Drawable is Drawable drawable)
{
- if (searchBar.CancelButtonColor != null)
- image.Drawable.SetColorFilter(searchBar.CancelButtonColor, FilterMode.SrcIn);
- else
- image.Drawable.ClearColorFilter();
+ if (searchBar.CancelButtonColor is not null)
+ drawable.SetColorFilter(searchBar.CancelButtonColor, FilterMode.SrcIn);
+ else if (TryGetDefaultStateColor(searchView, AAttribute.TextColorPrimary, out var color))
+ drawable.SetColorFilter(color, FilterMode.SrcIn);
}
}
}
@@ -200,5 +220,28 @@ internal static void SetInputType(this SearchView searchView, ISearchBar searchB
editText.SetInputType(searchBar);
}
+
+ static bool TryGetDefaultStateColor(SearchView searchView, int attribute, out Color color)
+ {
+ color = default;
+
+ if (!OperatingSystem.IsAndroidVersionAtLeast(23))
+ return false;
+
+ if (searchView.Context?.Theme is not Theme theme)
+ return false;
+
+ int[] s_disabledState = [-AAttribute.StateEnabled];
+ int[] s_enabledState = [AAttribute.StateEnabled];
+
+ using var ta = theme.ObtainStyledAttributes([attribute]);
+ var cs = ta.GetColorStateList(0);
+ if (cs is null)
+ return false;
+
+ var state = searchView.Enabled ? s_enabledState : s_disabledState;
+ color = new Color(cs.GetColorForState(state, Color.Black));
+ return true;
+ }
}
}
\ No newline at end of file
diff --git a/src/Core/src/Platform/Windows/MauiNavigationView.cs b/src/Core/src/Platform/Windows/MauiNavigationView.cs
index 73d9ee63a9cf..efbd6404639c 100644
--- a/src/Core/src/Platform/Windows/MauiNavigationView.cs
+++ b/src/Core/src/Platform/Windows/MauiNavigationView.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics.CodeAnalysis;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using WGridLength = Microsoft.UI.Xaml.GridLength;
@@ -64,6 +65,15 @@ void UpdateToPinnedDisplayMode()
}
}
+ [DynamicDependency(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields, typeof(ScrollViewer))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields, typeof(Grid))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields, typeof(StackPanel))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields, typeof(SplitView))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields, typeof(ItemsRepeater))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields, typeof(Button))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields, typeof(ColumnDefinition))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields, typeof(RowDefinition))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields, typeof(ContentControl))]
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
@@ -170,9 +180,6 @@ internal void UpdatePaneDisplayModeFromFlyoutBehavior(FlyoutBehavior flyoutBehav
{
case FlyoutBehavior.Flyout:
IsPaneToggleButtonVisible = true;
- // Workaround for
- // https://github.com/microsoft/microsoft-ui-xaml/issues/6493
- PaneDisplayMode = NavigationViewPaneDisplayMode.LeftCompact;
PaneDisplayMode = NavigationViewPaneDisplayMode.LeftMinimal;
break;
case FlyoutBehavior.Locked:
diff --git a/src/Core/src/Platform/Windows/NavigationViewItemViewModel.cs b/src/Core/src/Platform/Windows/NavigationViewItemViewModel.cs
index 1fa08a939541..aa0b0d9ba5c6 100644
--- a/src/Core/src/Platform/Windows/NavigationViewItemViewModel.cs
+++ b/src/Core/src/Platform/Windows/NavigationViewItemViewModel.cs
@@ -88,6 +88,7 @@ internal class NavigationViewItemViewModel : INotifyPropertyChanged
WBrush? _selectedTitleColor;
WBrush? _unselectedTitleColor;
WBrush? _unselectedForeground;
+ WBrush? _iconColor;
ObservableCollection? _menuItemsSource;
WIconElement? _icon;
WeakReference? _data;
@@ -106,7 +107,7 @@ public WIconElement? Icon
public WBrush? Foreground
{
- get => IsSelected ? SelectedForeground : UnselectedForeground;
+ get => IconColor ?? (IsSelected ? SelectedForeground : UnselectedForeground);
}
public WBrush? Background
@@ -171,6 +172,17 @@ public WBrush? UnselectedTitleColor
}
}
+ public WBrush? IconColor
+ {
+ get => _iconColor;
+ set
+ {
+ _iconColor = value;
+ OnPropertyChanged(nameof(IconColor));
+ UpdateForeground();
+ }
+ }
+
public WBrush? SelectedForeground
{
get => _selectedForeground;
diff --git a/src/Core/src/Platform/Windows/TransformationExtensions.cs b/src/Core/src/Platform/Windows/TransformationExtensions.cs
index d865a90f060f..2aa6b4bf7a06 100644
--- a/src/Core/src/Platform/Windows/TransformationExtensions.cs
+++ b/src/Core/src/Platform/Windows/TransformationExtensions.cs
@@ -2,63 +2,65 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;
-namespace Microsoft.Maui.Platform
+namespace Microsoft.Maui.Platform;
+
+public static class TransformationExtensions
{
- public static class TransformationExtensions
+ public static void UpdateTransformation(this FrameworkElement frameworkElement, IView view)
{
- public static void UpdateTransformation(this FrameworkElement frameworkElement, IView view)
- {
- double rotationX = view.RotationX;
- double rotationY = view.RotationY;
- double rotation = view.Rotation;
- double translationX = view.TranslationX;
- double translationY = view.TranslationY;
- double scaleX = view.Scale * view.ScaleX;
- double scaleY = view.Scale * view.ScaleY;
+ double rotationX = view.RotationX;
+ double rotationY = view.RotationY;
+ double rotation = view.Rotation;
+ double translationX = view.TranslationX;
+ double translationY = view.TranslationY;
+ double scaleX = view.Scale * view.ScaleX;
+ double scaleY = view.Scale * view.ScaleY;
- if (rotationX % 360 == 0 && rotationY % 360 == 0 && rotation % 360 == 0 &&
- translationX == 0 && translationY == 0 && scaleX == 1 && scaleY == 1)
+ if (rotationX % 360 == 0 && rotationY % 360 == 0 && rotation % 360 == 0 &&
+ translationX == 0 && translationY == 0 && scaleX == 1 && scaleY == 1)
+ {
+ if (!view.IsConnectingHandler())
{
frameworkElement.Projection = null;
frameworkElement.RenderTransform = null;
}
- else
- {
- double anchorX = view.AnchorX;
- double anchorY = view.AnchorY;
+ }
+ else
+ {
+ double anchorX = view.AnchorX;
+ double anchorY = view.AnchorY;
- frameworkElement.RenderTransformOrigin = new global::Windows.Foundation.Point(anchorX, anchorY);
- frameworkElement.RenderTransform = new ScaleTransform { ScaleX = scaleX, ScaleY = scaleY };
+ frameworkElement.RenderTransformOrigin = new global::Windows.Foundation.Point(anchorX, anchorY);
+ frameworkElement.RenderTransform = new ScaleTransform { ScaleX = scaleX, ScaleY = scaleY };
- // PlaneProjection removes touch and scrollwheel functionality on scrollable views such
- // as ScrollView, ListView, and TableView. If neither RotationX or RotationY are set
- // (i.e. their absolute value is 0), a CompositeTransform is instead used to allow for
- // rotation of the control on a 2D plane, and the other values are set. Otherwise, the
- // rotation values are set, but the aforementioned functionality will be lost.
- if (Math.Abs(view.RotationX) != 0 || Math.Abs(view.RotationY) != 0)
+ // PlaneProjection removes touch and scrollwheel functionality on scrollable views such
+ // as ScrollView, ListView, and TableView. If neither RotationX or RotationY are set
+ // (i.e. their absolute value is 0), a CompositeTransform is instead used to allow for
+ // rotation of the control on a 2D plane, and the other values are set. Otherwise, the
+ // rotation values are set, but the aforementioned functionality will be lost.
+ if (Math.Abs(view.RotationX) != 0 || Math.Abs(view.RotationY) != 0)
+ {
+ frameworkElement.Projection = new PlaneProjection
{
- frameworkElement.Projection = new PlaneProjection
- {
- CenterOfRotationX = anchorX,
- CenterOfRotationY = anchorY,
- GlobalOffsetX = translationX,
- GlobalOffsetY = translationY,
- RotationX = -rotationX,
- RotationY = -rotationY,
- RotationZ = -rotation
- };
- }
- else
+ CenterOfRotationX = anchorX,
+ CenterOfRotationY = anchorY,
+ GlobalOffsetX = translationX,
+ GlobalOffsetY = translationY,
+ RotationX = -rotationX,
+ RotationY = -rotationY,
+ RotationZ = -rotation
+ };
+ }
+ else
+ {
+ frameworkElement.RenderTransform = new CompositeTransform
{
- frameworkElement.RenderTransform = new CompositeTransform
- {
- Rotation = rotation,
- ScaleX = scaleX,
- ScaleY = scaleY,
- TranslateX = translationX,
- TranslateY = translationY
- };
- }
+ Rotation = rotation,
+ ScaleX = scaleX,
+ ScaleY = scaleY,
+ TranslateX = translationX,
+ TranslateY = translationY
+ };
}
}
}
diff --git a/src/Core/src/Platform/Windows/WrapperView.cs b/src/Core/src/Platform/Windows/WrapperView.cs
index 79ea64234fcc..86694b5ee903 100644
--- a/src/Core/src/Platform/Windows/WrapperView.cs
+++ b/src/Core/src/Platform/Windows/WrapperView.cs
@@ -97,6 +97,7 @@ void UpdateClip()
if (clipGeometry is null)
{
+ DisposeClip();
return;
}
@@ -167,13 +168,20 @@ void UpdateBorder()
partial void ShadowChanged()
{
- if (HasShadow)
+ if (Shadow?.Paint is { })
{
- UpdateShadowAsync().FireAndForget(IPlatformApplication.Current?.Services?.CreateLogger(nameof(WrapperView)));
+ if (HasShadow)
+ {
+ UpdateShadowAsync().FireAndForget(IPlatformApplication.Current?.Services?.CreateLogger(nameof(WrapperView)));
+ }
+ else
+ {
+ CreateShadowAsync().FireAndForget(IPlatformApplication.Current?.Services?.CreateLogger(nameof(WrapperView)));
+ }
}
else
{
- CreateShadowAsync().FireAndForget(IPlatformApplication.Current?.Services?.CreateLogger(nameof(WrapperView)));
+ DisposeShadow();
}
}
@@ -232,7 +240,7 @@ async Task CreateShadowAsync()
var visual = ElementCompositionPreview.GetElementVisual(Child);
- if (Clip != null && visual.Clip == null)
+ if (Clip is not null && visual.Clip is null)
{
return;
}
@@ -319,8 +327,9 @@ void UpdateShadowSize()
_shadowHost.Width = width;
_shadowHost.Height = height;
- Canvas.SetLeft(_shadowHost, Child.ActualOffset.X);
- Canvas.SetTop(_shadowHost, Child.ActualOffset.Y);
+ Vector3 actualOffset = Child.ActualOffset;
+ Canvas.SetLeft(_shadowHost, actualOffset.X);
+ Canvas.SetTop(_shadowHost, actualOffset.Y);
}
}
}
@@ -332,7 +341,7 @@ async Task SetShadowPropertiesAsync(DropShadow dropShadow, IShadow? mauiShadow)
Graphics.Color? shadowColor = Colors.Black;
Graphics.Point offset = Graphics.Point.Zero;
- if (mauiShadow != null)
+ if (mauiShadow is not null)
{
blurRadius = mauiShadow.Radius * 2;
opacity = mauiShadow.Opacity;
@@ -343,7 +352,7 @@ async Task SetShadowPropertiesAsync(DropShadow dropShadow, IShadow? mauiShadow)
dropShadow.BlurRadius = blurRadius;
dropShadow.Opacity = opacity;
- if (shadowColor != null)
+ if (shadowColor is not null)
{
dropShadow.Color = shadowColor.ToWindowsColor();
}
diff --git a/src/Core/src/Platform/iOS/TextFieldExtensions.cs b/src/Core/src/Platform/iOS/TextFieldExtensions.cs
index 3b5211076a0c..886b48fc5f4a 100644
--- a/src/Core/src/Platform/iOS/TextFieldExtensions.cs
+++ b/src/Core/src/Platform/iOS/TextFieldExtensions.cs
@@ -246,5 +246,24 @@ internal static void UpdateClearButtonColor(this UITextField textField, IEntry e
context?.FillRect(rect, CGBlendMode.SourceIn);
});
}
+
+ internal static void AddMauiDoneAccessoryView(this UITextField textField, IViewHandler handler)
+ {
+#if !MACCATALYST
+ var accessoryView = new MauiDoneAccessoryView();
+ accessoryView.SetDataContext(handler);
+ accessoryView.SetDoneClicked(OnDoneClicked);
+ textField.InputAccessoryView = accessoryView;
+#endif
+ }
+
+ static void OnDoneClicked(object sender)
+ {
+ if (sender is IEntryHandler entryHandler)
+ {
+ entryHandler.PlatformView.ResignFirstResponder();
+ entryHandler.VirtualView.Completed();
+ }
+ }
}
}
diff --git a/src/Core/src/Platform/iOS/TextViewExtensions.cs b/src/Core/src/Platform/iOS/TextViewExtensions.cs
index 10518c47314a..55b8af9713f3 100644
--- a/src/Core/src/Platform/iOS/TextViewExtensions.cs
+++ b/src/Core/src/Platform/iOS/TextViewExtensions.cs
@@ -177,5 +177,24 @@ static UITextPosition GetSelectionEnd(UITextView textView, IEditor editor, UITex
return end;
}
+
+ internal static void AddMauiDoneAccessoryView(this UITextView textView, IViewHandler handler)
+ {
+#if !MACCATALYST
+ var accessoryView = new MauiDoneAccessoryView();
+ accessoryView.SetDataContext(handler);
+ accessoryView.SetDoneClicked(OnDoneClicked);
+ textView.InputAccessoryView = accessoryView;
+#endif
+ }
+
+ static void OnDoneClicked(object sender)
+ {
+ if (sender is IEditorHandler entryHandler)
+ {
+ entryHandler.PlatformView.ResignFirstResponder();
+ entryHandler.VirtualView.Completed();
+ }
+ }
}
}
diff --git a/src/Core/src/Platform/iOS/WindowViewController.cs b/src/Core/src/Platform/iOS/WindowViewController.cs
index fb966fe8ed61..1afa57af2771 100644
--- a/src/Core/src/Platform/iOS/WindowViewController.cs
+++ b/src/Core/src/Platform/iOS/WindowViewController.cs
@@ -70,6 +70,19 @@ public WindowViewController(UIViewController contentViewController, IWindow wind
contentViewController.DidMoveToParentViewController(this);
}
+
+ public override void TraitCollectionDidChange(UITraitCollection? previousTraitCollection)
+ {
+#pragma warning disable CA1422 // Validate platform compatibility
+ base.TraitCollectionDidChange(previousTraitCollection);
+#pragma warning restore CA1422 // Validate platform compatibility
+
+ if (_titleBar is not null && _iTitleBarRef.TryGetTarget(out IView? iTitleBar) && iTitleBar?.Background is null)
+ {
+ _titleBar.BackgroundColor = UIColor.SecondarySystemBackground;
+ }
+ }
+
public override void ViewWillLayoutSubviews()
{
LayoutTitleBar();
diff --git a/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBaseOfT.Tests.cs b/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBaseOfT.Tests.cs
index c572eb268b07..dd31953997f8 100644
--- a/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBaseOfT.Tests.cs
+++ b/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBaseOfT.Tests.cs
@@ -45,7 +45,18 @@ public async Task SetFlowDirection(FlowDirection flowDirection)
};
var id = await GetValueAsync(view, handler => GetFlowDirection(handler));
+#if WINDOWS
+ if (typeof(THandler).Name.Contains("WebView", StringComparison.Ordinal))
+ {
+ Assert.Equal(FlowDirection.LeftToRight, id);
+ }
+ else
+ {
+ Assert.Equal(flowDirection, id);
+ }
+#else
Assert.Equal(flowDirection, id);
+#endif
}
[Theory(DisplayName = "Opacity is set correctly")]
diff --git a/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.cs
index 4e348ebd553b..49ed16161ba0 100644
--- a/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.cs
+++ b/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.cs
@@ -102,6 +102,24 @@ await AttachAndRun(searchBar, async (searchBarHandler) =>
await ValidatePropertyInitValue(searchBar, () => searchBar.IsTextPredictionEnabled, GetNativeIsTextPredictionEnabled, isEnabled);
}
+ [Theory(DisplayName = "IsTextPredictionEnabled Initializes Correctly for SearchBar")]
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task SearchBarIsTextPredictionEnabledInitializesCorrectly(bool isEnabled)
+ {
+ var searchBar = new Microsoft.Maui.Controls.SearchBar()
+ {
+ IsTextPredictionEnabled = isEnabled
+ };
+
+ await AttachAndRun(searchBar, async (searchBarHandler) =>
+ {
+ await AssertEventually(() => searchBarHandler.PlatformView.IsLoaded());
+ });
+
+ await ValidatePropertyInitValue(searchBar, () => searchBar.IsTextPredictionEnabled, GetNativeIsTextPredictionEnabled, isEnabled);
+ }
+
[Theory(DisplayName = "IsSpellCheckEnabled Initializes Correctly")]
[InlineData(true)]
[InlineData(false)]
diff --git a/src/Essentials/src/FileSystem/FileSystemUtils.android.cs b/src/Essentials/src/FileSystem/FileSystemUtils.android.cs
index 5dad4645a4f3..e80be6cd853e 100644
--- a/src/Essentials/src/FileSystem/FileSystemUtils.android.cs
+++ b/src/Essentials/src/FileSystem/FileSystemUtils.android.cs
@@ -124,9 +124,7 @@ static string ResolveDocumentPath(AndroidUri uri)
// This is the internal "external" memory, NOT the SD Card
if (storageType.Equals(storageTypePrimary, StringComparison.OrdinalIgnoreCase))
{
-#pragma warning disable CS0618 // Type or member is obsolete
var root = global::Android.OS.Environment.ExternalStorageDirectory.Path;
-#pragma warning restore CS0618 // Type or member is obsolete
return Path.Combine(root, uriPath);
}
@@ -179,10 +177,8 @@ static string ResolveDocumentPath(AndroidUri uri)
contentUri = MediaStore.Video.Media.ExternalContentUri;
else if (storageType.Equals(storageTypeAudio, StringComparison.OrdinalIgnoreCase))
contentUri = MediaStore.Audio.Media.ExternalContentUri;
-#pragma warning disable CS0618
- if (contentUri != null && GetDataFilePath(contentUri, $"{MediaStore.MediaColumns.Id}=?", new[] { uriPath }) is string filePath)
+ if (contentUri != null && GetDataFilePath(contentUri, $"{IBaseColumns.Id}=?", new[] { uriPath }) is string filePath)
return filePath;
-#pragma warning restore CS0618
}
}
@@ -218,9 +214,7 @@ static string CacheContentFile(AndroidUri uri)
return null;
// resolve or generate a valid destination path
-#pragma warning disable CS0618
- var filename = GetColumnValue(uri, MediaStore.Files.FileColumns.DisplayName) ?? Guid.NewGuid().ToString("N");
-#pragma warning restore CS0618
+ var filename = GetColumnValue(uri, MediaStore.IMediaColumns.DisplayName) ?? Guid.NewGuid().ToString("N");
if (!Path.HasExtension(filename) && !string.IsNullOrEmpty(extension))
filename = Path.ChangeExtension(filename, extension);
@@ -261,9 +255,10 @@ static bool IsVirtualFile(AndroidUri uri)
if (!string.IsNullOrEmpty(value) && int.TryParse(value, out var flagsInt))
{
var flags = (DocumentContractFlags)flagsInt;
-#pragma warning disable CA1416 // Introduced in API 24: https://developer.android.com/reference/android/provider/DocumentsContract.Document#FLAG_VIRTUAL_DOCUMENT
- return flags.HasFlag(DocumentContractFlags.VirtualDocument);
-#pragma warning restore CA1416
+
+ if (OperatingSystem.IsAndroidVersionAtLeast(24))
+ return flags.HasFlag(DocumentContractFlags.VirtualDocument);
+
}
return false;
@@ -307,13 +302,7 @@ static string GetColumnValue(AndroidUri contentUri, string column, string select
static string GetDataFilePath(AndroidUri contentUri, string selection = null, string[] selectionArgs = null)
{
-#pragma warning disable CS0618 // Type or member is obsolete
-#pragma warning disable CA1422 // Validate platform compatibility
-#pragma warning disable CA1416 // Validate platform compatibility
- const string column = MediaStore.Files.FileColumns.Data;
-#pragma warning restore CA1422 // Validate platform compatibility
-#pragma warning restore CA1416 // Validate platform compatibility
-#pragma warning restore CS0618 // Type or member is obsolete
+ const string column = MediaStore.IMediaColumns.Data;
// ask the content provider for the data column, which may contain the actual file path
var path = GetColumnValue(contentUri, column, selection, selectionArgs);
diff --git a/src/Essentials/src/Platform/IntermediateActivity.android.cs b/src/Essentials/src/Platform/IntermediateActivity.android.cs
index 46d44960fba3..51c742704ef4 100644
--- a/src/Essentials/src/Platform/IntermediateActivity.android.cs
+++ b/src/Essentials/src/Platform/IntermediateActivity.android.cs
@@ -32,13 +32,12 @@ protected override void OnCreate(Bundle? savedInstanceState)
// read the values
launched = extras?.GetBoolean(launchedExtra, false) ?? false;
-#pragma warning disable 618 // TODO: one day use the API 33+ version: https://developer.android.com/reference/android/os/Bundle#getParcelable(java.lang.String,%20java.lang.Class%3CT%3E)
-#pragma warning disable CA1422 // Validate platform compatibility
-#pragma warning disable CA1416 // Validate platform compatibility
- actualIntent = extras?.GetParcelable(actualIntentExtra) as Intent;
-#pragma warning restore CA1422 // Validate platform compatibility
-#pragma warning restore CA1416 // Validate platform compatibility
-#pragma warning restore 618
+
+ if (OperatingSystem.IsAndroidVersionAtLeast(33))
+ actualIntent = extras?.GetParcelable(actualIntentExtra, Java.Lang.Class.FromType(typeof(Intent))) as Intent;
+ else
+ actualIntent = extras?.GetParcelable(actualIntentExtra) as Intent;
+
guid = extras?.GetString(guidExtra);
requestCode = extras?.GetInt(requestCodeExtra, -1) ?? -1;
diff --git a/src/Graphics/src/Graphics/CanvasExtensions.cs b/src/Graphics/src/Graphics/CanvasExtensions.cs
index 499ca674f18a..4fb06bba66be 100644
--- a/src/Graphics/src/Graphics/CanvasExtensions.cs
+++ b/src/Graphics/src/Graphics/CanvasExtensions.cs
@@ -152,11 +152,48 @@ public static void DrawPath(this ICanvas target, PathF path)
target.DrawPath(path);
}
+ ///
+ /// Fills the specified path using the current fill color and the non-zero winding rule.
+ ///
+ /// The canvas to draw on.
+ /// The path to fill.
+ ///
+ /// Thrown when the path is invalid for fill operations. This can occur when:
+ ///
+ /// The path is empty or contains no drawable segments
+ /// The path contains invalid coordinates or operations
+ /// The path is not properly formed for the underlying graphics implementation
+ ///
+ ///
+ ///
+ /// For best results with fill operations, ensure the path represents a closed shape by calling
+ /// or manually connecting the end point back to the start point.
+ /// Unclosed paths may produce unexpected results or exceptions depending on the graphics backend.
+ ///
public static void FillPath(this ICanvas target, PathF path)
{
target.FillPath(path, WindingMode.NonZero);
}
+ ///
+ /// Fills the specified path using the current fill color and the specified winding rule.
+ ///
+ /// The canvas to draw on.
+ /// The path to fill.
+ /// The winding rule to use for determining which areas are inside the path.
+ ///
+ /// Thrown when the path is invalid for fill operations. This can occur when:
+ ///
+ /// The path is empty or contains no drawable segments
+ /// The path contains invalid coordinates or operations
+ /// The path is not properly formed for the underlying graphics implementation
+ ///
+ ///
+ ///
+ /// For best results with fill operations, ensure the path represents a closed shape by calling
+ /// or manually connecting the end point back to the start point.
+ /// Unclosed paths may produce unexpected results or exceptions depending on the graphics backend.
+ ///
public static void FillPath(this ICanvas target, PathF path, WindingMode windingMode)
{
target.FillPath(path, windingMode);
diff --git a/src/Graphics/src/Graphics/PathF.cs b/src/Graphics/src/Graphics/PathF.cs
index 748ed21b1a5b..4c93697e9139 100644
--- a/src/Graphics/src/Graphics/PathF.cs
+++ b/src/Graphics/src/Graphics/PathF.cs
@@ -8,6 +8,17 @@ namespace Microsoft.Maui.Graphics
///
/// Represents a geometric path consisting of lines, curves, and shapes using single-precision floating-point coordinates.
///
+ ///
+ ///
+ /// A path is composed of one or more sub-paths, each beginning with a Move operation and consisting of connected
+ /// line segments, curves, and arcs. For fill operations to work reliably, paths should typically be closed using
+ /// the method or by explicitly connecting the end point back to the starting point.
+ ///
+ ///
+ /// When creating paths for filling, ensure proper path construction to avoid exceptions during rendering.
+ /// Paths that start with operations will automatically create an initial MoveTo operation.
+ ///
+ ///
public class PathF : IDisposable
{
private const float K_RATIO = 0.551784777779014f; // ideal ratio of cubic Bezier points for a quarter circle
@@ -47,6 +58,10 @@ private PathF(List points, List arcSizes, List arcClockwise
}
}
+ ///
+ /// Initializes a new path by copying the segments, points, and arc metadata of another .
+ ///
+ /// The path to copy.
public PathF(PathF path) : this()
{
_operations.AddRange(path._operations);
@@ -59,16 +74,28 @@ public PathF(PathF path) : this()
_subPathsClosed = new List(path._subPathsClosed);
}
+ ///
+ /// Initializes a new path whose first (move) point is the specified point.
+ ///
+ /// The starting point.
public PathF(PointF point) : this()
{
MoveTo(point.X, point.Y);
}
+ ///
+ /// Initializes a new path whose first (move) point is at the specified coordinates.
+ ///
+ /// X coordinate of the starting point.
+ /// Y coordinate of the starting point.
public PathF(float x, float y) : this()
{
MoveTo(x, y);
}
+ ///
+ /// Initializes an empty path with no segments.
+ ///
public PathF()
{
_subPathCount = 0;
@@ -79,8 +106,14 @@ public PathF()
_subPathsClosed = new List();
}
+ ///
+ /// Gets the number of sub-paths (contiguous sequences beginning with ) in the path.
+ ///
public int SubPathCount => _subPathCount;
+ ///
+ /// Gets a value indicating whether the last sub-path has been explicitly closed with .
+ ///
public bool Closed
{
get
@@ -92,6 +125,9 @@ public bool Closed
}
}
+ ///
+ /// Gets the first point in the path, or the default value if the path is empty.
+ ///
public PointF FirstPoint
{
get
@@ -103,6 +139,9 @@ public PointF FirstPoint
}
}
+ ///
+ /// Enumerates the sequence of segment operations composing the path.
+ ///
public IEnumerable SegmentTypes
{
get
@@ -112,6 +151,9 @@ public IEnumerable SegmentTypes
}
}
+ ///
+ /// Enumerates all points used by the path's segments in logical order.
+ ///
public IEnumerable Points
{
get
@@ -121,6 +163,9 @@ public IEnumerable Points
}
}
+ ///
+ /// Gets the last point in the path, or the default value if the path is empty.
+ ///
public PointF LastPoint
{
get
@@ -132,6 +177,9 @@ public PointF LastPoint
}
}
+ ///
+ /// Gets the index of the last point, or -1 if the path is empty.
+ ///
public int LastPointIndex
{
get
@@ -143,6 +191,10 @@ public int LastPointIndex
}
}
+ ///
+ /// Gets the point at the specified index, or the default value if the index is out of range.
+ ///
+ /// Index of the point.
public PointF this[int index]
{
get
@@ -155,22 +207,42 @@ public PointF this[int index]
//set { points[index] = value; }
}
+ ///
+ /// Sets the coordinates of the point at the specified index.
+ ///
+ /// Index of the point.
+ /// New X value.
+ /// New Y value.
public void SetPoint(int index, float x, float y)
{
_points[index] = new PointF(x, y);
Invalidate();
}
+ ///
+ /// Sets the point at the specified index.
+ ///
+ /// Index of the point.
+ /// The new point value.
public void SetPoint(int index, PointF point)
{
_points[index] = point;
Invalidate();
}
+ ///
+ /// Gets the total number of points in the path.
+ ///
public int Count => _points.Count;
+ ///
+ /// Gets the number of segment operations (including move and close) in the path.
+ ///
public int OperationCount => _operations.Count;
+ ///
+ /// Gets the count of segment operations excluding a leading and a trailing , if present.
+ ///
public int SegmentCountExcludingOpenAndClose
{
get
@@ -198,11 +270,21 @@ public int SegmentCountExcludingOpenAndClose
}
}
+ ///
+ /// Gets the segment operation type at the specified index.
+ ///
+ /// Segment index.
+ /// The value.
public PathOperation GetSegmentType(int aIndex)
{
return _operations[aIndex];
}
+ ///
+ /// Gets an arc angle value at the specified index (stored as degrees).
+ ///
+ /// Angle index.
+ /// The angle in degrees, or 0 if out of range.
public float GetArcAngle(int aIndex)
{
if (_arcAngles.Count > aIndex)
@@ -213,6 +295,11 @@ public float GetArcAngle(int aIndex)
return 0;
}
+ ///
+ /// Sets an arc angle value (degrees) at the specified index.
+ ///
+ /// Angle index.
+ /// New angle in degrees.
public void SetArcAngle(int aIndex, float aValue)
{
if (_arcAngles.Count > aIndex)
@@ -223,6 +310,11 @@ public void SetArcAngle(int aIndex, float aValue)
Invalidate();
}
+ ///
+ /// Gets the stored clockwise flag for an arc segment at the specified index.
+ ///
+ /// Arc flag index.
+ /// true if clockwise; otherwise false .
public bool GetArcClockwise(int aIndex)
{
if (_arcClockwise.Count > aIndex)
@@ -233,6 +325,11 @@ public bool GetArcClockwise(int aIndex)
return false;
}
+ ///
+ /// Sets the stored clockwise flag for an arc segment.
+ ///
+ /// Arc flag index.
+ /// New clockwise value.
public void SetArcClockwise(int aIndex, bool aValue)
{
if (_arcClockwise.Count > aIndex)
@@ -243,11 +340,22 @@ public void SetArcClockwise(int aIndex, bool aValue)
Invalidate();
}
+ ///
+ /// Starts a new sub-path at the specified coordinates.
+ ///
+ /// X coordinate of the starting point.
+ /// Y coordinate of the starting point.
+ /// The current path for chaining.
public PathF MoveTo(float x, float y)
{
return MoveTo(new PointF(x, y));
}
+ ///
+ /// Starts a new sub-path at the specified point.
+ ///
+ /// Starting point of the new sub-path.
+ /// The current path for chaining.
public PathF MoveTo(PointF point)
{
_subPathCount++;
@@ -258,6 +366,14 @@ public PathF MoveTo(PointF point)
return this;
}
+ ///
+ /// Closes the current sub-path by appending a close segment if it is not already closed.
+ ///
+ ///
+ /// Closing a path is typically required for fill operations to work correctly. Attempting to fill
+ /// an unclosed path may result in undefined behavior or exceptions in some graphics implementations.
+ /// A closed path ensures that the shape is properly defined for filling operations.
+ ///
public void Close()
{
if (!Closed)
@@ -270,6 +386,9 @@ public void Close()
Invalidate();
}
+ ///
+ /// Reopens a previously closed last sub-path by removing its closing segment.
+ ///
public void Open()
{
if (_operations[_operations.Count - 1] == PathOperation.Close)
@@ -282,11 +401,27 @@ public void Open()
Invalidate();
}
+ ///
+ /// Adds a straight line segment to the specified coordinates.
+ ///
+ /// The x-coordinate of the end point.
+ /// The y-coordinate of the end point.
+ /// The current path.
public PathF LineTo(float x, float y)
{
return LineTo(new PointF(x, y));
}
+ ///
+ /// Adds a straight line segment to the specified end point (starting a new sub-path if the path is empty).
+ ///
+ /// The end point.
+ /// The current path.
+ ///
+ /// If this is the first operation on an empty path, it will automatically create an initial MoveTo operation
+ /// to the specified point. For paths intended to be filled, ensure the path forms a closed shape by calling
+ /// or explicitly connecting back to the starting point.
+ ///
public PathF LineTo(PointF point)
{
if (_points.Count == 0)
@@ -307,6 +442,12 @@ public PathF LineTo(PointF point)
return this;
}
+ ///
+ /// Inserts a line segment at a specific segment index.
+ ///
+ /// Line end point.
+ /// Segment index at which to insert.
+ /// The current path.
public PathF InsertLineTo(PointF point, int index)
{
if (index == 0)
@@ -329,11 +470,40 @@ public PathF InsertLineTo(PointF point, int index)
return this;
}
+ ///
+ /// Adds an elliptical arc segment using coordinate values instead of points.
+ ///
+ /// The X coordinate of the top-left corner of the bounding rectangle of the ellipse.
+ /// The Y coordinate of the top-left corner of the bounding rectangle of the ellipse.
+ /// The X coordinate of the bottom-right corner of the bounding rectangle of the ellipse.
+ /// The Y coordinate of the bottom-right corner of the bounding rectangle of the ellipse.
+ /// Starting angle of the arc in degrees. 0° points to the right (along the positive X axis). Angles increase counter-clockwise.
+ /// Ending angle of the arc in degrees, measured with the same convention as .
+ /// If true , the arc is drawn in the clockwise direction from to ; otherwise it is drawn counter-clockwise (the positive angle direction).
+ /// The current path for chaining.
public PathF AddArc(float x1, float y1, float x2, float y2, float startAngle, float endAngle, bool clockwise)
{
return AddArc(new PointF(x1, y1), new PointF(x2, y2), startAngle, endAngle, clockwise);
}
+ ///
+ /// Adds an elliptical arc segment to the current sub-path.
+ ///
+ /// The top-left point of the rectangle that bounds the full ellipse from which the arc segment is taken.
+ /// The bottom-right point of the bounding rectangle of the ellipse.
+ /// Starting angle of the arc in degrees. 0° points to the right (along the positive X axis). Angles increase counter-clockwise.
+ /// Ending angle of the arc in degrees, measured with the same convention as .
+ /// If true , the arc is drawn in the clockwise direction from to ; otherwise it is drawn counter-clockwise (the positive angle direction).
+ ///
+ /// Angle values are specified in degrees (not radians). The angular coordinate system used by for arcs is:
+ ///
+ /// 0° is the point on the ellipse at the positive X axis (to the right of center).
+ /// Positive angles advance counter-clockwise.
+ /// The direction of increasing Y on the drawing surface (often downwards in device pixels) does not change the counter-clockwise convention used for angles.
+ ///
+ /// The current point is not implicitly connected to the start of the arc. If you need a straight line connection, call first.
+ ///
+ /// The current so that calls can be chained fluently.
public PathF AddArc(PointF topLeft, PointF bottomRight, float startAngle, float endAngle, bool clockwise)
{
if (Count == 0 || OperationCount == 0 || GetSegmentType(OperationCount - 1) == PathOperation.Close)
@@ -352,11 +522,25 @@ public PathF AddArc(PointF topLeft, PointF bottomRight, float startAngle, float
return this;
}
+ ///
+ /// Adds a quadratic Bézier curve segment using coordinate values.
+ ///
+ /// X-coordinate of the control point.
+ /// Y-coordinate of the control point.
+ /// X-coordinate of the end point.
+ /// Y-coordinate of the end point.
+ /// The current path.
public PathF QuadTo(float cx, float cy, float x, float y)
{
return QuadTo(new PointF(cx, cy), new PointF(x, y));
}
+ ///
+ /// Adds a quadratic Bézier curve segment defined by a control point and an end point.
+ ///
+ /// Quadratic control point.
+ /// End point of the curve.
+ /// The current path.
public PathF QuadTo(PointF controlPoint, PointF point)
{
_points.Add(controlPoint);
@@ -366,6 +550,13 @@ public PathF QuadTo(PointF controlPoint, PointF point)
return this;
}
+ ///
+ /// Inserts a quadratic Bézier segment at a specific segment index.
+ ///
+ /// Control point.
+ /// End point.
+ /// Insertion segment index.
+ /// The current path.
public PathF InsertQuadTo(PointF controlPoint, PointF point, int index)
{
if (index == 0)
@@ -389,11 +580,28 @@ public PathF InsertQuadTo(PointF controlPoint, PointF point, int index)
return this;
}
+ ///
+ /// Adds a cubic Bézier curve segment using coordinate values.
+ ///
+ /// X-coordinate of the first control point.
+ /// Y-coordinate of the first control point.
+ /// X-coordinate of the second control point.
+ /// Y-coordinate of the second control point.
+ /// X-coordinate of the end point.
+ /// Y-coordinate of the end point.
+ /// The current path.
public PathF CurveTo(float c1X, float c1Y, float c2X, float c2Y, float x, float y)
{
return CurveTo(new PointF(c1X, c1Y), new PointF(c2X, c2Y), new PointF(x, y));
}
+ ///
+ /// Adds a cubic Bézier curve segment defined by two control points and an end point.
+ ///
+ /// First control point.
+ /// Second control point.
+ /// End point of the curve.
+ /// The current path.
public PathF CurveTo(PointF controlPoint1, PointF controlPoint2, PointF point)
{
_points.Add(controlPoint1);
@@ -404,6 +612,14 @@ public PathF CurveTo(PointF controlPoint1, PointF controlPoint2, PointF point)
return this;
}
+ ///
+ /// Inserts a cubic Bézier segment at a specific segment index.
+ ///
+ /// First control point.
+ /// Second control point.
+ /// End point.
+ /// Insertion segment index.
+ /// The current path.
public PathF InsertCurveTo(PointF controlPoint1, PointF controlPoint2, PointF point, int index)
{
if (index == 0)
@@ -428,6 +644,11 @@ public PathF InsertCurveTo(PointF controlPoint1, PointF controlPoint2, PointF po
return this;
}
+ ///
+ /// Computes the starting point index in the internal point list for a given segment index.
+ ///
+ /// Segment index.
+ /// The point index, or -1 if not found.
public int GetSegmentPointIndex(int index)
{
if (index <= OperationCount)
@@ -482,6 +703,14 @@ public int GetSegmentPointIndex(int index)
return -1;
}
+ ///
+ /// Retrieves segment metadata, returning the segment type and output indices pointing into internal collections.
+ ///
+ /// Segment index.
+ /// Receives the starting point index.
+ /// Receives the starting arc angle index.
+ /// Receives the arc clockwise flag index.
+ /// The segment operation type, or if invalid.
public PathOperation GetSegmentInfo(int segmentIndex, out int pointIndex, out int arcAngleIndex, out int arcClockwiseIndex)
{
pointIndex = 0;
@@ -537,6 +766,11 @@ public PathOperation GetSegmentInfo(int segmentIndex, out int pointIndex, out in
return PathOperation.Close;
}
+ ///
+ /// Determines which segment uses the point at a specified index.
+ ///
+ /// Point index.
+ /// The segment index, or -1 if not found.
public int GetSegmentForPoint(int pointIndex)
{
if (pointIndex < _points.Count)
@@ -606,6 +840,11 @@ public int GetSegmentForPoint(int pointIndex)
return -1;
}
+ ///
+ /// Gets the points defining the segment at the specified index.
+ ///
+ /// Segment index.
+ /// An array of points (length varies by segment type), an empty array for close segments, or null if invalid.
public PointF[] GetPointsForSegment(int segmentIndex)
{
if (segmentIndex <= OperationCount)
@@ -710,6 +949,10 @@ private void RemoveAllAfter(int pointIndex, int segmentIndex, int arcIndex, int
Invalidate();
}
+ ///
+ /// Removes the specified segment and all segments that follow it.
+ ///
+ /// Segment index at which truncation begins.
public void RemoveAllSegmentsAfter(int segmentIndex)
{
if (segmentIndex <= OperationCount)
@@ -755,6 +998,10 @@ public void RemoveAllSegmentsAfter(int segmentIndex)
Invalidate();
}
+ ///
+ /// Removes a single segment, adjusting internal point and arc data accordingly.
+ ///
+ /// Segment index to remove.
public void RemoveSegment(int segmentIndex)
{
if (segmentIndex <= OperationCount)
@@ -873,6 +1120,16 @@ public void RemoveSegment(int segmentIndex)
}
}
+ ///
+ /// Creates a new representing this path rotated by the specified angle about a pivot point.
+ ///
+ /// The rotation angle in degrees. Positive angles rotate counter-clockwise; 0° keeps the path unchanged.
+ /// The pivot point about which all points (and ellipse bounding rectangles for arc segments) are rotated.
+ /// A new containing the rotated geometry. The original path is not modified.
+ ///
+ /// Rotation uses the same degree-based, counter-clockwise positive convention as arc angles (see ).
+ /// Arc segments preserve their original start and end angle values; only their bounding rectangle corner points are rotated.
+ ///
public PathF Rotate(float angleAsDegrees, PointF pivot)
{
var path = new PathF();
@@ -925,12 +1182,26 @@ public PathF Rotate(float angleAsDegrees, PointF pivot)
return path;
}
+ ///
+ /// Computes the position of a point in the path after rotation about a pivot.
+ ///
+ /// Index into the internal point list.
+ /// The pivot point for rotation.
+ /// Rotation angle in degrees (counter-clockwise positive).
+ /// The rotated point.
+ ///
+ /// This helper applies the same rotation semantics used by and does not cache results.
+ ///
public PointF GetRotatedPoint(int pointIndex, PointF pivotPoint, float angle)
{
var point = _points[pointIndex];
return GeometryUtil.RotatePoint(pivotPoint, point, angle);
}
+ ///
+ /// Applies a 2D affine transformation matrix to all points in the path in place.
+ ///
+ /// The transformation matrix.
public void Transform(Matrix3x2 transform)
{
for (var i = 0; i < _points.Count; i++)
@@ -939,6 +1210,10 @@ public void Transform(Matrix3x2 transform)
Invalidate();
}
+ ///
+ /// Splits the path into individual sub-path objects.
+ ///
+ /// A list of sub-paths.
public List Separate()
{
var paths = new List();
@@ -987,6 +1262,10 @@ public List Separate()
return paths;
}
+ ///
+ /// Creates a new path with the segment and point order reversed.
+ ///
+ /// A new reversed path.
public PathF Reverse()
{
var points = new List(_points);
@@ -1031,11 +1310,22 @@ public PathF Reverse()
return new PathF(points, arcSizes, arcClockwise, operations, _subPathCount);
}
+ ///
+ /// Appends an approximated ellipse path inside the specified rectangle.
+ ///
+ /// The bounding rectangle for the ellipse.
public void AppendEllipse(RectF rect)
{
AppendEllipse(rect.X, rect.Y, rect.Width, rect.Height);
}
+ ///
+ /// Appends an approximated ellipse path (using 4 cubic curves) inside the specified rectangle.
+ ///
+ /// Left.
+ /// Top.
+ /// Width.
+ /// Height.
public void AppendEllipse(float x, float y, float w, float h)
{
var minX = x;
@@ -1055,11 +1345,22 @@ public void AppendEllipse(float x, float y, float w, float h)
Close();
}
+ ///
+ /// Appends an approximated circle path centered at the specified point.
+ ///
+ /// Center point.
+ /// Radius.
public void AppendCircle(PointF center, float r)
{
AppendCircle(center.X, center.Y, r);
}
+ ///
+ /// Appends an approximated circle path centered at the specified point.
+ ///
+ /// Center X.
+ /// Center Y.
+ /// Radius.
public void AppendCircle(float cx, float cy, float r)
{
var minX = cx - r;
@@ -1079,11 +1380,24 @@ public void AppendCircle(float cx, float cy, float r)
Close();
}
+ ///
+ /// Appends a rectangle path using the specified rectangle bounds.
+ ///
+ /// The rectangle bounds.
+ /// Include a final duplicate line to the first point before closing.
public void AppendRectangle(RectF rect, bool includeLast = false)
{
AppendRectangle(rect.X, rect.Y, rect.Width, rect.Height, includeLast);
}
+ ///
+ /// Appends a rectangle path.
+ ///
+ /// Left.
+ /// Top.
+ /// Width.
+ /// Height.
+ /// Include a final duplicate line to the first point before closing.
public void AppendRectangle(float x, float y, float w, float h, bool includeLast = false)
{
var minX = x;
@@ -1104,11 +1418,26 @@ public void AppendRectangle(float x, float y, float w, float h, bool includeLast
Close();
}
+ ///
+ /// Appends a rounded rectangle using the specified rectangle bounds and uniform corner radius.
+ ///
+ /// The rectangle bounds.
+ /// Corner radius (clamped to half width/height).
+ /// Include a duplicate final line before closing.
public void AppendRoundedRectangle(RectF rect, float cornerRadius, bool includeLast = false)
{
AppendRoundedRectangle(rect.X, rect.Y, rect.Width, rect.Height, cornerRadius, includeLast);
}
+ ///
+ /// Appends a rounded rectangle where all four corners share the same radius.
+ ///
+ /// Left.
+ /// Top.
+ /// Width.
+ /// Height.
+ /// Corner radius (clamped to half width/height).
+ /// Include a duplicate final line before closing.
public void AppendRoundedRectangle(float x, float y, float w, float h, float cornerRadius, bool includeLast = false)
{
cornerRadius = ClampCornerRadius(cornerRadius, w, h);
@@ -1138,11 +1467,26 @@ public void AppendRoundedRectangle(float x, float y, float w, float h, float cor
Close();
}
+ ///
+ /// Appends a rounded rectangle using the specified rectangle bounds and individual corner radii.
+ ///
+ /// Bounding rectangle.
+ /// Top-left corner radius.
+ /// Top-right corner radius.
+ /// Bottom-left corner radius.
+ /// Bottom-right corner radius.
+ /// Include a duplicate final line before closing.
public void AppendRoundedRectangle(RectF rect, float topLeftCornerRadius, float topRightCornerRadius, float bottomLeftCornerRadius, float bottomRightCornerRadius, bool includeLast = false)
{
AppendRoundedRectangle(rect.X, rect.Y, rect.Width, rect.Height, topLeftCornerRadius, topRightCornerRadius, bottomLeftCornerRadius, bottomRightCornerRadius, includeLast);
}
+ ///
+ /// Appends a rounded rectangle using distinct horizontal and vertical radii (elliptical corners).
+ ///
+ /// Bounding rectangle.
+ /// Horizontal corner radius.
+ /// Vertical corner radius.
public void AppendRoundedRectangle(RectF rect, float xCornerRadius, float yCornerRadius)
{
xCornerRadius = Math.Min(xCornerRadius, rect.Width / 2);
@@ -1190,6 +1534,18 @@ public void AppendRoundedRectangle(RectF rect, float xCornerRadius, float yCorne
LineTo(new PointF(minX, minY + yCornerRadius));
}
+ ///
+ /// Appends a rounded rectangle specifying individual corner radii.
+ ///
+ /// Left.
+ /// Top.
+ /// Width.
+ /// Height.
+ /// Top-left radius.
+ /// Top-right radius.
+ /// Bottom-left radius.
+ /// Bottom-right radius.
+ /// Include a duplicate final line before closing.
public void AppendRoundedRectangle(float x, float y, float w, float h, float topLeftCornerRadius, float topRightCornerRadius, float bottomLeftCornerRadius, float bottomRightCornerRadius, bool includeLast = false)
{
topLeftCornerRadius = ClampCornerRadius(topLeftCornerRadius, w, h);
@@ -1235,6 +1591,11 @@ private float ClampCornerRadius(float cornerRadius, float w, float h)
return cornerRadius;
}
+ ///
+ /// Indicates whether the specified sub-path is closed.
+ ///
+ /// Zero-based sub-path index.
+ /// true if closed; otherwise false .
public bool IsSubPathClosed(int subPathIndex)
{
if (subPathIndex >= 0 && subPathIndex < SubPathCount)
@@ -1245,6 +1606,9 @@ public bool IsSubPathClosed(int subPathIndex)
return false;
}
+ ///
+ /// Gets or sets a platform-specific native path object associated with this path. Setting a new value disposes the previous one if disposable.
+ ///
public object PlatformPath
{
get => _platformPath;
@@ -1255,12 +1619,18 @@ public object PlatformPath
}
}
+ ///
+ /// Clears cached bounds and releases any native platform path.
+ ///
public void Invalidate()
{
_cachedBounds = null;
ReleaseNative();
}
+ ///
+ /// Releases native resources associated with the path.
+ ///
public void Dispose()
{
ReleaseNative();
@@ -1274,6 +1644,11 @@ private void ReleaseNative()
_platformPath = null;
}
+ ///
+ /// Offsets every point in the path by the specified amounts.
+ ///
+ /// Delta X.
+ /// Delta Y.
public void Move(float x, float y)
{
for (var i = 0; i < _points.Count; i++)
@@ -1284,12 +1659,19 @@ public void Move(float x, float y)
Invalidate();
}
+ ///
+ /// Offsets a single point by the specified deltas.
+ ///
+ /// Point index.
+ /// Delta X.
+ /// Delta Y.
public void MovePoint(int index, float dx, float dy)
{
_points[index] = _points[index].Offset(dx, dy);
Invalidate();
}
+ ///
public override bool Equals(object obj)
{
if (obj is PathF compareTo)
@@ -1335,6 +1717,7 @@ public override bool Equals(object obj)
return true;
}
+ ///
public override int GetHashCode()
{
unchecked
@@ -1347,6 +1730,12 @@ public override int GetHashCode()
}
}
+ ///
+ /// Determines whether this path and another have equivalent geometry within a tolerance.
+ ///
+ /// The other path.
+ /// Maximum allowed difference per component.
+ /// true if equivalent; otherwise false .
public bool Equals(object obj, float epsilon)
{
if (obj is PathF compareTo)
@@ -1392,6 +1781,9 @@ public bool Equals(object obj, float epsilon)
return true;
}
+ ///
+ /// Gets the axis-aligned bounding box of the path (cached until modified).
+ ///
public RectF Bounds
{
get
@@ -1415,6 +1807,11 @@ public RectF Bounds
}
}
+ ///
+ /// Computes bounds by flattening curves with the given flatness, updating the cache.
+ ///
+ /// Maximum allowed deviation when flattening (smaller = more points).
+ /// The bounding rectangle.
public RectF GetBoundsByFlattening(float flatness = 0.001f)
{
if (_cachedBounds != null)
@@ -1453,6 +1850,12 @@ public RectF GetBoundsByFlattening(float flatness = 0.001f)
return (RectF)_cachedBounds;
}
+ ///
+ /// Creates a new path consisting only of line segments approximating all curves and arcs.
+ ///
+ /// Maximum allowed deviation per segment (smaller = more segments).
+ /// If true , flattens all sub-paths; otherwise stops after the first closed one.
+ /// A flattened path.
public PathF GetFlattenedPath(float flatness = .001f, bool includeSubPaths = false)
{
var flattenedPath = new PathF();
diff --git a/src/Graphics/tests/DeviceTests/Graphics.DeviceTests.csproj b/src/Graphics/tests/DeviceTests/Graphics.DeviceTests.csproj
index 6b3ab49a04ab..338f7f8911b4 100644
--- a/src/Graphics/tests/DeviceTests/Graphics.DeviceTests.csproj
+++ b/src/Graphics/tests/DeviceTests/Graphics.DeviceTests.csproj
@@ -29,15 +29,6 @@