diff --git a/src/Controls/tests/DeviceTests/DispatchingTests.cs b/src/Controls/tests/DeviceTests/Components/DispatchingTests.cs similarity index 100% rename from src/Controls/tests/DeviceTests/DispatchingTests.cs rename to src/Controls/tests/DeviceTests/Components/DispatchingTests.cs diff --git a/src/Controls/tests/DeviceTests/Elements/FormattedStringTests.cs b/src/Controls/tests/DeviceTests/Components/FormattedStringTests.cs similarity index 87% rename from src/Controls/tests/DeviceTests/Elements/FormattedStringTests.cs rename to src/Controls/tests/DeviceTests/Components/FormattedStringTests.cs index 7c6a56c36606..686fbdd803ee 100644 --- a/src/Controls/tests/DeviceTests/Elements/FormattedStringTests.cs +++ b/src/Controls/tests/DeviceTests/Components/FormattedStringTests.cs @@ -2,7 +2,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Maui.Controls; using Microsoft.Maui.Controls.Platform; -using Microsoft.Maui.Graphics; +using Microsoft.Maui.Hosting; using Microsoft.Maui.Handlers; using Xunit; @@ -11,6 +11,11 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Label)] public partial class FormattedStringTests : ControlsHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); + [Fact] public async Task NativeFormattedStringContainsSpan() { diff --git a/src/Controls/tests/DeviceTests/GestureTests.iOS.cs b/src/Controls/tests/DeviceTests/Components/GestureTests.iOS.cs similarity index 100% rename from src/Controls/tests/DeviceTests/GestureTests.iOS.cs rename to src/Controls/tests/DeviceTests/Components/GestureTests.iOS.cs diff --git a/src/Controls/tests/DeviceTests/MapperTests.cs b/src/Controls/tests/DeviceTests/Components/MapperTests.cs similarity index 92% rename from src/Controls/tests/DeviceTests/MapperTests.cs rename to src/Controls/tests/DeviceTests/Components/MapperTests.cs index 581aa2de9642..24ba44ae4612 100644 --- a/src/Controls/tests/DeviceTests/MapperTests.cs +++ b/src/Controls/tests/DeviceTests/Components/MapperTests.cs @@ -18,7 +18,10 @@ public class MapperTests : ControlsHandlerTestBase [ClassData(typeof(MapperGenericTypeCases))] public void ValidateMapperGenerics(IPropertyMapper propertyMapper, Type viewType, Type handlerType) { - EnsureHandlerCreated(builder => builder.ConfigureMauiHandlers(h => h.AddMauiControlsHandlers())); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(h => + h.AddMauiControlsHandlers())); + var generics = propertyMapper.GetType().GenericTypeArguments; Assert.Equal(viewType, generics[0]); Assert.Equal(handlerType, generics[1]); diff --git a/src/Controls/tests/DeviceTests/Elements/PlatformBehaviorTests.cs b/src/Controls/tests/DeviceTests/Components/PlatformBehaviorTests.cs similarity index 100% rename from src/Controls/tests/DeviceTests/Elements/PlatformBehaviorTests.cs rename to src/Controls/tests/DeviceTests/Components/PlatformBehaviorTests.cs diff --git a/src/Controls/tests/DeviceTests/ControlsDeviceTestExtensions.cs b/src/Controls/tests/DeviceTests/ControlsDeviceTestExtensions.cs index 5f7dec1aac41..3e9d3e028d24 100644 --- a/src/Controls/tests/DeviceTests/ControlsDeviceTestExtensions.cs +++ b/src/Controls/tests/DeviceTests/ControlsDeviceTestExtensions.cs @@ -1,10 +1,13 @@ -using Microsoft.Maui.Controls; +using System.Threading.Tasks; +using Microsoft.Maui.Controls; +using Microsoft.Maui.Controls.Handlers; using Microsoft.Maui.Controls.Hosting; using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.Handlers; using Microsoft.Maui.Hosting; using Microsoft.Maui.LifecycleEvents; using Xunit; + #if ANDROID || IOS || MACCATALYST using ShellHandler = Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer; #endif @@ -44,6 +47,9 @@ public static MauiAppBuilder ConfigureTestBuilder(this MauiAppBuilder mauiAppBui }) .ConfigureMauiHandlers(handlers => { + // TODO: removing these causes a crash and it is very hard to fugure out which test + // is needing these mappers + handlers.AddHandler(typeof(Editor), typeof(EditorHandler)); handlers.AddHandler(typeof(VerticalStackLayout), typeof(LayoutHandler)); handlers.AddHandler(typeof(Controls.Window), typeof(WindowHandlerStub)); @@ -53,5 +59,36 @@ public static MauiAppBuilder ConfigureTestBuilder(this MauiAppBuilder mauiAppBui #endif }); } + + + public static Task Wait(this Image image, int timeout = 1000) => + AssertionExtensions.Wait(() => !image.IsLoading, timeout); + + public static void SetupShellHandlers(this MauiAppBuilder builder) + { + builder.ConfigureMauiHandlers(SetupShellHandlers); + } + + public static void SetupShellHandlers(this IMauiHandlersCollection handlers) + { + handlers.TryAddHandler(typeof(Controls.Shell), typeof(ShellHandler)); + handlers.TryAddHandler(); + handlers.TryAddHandler(); + handlers.TryAddHandler(); + handlers.TryAddHandler(); + handlers.TryAddHandler(); + handlers.TryAddHandler(typeof(Toolbar), typeof(ToolbarHandler)); + handlers.TryAddHandler(typeof(MenuBar), typeof(MenuBarHandler)); + handlers.TryAddHandler(typeof(MenuBarItem), typeof(MenuBarItemHandler)); + handlers.TryAddHandler(typeof(MenuFlyoutItem), typeof(MenuFlyoutItemHandler)); + handlers.TryAddHandler(typeof(MenuFlyoutSubItem), typeof(MenuFlyoutSubItemHandler)); + handlers.TryAddHandler(); + +#if WINDOWS + handlers.TryAddHandler(typeof(ShellItem), typeof(ShellItemHandler)); + handlers.TryAddHandler(typeof(ShellSection), typeof(ShellSectionHandler)); + handlers.TryAddHandler(typeof(ShellContent), typeof(ShellContentHandler)); +#endif + } } } diff --git a/src/Controls/tests/DeviceTests/ControlsHandlerTestBase.cs b/src/Controls/tests/DeviceTests/ControlsHandlerTestBase.cs index cc34e9d47d3f..0fda01019765 100644 --- a/src/Controls/tests/DeviceTests/ControlsHandlerTestBase.cs +++ b/src/Controls/tests/DeviceTests/ControlsHandlerTestBase.cs @@ -33,9 +33,6 @@ protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder return mauiAppBuilder.ConfigureTestBuilder(); } - protected void SetupShellHandlers(IMauiHandlersCollection handlers) => - handlers.SetupShellHandlers(); - protected THandler CreateHandler(IElement view) where THandler : IElementHandler, new() { @@ -542,9 +539,6 @@ protected IToolbar GetToolbar(IElementHandler handler) ?.Toolbar; } - protected Task ValidateHasColor(IView view, Color color, Action action = null) => - ValidateHasColor(view, color, typeof(THandler), action); - protected static void MockAccessibilityExpectations(View view) { #if IOS || MACCATALYST diff --git a/src/Controls/tests/DeviceTests/Elements/Accessibility/AccessibilityTests.cs b/src/Controls/tests/DeviceTests/Elements/Accessibility/AccessibilityTests.cs index 1e233ea223b1..cc247c3ed778 100644 --- a/src/Controls/tests/DeviceTests/Elements/Accessibility/AccessibilityTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Accessibility/AccessibilityTests.cs @@ -22,6 +22,10 @@ public partial class AccessibilityTests : ControlsHandlerTestBase [InlineData(false)] public async Task IsInAccessibleTree(bool result) { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + var button = new Button(); AutomationProperties.SetIsInAccessibleTree(button, result); var important = await GetValueAsync(button, handler => button.IsAccessibilityElement()); @@ -34,6 +38,10 @@ public async Task IsInAccessibleTree(bool result) [InlineData(false)] public async Task ExcludedWithChildren(bool result) { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + var button = new Button(); AutomationProperties.SetExcludedWithChildren(button, result); var excluded = await GetValueAsync(button, handler => button.IsExcludedWithChildren()); diff --git a/src/Controls/tests/DeviceTests/Elements/Border/BorderTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/Border/BorderTests.Windows.cs index cabcf59c4f83..6810cb536679 100644 --- a/src/Controls/tests/DeviceTests/Elements/Border/BorderTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/Border/BorderTests.Windows.cs @@ -18,8 +18,6 @@ public partial class BorderTests : ControlsHandlerTestBase [InlineData(24)] public async Task InnerCornerRadiusInitializesCorrectly(int cornerRadius) { - SetupBuilder(); - var expected = Colors.Red; var border = new Border() diff --git a/src/Controls/tests/DeviceTests/Elements/Border/BorderTests.cs b/src/Controls/tests/DeviceTests/Elements/Border/BorderTests.cs index 3b3f9a4f5b57..94d58e083084 100644 --- a/src/Controls/tests/DeviceTests/Elements/Border/BorderTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Border/BorderTests.cs @@ -12,18 +12,14 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Border)] public partial class BorderTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); }); - }); - } [Fact(DisplayName = "Rounded Rectangle Border occupies correct space")] public Task RoundedRectangleBorderLayoutIsCorrect() @@ -43,7 +39,7 @@ public Task RoundedRectangleBorderLayoutIsCorrect() WidthRequest = 100 }; - return AssertColorAtPoint(border, expected, typeof(BorderHandler), 10, 10); + return AssertColorAtPoint(border, expected, 10, 10); } [Fact(DisplayName = "StrokeThickness does not inset stroke path")] @@ -81,7 +77,7 @@ public async Task BorderStrokeThicknessDoesNotInsetStrokePath() #if IOS // FIXME: iOS seems to have a white boarder around the Border stroke #else - await AssertColorAtPoint(grid, Colors.Black, typeof(LayoutHandler), 1, 1); + await AssertColorAtPoint(grid, Colors.Black, 1, 1); #endif } @@ -90,7 +86,6 @@ public async Task BorderStrokeThicknessDoesNotInsetStrokePath() [Fact("Border Does Not Leak")] public async Task DoesNotLeak() { - SetupBuilder(); WeakReference platformViewReference = null; WeakReference handlerReference = null; diff --git a/src/Controls/tests/DeviceTests/Elements/BoxView/BoxViewTests.cs b/src/Controls/tests/DeviceTests/Elements/BoxView/BoxViewTests.cs index 9c3e392fc726..e2cb94c13b1e 100644 --- a/src/Controls/tests/DeviceTests/Elements/BoxView/BoxViewTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/BoxView/BoxViewTests.cs @@ -11,6 +11,11 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.BoxView)] public partial class BoxViewTests : ControlsHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); + [Theory(DisplayName = "BoxView Initializes Correctly")] [InlineData(0xFFFF0000)] [InlineData(0xFF00FF00)] @@ -26,7 +31,7 @@ public async Task BoxViewInitializesCorrectly(uint color) WidthRequest = 200 }; - await ValidateHasColor(boxView, expected, typeof(ShapeViewHandler)); + await ValidateHasColor(boxView, expected); } } } \ No newline at end of file diff --git a/src/Controls/tests/DeviceTests/Elements/Button/ButtonTests.cs b/src/Controls/tests/DeviceTests/Elements/Button/ButtonTests.cs index 3870bd932a71..7f543cc21863 100644 --- a/src/Controls/tests/DeviceTests/Elements/Button/ButtonTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Button/ButtonTests.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.Maui.Controls; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests @@ -8,6 +9,11 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Button)] public partial class ButtonTests : ControlsHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); + [Theory] [ClassData(typeof(TextTransformCases))] public async Task InitialTextTransformApplied(string text, TextTransform transform, string expected) diff --git a/src/Controls/tests/DeviceTests/Elements/CarouselView/CarouselViewTests.cs b/src/Controls/tests/DeviceTests/Elements/CarouselView/CarouselViewTests.cs index efb175da3265..b5365ebed9bf 100644 --- a/src/Controls/tests/DeviceTests/Elements/CarouselView/CarouselViewTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/CarouselView/CarouselViewTests.cs @@ -11,25 +11,19 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.CarouselView)] public partial class CarouselViewTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); }); - }); - } [Fact] public async Task CarouselViewDataTemplateSelectorSelectorNoCrash() { - SetupBuilder(); - ObservableCollection data = new ObservableCollection() { 1, @@ -77,8 +71,6 @@ await CreateHandlerAndAddToWindow(layout, async (handler) => [Fact] public async Task HiddenCarouselViewNoCrash() { - SetupBuilder(); - ObservableCollection data = new ObservableCollection() { 1, diff --git a/src/Controls/tests/DeviceTests/Elements/CheckBox/CheckBoxTests.cs b/src/Controls/tests/DeviceTests/Elements/CheckBox/CheckBoxTests.cs index 816ee52b0317..7cc000bbd87c 100644 --- a/src/Controls/tests/DeviceTests/Elements/CheckBox/CheckBoxTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/CheckBox/CheckBoxTests.cs @@ -11,16 +11,10 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.CheckBox)] public partial class CheckBoxTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - }); - }); - } + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); [Theory("Checkbox Background Updates Correctly With BackgroundColor Property" #if WINDOWS @@ -41,7 +35,7 @@ public async Task UpdatingCheckBoxBackgroundColorUpdatesBackground(string colorS checkBox.BackgroundColor = color; - await ValidateHasColor(checkBox, color); + await ValidateHasColor(checkBox, color); } } } \ No newline at end of file diff --git a/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.Android.cs index 85f861d20ed3..4fb332d4c38c 100644 --- a/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.Android.cs @@ -25,8 +25,6 @@ public async Task PushAndPopPageWithCollectionView() modalPage.Content = collectionView; - SetupBuilder(); - await CreateHandlerAndAddToWindow(rootPage, async (_) => { @@ -54,8 +52,6 @@ await CreateHandlerAndAddToWindow(rootPage, [Fact] public async Task NullItemsSourceDisplaysHeaderFooterAndEmptyView() { - SetupBuilder(); - var emptyView = new Label { Text = "Empty" }; var header = new Label { Text = "Header" }; var footer = new Label { Text = "Footer" }; diff --git a/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.Windows.cs index c45a9ad76ada..20c6265d14dc 100644 --- a/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.Windows.cs @@ -15,8 +15,6 @@ public partial class CollectionViewTests [Fact(DisplayName = "CollectionView Disconnects Correctly")] public async Task CollectionViewHandlerDisconnects() { - SetupBuilder(); - ObservableCollection data = new ObservableCollection() { "Item 1", @@ -57,7 +55,6 @@ await CreateHandlerAndAddToWindow(layout, (handler) => [Fact(Skip = "FIX FOR .NET8")] public async Task ValidateItemContainerDefaultHeight() { - SetupBuilder(); ObservableCollection data = new ObservableCollection() { "Item 1", @@ -104,7 +101,6 @@ void ValidateItemContainerStyle(CollectionView collectionView) [Fact] public async Task ValidateSendRemainingItemsThresholdReached() { - SetupBuilder(); ObservableCollection data = new(); for (int i = 0; i < 20; i++) { diff --git a/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.cs b/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.cs index 1b7c85bebd71..3140d6a12a76 100644 --- a/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.cs @@ -19,11 +19,9 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.CollectionView)] public partial class CollectionViewTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(typeof(Toolbar), typeof(ToolbarHandler)); handlers.AddHandler(typeof(NavigationPage), typeof(NavigationViewHandler)); @@ -35,14 +33,10 @@ void SetupBuilder() handlers.AddHandler(); handlers.AddHandler(); }); - }); - } [Fact] public async Task ItemsSourceDoesNotLeak() { - SetupBuilder(); - IList logicalChildren = null; WeakReference weakReference = null; var collectionView = new CollectionView @@ -102,8 +96,6 @@ public async Task CollectionViewCanSizeToContent(CollectionViewSizingTestCase te double tolerance = 1; - SetupBuilder(); - var collectionView = new CollectionView { ItemsLayout = itemsLayout, @@ -178,8 +170,6 @@ await CreateHandlerAndAddToWindow(layout, async handler => [InlineData(false, true, true)] public async Task CollectionViewStructuralItems(bool hasHeader, bool hasFooter, bool hasData) { - SetupBuilder(); - double containerHeight = 500; double containerWidth = 500; var layout = new Grid() { IgnoreSafeArea = true, HeightRequest = containerHeight, WidthRequest = containerWidth }; diff --git a/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.iOS.cs index 932f0bdd9bfc..1290587520e9 100644 --- a/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/CollectionView/CollectionViewTests.iOS.cs @@ -18,8 +18,6 @@ public partial class CollectionViewTests [Fact] public async Task ItemsSourceGroupedClearDoestCrash() { - SetupBuilder(); - var data = new List { "test 1", "test 2", "test 3" }; var groupData = new ObservableCollection { @@ -55,8 +53,6 @@ public CollectionViewStringGroup(string header, IEnumerable data) : base [Fact] public async Task CollectionViewContentRespectsMargin() { - SetupBuilder(); - // We'll use an EmptyView to assess whether the CollectionView's content // is being properly offset by the margin var emptyView = new VerticalStackLayout(); @@ -94,8 +90,6 @@ await CreateHandlerAndAddToWindow(collectionView, async h [Fact("Cells Do Not Leak")] public async Task CellsDoNotLeak() { - SetupBuilder(); - var labels = new List(); VerticalCell cell = null; diff --git a/src/Controls/tests/DeviceTests/Elements/Compatibility/VisualElementRendererTests.cs b/src/Controls/tests/DeviceTests/Elements/Compatibility/VisualElementRendererTests.cs index 1d6e91b2aa14..b6ee8ba1773a 100644 --- a/src/Controls/tests/DeviceTests/Elements/Compatibility/VisualElementRendererTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Compatibility/VisualElementRendererTests.cs @@ -12,6 +12,22 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Compatibility)] public partial class VisualElementRendererTests : ControlsHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder).ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(); + }); + + [Fact] + public async Task CompatibilityRendererWorksWithNoInnerContrlSpecified() + { + var renderer = await InvokeOnMainThreadAsync(() => new LegacyComponent().ToPlatform(MauiContext)); + + await InvokeOnMainThreadAsync(() => Assert.Equal(renderer, (renderer as IPlatformViewHandler).PlatformView)); + + Assert.NotNull(renderer); + } + class LegacyComponent : View { @@ -26,33 +42,10 @@ class LegacyComponentRenderer : VisualElementRenderer #if ANDROID public LegacyComponentRenderer(Android.Content.Context context) : base(context) { - + } #endif } - - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - }); - }); - } - - [Fact] - public async Task CompatibilityRendererWorksWithNoInnerContrlSpecified() - { - SetupBuilder(); - - var renderer = await InvokeOnMainThreadAsync(() => new LegacyComponent().ToPlatform(MauiContext)); - - await InvokeOnMainThreadAsync(() => Assert.Equal(renderer, (renderer as IPlatformViewHandler).PlatformView)); - - Assert.NotNull(renderer); - } } } \ No newline at end of file diff --git a/src/Controls/tests/DeviceTests/Elements/ContentView/ContentViewTests.cs b/src/Controls/tests/DeviceTests/Elements/ContentView/ContentViewTests.cs index 258939f5580b..623ddb3b7b5c 100644 --- a/src/Controls/tests/DeviceTests/Elements/ContentView/ContentViewTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/ContentView/ContentViewTests.cs @@ -11,23 +11,18 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.ContentView)] public partial class ContentViewTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); }); - }); - } [Fact("ContentView updating it's ControlTemplate works")] public async Task ControlTemplateUpdates() { - SetupBuilder(); var child = new Label { Text = "Content 1" }; var contentView = new Microsoft.Maui.Controls.ContentView(); var header = new Label { Text = "Header" }; @@ -55,8 +50,6 @@ await InvokeOnMainThreadAsync(() => [Fact] public async Task PropagateContextCorrectly() { - SetupBuilder(); - var bindingContext = new object(); var child = new Label { Text = "Content 1" }; diff --git a/src/Controls/tests/DeviceTests/Elements/ContextFlyout/ContextFlyoutTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/ContextFlyout/ContextFlyoutTests.Windows.cs index 4bb311e94a9c..0e5dce2ade31 100644 --- a/src/Controls/tests/DeviceTests/Elements/ContextFlyout/ContextFlyoutTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/ContextFlyout/ContextFlyoutTests.Windows.cs @@ -13,7 +13,6 @@ public partial class ContextFlyoutTests : ControlsHandlerTestBase [Fact(DisplayName = "Context flyout creates expected WinUI elements")] public async Task ContextFlyoutCreatesExpectedWinUIElements() { - SetupBuilder(); var toolbarItem = new ToolbarItem() { Text = "Toolbar Item 1" }; var firstPage = new ContentPage(); diff --git a/src/Controls/tests/DeviceTests/Elements/ContextFlyout/ContextFlyoutTests.cs b/src/Controls/tests/DeviceTests/Elements/ContextFlyout/ContextFlyoutTests.cs index 9e07c74b7824..8bef4b9d5f45 100644 --- a/src/Controls/tests/DeviceTests/Elements/ContextFlyout/ContextFlyoutTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/ContextFlyout/ContextFlyoutTests.cs @@ -15,15 +15,12 @@ namespace Microsoft.Maui.DeviceTests { - [Category(TestCategory.MenuFlyout)] public partial class ContextFlyoutTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(); handlers.AddHandler(); @@ -34,7 +31,5 @@ void SetupBuilder() handlers.AddHandler(); handlers.AddHandler(); }); - }); - } } } diff --git a/src/Controls/tests/DeviceTests/Elements/Editor/EditorTests.cs b/src/Controls/tests/DeviceTests/Elements/Editor/EditorTests.cs index b7873693d14d..43117cad4b5b 100644 --- a/src/Controls/tests/DeviceTests/Elements/Editor/EditorTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Editor/EditorTests.cs @@ -10,22 +10,23 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Editor)] public partial class EditorTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - }); - }); - } - + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); + +#if !IOS && !MACCATALYST + // iOS is broken until this point + // https://github.com/dotnet/maui/issues/3425 [Theory] [InlineData(EditorAutoSizeOption.Disabled)] [InlineData(EditorAutoSizeOption.TextChanges)] public async Task AutoSizeInitializesCorrectly(EditorAutoSizeOption option) { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + var editor = new Editor { AutoSize = option, @@ -60,6 +61,7 @@ await CreateHandlerAndAddToWindow(layout, async (_) => Assert.Equal(initialHeight, editor.Height); }); } +#endif static async Task WaitForUIUpdate(Graphics.Rect frame, Editor collectionView, int timeout = 1000, int interval = 100) { diff --git a/src/Controls/tests/DeviceTests/Elements/Entry/EntryTests.cs b/src/Controls/tests/DeviceTests/Elements/Entry/EntryTests.cs index 89704bd6b915..9c696a9c2f06 100644 --- a/src/Controls/tests/DeviceTests/Elements/Entry/EntryTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Entry/EntryTests.cs @@ -12,16 +12,10 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Entry)] public partial class EntryTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - }); - }); - } + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); [Fact] public async Task MaxLengthTrims() diff --git a/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.Windows.cs index c2a56e2e7a30..dba49d2e1c0a 100644 --- a/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.Windows.cs @@ -26,7 +26,6 @@ public partial class FlyoutPageTests : ControlsHandlerTestBase [ClassData(typeof(FlyoutPageLayoutBehaviorTestCases))] public async Task FlyoutPageInitializesWithFlyoutCustomContentSet(Type flyoutPageType) { - SetupBuilder(); var flyoutPage = CreateBasicFlyoutPage(flyoutPageType); await CreateHandlerAndAddToWindow(flyoutPage, (handler) => @@ -42,7 +41,6 @@ await CreateHandlerAndAddToWindow(flyoutPage, (handler) => [ClassData(typeof(FlyoutPageLayoutBehaviorTestCases))] public async Task FlyoutPageInitializesWithHeaderSet(Type flyoutPageType) { - SetupBuilder(); var flyoutPage = CreateBasicFlyoutPage(flyoutPageType); await CreateHandlerAndAddToWindow(new Window(flyoutPage), (handler) => @@ -57,7 +55,6 @@ await CreateHandlerAndAddToWindow(new Window(flyoutPage), (ha [ClassData(typeof(FlyoutPageLayoutBehaviorTestCases))] public async Task FlyoutLockedOffset(Type flyoutPageType) { - SetupBuilder(); var flyout = CreateBasicFlyoutPage(flyoutPageType); await CreateHandlerAndAddToWindow(flyout, (handler) => { @@ -72,7 +69,6 @@ await CreateHandlerAndAddToWindow(flyout, (handler) => [ClassData(typeof(FlyoutPageLayoutBehaviorTestCases))] public async Task FlyoutLockedOffsetFromAppTitleBarWithPushedPage(Type flyoutPageType) { - SetupBuilder(); var flyout = CreateBasicFlyoutPage(flyoutPageType); await CreateHandlerAndAddToWindow(flyout, async (handler) => { diff --git a/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.cs b/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.cs index 333d52f96ca1..08f70d066b64 100644 --- a/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.cs @@ -25,11 +25,9 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.FlyoutPage)] public partial class FlyoutPageTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(typeof(Controls.Label), typeof(LabelHandler)); handlers.AddHandler(typeof(Controls.Toolbar), typeof(ToolbarHandler)); @@ -43,14 +41,11 @@ void SetupBuilder() handlers.AddHandler(); handlers.AddHandler(); }); - }); - } [Theory] [ClassData(typeof(FlyoutPageLayoutBehaviorTestCases))] public async Task PoppingFlyoutPageDoesntCrash(Type flyoutPageType) { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage()) { Title = "App Page" }; await CreateHandlerAndAddToWindow(new Window(navPage), async (handler) => @@ -69,8 +64,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [ClassData(typeof(FlyoutPageLayoutBehaviorTestCases))] public async Task SwappingDetailPageWorksForSplitFlyoutBehavior(Type flyoutPageType) { - SetupBuilder(); - var flyoutPage = CreateFlyoutPage( flyoutPageType, new NavigationPage(new ContentPage() { Content = new Frame(), Title = "Detail" }), @@ -96,8 +89,6 @@ await CreateHandlerAndAddToWindow(new Window(flyoutPage), asy [ClassData(typeof(FlyoutPageLayoutBehaviorTestCases))] public async Task FlyoutPageWithToolbar(Type flyoutPageType) { - SetupBuilder(); - var flyoutPage = CreateFlyoutPage( flyoutPageType, @@ -116,8 +107,6 @@ await CreateHandlerAndAddToWindow(flyoutPage, (handler) => [ClassData(typeof(FlyoutPageLayoutBehaviorTestCases))] public async Task DetailsViewUpdatesWithNavigationPage(Type flyoutPageType) { - SetupBuilder(); - var flyoutPage = CreateFlyoutPage( flyoutPageType, @@ -139,7 +128,6 @@ await CreateHandlerAndAddToWindow(flyoutPage, async (handler) [ClassData(typeof(FlyoutPageLayoutBehaviorTestCases))] public async Task DetailsViewUpdates(Type flyoutPageType) { - SetupBuilder(); var flyoutPage = CreateFlyoutPage( flyoutPageType, @@ -177,7 +165,6 @@ FlyoutPage CreateFlyoutPage(Type type, Page detail, Page flyout) [InlineData(true)] public async Task DetailsPageMeasuresCorrectlyInSplitMode(bool isRtl) { - SetupBuilder(); var flyoutLabel = new Label() { Text = "Content" }; var flyoutPage = await InvokeOnMainThreadAsync(() => new FlyoutPage() { diff --git a/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.iOS.cs index 9c601bde6524..090318763866 100644 --- a/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/FlyoutPage/FlyoutPageTests.iOS.cs @@ -30,7 +30,6 @@ public partial class FlyoutPageTests [Fact(DisplayName = "Flyout Page Takes Into Account Safe Area by Default")] public async Task FlyoutPageTakesIntoAccountSafeAreaByDefault() { - SetupBuilder(); var flyoutLabel = new Label() { Text = "Content" }; var flyoutPage = await InvokeOnMainThreadAsync(() => new FlyoutPage() { @@ -62,7 +61,6 @@ await CreateHandlerAndAddToWindow(flyoutPage, async (ha [InlineData(true)] public async Task DetailsViewPopOverLayoutIsCorrectForIdiom(bool isRtl) { - SetupBuilder(); var flyoutLabel = new Label() { Text = "Content" }; var flyoutPage = await InvokeOnMainThreadAsync(() => new FlyoutPage() { diff --git a/src/Controls/tests/DeviceTests/Elements/Frame/FrameHandlerTest.Android.cs b/src/Controls/tests/DeviceTests/Elements/Frame/FrameHandlerTest.Android.cs index 0b754454b489..b81f0abe89e5 100644 --- a/src/Controls/tests/DeviceTests/Elements/Frame/FrameHandlerTest.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/Frame/FrameHandlerTest.Android.cs @@ -20,7 +20,7 @@ public override async Task ReturnsNonEmptyNativeBoundingBox(int size) WidthRequest = size }; - var nativeBoundingBox = await GetValueAsync(view, handler => GetBoundingBox(handler)); + var nativeBoundingBox = await GetValueAsync(view, GetBoundingBox); Assert.NotEqual(nativeBoundingBox, Graphics.Rect.Zero); AssertWithinTolerance(expectedBounds.Size, nativeBoundingBox.Size); diff --git a/src/Controls/tests/DeviceTests/Elements/Frame/FrameHandlerTest.cs b/src/Controls/tests/DeviceTests/Elements/Frame/FrameHandlerTest.cs index db2f32b18406..5abf9318bcad 100644 --- a/src/Controls/tests/DeviceTests/Elements/Frame/FrameHandlerTest.cs +++ b/src/Controls/tests/DeviceTests/Elements/Frame/FrameHandlerTest.cs @@ -1,12 +1,22 @@ #if WINDOWS || ANDROID using Microsoft.Maui.Controls.Handlers.Compatibility; using Microsoft.Maui.DeviceTests.Stubs; +using Microsoft.Maui.Controls; +using Microsoft.Maui.Hosting; namespace Microsoft.Maui.DeviceTests { [Category(TestCategory.Frame)] public partial class FrameHandlerTest : HandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(); + handlers.AddHandler(); + }); + public FrameHandlerTest() { diff --git a/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.Android.cs index 60e13ac9ae63..9442aca37c14 100644 --- a/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.Android.cs @@ -18,8 +18,6 @@ public partial class FrameTests [Fact(DisplayName = "Update Frame Content Test")] public async Task UpdateFrameContentTest() { - SetupBuilder(); - var layout = new StackLayout(); var frame = new Frame() @@ -70,8 +68,6 @@ await frame.ToPlatform(MauiContext).AttachAndRun(() => [Fact] public async Task FrameContentAccountsForBorderThickness() { - SetupBuilder(); - double contentSize = 50; var innerFrame = new Frame() { diff --git a/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.cs b/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.cs index c5590108fea2..badf7618eccf 100644 --- a/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.cs @@ -18,11 +18,9 @@ public partial class FrameTests : ControlsHandlerTestBase // This a hard-coded legacy value const int FrameBorderThickness = 1; - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(); handlers.AddHandler(); @@ -31,14 +29,10 @@ void SetupBuilder() handlers.AddHandler(); handlers.AddHandler(); }); - }); - } [Fact(DisplayName = "Basic Frame Test")] public async Task BasicFrameTest() { - SetupBuilder(); - var frame = new Frame() { HeightRequest = 300, @@ -71,8 +65,6 @@ await AttachAndRun(frame, async (handler) => [Fact(DisplayName = "Frame With Entry Measures")] public async Task FrameWithEntryMeasuresCorrectly() { - SetupBuilder(); - var entry = new Entry() { Text = "Hello Frame" @@ -110,8 +102,6 @@ public async Task FrameWithEntryMeasuresCorrectly() [InlineData("#000000")] public async Task FrameBackgroundColorInitializesCorrectly(string colorHex) { - SetupBuilder(); - var expectedColor = Graphics.Color.FromArgb(colorHex); var frame = new Frame() @@ -141,8 +131,6 @@ await InvokeOnMainThreadAsync(() => [InlineData("#000000")] public async Task FrameBorderColorInitializesCorrectly(string colorHex) { - SetupBuilder(); - var expectedColor = Graphics.Color.FromArgb(colorHex); var frame = new Frame() @@ -168,8 +156,6 @@ await InvokeOnMainThreadAsync(() => [Fact(DisplayName = "Frame Respects minimum height/width")] public async Task FrameRespectsMinimums() { - SetupBuilder(); - var content = new Button { Text = "Hey", WidthRequest = 50, HeightRequest = 50 }; var frame = new Frame() @@ -198,8 +184,6 @@ public async Task FrameRespectsMinimums() [Fact] public async Task FrameDoesNotInterpretConstraintsAsMinimums() { - SetupBuilder(); - var content = new Button { Text = "Hey", WidthRequest = 50, HeightRequest = 50 }; var frame = new Frame() @@ -228,8 +212,6 @@ public async Task FrameDoesNotInterpretConstraintsAsMinimums() [Fact] public async Task FrameIncludesBorderThickness() { - SetupBuilder(); - double contentSize = 50; var content = new Label { Text = "Hey", WidthRequest = contentSize, HeightRequest = contentSize }; @@ -266,8 +248,6 @@ public async Task FrameIncludesBorderThickness() [Fact] public async Task FrameIncludesPadding() { - SetupBuilder(); - double contentSize = 50; var content = new Label { Text = "Hey", WidthRequest = contentSize, HeightRequest = contentSize }; var padding = 10; @@ -306,8 +286,6 @@ public async Task FrameIncludesPadding() [Fact] public async Task FrameResizesItsContents() { - SetupBuilder(); - var originalLayoutDimensions = 300; var shrunkWindowWidth = originalLayoutDimensions - 100; @@ -367,8 +345,6 @@ await CreateHandlerAndAddToWindow(layout, async (handler) [InlineData(double.PositiveInfinity, 500)] public async Task FramesWithinFrames(double widthConstraint, double heightConstraint) { - SetupBuilder(); - var frameMargin = 30; var middleFrameMarginWidth = 0; var middleFrameMarginHeight = 0; diff --git a/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.iOS.cs index 96976c61a850..054ae75e3e01 100644 --- a/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/Frame/FrameTests.iOS.cs @@ -11,8 +11,6 @@ public partial class FrameTests [Fact(DisplayName = "Frame HasShadow Test")] public async Task FrameHasShadowTest() { - SetupBuilder(); - var frame = new Frame() { HasShadow = true, @@ -54,8 +52,6 @@ await InvokeOnMainThreadAsync(() => [InlineData(null)] public async Task FrameClipsCorrectly(bool? isClipped) { - SetupBuilder(); - var frame = new Frame() { HeightRequest = 300, diff --git a/src/Controls/tests/DeviceTests/Elements/Image/ImageTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/Image/ImageTests.Android.cs index d7e98d037434..fa12636e2671 100644 --- a/src/Controls/tests/DeviceTests/Elements/Image/ImageTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/Image/ImageTests.Android.cs @@ -43,7 +43,6 @@ await InvokeOnMainThreadAsync(async () => [Fact] public async Task ImageSetFromStreamRenders() { - SetupBuilder(); var layout = new VerticalStackLayout(); using var stream = GetType().Assembly.GetManifestResourceStream("red-embedded.png"); diff --git a/src/Controls/tests/DeviceTests/Elements/Image/ImageTests.cs b/src/Controls/tests/DeviceTests/Elements/Image/ImageTests.cs index 644e21562474..e52488b5d0dc 100644 --- a/src/Controls/tests/DeviceTests/Elements/Image/ImageTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Image/ImageTests.cs @@ -15,21 +15,16 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Image)] public partial class ImageTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(); }); - }); - } [Fact] public async Task ImageWithUndefinedSizeAndWithBackgroundSetRenders() { - SetupBuilder(); var layout = new VerticalStackLayout(); var image = new Image @@ -53,7 +48,6 @@ await InvokeOnMainThreadAsync(async () => [Fact("Image Does Not Leak")] public async Task DoesNotLeak() { - SetupBuilder(); WeakReference platformViewReference = null; WeakReference handlerReference = null; diff --git a/src/Controls/tests/DeviceTests/Elements/Label/LabelTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/Label/LabelTests.Android.cs index 2fae65ce8fdb..493146bfa934 100644 --- a/src/Controls/tests/DeviceTests/Elements/Label/LabelTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/Label/LabelTests.Android.cs @@ -35,7 +35,7 @@ public async Task FormattedStringSpanTextHasCorrectColorWhenChanges() formattedLabel.TextColor = expected; - await ValidateHasColor(formattedLabel, expected); + await ValidateHasColor(formattedLabel, expected); } [Fact(DisplayName = "Html Text Initializes Correctly")] diff --git a/src/Controls/tests/DeviceTests/Elements/Label/LabelTests.cs b/src/Controls/tests/DeviceTests/Elements/Label/LabelTests.cs index ceb267150b7a..d443473afe70 100644 --- a/src/Controls/tests/DeviceTests/Elements/Label/LabelTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Label/LabelTests.cs @@ -15,17 +15,10 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Label)] public partial class LabelTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - handlers.AddHandler(); - }); - }); - } + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); [Theory] [ClassData(typeof(TextTransformCases))] @@ -245,7 +238,9 @@ public async Task NegativeMaxValueWithWrapIsCorrect(int expectedLines) [Fact] public async Task ChangingTextTypeWithFormattedTextSwitchesTextSource() { - SetupBuilder(); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); Label label; var layout = new VerticalStackLayout @@ -474,13 +469,8 @@ await InvokeOnMainThreadAsync(() => public async Task LabelTruncatesCorrectly(TextAlignment textAlignment, LineBreakMode lineBreakMode) { EnsureHandlerCreated(builder => - { builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - handlers.AddHandler(); - }); - }); + handlers.AddHandler())); var labelStart = new Label { diff --git a/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.Android.cs index a2e27f1cd6d6..edb65229751b 100644 --- a/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.Android.cs @@ -22,15 +22,11 @@ public partial class LayoutTests public async Task NestedButtonHasExpectedIconPosition(Button.ButtonContentLayout.ImagePosition imagePosition) { EnsureHandlerCreated(builder => - { builder.ConfigureMauiHandlers(handlers => { handlers.AddHandler(); handlers.AddHandler(); - handlers.AddHandler(); - handlers.AddHandler(); - }); - }); + })); var button = new Button() { diff --git a/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.cs b/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.cs index 2ddee80e377a..95e74a57e649 100644 --- a/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.cs @@ -13,20 +13,20 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Layout)] public partial class LayoutTests : ControlsHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + }); + [Theory] [InlineData(true)] [InlineData(false)] public async Task InputTransparentCorrectlyAppliedToPlatformView(bool inputTransparent) { - EnsureHandlerCreated((builder) => - { - builder.ConfigureMauiHandlers(handler => - { - handler.AddHandler(typeof(Button), typeof(ButtonHandler)); - handler.AddHandler(typeof(Layout), typeof(LayoutHandler)); - }); - }); - var control = new Grid() { InputTransparent = inputTransparent, CascadeInputTransparent = false }; var child = new Button(); control.Add(child); @@ -42,15 +42,6 @@ await InvokeOnMainThreadAsync(() => [InlineData(false)] public async Task InputTransparentUpdatesCorrectlyOnPlatformView(bool finalInputTransparent) { - EnsureHandlerCreated((builder) => - { - builder.ConfigureMauiHandlers(handler => - { - handler.AddHandler(typeof(Button), typeof(ButtonHandler)); - handler.AddHandler(typeof(Layout), typeof(LayoutHandler)); - }); - }); - var control = new Grid() { InputTransparent = !finalInputTransparent, CascadeInputTransparent = false }; var child = new Button(); control.Add(child); diff --git a/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.iOS.cs index 0069df6c74d7..348172f950da 100644 --- a/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.iOS.cs @@ -187,14 +187,8 @@ async Task WaitForLayout(UIView view, CGRect initialFrame, int timeout) public async Task NestedLayoutsInRTLRemainOnScreen() { EnsureHandlerCreated((builder) => - { builder.ConfigureMauiHandlers(handler => - { - handler.AddHandler(typeof(Button), typeof(ButtonHandler)); - handler.AddHandler(typeof(Layout), typeof(LayoutHandler)); - handler.AddHandler(typeof(Controls.ContentView), typeof(ContentViewHandler)); - }); - }); + handler.AddHandler(typeof(Controls.ContentView), typeof(ContentViewHandler)))); var level0 = new Controls.ContentView() { FlowDirection = FlowDirection.RightToLeft }; var level1 = new Grid() { HorizontalOptions = LayoutOptions.End, WidthRequest = 200 }; diff --git a/src/Controls/tests/DeviceTests/Elements/ListView/ListViewTests.cs b/src/Controls/tests/DeviceTests/Elements/ListView/ListViewTests.cs index ffb9f825f0e5..928d82d24834 100644 --- a/src/Controls/tests/DeviceTests/Elements/ListView/ListViewTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/ListView/ListViewTests.cs @@ -16,11 +16,9 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.ListView)] public partial class ListViewTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(); handlers.AddHandler(); @@ -29,13 +27,10 @@ void SetupBuilder() handlers.AddHandler(); handlers.AddHandler(); }); - }); - } [Fact] public async Task RemovingFirstItemOfListViewDoesntCrash() { - SetupBuilder(); ObservableCollection data = new ObservableCollection() { "cat", @@ -83,7 +78,6 @@ await CreateHandlerAndAddToWindow(layout, async (handler) => [Fact(DisplayName = "ReAssigning ListView in VSL Crashes")] public async Task ReAssigninListViewInVSLCrashes() { - SetupBuilder(); var listView = new ListView() { ItemTemplate = new DataTemplate(() => @@ -120,7 +114,6 @@ await CreateHandlerAndAddToWindow(layout, async (handler) => [Fact] public async Task EntryCellBindingCorrectlyUpdates() { - SetupBuilder(); var vm = new EntryCellBindingCorrectlyUpdatesVM(); var data = new[] { @@ -176,7 +169,6 @@ public void ChangeValue() [Fact] public async Task ClearItemsListViewDoesntCrash() { - SetupBuilder(); ObservableCollection data = new ObservableCollection() { "cat", @@ -221,7 +213,6 @@ await CreateHandlerAndAddToWindow(layout, async (handler) => ] public async Task NullTemplateDoesntCrash() { - SetupBuilder(); ObservableCollection data = new ObservableCollection() { "cat", diff --git a/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.Android.cs index 18f389332c83..64737af28f8d 100644 --- a/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.Android.cs @@ -15,7 +15,6 @@ public partial class ModalTests : ControlsHandlerTestBase [Fact] public async Task ChangeModalStackWhileDeactivated() { - SetupBuilder(); var page = new ContentPage(); var modalPage = new ContentPage() { @@ -43,7 +42,6 @@ await CreateHandlerAndAddToWindow(window, [Fact] public async Task DontPushModalPagesWhenWindowIsDeactivated() { - SetupBuilder(); var page = new ContentPage(); var modalPage = new ContentPage() { @@ -69,8 +67,6 @@ await CreateHandlerAndAddToWindow(window, [InlineData(WindowSoftInputModeAdjust.Pan)] public async Task ModalPageMarginCorrectAfterKeyboardOpens(WindowSoftInputModeAdjust panSize) { - SetupBuilder(); - var navPage = new NavigationPage(new ContentPage()); var window = new Window(navPage); await CreateHandlerAndAddToWindow(window, diff --git a/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.Windows.cs index 73d327797156..a5c34a3b34ab 100644 --- a/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.Windows.cs @@ -19,8 +19,6 @@ public partial class ModalTests : ControlsHandlerTestBase [InlineData(false)] public async Task PushingPageWithBackgroundStacksAndUnStacksCorrectly(bool useColor) { - SetupBuilder(); - var navPage = new NavigationPage(new ContentPage() { Content = new Label() { Text = "Root Page" } }); await CreateHandlerAndAddToWindow(new Window(navPage), @@ -57,8 +55,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), [Fact] public async Task WindowTitleSetToModalTitleContainer() { - SetupBuilder(); - var navPage = new NavigationPage(new ContentPage()); var window = new Window(navPage) { Title = "Original Title" }; @@ -92,8 +88,6 @@ public async Task WindowTitleIsCorrectAfterPushAndPop() const string OriginalTitle = "Original Title"; const string UpdatedTitle = "Updated Title"; - SetupBuilder(); - var navPage = new NavigationPage(new ContentPage()); var window = new Window(navPage) { Title = OriginalTitle }; diff --git a/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.cs b/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.cs index b74ffd24f80d..bdae751fe5ef 100644 --- a/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.cs @@ -30,28 +30,23 @@ namespace Microsoft.Maui.DeviceTests #endif public partial class ModalTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(typeof(NavigationPage), typeof(NavigationViewHandler)); handlers.AddHandler(typeof(FlyoutPage), typeof(FlyoutViewHandler)); handlers.AddHandler(typeof(TabbedPage), typeof(TabbedViewHandler)); handlers.AddHandler(); handlers.AddHandler(); - SetupShellHandlers(handlers); + handlers.SetupShellHandlers(); }); - }); - } [Theory] [InlineData(true)] [InlineData(false)] public async Task AppearingAndDisappearingFireOnWindowAndModal(bool useShell) { - SetupBuilder(); var windowPage = new ContentPage() { Content = new Label() { Text = "AppearingAndDisappearingFireOnWindowAndModal.Window" } @@ -101,7 +96,6 @@ await CreateHandlerAndAddToWindow(window, [InlineData(false)] public async Task AppearingAndDisappearingFireOnMultipleModals(bool useShell) { - SetupBuilder(); var windowPage = new ContentPage() { Content = new Label() { Text = "AppearingAndDisappearingFireOnWindowAndModal.Window" } @@ -162,7 +156,6 @@ await CreateHandlerAndAddToWindow(window, [Fact] public async Task PushingNavigationPageModallyWithShellShowsToolbarCorrectly() { - SetupBuilder(); var windowPage = new LifeCycleTrackingPage() { Title = "Window Page Title" @@ -208,7 +201,6 @@ await CreateHandlerAndAddToWindow(window, [InlineData(false)] public async Task LifeCycleEventsFireOnModalPagesPushedBeforeWindowHasLoaded(bool useShell) { - SetupBuilder(); var windowPage = new LifeCycleTrackingPage(); var modalPage = new LifeCycleTrackingPage() { @@ -242,7 +234,6 @@ await CreateHandlerAndAddToWindow(window, [InlineData(false)] public async Task PushModalFromAppearing(bool useShell) { - SetupBuilder(); var windowPage = new ContentPage() { Content = new Label() @@ -313,7 +304,6 @@ await windowPage.Navigation.PushModalAsync(new ContentPage() [InlineData(false)] public async Task PushModalModalWithoutAwaiting(bool useShell) { - SetupBuilder(); var windowPage = new LifeCycleTrackingPage(); var modalPage = new LifeCycleTrackingPage() { @@ -358,7 +348,6 @@ await CreateHandlerAndAddToWindow(window, [Fact] public async Task LoadModalPagesBeforeWindowHasLoaded() { - SetupBuilder(); var page = new ContentPage(); var modalPage = new ContentPage() { @@ -382,7 +371,6 @@ await CreateHandlerAndAddToWindow(window, [Fact] public async Task SwapWindowPageDuringModalAppearing() { - SetupBuilder(); var page = new ContentPage(); var newRootPage = new ContentPage() { @@ -411,7 +399,6 @@ await CreateHandlerAndAddToWindow(window, [Fact] public async Task ChangePageOnWindowRemovesModalStack() { - SetupBuilder(); var page = new ContentPage() { Content = new Label() @@ -448,8 +435,6 @@ await CreateHandlerAndAddToWindow(window, [Fact] public async Task RecreatingStackCorrectlyRecreatesModalStack() { - SetupBuilder(); - var page = new ContentPage(); var modalPage = new ContentPage() { @@ -484,8 +469,6 @@ await CreateHandlerAndAddToWindow(window, async (handler) => [ClassData(typeof(PageTypes))] public async Task SwappingRootPageWhileModalPageIsOpenDoesntCrash(Page rootPage, Page newRootPage) { - SetupBuilder(); - await CreateHandlerAndAddToWindow(rootPage, async (_) => { @@ -501,7 +484,6 @@ await CreateHandlerAndAddToWindow(rootPage, [ClassData(typeof(PageTypes))] public async Task BasicPushAndPop(Page rootPage, Page modalPage) { - SetupBuilder(); await CreateHandlerAndAddToWindow(rootPage, async (_) => diff --git a/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.iOS.cs index ea1f92154cfe..4cd5147824a6 100644 --- a/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/Modal/ModalTests.iOS.cs @@ -14,8 +14,6 @@ public partial class ModalTests : ControlsHandlerTestBase [ClassData(typeof(PageTypes))] public async Task PushModalUsingTransparencies(Page rootPage, Page modalPage) { - SetupBuilder(); - var expected = Colors.Red; rootPage.BackgroundColor = expected; diff --git a/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.Android.cs index c216ebe20bec..e32b594ba502 100644 --- a/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.Android.cs @@ -22,7 +22,6 @@ public partial class NavigationPageTests : ControlsHandlerTestBase [Fact(DisplayName = "Pushing And Popping Doesnt Fire BackButtonVisible Toolbar Events")] public async Task PushingAndPoppingDoesntFireBackButtonVisibleToolbarEvents() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage() { Title = "Page Title" diff --git a/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.Windows.cs index e62c59598717..bf96e4c4b91e 100644 --- a/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.Windows.cs @@ -24,7 +24,6 @@ public partial class NavigationPageTests : ControlsHandlerTestBase [Fact(DisplayName = "Back Button Enabled Changes with push/pop")] public async Task BackButtonEnabledChangesWithPushPop() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage()); await CreateHandlerAndAddToWindow(navPage, async (handler) => @@ -41,7 +40,6 @@ await CreateHandlerAndAddToWindow(navPage, async (handler [Fact(DisplayName = "App Title Bar Margin Sets when Back Button Visible")] public async Task AppTitleBarMarginSetsWhenBackButtonVisible() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage()); await CreateHandlerAndAddToWindow(navPage, async (handler) => diff --git a/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.cs b/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.cs index 1cf7938164c7..d917b0ca707a 100644 --- a/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.cs @@ -17,11 +17,9 @@ namespace Microsoft.Maui.DeviceTests [Collection(ControlsHandlerTestBase.RunInNewWindowCollection)] public partial class NavigationPageTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(typeof(Toolbar), typeof(ToolbarHandler)); #if IOS || MACCATALYST @@ -40,13 +38,10 @@ void SetupBuilder() handlers.AddHandler(typeof(Controls.ContentView), typeof(ContentViewHandler)); handlers.AddHandler(typeof(ScrollView), typeof(ScrollViewHandler)); }); - }); - } [Fact] public async Task PoppingNavigationPageDoesntCrash() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage()) { Title = "App Page" }; await CreateHandlerAndAddToWindow(new Window(navPage), async (handler) => @@ -59,7 +54,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact] public async Task InitialPageFiresNavigatedEvent() { - SetupBuilder(); var page = new ContentPage(); var navPage = new NavigationPage(page) { Title = "App Page" }; @@ -73,8 +67,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact] public async Task PushedPageFiresNavigatedEventOnInitialLoad() { - SetupBuilder(); - bool pageFiredNavigated = false; var page = new ContentPage(); page.NavigatedTo += (_, _) => pageFiredNavigated = true; @@ -98,7 +90,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "Swapping Navigation Toggles BackButton Correctly")] public async Task SwappingNavigationTogglesBackButtonCorrectly() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage()); await CreateHandlerAndAddToWindow(new Window(navPage), async (handler) => @@ -136,7 +127,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "Back Button Visibility Changes with push/pop")] public async Task BackButtonVisibilityChangesWithPushPop() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage()); await CreateHandlerAndAddToWindow(new Window(navPage), async (handler) => @@ -152,7 +142,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "Set Has Back Button")] public async Task SetHasBackButton() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage()); await CreateHandlerAndAddToWindow(new Window(navPage), async (handler) => @@ -169,7 +158,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "Set Has Navigation Bar")] public async Task SetHasNavigationBar() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage() { Title = "Nav Bar" }); await CreateHandlerAndAddToWindow(new Window(navPage), async (handler) => @@ -185,7 +173,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "NavigationBar Removes When MainPage Set To ContentPage")] public async Task NavigationBarRemovesWhenMainPageSetToContentPage() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage()); var window = new Window(navPage); @@ -201,7 +188,6 @@ await CreateHandlerAndAddToWindow(window, async (handler) => [Fact(DisplayName = "Insert Page Before Root Page and then PopToRoot")] public async Task InsertPageBeforeRootPageAndThenPopToRoot() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage() { Title = "Page Title" @@ -221,7 +207,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "Insert Page Before RootPage ShowsBackButton")] public async Task InsertPageBeforeRootPageShowsBackButton() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage() { Title = "Page Title" @@ -243,7 +228,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "Remove Root Page Hides Back Button")] public async Task RemoveRootPageHidesBackButton() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage() { Title = "Page Title" @@ -265,7 +249,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "Pushing a Tabbed Page Doesn't Throw Exception")] public async Task PushingATabbedPageDoesntThrowException() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage() { Title = "Page Title" @@ -297,13 +280,11 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "NavigationPage Does Not Leak")] public async Task DoesNotLeak() { - #if ANDROID if (!OperatingSystem.IsAndroidVersionAtLeast(30)) return; #endif - SetupBuilder(); WeakReference pageReference = null; var navPage = new NavigationPage(new ContentPage { Title = "Page 1" }); @@ -337,7 +318,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async )] public async Task CanReusePages() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage { Title = "Page 1" }); var reusedPage = new ContentPage { diff --git a/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.iOS.cs index eca6b8284954..9e5982e070e6 100644 --- a/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.iOS.cs @@ -20,7 +20,6 @@ public partial class NavigationPageTests : ControlsHandlerTestBase [Fact] public async Task NavigatingBackViaBackButtonFiresNavigatedEvent() { - SetupBuilder(); var page = new ContentPage(); var navPage = new NavigationPage(page) { Title = "App Page" }; @@ -43,7 +42,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [InlineData(false)] public async Task PrefersLargeTitles(bool enabled) { - SetupBuilder(); var page = new ContentPage(); var navPage = new NavigationPage(page) { Title = "App Page" }; Controls.PlatformConfiguration.iOSSpecific.NavigationPage.SetPrefersLargeTitles(navPage, enabled); @@ -57,7 +55,6 @@ public async Task PrefersLargeTitles(bool enabled) [InlineData(false)] public async Task TranslucentNavigationBar(bool enabled) { - SetupBuilder(); var page = new ContentPage(); var navPage = new NavigationPage(page) { Title = "App Page" }; Controls.PlatformConfiguration.iOSSpecific.NavigationPage.SetIsNavigationBarTranslucent(navPage, enabled); diff --git a/src/Controls/tests/DeviceTests/Elements/Page/PageTests.cs b/src/Controls/tests/DeviceTests/Elements/Page/PageTests.cs index 458bb8836fea..ca20e0ee6706 100644 --- a/src/Controls/tests/DeviceTests/Elements/Page/PageTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Page/PageTests.cs @@ -3,6 +3,7 @@ using Microsoft.Maui.Controls; using Microsoft.Maui.Graphics; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests @@ -11,6 +12,11 @@ namespace Microsoft.Maui.DeviceTests [Collection(ControlsHandlerTestBase.RunInNewWindowCollection)] public partial class PageTests : ControlsHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); + [Theory("Page Background Initializes Correctly With Background Property")] [InlineData("#FF0000")] [InlineData("#00FF00")] diff --git a/src/Controls/tests/DeviceTests/Elements/Page/PageTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/Page/PageTests.iOS.cs index 1c71d20140cb..02da3e480d84 100644 --- a/src/Controls/tests/DeviceTests/Elements/Page/PageTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/Page/PageTests.iOS.cs @@ -12,21 +12,12 @@ namespace Microsoft.Maui.DeviceTests { public partial class PageTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => - { - SetupShellHandlers(handlers); - }); - }); - } - [Fact("SafeAreaInset Property is Set")] public async Task SafeAreaInsetIsSet() { - SetupBuilder(); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.SetupShellHandlers())); var page = new ContentPage { Background = Colors.Blue }; diff --git a/src/Controls/tests/DeviceTests/Elements/Path/PathTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/Path/PathTests.Windows.cs index 0fdc44eb76f1..28fd9498ab30 100644 --- a/src/Controls/tests/DeviceTests/Elements/Path/PathTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/Path/PathTests.Windows.cs @@ -6,6 +6,7 @@ using Microsoft.Maui.Graphics.Platform; using Microsoft.Maui.Graphics.Win2D; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Microsoft.Maui.Platform; using Microsoft.UI.Xaml.Automation.Peers; using Microsoft.UI.Xaml.Automation.Provider; @@ -19,7 +20,12 @@ public partial class PathTests [Fact(DisplayName = "Update Path Data Test")] public async Task UpdatePathDataTest() { - SetupBuilder(); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(); + handlers.AddHandler(); + })); var layout = new StackLayout(); diff --git a/src/Controls/tests/DeviceTests/Elements/Path/PathTests.cs b/src/Controls/tests/DeviceTests/Elements/Path/PathTests.cs index 56185bdfd788..8f85263a8425 100644 --- a/src/Controls/tests/DeviceTests/Elements/Path/PathTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Path/PathTests.cs @@ -9,17 +9,9 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Path)] public partial class PathTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - handlers.AddHandler(); - handlers.AddHandler(); - }); - }); - } + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); } } \ No newline at end of file diff --git a/src/Controls/tests/DeviceTests/Elements/Picker/PickerTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/Picker/PickerTests.Android.cs index d7a24e0fe2f1..4be49a2c3ffa 100644 --- a/src/Controls/tests/DeviceTests/Elements/Picker/PickerTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/Picker/PickerTests.Android.cs @@ -9,7 +9,6 @@ namespace Microsoft.Maui.DeviceTests { - [Category(TestCategory.Picker)] public partial class PickerTests : ControlsHandlerTestBase { protected Task GetPlatformControlText(MauiPicker platformView) diff --git a/src/Controls/tests/DeviceTests/Elements/Picker/PickerTests.cs b/src/Controls/tests/DeviceTests/Elements/Picker/PickerTests.cs index 7b00d5ab1ef4..1ced92a35700 100644 --- a/src/Controls/tests/DeviceTests/Elements/Picker/PickerTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Picker/PickerTests.cs @@ -5,6 +5,7 @@ using Microsoft.Maui.Controls; using Microsoft.Maui.Graphics; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Microsoft.Maui.Platform; using Xunit; @@ -13,6 +14,11 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Picker)] public partial class PickerTests : ControlsHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); + [Fact] public async Task ItemsUpdateWithCollectionChanges() { diff --git a/src/Controls/tests/DeviceTests/Elements/RadioButton/RadioButtonTests.cs b/src/Controls/tests/DeviceTests/Elements/RadioButton/RadioButtonTests.cs index 00631e998766..b4cba667aa88 100644 --- a/src/Controls/tests/DeviceTests/Elements/RadioButton/RadioButtonTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/RadioButton/RadioButtonTests.cs @@ -10,6 +10,11 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.RadioButton)] public partial class RadioButtonTests : ControlsHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); + #if WINDOWS [Theory(DisplayName = "IsChecked Initializes Correctly")] [InlineData(false)] @@ -17,13 +22,8 @@ public partial class RadioButtonTests : ControlsHandlerTestBase public async Task IsCheckedInitializesCorrectly(bool isChecked) { EnsureHandlerCreated(builder => - { builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - }); - }); - + handlers.AddHandler())); await InvokeOnMainThreadAsync(async () => { @@ -41,10 +41,10 @@ await InvokeOnMainThreadAsync(async () => layoutSecond.Add(rdSecond); layoutSecond.Add(new RadioButton { GroupName = "SecondGroup" }); var layout = new VerticalStackLayout - { - layoutFirst, - layoutSecond - }; + { + layoutFirst, + layoutSecond + }; var valuesFirst = await GetValueAsync(rdFirst, (handler) => { return new { ViewValue = rdFirst.IsChecked, PlatformViewValue = GetNativeIsChecked(handler as RadioButtonHandler) }; }); var valuesSecond = await GetValueAsync(rdSecond, (handler) => { return new { ViewValue = rdSecond.IsChecked, PlatformViewValue = GetNativeIsChecked(handler as RadioButtonHandler) }; }); Assert.Equal(xplatIsChecked, valuesFirst.ViewValue); diff --git a/src/Controls/tests/DeviceTests/Elements/RefreshView/RefreshViewTests.cs b/src/Controls/tests/DeviceTests/Elements/RefreshView/RefreshViewTests.cs index 6689b3336ba5..82952ba9386e 100644 --- a/src/Controls/tests/DeviceTests/Elements/RefreshView/RefreshViewTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/RefreshView/RefreshViewTests.cs @@ -10,16 +10,10 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.RefreshView)] public partial class RefreshViewTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - }); - }); - } + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); } } diff --git a/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.cs b/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.cs index 1a5f3385cc60..54b0ec1662ca 100644 --- a/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.cs @@ -16,11 +16,20 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.ScrollView)] public partial class ScrollViewTests : ControlsHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); + [Theory] [InlineData(ScrollOrientation.Vertical)] [InlineData(ScrollOrientation.Both)] public async Task TestContentSizeChangedHorizontal(ScrollOrientation orientation) { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + var handler = await SetUpScrollView(orientation); var scroll = handler.VirtualView as ScrollView; var changed = WatchContentSizeChanged(scroll); @@ -43,6 +52,10 @@ await AttachAndRun(scroll, async (handler) => [InlineData(ScrollOrientation.Both)] public async Task TestContentSizeChangedVertical(ScrollOrientation orientation) { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + var handler = await SetUpScrollView(orientation); var scroll = handler.VirtualView as ScrollView; var changed = WatchContentSizeChanged(scroll); @@ -67,10 +80,13 @@ await AttachAndRun(scroll, async (handler) => public async Task TestScrollContentMargin(ScrollOrientation orientation, int verticalMargin, int expectedHeight, int horizontalMargin, int expectedWidth) { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + var handler = await SetUpScrollView(orientation, verticalMargin: verticalMargin, horizontalMargin: horizontalMargin); var scroll = handler.VirtualView as ScrollView; - await AttachAndRun(scroll, async (handler) => { var expectedSize = new Size(expectedWidth, expectedHeight); @@ -83,7 +99,6 @@ await AttachAndRun(scroll, async (handler) => [Fact(DisplayName = "ScrollView Does Not Leak")] public async Task DoesNotLeak() { - SetupBuilder(); WeakReference viewReference = null; WeakReference handlerReference = null; WeakReference platformReference = null; @@ -106,19 +121,6 @@ await CreateHandlerAndAddToWindow(page, () => Assert.False(platformReference.IsAlive, "PlatformView should not be alive!"); } - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - handlers.AddHandler(); - handlers.AddHandler(); - }); - }); - } - static async Task AssertContentSizeChanged(Task changed) { await WaitAssert(() => changed.IsCompleted && changed.Result, timeout: 5000, message: "PropertyChanged event with PropertyName 'ContentSize' did not fire").ConfigureAwait(false); diff --git a/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.iOS.cs index 8b441eb28761..1b91f749e59e 100644 --- a/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.iOS.cs @@ -16,7 +16,9 @@ public partial class ScrollViewTests [Fact] public async Task ScrollViewContentSizeSet() { - EnsureHandlerCreated(builder => { builder.ConfigureMauiHandlers(handlers => { handlers.AddHandler(); }); }); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); var scrollView = new ScrollView(); var entry = new Entry() { Text = "In a ScrollView", HeightRequest = 10000 }; diff --git a/src/Controls/tests/DeviceTests/Elements/SearchBar/SearchBarTests.cs b/src/Controls/tests/DeviceTests/Elements/SearchBar/SearchBarTests.cs index 7982a2220c8f..294c4c777a99 100644 --- a/src/Controls/tests/DeviceTests/Elements/SearchBar/SearchBarTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/SearchBar/SearchBarTests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Microsoft.Maui.Controls; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Microsoft.Maui.Platform; using Xunit; @@ -10,6 +11,11 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.SearchBar)] public partial class SearchBarTests : ControlsHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); + // TODO: remove these 2 tests and use SearchBarTextInputTests below [Theory(DisplayName = "Text is Transformed Correctly at Initialization")] diff --git a/src/Controls/tests/DeviceTests/Elements/Shape/ShapeTests.cs b/src/Controls/tests/DeviceTests/Elements/Shape/ShapeTests.cs index 3f39b5f27224..25d882d9fd34 100644 --- a/src/Controls/tests/DeviceTests/Elements/Shape/ShapeTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Shape/ShapeTests.cs @@ -12,19 +12,15 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Shape)] public partial class ShapeTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); }); - }); - } [Theory(DisplayName = "Shape Updates brush Correctly")] [InlineData(0xFFFF0000)] @@ -32,8 +28,6 @@ void SetupBuilder() [InlineData(0xFF0000FF)] public async Task ShapeUpdatesBrushCorrectly(uint color) { - SetupBuilder(); - var expected = Color.FromUint(color); var layout = new StackLayout(); diff --git a/src/Controls/tests/DeviceTests/Elements/Shell/ShellFlyoutTests.cs b/src/Controls/tests/DeviceTests/Elements/Shell/ShellFlyoutTests.cs index e5d5b1afde08..7bc5ef479d75 100644 --- a/src/Controls/tests/DeviceTests/Elements/Shell/ShellFlyoutTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Shell/ShellFlyoutTests.cs @@ -302,9 +302,9 @@ Thickness GetSafeArea() return Thickness.Zero; #endif } + async Task RunShellTest(Action action, Func testAction) { - SetupBuilder(); var shell = await CreateShellAsync((shell) => { action(shell); diff --git a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTabBarTests.cs b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTabBarTests.cs index fa92eb31a16e..8d541ed1eb69 100644 --- a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTabBarTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTabBarTests.cs @@ -23,8 +23,6 @@ public partial class ShellTests [Fact(DisplayName = "ForegroundColor sets icon and title color sets title")] public async Task ForegroundColorSetsIconAndTitleColorSetsTitle() { - SetupBuilder(); - var titleColor = Color.FromArgb("#FFFF0000"); var foregroundColor = Color.FromArgb("#FF00FF00"); await RunShellTabBarTests(shell => @@ -48,8 +46,6 @@ await RunShellTabBarTests(shell => public async Task ShellTabBarTitleColorInitializesCorrectly(string colorHex) { - SetupBuilder(); - var expectedColor = Color.FromArgb(colorHex); await RunShellTabBarTests(shell => Shell.SetTabBarTitleColor(shell, expectedColor), async (shell) => @@ -89,8 +85,6 @@ await RunShellTabBarTests(shell => Shell.SetTabBarUnselectedColor(shell, expecte async Task RunShellTabBarTests(Action setup, Func runTest) { - SetupBuilder(); - var selectedContent = new ShellContent() { Route = "Tab1", diff --git a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.Android.cs index 6bca7f7cad4d..22fd66d8670c 100644 --- a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.Android.cs @@ -69,7 +69,6 @@ void OnLayoutChanged(object sender, Android.Views.View.LayoutChangeEventArgs e) [Fact(DisplayName = "FlyoutItems Render When FlyoutBehavior Starts As Locked")] public async Task FlyoutItemsRendererWhenFlyoutBehaviorStartsAsLocked() { - SetupBuilder(); var shell = await CreateShellAsync(shell => { shell.CurrentItem = new FlyoutItem() { Items = { new ContentPage() }, Title = "Flyout Item" }; @@ -91,7 +90,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Shell with Flyout Disabled Doesn't Render Flyout")] public async Task ShellWithFlyoutDisabledDoesntRenderFlyout() { - SetupBuilder(); var shell = await CreateShellAsync((shell) => { shell.Items.Add(new ContentPage()); @@ -112,7 +110,6 @@ await CreateHandlerAndAddToWindow(shell, (handler) => [Fact(DisplayName = "FooterTemplate Measures to Set Flyout Width When Flyout Locked")] public async Task FooterTemplateMeasuresToSetFlyoutWidth() { - SetupBuilder(); VerticalStackLayout footer = new VerticalStackLayout() { new Label(){ Text = "Hello there"} @@ -137,7 +134,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Flyout Footer and Default Flyout Items Render")] public async Task FlyoutFooterRenderersWithDefaultFlyoutItems() { - SetupBuilder(); VerticalStackLayout footer = new VerticalStackLayout() { new Label() { Text = "Hello there"} @@ -165,7 +161,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact] public async Task FlyoutItemsRenderWhenFlyoutHeaderIsSet() { - SetupBuilder(); VerticalStackLayout header = new VerticalStackLayout() { new Label() { Text = "Hello there"} @@ -193,7 +188,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact] public async Task FlyoutHeaderRendersCorrectSizeWithFlyoutContentSet() { - SetupBuilder(); VerticalStackLayout header = new VerticalStackLayout() { new Label() { Text = "Flyout Header"} @@ -227,8 +221,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact] public async Task SwappingOutAndroidContextDoesntCrash() { - SetupBuilder(); - var shell = await CreateShellAsync(shell => { shell.Items.Add(new FlyoutItem() { Route = "FlyoutItem1", Items = { new ContentPage() }, Title = "Flyout Item" }); @@ -261,8 +253,6 @@ await CreateHandlerAndAddToWindow(window, async (handler) => [Fact] public async Task ChangingBottomTabAttributesDoesntRecreateBottomTabs() { - SetupBuilder(); - var shell = await CreateShellAsync(shell => { shell.Items.Add(new Tab() { Items = { new ContentPage() }, Title = "Tab 1", Icon = "red.png" }); @@ -305,8 +295,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact] public async Task RemovingBottomTabDoesntRecreateMenu() { - SetupBuilder(); - var shell = await CreateShellAsync(shell => { shell.Items.Add(new Tab() { Items = { new ContentPage() }, Title = "Tab 1", Icon = "red.png" }); @@ -335,8 +323,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact] public async Task AddingBottomTabDoesntRecreateMenu() { - SetupBuilder(); - var shell = await CreateShellAsync(shell => { shell.Items.Add(new Tab() { Items = { new ContentPage() }, Title = "Tab 1", Icon = "red.png" }); diff --git a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.Windows.cs index 296362f275e2..0be65dd07f81 100644 --- a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.Windows.cs @@ -31,8 +31,6 @@ protected Task CheckFlyoutState(ShellHandler handler, bool desiredState) [Fact(DisplayName = "Shell FlyoutIcon Initializes Correctly")] public async Task ShellFlyoutIconInitializesCorrectly() { - SetupBuilder(); - var shell = await CreateShellAsync((shell) => { shell.FlyoutBehavior = FlyoutBehavior.Flyout; @@ -69,8 +67,6 @@ await AssertionExtensions.Wait(() => [InlineData("#000000")] public async Task ShellFlyoutBackgroundInitializesCorrectly(string colorHex) { - SetupBuilder(); - var expectedColor = Color.FromArgb(colorHex); var shell = await CreateShellAsync((shell) => @@ -106,13 +102,12 @@ await AssertionExtensions.Wait(() => }); }); - await ValidateHasColor(shell, expectedColor, typeof(ShellHandler)); + await ValidateHasColor(shell, expectedColor); } [Fact(DisplayName = "Back Button Enabled/Disabled")] public async Task BackButtonEnabledAndDisabled() { - SetupBuilder(); var shell = await CreateShellAsync((shell) => { shell.Items.Add(new ContentPage()); @@ -136,7 +131,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Shell with Single Content Page Has Panes Disabled")] public async Task BasicShellHasPaneDisplayModeDisabled() { - SetupBuilder(); var shell = await CreateShellAsync((shell) => { shell.Items.Add(new ContentPage()); @@ -161,7 +155,6 @@ await CreateHandlerAndAddToWindow(shell, (handler) => [Fact(DisplayName = "Shell With Only Flyout Items")] public async Task ShellWithOnlyFlyoutItems() { - SetupBuilder(); var shell = await CreateShellAsync((shell) => { var shellItem1 = new FlyoutItem(); @@ -193,7 +186,6 @@ await CreateHandlerAndAddToWindow(shell, (handler) => [Fact(DisplayName = "Shell With Only Top Tabs")] public async Task ShellWithOnlyTopTabs() { - SetupBuilder(); var shell = await CreateShellAsync((shell) => { var shellItem = new TabBar(); @@ -228,7 +220,6 @@ await CreateHandlerAndAddToWindow(shell, (handler) => [Fact(DisplayName = "Flyout Locked Offset from AppTitleBar")] public async Task FlyoutLockedOffsetFromAppTitleBar() { - SetupBuilder(); var label = new Controls.StackLayout() { HeightRequest = 10 @@ -260,7 +251,6 @@ await CreateHandlerAndAddToWindow(shell, (handler) => [Fact(DisplayName = "Flyout Locked Offsets Correctly from Content")] public async Task FlyoutLockedOffsetsCorrectlyFromContent() { - SetupBuilder(); var flyoutContent = new VerticalStackLayout() { HorizontalOptions = LayoutOptions.Fill @@ -294,7 +284,6 @@ await CreateHandlerAndAddToWindow(shell, (handler) => [Fact(DisplayName = "Content Offsets Correctly From App Title Bar")] public async Task ContentOffsetsCorrectlyFromAppTitleBar() { - SetupBuilder(); var flyoutContent = new VerticalStackLayout() { HorizontalOptions = LayoutOptions.Fill @@ -329,8 +318,6 @@ await CreateHandlerAndAddToWindow(shell, (handler) => [Fact(DisplayName = "Shell Has Correct Item Count")] public async Task ShellContentHasCorrectItemCount() { - SetupBuilder(); - var content1 = new ShellContent(); content1.Title = "Hello"; content1.Route = $"..."; @@ -361,7 +348,6 @@ await CreateHandlerAndAddToWindow(shell, (handler) => [Fact(DisplayName = "Single Shell Section with Multiple Children")] public async Task SingleShellSectionWithMultipleChildren() { - SetupBuilder(); var page1 = new ContentPage(); var page2 = new ContentPage(); @@ -408,7 +394,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Single Tab Bar with Multiple Children")] public async Task SingleTabBarWithMultipleChildren() { - SetupBuilder(); var page1 = new ContentPage(); var page2 = new ContentPage(); @@ -458,7 +443,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Selected Item On ShellView Correct With Implict Flyout Item")] public async Task SelectedItemOnShellViewCorrectWithImplictFlyoutItem() { - SetupBuilder(); var page1 = new ContentPage(); var page2 = new ContentPage(); var page3 = new ContentPage(); @@ -515,8 +499,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Shell Toolbar With Only MenuBarItems Is Visible")] public async Task ShellToolbarWithOnlyMenuBarItemsIsVisible() { - SetupBuilder(); - var shell = await CreateShellAsync((shell) => { var contentPage = new ContentPage(); @@ -539,8 +521,6 @@ await CreateHandlerAndAddToWindow(shell, (handler) => [Fact(DisplayName = "Shell Toolbar With Only ToolbarItems Is Visible")] public async Task ShellToolbarWithOnlyToolbarItemsIsVisible() { - SetupBuilder(); - var shell = await CreateShellAsync((shell) => { var contentPage = new ContentPage(); @@ -561,8 +541,6 @@ await CreateHandlerAndAddToWindow(shell, (handler) => [Fact] public async Task EmptyShellHasNoTopMargin() { - SetupBuilder(); - var mainPage = new ContentPage(); var shell = new Shell() { CurrentItem = mainPage }; @@ -621,8 +599,6 @@ internal Graphics.Rect GetFlyoutFrame(ShellHandler shellRenderer) [Fact(DisplayName = "Shell Toolbar not visible when only back button is present")] public async Task ShellToolbarNotVisibleWhenOnlyBackButtonIsPresent() { - SetupBuilder(); - var shell = await CreateShellAsync((shell) => { shell.CurrentItem = new ContentPage(); @@ -638,8 +614,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact] public async Task SelectingTabUpdatesSelectedFlyoutItem() { - SetupBuilder(); - var flyoutItem = new FlyoutItem() { FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems, diff --git a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.cs b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.cs index 8b2d1b75397b..491c152ffd29 100644 --- a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.cs @@ -31,27 +31,21 @@ namespace Microsoft.Maui.DeviceTests [Collection(ControlsHandlerTestBase.RunInNewWindowCollection)] public partial class ShellTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { - SetupShellHandlers(handlers); + handlers.SetupShellHandlers(); handlers.AddHandler(typeof(NavigationPage), typeof(NavigationViewHandler)); handlers.AddHandler(typeof(Button), typeof(ButtonHandler)); handlers.AddHandler(typeof(Controls.ContentView), typeof(ContentViewHandler)); handlers.AddHandler(typeof(ScrollView), typeof(ScrollViewHandler)); handlers.AddHandler(typeof(CollectionView), typeof(CollectionViewHandler)); }); - }); - } [Fact] public async Task PageLayoutDoesNotExceedWindowBounds() { - SetupBuilder(); - var button = new Button() { Text = "Test me" @@ -85,8 +79,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact] public async Task SearchHandlerRendersCorrectly() { - SetupBuilder(); - var shell = await CreateShellAsync(shell => { shell.Items.Add(new FlyoutItem() { Route = "FlyoutItem1", Items = { new ContentPage() }, Title = "Flyout Item" }); @@ -110,8 +102,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact] public async Task FlyoutWithAsMultipleItemsRendersWithoutCrashing() { - SetupBuilder(); - Shell shell = await CreateShellAsync(shell => { shell.Items.Add(new FlyoutItem() @@ -158,7 +148,6 @@ await CreateHandlerAndAddToWindow(shell, (_) => [Fact(DisplayName = "Appearing Fires Before NavigatedTo")] public async Task AppearingFiresBeforeNavigatedTo() { - SetupBuilder(); var contentPage = new ContentPage(); int contentPageAppearingFired = 0; int navigatedToFired = 0; @@ -219,7 +208,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Navigating During Navigated Doesnt ReFire Appearing")] public async Task NavigatingDuringNavigatedDoesntReFireAppearing() { - SetupBuilder(); var contentPage = new ContentPage(); var secondContentPage = new ContentPage(); int contentPageAppearingFired = 0; @@ -282,7 +270,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Swap Shell Root Page for NavigationPage")] public async Task SwapShellRootPageForNavigationPage() { - SetupBuilder(); var shell = await CreateShellAsync(shell => { shell.CurrentItem = new ContentPage(); @@ -302,7 +289,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "PopToRootAsync correctly navigates to root page")] public async Task PopToRootAsyncCorrectlyNavigationsBackToRootPage() { - SetupBuilder(); var rootPage = new ContentPage(); var shell = await CreateShellAsync(shell => { @@ -323,7 +309,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "FlyoutContent Renderers When FlyoutBehavior Starts As Locked")] public async Task FlyoutContentRenderersWhenFlyoutBehaviorStartsAsLocked() { - SetupBuilder(); var flyoutContent = new VerticalStackLayout() { Children = { new Label() { Text = "Rendered" } } }; var shell = await CreateShellAsync(shell => { @@ -346,7 +331,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Flyout Starts as Open correctly")] public async Task FlyoutIsPresented() { - SetupBuilder(); var shell = await CreateShellAsync(shell => { shell.CurrentItem = new FlyoutItem() { Items = { new ContentPage() } }; @@ -365,7 +349,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Back Button Visibility Changes with push/pop")] public async Task BackButtonVisibilityChangesWithPushPop() { - SetupBuilder(); var shell = await CreateShellAsync(shell => { shell.CurrentItem = new ContentPage(); @@ -385,7 +368,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Pushing the Same Page Disconnects Previous Toolbar Items")] public async Task PushingTheSamePageUpdatesToolbar() { - SetupBuilder(); bool canExecute = false; var command = new Command(() => { }, () => canExecute); var pushedPage = new ContentPage() @@ -417,8 +399,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Set Has Back Button")] public async Task SetHasBackButton() { - SetupBuilder(); - var shell = await CreateShellAsync(shell => { shell.CurrentItem = new ContentPage(); @@ -446,8 +426,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Correctly Adjust to Making Currently Visible Shell Page Invisible")] public async Task CorrectlyAdjustToMakingCurrentlyVisibleShellPageInvisible() { - SetupBuilder(); - var page1 = new ContentPage() { Content = new Label() { Text = "Page 1" }, Title = "Page 1" }; var page2 = new ContentPage() @@ -486,8 +464,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Empty Shell")] public async Task DetailsViewUpdates() { - SetupBuilder(); - var shell = await InvokeOnMainThreadAsync(() => { return new Shell() @@ -507,8 +483,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "TitleView Updates to Currently Visible Page")] public async Task TitleViewUpdateToCurrentlyVisiblePage() { - SetupBuilder(); - var page1 = new ContentPage(); var page2 = new ContentPage(); var page3 = new ContentPage(); @@ -568,8 +542,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "TitleView Set On Shell Works After Navigation")] public async Task TitleViewSetOnShellWorksAfterNavigation() { - SetupBuilder(); - var page1 = new ContentPage(); var page2 = new ContentPage(); var page3 = new ContentPage(); @@ -635,8 +607,6 @@ bool WaitCondition() [Fact(DisplayName = "Handlers not recreated when changing tabs")] public async Task HandlersNotRecreatedWhenChangingTabs() { - SetupBuilder(); - var page1 = new ContentPage(); var page2 = new ContentPage(); @@ -672,8 +642,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Navigation Routes Correctly After Switching Flyout Items")] public async Task NavigatedFiresAfterSwitchingFlyoutItems() { - SetupBuilder(); - var shellContent1 = new ShellContent() { Content = new ContentPage() }; var shellContent2 = new ShellContent() { Content = new ContentPage() }; @@ -711,8 +679,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact] public async Task ChangingToNewMauiContextDoesntCrash() { - SetupBuilder(); - var shell = new Shell(); shell.Items.Add(new FlyoutItem() { Route = "FlyoutItem1", Items = { new ContentPage() }, Title = "Flyout Item" }); shell.Items.Add(new FlyoutItem() { Route = "FlyoutItem2", Items = { new ContentPage() }, Title = "Flyout Item" }); @@ -746,7 +712,6 @@ await CreateHandlerAndAddToWindow(window, async (handler) => [ClassData(typeof(ShellBasicNavigationTestCases))] public async Task BasicShellNavigationStructurePermutations(ShellItem[] shellItems) { - SetupBuilder(); var shell = await InvokeOnMainThreadAsync(() => { var value = new Shell(); @@ -768,8 +733,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Navigate to Root with BackButtonBehavior no Crash")] public async Task NavigateToRootWithBackButtonBehaviorNoCrash() { - SetupBuilder(); - var shell = await CreateShellAsync(shell => { shell.CurrentItem = new ContentPage(); @@ -807,8 +770,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "LifeCycleEvents Fire When Navigating Top Tabs")] public async Task LifeCycleEventsFireWhenNavigatingTopTabs() { - SetupBuilder(); - var page1 = new LifeCycleTrackingPage() { Content = new Label() { Padding = 40, Text = "Page 1", Background = SolidColorBrush.Purple } }; var page2 = new LifeCycleTrackingPage() { Content = new Label() { Padding = 40, Text = "Page 2", Background = SolidColorBrush.Green } }; @@ -846,7 +807,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Toolbar Title")] public async Task ToolbarTitle() { - SetupBuilder(); var navPage = new Shell() { CurrentItem = new ContentPage() @@ -866,7 +826,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), (handl [Fact(DisplayName = "Toolbar Title View Updates")] public async Task ToolbarTitleViewUpdates() { - SetupBuilder(); var page1 = new ContentPage() { Title = "Page 1" @@ -899,7 +858,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "Toolbar Title Updates")] public async Task ToolbarTitleUpdates() { - SetupBuilder(); var page1 = new ContentPage() { Title = "Page 1" @@ -929,7 +887,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "Title View Measures")] public async Task TitleViewMeasures() { - SetupBuilder(); var page1 = new ContentPage() { Title = "Page 1" @@ -967,7 +924,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "Pages Do Not Leak")] public async Task PagesDoNotLeak() { - SetupBuilder(); var shell = await CreateShellAsync(shell => { shell.CurrentItem = new ContentPage() { Title = "Page 1" }; @@ -1004,7 +960,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Can Reuse Pages")] public async Task CanReusePages() { - SetupBuilder(); var rootPage = new ContentPage(); var shell = await CreateShellAsync(shell => { @@ -1030,7 +985,6 @@ public async Task ShellAddRemoveItems() ShellItem homeItem = null; int itemCount = 3; - SetupBuilder(); var shell = await CreateShellAsync((shell) => { shell.FlyoutBehavior = FlyoutBehavior.Locked; @@ -1088,7 +1042,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Can Clear ShellContent")] public async Task CanClearShellContent() { - SetupBuilder(); var page = new ContentPage(); var shell = await CreateShellAsync(shell => { diff --git a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.iOS.cs index 288b499a5244..d38e21b6df93 100644 --- a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.iOS.cs @@ -27,7 +27,6 @@ public partial class ShellTests [Fact(DisplayName = "Page Adjust When Top Tabs Are Present")] public async Task PageAdjustsWhenTopTabsArePresent() { - SetupBuilder(); var pageWithTopTabs = new ContentPage() { Content = new Label() { Text = "Page With Top Tabs" } }; var pageWithoutTopTabs = new ContentPage() { Content = new Label() { Text = "Page With Bottom Tabs" } }; @@ -76,7 +75,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Swiping Away Modal Propagates to Shell")] public async Task SwipingAwayModalPropagatesToShell() { - SetupBuilder(); var shell = await CreateShellAsync((shell) => { shell.Items.Add(new ContentPage()); @@ -117,7 +115,6 @@ public async Task SwipingAwayModalRemovesEntireNavigationPage() { Routing.RegisterRoute(nameof(SwipingAwayModalRemovesEntireNavigationPage), typeof(ModalShellPage)); - SetupBuilder(); var shell = await CreateShellAsync((shell) => { shell.Items.Add(new ContentPage()); @@ -158,7 +155,6 @@ void ShellNavigated(object sender, ShellNavigatedEventArgs e) [Fact(DisplayName = "Clicking BackButton Fires Correct Navigation Events")] public async Task ShellWithFlyoutDisabledDoesntRenderFlyout() { - SetupBuilder(); var shell = await CreateShellAsync((shell) => { shell.Items.Add(new ContentPage()); @@ -205,7 +201,6 @@ void ShellNavigating(object sender, ShellNavigatingEventArgs e) [Fact(DisplayName = "Cancel BackButton Navigation")] public async Task CancelBackButtonNavigation() { - SetupBuilder(); var shell = await CreateShellAsync((shell) => { shell.Items.Add(new ContentPage()); @@ -253,8 +248,6 @@ void ShellNavigating(object sender, ShellNavigatingEventArgs e) [Fact(DisplayName = "TitleView renders correctly")] public async Task TitleViewRendersCorrectly() { - SetupBuilder(); - var expected = Colors.Red; var shellTitleView = new VerticalStackLayout { BackgroundColor = expected }; @@ -338,7 +331,6 @@ protected async Task ScrollFlyoutToBottom(ShellRenderer shellRenderer) [Fact(DisplayName = "Back Button Text Has Correct Default")] public async Task BackButtonTextHasCorrectDefault() { - SetupBuilder(); var shell = await CreateShellAsync(shell => { shell.CurrentItem = new ContentPage() { Title = "Page 1" }; @@ -358,7 +350,6 @@ await CreateHandlerAndAddToWindow(shell, async (handler) => [Fact(DisplayName = "Back Button Behavior Text")] public async Task BackButtonBehaviorText() { - SetupBuilder(); var shell = await CreateShellAsync(shell => { shell.CurrentItem = new ContentPage() { Title = "Page 1" }; diff --git a/src/Controls/tests/DeviceTests/Elements/SwipeView/SwipeViewTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/SwipeView/SwipeViewTests.Android.cs index 9006a022a5ff..e8a254e72843 100644 --- a/src/Controls/tests/DeviceTests/Elements/SwipeView/SwipeViewTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/SwipeView/SwipeViewTests.Android.cs @@ -14,8 +14,6 @@ public partial class SwipeViewTests : ControlsHandlerTestBase [Fact(DisplayName = "SwipeItem Size Initializes Correctly")] public async Task SwipeItemSizeInitializesCorrectly() { - SetupBuilder(); - var expectedColor = Colors.Red; var content = new VerticalStackLayout diff --git a/src/Controls/tests/DeviceTests/Elements/SwipeView/SwipeViewTests.cs b/src/Controls/tests/DeviceTests/Elements/SwipeView/SwipeViewTests.cs index 173bfa1d5d54..8520cc0c82ae 100644 --- a/src/Controls/tests/DeviceTests/Elements/SwipeView/SwipeViewTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/SwipeView/SwipeViewTests.cs @@ -11,28 +11,20 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.SwipeView)] public partial class SwipeViewTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { - handlers.AddHandler(typeof(VerticalStackLayout), typeof(LayoutHandler)); - handlers.AddHandler(typeof(Grid), typeof(LayoutHandler)); - handlers.AddHandler(typeof(Button), typeof(ButtonHandler)); + handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); }); - }); - } #if !WINDOWS [Fact(DisplayName = "SwipeView LogicalChildren Works Correctly")] public async Task SwipeViewLogicalChildren() { - SetupBuilder(); - var content = new Grid { HeightRequest = 60, @@ -75,8 +67,6 @@ await swipeViewHandler.PlatformView.AttachAndRun(async () => [Fact("Items Do Not Leak")] public async Task ItemsDoNotLeak() { - SetupBuilder(); - WeakReference viewReference = null; WeakReference platformViewReference = null; WeakReference handlerReference = null; diff --git a/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Android.cs b/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Android.cs index bbb9ae082f88..c7d55f565c34 100644 --- a/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Android.cs +++ b/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Android.cs @@ -27,8 +27,6 @@ public partial class TabbedPageTests : ControlsHandlerTestBase [Fact(DisplayName = "Using SelectedTab Color doesnt crash")] public async Task SelectedTabColorNoDoesntCrash() { - SetupBuilder(); - var tabbedPage = CreateBasicTabbedPage(); tabbedPage.SelectedTabColor = Colors.Red; @@ -43,8 +41,6 @@ await CreateHandlerAndAddToWindow(new Window(tabbedPage), (ha [Fact] public async Task ChangingBottomTabAttributesDoesntRecreateBottomTabs() { - SetupBuilder(); - var tabbedPage = CreateBasicTabbedPage(true, pages: new[] { new ContentPage() { Title = "Tab 1", IconImageSource = "red.png" }, @@ -87,13 +83,9 @@ await CreateHandlerAndAddToWindow(tabbedPage, async (handler) [Fact(DisplayName = "Custom RecyclerView Adapter Doesn't Crash")] public async Task CustomRecyclerViewAdapterDoesNotCrash() { - SetupBuilder(builder => - { + EnsureHandlerCreated(builder => builder.ConfigureMauiHandlers(handler => - { - handler.AddHandler(); - }); - }); + handler.AddHandler())); var tabbedPage = CreateBasicTabbedPage(); diff --git a/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Windows.cs index 9d218215a3f0..f52dc5591bfc 100644 --- a/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Windows.cs @@ -24,7 +24,6 @@ public partial class TabbedPageTests : ControlsHandlerTestBase [Fact(DisplayName = "Toolbar Visible When Pushing To TabbedPage")] public async Task ToolbarVisibleWhenPushingToTabbedPage() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage()) { Title = "App Page" }; await CreateHandlerAndAddToWindow(new Window(navPage), async (handler) => @@ -55,7 +54,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [Fact(DisplayName = "TabbedPage Disconnects")] public async Task TabbedViewHandlerDisconnects() { - SetupBuilder(); var tabbedPage = CreateBasicTabbedPage(); await CreateHandlerAndAddToWindow(tabbedPage, (handler) => @@ -69,7 +67,6 @@ await CreateHandlerAndAddToWindow(tabbedPage, (handler) => [Fact(DisplayName = "BarBackground Color")] public async Task BarBackgroundColor() { - SetupBuilder(); var tabbedPage = CreateBasicTabbedPage(); tabbedPage.BarBackground = SolidColorBrush.Purple; @@ -85,7 +82,6 @@ await CreateHandlerAndAddToWindow(new Window(tabbedPage), (ha [Fact(DisplayName = "Swapping Root Window Content for New Tabbed Page")] public async Task SwapWindowContentForNewTabbedPage() { - SetupBuilder(); var window = new Window() { Page = CreateBasicTabbedPage() @@ -111,7 +107,6 @@ await CreateHandlerAndAddToWindow(window, async windowHandler [Fact(DisplayName = "Bar Text Color")] public async Task BarTextColor() { - SetupBuilder(); var tabbedPage = CreateBasicTabbedPage(); tabbedPage.BarTextColor = Colors.Red; await CreateHandlerAndAddToWindow(tabbedPage, handler => @@ -130,7 +125,6 @@ await CreateHandlerAndAddToWindow(tabbedPage, handler => [Fact(DisplayName = "Tab Title")] public async Task TabTitle() { - SetupBuilder(); await CreateHandlerAndAddToWindow(CreateBasicTabbedPage(), handler => { var navView = GetMauiNavigationView(handler.MauiContext); @@ -145,7 +139,6 @@ await CreateHandlerAndAddToWindow(CreateBasicTabbedPage(), ha [Fact(DisplayName = "Selected/Unselected Color")] public async Task SelectedAndUnselectedTabColor() { - SetupBuilder(); var tabbedPage = CreateBasicTabbedPage(); tabbedPage.Children.Add(new ContentPage() { Title = "Page 2" }); @@ -173,7 +166,6 @@ await CreateHandlerAndAddToWindow(tabbedPage, handler => [Fact(DisplayName = "Adding and Removing Pages Propagates Correctly")] public async Task AddingAndRemovingPagesPropagatesCorrectly() { - SetupBuilder(); await CreateHandlerAndAddToWindow(CreateBasicTabbedPage(), async handler => { var navView = GetMauiNavigationView(handler.MauiContext); @@ -197,13 +189,9 @@ await CreateHandlerAndAddToWindow(CreateBasicTabbedPage(), as [Fact(DisplayName = "Selected Item Changed Propagates to CurrentPage")] public async Task SelectedItemChangedPropagatesToCurrentPage() { - SetupBuilder(); - var tabbedPage = CreateBasicTabbedPage(); tabbedPage.Children.Add(new ContentPage()); - - await CreateHandlerAndAddToWindow(tabbedPage, handler => { var navView = GetMauiNavigationView(handler.MauiContext); diff --git a/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.cs b/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.cs index d02b201999c4..3077b67d7127 100644 --- a/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.cs @@ -16,37 +16,28 @@ using Microsoft.Maui.Platform; using Xunit; +#if IOS || MACCATALYST +using TabbedViewHandler = Microsoft.Maui.Controls.Handlers.Compatibility.TabbedRenderer; +using NavigationViewHandler = Microsoft.Maui.Controls.Handlers.Compatibility.NavigationRenderer; +#endif + namespace Microsoft.Maui.DeviceTests { [Category(TestCategory.TabbedPage)] public partial class TabbedPageTests : ControlsHandlerTestBase { - void SetupBuilder(Action additionalCreationActions = null) - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { - handlers.AddHandler(typeof(VerticalStackLayout), typeof(LayoutHandler)); - handlers.AddHandler(typeof(Toolbar), typeof(ToolbarHandler)); - handlers.AddHandler(typeof(Button), typeof(ButtonHandler)); + handlers.AddHandler(); + handlers.AddHandler(); handlers.AddHandler(); - handlers.AddHandler(); - -#if IOS || MACCATALYST - handlers.AddHandler(typeof(TabbedPage), typeof(TabbedRenderer)); - handlers.AddHandler(typeof(NavigationPage), typeof(NavigationRenderer)); -#else - handlers.AddHandler(typeof(TabbedPage), typeof(TabbedViewHandler)); - handlers.AddHandler(typeof(NavigationPage), typeof(NavigationViewHandler)); -#endif + handlers.AddHandler(); + handlers.AddHandler(); }); - additionalCreationActions?.Invoke(builder); - }); - } - #if !IOS && !MACCATALYST // iOS currently can't handle recreating a handler if it's disconnecting // This is left over behavior from Forms and will be fixed by a different PR @@ -54,7 +45,9 @@ void SetupBuilder(Action additionalCreationActions = null) [ClassData(typeof(TabbedPagePivots))] public async Task DisconnectEachPageHandlerAfterNavigation(bool bottomTabs, bool isSmoothScrollEnabled) { - SetupBuilder(); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handler => + handler.AddHandler())); List navPages = new List(); var pageCount = 5; @@ -95,7 +88,6 @@ await CreateHandlerAndAddToWindow(new Window(tabbedPage), asy [ClassData(typeof(TabbedPagePivots))] public async Task PoppingTabbedPageDoesntCrash(bool bottomTabs, bool isSmoothScrollEnabled) { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage()) { Title = "App Page" }; await CreateHandlerAndAddToWindow(new Window(navPage), async (handler) => @@ -109,8 +101,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), async [ClassData(typeof(TabbedPagePivots))] public async Task RemoveCurrentPageAndThenReAddDoesntCrash(bool bottomTabs, bool isSmoothScrollEnabled) { - SetupBuilder(); - var tabbedPage = CreateBasicTabbedPage(bottomTabs, isSmoothScrollEnabled); var firstPage = new NavigationPage(new ContentPage()); @@ -143,7 +133,6 @@ await CreateHandlerAndAddToWindow(new Window(tabbedPage), asy [ClassData(typeof(TabbedPagePivots))] public async Task SettingCurrentPageToNotBePositionZeroWorks(bool bottomTabs, bool isSmoothScrollEnabled) { - SetupBuilder(); var tabbedPage = CreateBasicTabbedPage(bottomTabs, isSmoothScrollEnabled); var firstPage = new NavigationPage(new ContentPage()); tabbedPage.Children.Insert(0, firstPage); @@ -161,7 +150,9 @@ await CreateHandlerAndAddToWindow(new Window(tabbedPage), asy [ClassData(typeof(TabbedPagePivots))] public async Task MovingBetweenMultiplePagesWithNestedNavigationPages(bool bottomTabs, bool isSmoothScrollEnabled) { - SetupBuilder(); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handler => + handler.AddHandler())); var pages = new NavigationPage[5]; @@ -229,7 +220,6 @@ await CreateHandlerAndAddToWindow(new Window(tabbedPage), asy [ClassData(typeof(TabbedPagePivots))] public async Task RemovingAllPagesDoesntCrash(bool bottomTabs, bool isSmoothScrollEnabled) { - SetupBuilder(); var tabbedPage = CreateBasicTabbedPage(bottomTabs, isSmoothScrollEnabled); var secondPage = new NavigationPage(new ContentPage()) { Title = "Second Page" }; tabbedPage.Children.Add(secondPage); @@ -262,8 +252,6 @@ await CreateHandlerAndAddToWindow(new Window(tabbedPage), asy [InlineData(false)] public async Task NavigatingAwayFromTabbedPageResizesContentPage(bool bottomTabs) { - SetupBuilder(); - var tabbedPage = CreateBasicTabbedPage(bottomTabs); var navPage = new NavigationPage(tabbedPage); diff --git a/src/Controls/tests/DeviceTests/Elements/TemplatedView/TemplatedViewTests.cs b/src/Controls/tests/DeviceTests/Elements/TemplatedView/TemplatedViewTests.cs index 8cef88dc07f7..ff0aa243ccf0 100644 --- a/src/Controls/tests/DeviceTests/Elements/TemplatedView/TemplatedViewTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/TemplatedView/TemplatedViewTests.cs @@ -9,18 +9,13 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.TemplatedView)] public partial class TemplatedViewTests : ControlsHandlerTestBase { - public TemplatedViewTests() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { handlers.AddHandler(); - handlers.AddHandler(); handlers.AddHandler(); }); - }); - } [Fact] public async Task ControlTemplateInitializesCorrectly() diff --git a/src/Controls/tests/DeviceTests/Elements/TextInput/TextInputFocusTests.cs b/src/Controls/tests/DeviceTests/Elements/TextInput/TextInputFocusTests.cs index 6db30c303ca8..49641f113f41 100644 --- a/src/Controls/tests/DeviceTests/Elements/TextInput/TextInputFocusTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/TextInput/TextInputFocusTests.cs @@ -1,4 +1,5 @@ using Microsoft.Maui.Controls; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests @@ -8,5 +9,9 @@ public abstract partial class TextInputFocusTests : ControlsHan where THandler : class, IViewHandler, IPlatformViewHandler, new() where TView : VisualElement, ITextInput, new() { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); } } diff --git a/src/Controls/tests/DeviceTests/Elements/TextInput/TextInputTests.cs b/src/Controls/tests/DeviceTests/Elements/TextInput/TextInputTests.cs index 23e1fb262b7a..bb5f3057260d 100644 --- a/src/Controls/tests/DeviceTests/Elements/TextInput/TextInputTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/TextInput/TextInputTests.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.Maui.Controls; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests @@ -9,6 +10,11 @@ public abstract partial class TextInputTests : ControlsHandlerT where THandler : class, IViewHandler, IPlatformViewHandler, new() where TView : InputView, IView, ITextInput, new() { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); + protected abstract int GetPlatformCursorPosition(THandler handler); protected abstract int GetPlatformSelectionLength(THandler handler); diff --git a/src/Controls/tests/DeviceTests/Elements/Toolbar/ToolbarTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/Toolbar/ToolbarTests.Windows.cs index 37355fa95390..39244e6f18cb 100644 --- a/src/Controls/tests/DeviceTests/Elements/Toolbar/ToolbarTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/Toolbar/ToolbarTests.Windows.cs @@ -24,7 +24,6 @@ public partial class ToolbarTests : ControlsHandlerTestBase [Fact(DisplayName = "Toolbar Default Label Position")] public async Task ToolbarDefaultLabelPositionWithNoImages() { - SetupBuilder(); var item1 = new ToolbarItem() { Text = "Toolbar Item 1" }; var item2 = new ToolbarItem() { Text = "Toolbar Item 2" }; @@ -49,7 +48,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), (handl [Fact(DisplayName = "Toolbar Default Label Position with Image and Text")] public async Task ToolbarDefaultLabelPositionWithTextAndImages() { - SetupBuilder(); var item1 = new ToolbarItem() { IconImageSource = "red.png" }; var item2 = new ToolbarItem() { Text = "Toolbar Item 2" }; var item3 = new ToolbarItem() { Text = "Toolbar Item 2", IconImageSource = "red.png" }; @@ -76,7 +74,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), (handl [Fact(DisplayName = "Toolbar Default Label Position With Images")] public async Task ToolbarDefaultLabelPositionOnlyImages() { - SetupBuilder(); var item1 = new ToolbarItem() { IconImageSource = "red.png" }; var item2 = new ToolbarItem() { IconImageSource = "red.png" }; @@ -101,8 +98,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), (handl [Fact(DisplayName = "Toolbar Default Label Position Add Text to Images")] public async Task ToolbarDefaultLabelPositionAddText() { - SetupBuilder(); - var item1 = new ToolbarItem() { IconImageSource = "red.png" }; var item2 = new ToolbarItem() { IconImageSource = "red.png" }; diff --git a/src/Controls/tests/DeviceTests/Elements/Toolbar/ToolbarTests.cs b/src/Controls/tests/DeviceTests/Elements/Toolbar/ToolbarTests.cs index cc6286a91b80..f01d692192bc 100644 --- a/src/Controls/tests/DeviceTests/Elements/Toolbar/ToolbarTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Toolbar/ToolbarTests.cs @@ -25,31 +25,25 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Toolbar)] public partial class ToolbarTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { - handlers.AddHandler(typeof(Controls.Label), typeof(LabelHandler)); - handlers.AddHandler(typeof(Controls.Toolbar), typeof(ToolbarHandler)); - handlers.AddHandler(typeof(FlyoutPage), typeof(FlyoutViewHandler)); - handlers.AddHandler(typeof(Controls.NavigationPage), typeof(NavigationViewHandler)); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); - handlers.AddHandler(typeof(TabbedPage), typeof(TabbedViewHandler)); + handlers.AddHandler(); - SetupShellHandlers(handlers); + handlers.SetupShellHandlers(); }); - }); - } - #if !IOS && !MACCATALYST [Fact(DisplayName = "Toolbar Items Map Correctly")] public async Task ToolbarItemsMapCorrectly() { - SetupBuilder(); var toolbarItem = new ToolbarItem() { Text = "Toolbar Item 1" }; var navPage = new NavigationPage(new ContentPage() { @@ -69,7 +63,6 @@ await CreateHandlerAndAddToWindow(new Window(navPage), (handl [Fact(DisplayName = "Toolbar Items Order Updates Correctly After Navigation")] public async Task ToolbarItemsOrderUpdatesCorrectlyAfterNavigation() { - SetupBuilder(); var toolbarItemFirstPage = new ToolbarItem() { Text = "Toolbar Item 1" }; var toolbarItemSecondPage = new ToolbarItem() { Text = "Toolbar Item Second Page", Order = ToolbarItemOrder.Secondary }; @@ -103,7 +96,6 @@ await navPage.PushAsync(new ContentPage() [Fact(DisplayName = "Toolbar Title")] public async Task ToolbarTitle() { - SetupBuilder(); var navPage = new NavigationPage(new ContentPage() { Title = "Page Title" @@ -127,14 +119,12 @@ public async Task ToolbarUpdatesCorrectlyWhenSwappingMainPageWithAlreadyUsedPage { string[] pageSet = pages.Split(','); - SetupBuilder(); Dictionary createdPages = new Dictionary(); var nextPage = GetPage(pageSet[0]); var window = new Window(nextPage); - await CreateHandlerAndAddToWindow(window, async (handler) => { await OnLoadedAsync(window.Page); @@ -188,7 +178,6 @@ Page GetPage(string name) [InlineData(nameof(Shell))] public async Task ToolbarRecreatesWithNewMauiContext(string type) { - SetupBuilder(); Page page = null; if (type == nameof(FlyoutPage)) diff --git a/src/Controls/tests/DeviceTests/Elements/View/ViewTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/View/ViewTests.iOS.cs index 5ea79a2256d8..527d1631b208 100644 --- a/src/Controls/tests/DeviceTests/Elements/View/ViewTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/View/ViewTests.iOS.cs @@ -23,6 +23,10 @@ public partial class ViewTests [Fact] public async Task GestureRecognizersAttachToPlatformViewWhenNoContainerViewIsPresent() { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handler => + handler.AddHandler())); + var view = new Label() { GestureRecognizers = { new TapGestureRecognizer() } @@ -49,6 +53,10 @@ public async Task GestureRecognizersAttachToPlatformViewWhenNoContainerViewIsPre [Fact] public async Task GestureRecognizersAttachToContainerViewWhenUsingContainerView() { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handler => + handler.AddHandler())); + var view = new Label() { Shadow = new Shadow(), // this results in a container view diff --git a/src/Controls/tests/DeviceTests/Elements/VisualElementTests.cs b/src/Controls/tests/DeviceTests/Elements/VisualElement/VisualElementTests.cs similarity index 93% rename from src/Controls/tests/DeviceTests/Elements/VisualElementTests.cs rename to src/Controls/tests/DeviceTests/Elements/VisualElement/VisualElementTests.cs index 9589b1bec7aa..23e7c2fb23bc 100644 --- a/src/Controls/tests/DeviceTests/Elements/VisualElementTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/VisualElement/VisualElementTests.cs @@ -15,6 +15,10 @@ public partial class VisualElementTests : ControlsHandlerTestBase [Fact] public async Task CanCreateHandler() { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handler => + handler.AddHandler())); + var image = new Image(); await CreateHandlerAsync(image); } @@ -22,6 +26,10 @@ public async Task CanCreateHandler() [Fact] public async Task SettingHandlerDoesNotThrow() { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handler => + handler.AddHandler())); + var image = new Image(); var handler = await CreateHandlerAsync(image); image.Handler = handler; diff --git a/src/Controls/tests/DeviceTests/Elements/VisualElementTree/VisualElementTreeTests.cs b/src/Controls/tests/DeviceTests/Elements/VisualElementTree/VisualElementTreeTests.cs index 36ddc4b86a5b..35c3c3acde44 100644 --- a/src/Controls/tests/DeviceTests/Elements/VisualElementTree/VisualElementTreeTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/VisualElementTree/VisualElementTreeTests.cs @@ -9,10 +9,15 @@ using System.Collections.Generic; using ContentView = Microsoft.Maui.Controls.ContentView; using Microsoft.Maui.Controls.Handlers.Items; + #if ANDROID || IOS || MACCATALYST using ShellHandler = Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer; #endif +#if IOS || MACCATALYST +using NavigationViewHandler = Microsoft.Maui.Controls.Handlers.Compatibility.NavigationRenderer; +#endif + namespace Microsoft.Maui.DeviceTests { [Category(TestCategory.VisualElementTree)] @@ -21,30 +26,34 @@ namespace Microsoft.Maui.DeviceTests #endif public partial class VisualElementTreeTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.SetupShellHandlers(); - - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { -#if IOS || MACCATALYST - handlers.AddHandler(typeof(Controls.NavigationPage), typeof(Controls.Handlers.Compatibility.NavigationRenderer)); -#else - handlers.AddHandler(typeof(Controls.NavigationPage), typeof(NavigationViewHandler)); -#endif + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); +#if WINDOWS + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); +#endif }); - }); - } [Fact] public async Task GetVisualTreeElements() { - SetupBuilder(); var label = new Label() { Text = "Find Me" }; var page = new ContentPage() { Title = "Title Page" }; page.Content = new VerticalStackLayout() @@ -88,7 +97,6 @@ await CreateHandlerAndAddToWindow(rootPage, async handler => [Fact] public async Task FindPlatformViewInsideLayout() { - SetupBuilder(); var button = new Button(); VerticalStackLayout views = new VerticalStackLayout() { @@ -110,7 +118,6 @@ await CreateHandlerAndAddToWindow(views, () => [Fact] public async Task FindPlatformViewInsideScrollView() { - SetupBuilder(); var button = new Button(); ScrollView view = new ScrollView() { @@ -129,7 +136,6 @@ await CreateHandlerAndAddToWindow(view, () => [Fact] public async Task FindPlatformViewViaDefaultContainer() { - SetupBuilder(); var button = new Button(); NestingView view = new NestingView(); view.AddLogicalChild(button); @@ -146,7 +152,6 @@ await CreateHandlerAndAddToWindow(view, () => [Fact] public async Task FindVisualTreeElementWithArbitraryPlatformViewsAdded() { - SetupBuilder(); var button = new Button(); NestingView view = new NestingView(); @@ -171,7 +176,6 @@ await CreateHandlerAndAddToWindow(view, (handler) => [InlineData(true)] public async Task FindFirstMauiParentElement(bool searchAncestors) { - SetupBuilder(); var viewToLocate = new NestingView(); NestingView view = new NestingView(); @@ -197,8 +201,6 @@ await CreateHandlerAndAddToWindow(view, (handler) => [ClassData(typeof(FindVisualTreeElementInsideTestCases))] public async Task FindPlatformViewInsideView(FindVisualTreeElementInsideTestCase testCase) { - SetupBuilder(); - VisualElement rootView; VisualElement viewToLocate; diff --git a/src/Controls/tests/DeviceTests/Elements/WebView/WebViewTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/WebView/WebViewTests.Windows.cs index 841f1c102f17..b0fb444e33bf 100644 --- a/src/Controls/tests/DeviceTests/Elements/WebView/WebViewTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/WebView/WebViewTests.Windows.cs @@ -12,8 +12,6 @@ public partial class WebViewTests : ControlsHandlerTestBase [Fact(DisplayName = "Evaluate JavaScript returning a String value")] public async Task EvaluateJavaScriptWithString() { - SetupBuilder(); - string actual = string.Empty; var pageLoadTimeout = TimeSpan.FromSeconds(2); @@ -81,8 +79,6 @@ await AttachAndRun(webView, async (handler) => [Fact(DisplayName = "Evaluate JavaScript returning an Integer value")] public async Task EvaluateJavaScriptWithInteger() { - SetupBuilder(); - string actual = string.Empty; var pageLoadTimeout = TimeSpan.FromSeconds(2); diff --git a/src/Controls/tests/DeviceTests/Elements/WebView/WebViewTests.cs b/src/Controls/tests/DeviceTests/Elements/WebView/WebViewTests.cs index e5b84c942ae5..d4e033db5cb3 100644 --- a/src/Controls/tests/DeviceTests/Elements/WebView/WebViewTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/WebView/WebViewTests.cs @@ -7,15 +7,9 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.WebView)] public partial class WebViewTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(); - }); - }); - } + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler()); } } diff --git a/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.Windows.cs b/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.Windows.cs index 999a87590255..4c0842bf9479 100644 --- a/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.Windows.cs +++ b/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.Windows.cs @@ -17,8 +17,6 @@ public partial class WindowTests : ControlsHandlerTestBase [Fact(DisplayName = "Swapping MainPage doesn't Crash")] public async Task SwappingMainPageDoesntCrash() { - SetupBuilder(); - var mainPage = new ContentPage { BackgroundColor = Colors.Red @@ -47,8 +45,6 @@ await CreateHandlerAndAddToWindow(mainPage, (handler) => [Fact] public async Task AdornerLayerAdded() { - SetupBuilder(); - var mainPage = new NavigationPage(new ContentPage()); await CreateHandlerAndAddToWindow(mainPage, (handler) => @@ -69,8 +65,6 @@ await CreateHandlerAndAddToWindow(mainPage, (handler) => [Fact(DisplayName = "Swapping Root Page Removes Previous Page from WindowRootViewContainer")] public async Task SwappingRootPageRemovesPreviousPageFromWindowRootViewContainer() { - SetupBuilder(); - var mainPage = new Shell() { CurrentItem = new ContentPage() }; var swappedInMainPage = new NavigationPage(new ContentPage()); @@ -94,8 +88,6 @@ await CreateHandlerAndAddToWindow(mainPage, async (handler) => [Fact] public async Task HeaderCorrectlyOffsetFromAppTitleBar() { - SetupBuilder(); - var mainPage = new NavigationPage(new ContentPage() { Title = "title", @@ -127,8 +119,6 @@ await CreateHandlerAndAddToWindow(mainPage, async (handler) => [ClassData(typeof(WindowPageSwapTestCases))] public async Task HeaderCorrectlyOffsetsWhenSwappingMainPage(WindowPageSwapTestCase swapOrder) { - SetupBuilder(); - var firstRootPage = swapOrder.GetNextPageType(); var window = new Window(firstRootPage); diff --git a/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.cs b/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.cs index 408db0674023..a7475ddf269b 100644 --- a/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.cs @@ -33,13 +33,11 @@ namespace Microsoft.Maui.DeviceTests #endif public partial class WindowTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { - SetupShellHandlers(handlers); + handlers.SetupShellHandlers(); #if ANDROID || WINDOWS handlers.AddHandler(typeof(NavigationPage), typeof(NavigationViewHandler)); @@ -56,15 +54,12 @@ void SetupBuilder() handlers.AddHandler(); handlers.AddHandler(); }); - }); - } #if !IOS [Theory] [ClassData(typeof(ChangingToNewMauiContextDoesntCrashTestCases))] public async Task ChangingToNewMauiContextDoesntCrash(bool useAppMainPage, Type rootPageType) { - SetupBuilder(); IWindow window; var rootPage = (Page)Activator.CreateInstance(rootPageType); @@ -118,8 +113,6 @@ await CreateHandlerAndAddToWindow(window, async (handler) => [ClassData(typeof(WindowPageSwapTestCases))] public async Task MainPageSwapTests(WindowPageSwapTestCase swapOrder) { - SetupBuilder(); - var firstRootPage = swapOrder.GetNextPageType(); var window = new Window(firstRootPage); @@ -171,7 +164,6 @@ await CreateHandlerAndAddToWindow(window, async (handler) => [Fact(DisplayName = "Toolbar Items Update when swapping out Main Page on Handler")] public async Task ToolbarItemsUpdateWhenSwappingOutMainPageOnHandler() { - SetupBuilder(); var toolbarItem = new ToolbarItem() { Text = "Toolbar Item 1" }; var firstPage = new ContentPage(); diff --git a/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.iOS.cs index a545ab7f8f56..9a3d472edde6 100644 --- a/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.iOS.cs @@ -16,7 +16,6 @@ public partial class WindowTests [InlineData(typeof(SearchBar))] public async Task FocusedTextInputAddsResignFirstResponderGesture(Type controlType) { - SetupBuilder(); var layout = new VerticalStackLayout(); var view = (View)Activator.CreateInstance(controlType); layout.Children.Add(view); @@ -45,7 +44,6 @@ await CreateHandlerAndAddToWindow(layout, async (handler) => [InlineData(typeof(SearchBar))] public async Task RemovingControlFromWindowRemovesGesture(Type controlType) { - SetupBuilder(); var layout = new VerticalStackLayout(); var view = (View)Activator.CreateInstance(controlType); diff --git a/src/Controls/tests/DeviceTests/Extensions.cs b/src/Controls/tests/DeviceTests/Extensions.cs deleted file mode 100644 index aae2e12c79bd..000000000000 --- a/src/Controls/tests/DeviceTests/Extensions.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.Maui.Controls; -using Microsoft.Maui.Controls.Handlers; -using Microsoft.Maui.Controls.Hosting; -using Microsoft.Maui.Devices; -using Microsoft.Maui.DeviceTests.Stubs; -using Microsoft.Maui.Graphics; -using Microsoft.Maui.Handlers; -using Microsoft.Maui.Hosting; -using Microsoft.Maui.Platform; -using Xunit; -#if ANDROID || IOS || MACCATALYST -using ShellHandler = Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer; -#endif - -namespace Microsoft.Maui.DeviceTests -{ - public static class Extensions - { - public static Task Wait(this Image image, int timeout = 1000) => - AssertionExtensions.Wait(() => !image.IsLoading, timeout); - - public static void SetupShellHandlers(this MauiAppBuilder builder) - { - builder.ConfigureMauiHandlers(SetupShellHandlers); - } - - public static void SetupShellHandlers(this IMauiHandlersCollection handlers) - { - handlers.TryAddHandler(typeof(Controls.Shell), typeof(ShellHandler)); - handlers.TryAddHandler(); - handlers.TryAddHandler(); - handlers.TryAddHandler(); - handlers.TryAddHandler(); - handlers.TryAddHandler(); - handlers.TryAddHandler(typeof(Toolbar), typeof(ToolbarHandler)); - handlers.TryAddHandler(typeof(MenuBar), typeof(MenuBarHandler)); - handlers.TryAddHandler(typeof(MenuBarItem), typeof(MenuBarItemHandler)); - handlers.TryAddHandler(typeof(MenuFlyoutItem), typeof(MenuFlyoutItemHandler)); - handlers.TryAddHandler(typeof(MenuFlyoutSubItem), typeof(MenuFlyoutSubItemHandler)); - handlers.TryAddHandler(); - -#if WINDOWS - handlers.TryAddHandler(typeof(ShellItem), typeof(ShellItemHandler)); - handlers.TryAddHandler(typeof(ShellSection), typeof(ShellSectionHandler)); - handlers.TryAddHandler(typeof(ShellContent), typeof(ShellContentHandler)); -#endif - } - } -} - diff --git a/src/Controls/tests/DeviceTests/Memory/MemoryTests.cs b/src/Controls/tests/DeviceTests/Memory/MemoryTests.cs index 74b06b3cd080..f4637f21cfbe 100644 --- a/src/Controls/tests/DeviceTests/Memory/MemoryTests.cs +++ b/src/Controls/tests/DeviceTests/Memory/MemoryTests.cs @@ -10,38 +10,38 @@ namespace Microsoft.Maui.DeviceTests.Memory; public class MemoryTests : ControlsHandlerTestBase { - void SetupBuilder() - { - EnsureHandlerCreated(builder => - { - builder.ConfigureMauiHandlers(handlers => + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => { + handlers.AddHandler(); + handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); - handlers.AddHandler(); handlers.AddHandler(); + handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); - handlers.AddHandler(); handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); handlers.AddHandler(); handlers.AddHandler(); }); - }); - } [Theory("Handler Does Not Leak")] [InlineData(typeof(Border))] - [InlineData(typeof(ContentView))] [InlineData(typeof(CheckBox))] + [InlineData(typeof(ContentView))] [InlineData(typeof(DatePicker))] - [InlineData(typeof(Entry))] [InlineData(typeof(Editor))] + [InlineData(typeof(Entry))] [InlineData(typeof(GraphicsView))] [InlineData(typeof(Image))] [InlineData(typeof(Label))] @@ -52,8 +52,6 @@ void SetupBuilder() [InlineData(typeof(TimePicker))] public async Task HandlerDoesNotLeak(Type type) { - SetupBuilder(); - #if ANDROID // NOTE: skip certain controls on older Android devices if (type == typeof (DatePicker) && !OperatingSystem.IsAndroidVersionAtLeast(30)) diff --git a/src/Controls/tests/DeviceTests/TextTransformCases.cs b/src/Controls/tests/DeviceTests/TestCases/TextTransformCases.cs similarity index 100% rename from src/Controls/tests/DeviceTests/TextTransformCases.cs rename to src/Controls/tests/DeviceTests/TestCases/TextTransformCases.cs diff --git a/src/Core/tests/DeviceTests.Shared/HandlerTests/Focus/FocusHandlerTests.cs b/src/Core/tests/DeviceTests.Shared/HandlerTests/Focus/FocusHandlerTests.cs index 9baba69af963..f9239caebd13 100644 --- a/src/Core/tests/DeviceTests.Shared/HandlerTests/Focus/FocusHandlerTests.cs +++ b/src/Core/tests/DeviceTests.Shared/HandlerTests/Focus/FocusHandlerTests.cs @@ -10,6 +10,13 @@ public abstract partial class FocusHandlerTests : where TStub : IStubBase, new() where TLayoutStub : IStubBase, ILayout, new() { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(); + }); + [Fact] public async Task FocusAndIsFocusedIsWorking() { diff --git a/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBaseOfT.Tests.cs b/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBaseOfT.Tests.cs index c5ef4fe3d7d8..1a89163a60ae 100644 --- a/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBaseOfT.Tests.cs +++ b/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBaseOfT.Tests.cs @@ -361,5 +361,20 @@ public void HandlersHaveAllExpectedContructors() Assert.True(hasBothMappers, "Missing constructor with IPropertyMapper and ICommandMapper"); } + + protected void MockAccessibilityExpectations(TStub view) + { +#if IOS || MACCATALYST + var mapperOverride = new PropertyMapper(); + view.PropertyMapperOverrides = mapperOverride; + + mapperOverride + .ModifyMapping(nameof(IView.Semantics), (handler, view, _) => + { + (handler.PlatformView as UIKit.UIView)?.SetupAccessibilityExpectationIfVoiceOverIsOff(); + mapperOverride.Chained[0]!.UpdateProperty(handler, view, nameof(IView.Semantics)); + }); +#endif + } } } diff --git a/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBasement.cs b/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBasement.cs index 064c3294d722..aaacb88c83e1 100644 --- a/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBasement.cs +++ b/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBasement.cs @@ -25,23 +25,23 @@ public class HandlerTestBasement : TestBase, IDisposable IMauiContext _mauiContext; bool _isCreated; + // Builder + public void EnsureHandlerCreated(Action additionalCreationActions = null) { if (_isCreated) - { return; - } _isCreated = true; - var appBuilder = MauiApp.CreateBuilder(); appBuilder.Services.AddSingleton(svc => TestDispatcher.Provider); appBuilder.Services.AddScoped(svc => TestDispatcher.Current); appBuilder.Services.AddSingleton((_) => new CoreApplicationStub()); - appBuilder = ConfigureBuilder(appBuilder); + ConfigureBuilder(appBuilder); + additionalCreationActions?.Invoke(appBuilder); _mauiApp = appBuilder.Build(); @@ -50,10 +50,8 @@ public void EnsureHandlerCreated(Action additionalCreationAction _mauiContext = new ContextStub(_servicesProvider); } - protected virtual MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) - { - return mauiAppBuilder; - } + protected virtual MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + mauiAppBuilder; protected IMauiContext MauiContext { @@ -73,6 +71,8 @@ protected IServiceProvider ApplicationServices } } + // Values + protected Task SetValueAsync(IView view, TValue value, Action func) where THandler : IElementHandler, new() { @@ -83,9 +83,7 @@ protected Task SetValueAsync(IView view, TValue value, Action< }); } - protected THandler CreateHandler(IElement view, IMauiContext mauiContext = null) - where THandler : IElementHandler, new() - => CreateHandler(view, mauiContext); + // Handlers protected void InitializeViewHandler(IElement element, IElementHandler handler, IMauiContext mauiContext = null) { @@ -152,45 +150,23 @@ void SwipeViewLoaded(object s, RoutedEventArgs e) } } - protected TCustomHandler CreateHandler(IElement element, IMauiContext mauiContext) - where THandler : IElementHandler, new() - where TCustomHandler : THandler, new() + protected THandler CreateHandler(IElement element, IMauiContext mauiContext = null) + where THandler : IElementHandler { - if (element.Handler is TCustomHandler t) + if (element.Handler is THandler t) return t; mauiContext ??= MauiContext; - var handler = Activator.CreateInstance(); + var handler = mauiContext.Handlers.GetHandler(element.GetType()); + Assert.IsAssignableFrom(handler); InitializeViewHandler(element, handler, mauiContext); - return handler; - } - - protected IPlatformViewHandler CreateHandler(IElement view, Type handlerType) - { - if (view.Handler is IPlatformViewHandler t) - return t; - - var handler = (IPlatformViewHandler)Activator.CreateInstance(handlerType); - InitializeViewHandler(view, handler, MauiContext); - return handler; - + return (THandler)handler; } - protected Task ValidateHasColor(IView view, Color color, Type handlerType, Action action = null, string updatePropertyValue = null, double? tolerance = null) - { - return InvokeOnMainThreadAsync(async () => - { - var handler = CreateHandler(view, handlerType); - var plaformView = handler.ToPlatform(); - action?.Invoke(); - if (!string.IsNullOrEmpty(updatePropertyValue)) - { - handler.UpdateValue(updatePropertyValue); - } + protected IElementHandler CreateHandler(IElement element, IMauiContext mauiContext = null) => + CreateHandler(element, mauiContext); - await plaformView.AssertContainsColor(color, MauiContext, tolerance: tolerance); - }); - } + // AttachAndRun public Task AttachAndRun(IView view, Action action) => AttachAndRun(view, (handler) => @@ -258,19 +234,47 @@ public Task AttachAndRun(IView view, Action return result; }); - protected Task AssertColorAtPoint(IView view, Color color, Type handlerType, int x, int y) + // AssertColor* + + protected Task AssertColorAtPoint(IView view, Color color, int x, int y) { return InvokeOnMainThreadAsync(async () => { - var plaformView = CreateHandler(view, handlerType).ToPlatform(); + var handler = CreateHandler(view); + var platformView = handler.ToPlatform(); #if WINDOWS - await plaformView.AssertColorAtPointAsync(color.ToWindowsColor(), x, y, MauiContext); + await platformView.AssertColorAtPointAsync(color.ToWindowsColor(), x, y, MauiContext); #else - await plaformView.AssertColorAtPointAsync(color.ToPlatform(), x, y, MauiContext); + await platformView.AssertColorAtPointAsync(color.ToPlatform(), x, y, MauiContext); #endif }); } + protected Task ValidateHasColor(IView view, Color color, Action action = null, string updatePropertyValue = null, double? tolerance = null) + { + return InvokeOnMainThreadAsync(async () => + { + var handler = CreateHandler(view); + var platformView = handler.ToPlatform(); + + action?.Invoke(); + + if (!string.IsNullOrEmpty(updatePropertyValue)) + { + handler.UpdateValue(updatePropertyValue); + } + + await platformView.AssertContainsColor(color, MauiContext, tolerance: tolerance); + }); + } + + // Helpers + + public static Task Wait(Func exitCondition, int timeout = 1000) => + AssertionExtensions.Wait(exitCondition, timeout); + + // Dispose + public void Dispose() { ((IDisposable)_mauiApp)?.Dispose(); diff --git a/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBasementOfT.cs b/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBasementOfT.cs index 477deeb2aebb..747ef2e37c0e 100644 --- a/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBasementOfT.cs +++ b/src/Core/tests/DeviceTests.Shared/HandlerTests/HandlerTestBasementOfT.cs @@ -10,27 +10,31 @@ public partial class HandlerTestBasement : HandlerTestBasement where THandler : class, IViewHandler, new() where TStub : IStubBase, IView, new() { - public static Task Wait(Func exitCondition, int timeout = 1000) => - AssertionExtensions.Wait(exitCondition, timeout); + // Handlers protected THandler CreateHandler(IView view, IMauiContext mauiContext = null) => CreateHandler(view, mauiContext); - public Task AttachAndRun(IView view, Action action) => + protected Task CreateHandlerAsync(IView view, IMauiContext mauiContext = null) => + InvokeOnMainThreadAsync(() => CreateHandler(view, mauiContext)); + + // AttachAndRun + + protected Task AttachAndRun(IView view, Action action) => AttachAndRun(view, (handler) => { action(handler); return Task.FromResult(true); }); - public Task AttachAndRun(IView view, Func action) => + protected Task AttachAndRun(IView view, Func action) => AttachAndRun(view, async (handler) => { await action(handler); return true; }); - public Task AttachAndRun(IView view, Func action) + protected Task AttachAndRun(IView view, Func action) { Func> boop = (handler) => { @@ -40,7 +44,7 @@ public Task AttachAndRun(IView view, Func action) return AttachAndRun(view, boop); } - public Task AttachAndRun(IView view, Func> action) + protected Task AttachAndRun(IView view, Func> action) { return view.AttachAndRun((handler) => { @@ -48,13 +52,7 @@ public Task AttachAndRun(IView view, Func> action) }, MauiContext, async (view) => (IPlatformViewHandler)(await CreateHandlerAsync(view))); } - protected Task CreateHandlerAsync(IView view) - { - return InvokeOnMainThreadAsync(() => - { - return CreateHandler(view); - }); - } + // Values protected Task GetValueAsync(IView view, Func func) { @@ -74,32 +72,12 @@ protected Task GetValueAsync(IView view, Func GetValueAsync(IView view, Func func) - where TCustomHandler : IElementHandler, new() - { - return InvokeOnMainThreadAsync(() => - { - var handler = CreateHandler(view); - return func(handler); - }); - } - - protected Task GetValueAsync(IView view, Func> func) - where TCustomHandler : IElementHandler, new() - { - return InvokeOnMainThreadAsync(() => - { - var handler = CreateHandler(view); - return func(handler); - }); - } - protected Task SetValueAsync(IView view, TValue value, Action func) { return SetValueAsync(view, value, func); } - async protected Task ValidatePropertyInitValue( + protected async Task ValidatePropertyInitValue( IView view, Func GetValue, Func GetPlatformValue, @@ -118,27 +96,7 @@ async protected Task ValidatePropertyInitValue( Assert.Equal(expectedValue, values.PlatformViewValue); } - async protected Task ValidatePropertyInitValue( - IView view, - Func GetValue, - Func GetPlatformValue, - TValue expectedValue) - where TCustomHandler : IElementHandler, new() - { - var values = await GetValueAsync(view, (TCustomHandler handler) => - { - return new - { - ViewValue = GetValue(), - PlatformViewValue = GetPlatformValue(handler) - }; - }); - - Assert.Equal(expectedValue, values.ViewValue); - Assert.Equal(expectedValue, values.PlatformViewValue); - } - - async protected Task ValidatePropertyInitValue( + protected async Task ValidatePropertyInitValue( IView view, Func GetValue, Func GetPlatformValue, @@ -158,28 +116,7 @@ async protected Task ValidatePropertyInitValue( Assert.Equal(expectedPlatformValue, values.PlatformViewValue); } - async protected Task ValidatePropertyInitValue( - IView view, - Func GetValue, - Func GetPlatformValue, - TValue expectedValue, - TValue expectedPlatformValue) - where TCustomHandler : IElementHandler, new() - { - var values = await GetValueAsync(view, (TCustomHandler handler) => - { - return new - { - ViewValue = GetValue(), - PlatformViewValue = GetPlatformValue(handler) - }; - }); - - Assert.Equal(expectedValue, values.ViewValue); - Assert.Equal(expectedPlatformValue, values.PlatformViewValue); - } - - async protected Task ValidatePropertyUpdatesValue( + protected async Task ValidatePropertyUpdatesValue( IView view, string property, Func GetPlatformValue, @@ -204,7 +141,7 @@ async protected Task ValidatePropertyUpdatesValue( await ValidatePropertyUpdatesAfterInitValue(handler, property, GetPlatformValue, expectedSetValue, expectedUnsetValue); } - async protected Task ValidatePropertyUpdatesAfterInitValue( + protected async Task ValidatePropertyUpdatesAfterInitValue( THandler handler, string property, Func GetPlatformValue, @@ -241,7 +178,7 @@ async protected Task ValidatePropertyUpdatesAfterInitValue( Assert.Equal(expectedSetValue, nativeVal); } - async protected Task ValidateUnrelatedPropertyUnaffected( + protected async Task ValidateUnrelatedPropertyUnaffected( IView view, Func GetPlatformValue, string property, @@ -270,23 +207,7 @@ async protected Task ValidateUnrelatedPropertyUnaffected( Assert.Equal(initialNativeVal, newNativeVal); } - protected Task ValidateHasColor(IView view, Color color, Action action = null, string updatePropertyValue = null, double? tolerance = null) => - ValidateHasColor(view, color, typeof(THandler), action, updatePropertyValue, tolerance: tolerance); - - protected void MockAccessibilityExpectations(TStub view) - { -#if IOS || MACCATALYST - var mapperOverride = new PropertyMapper(); - view.PropertyMapperOverrides = mapperOverride; - - mapperOverride - .ModifyMapping(nameof(IView.Semantics), (handler, view, _) => - { - (handler.PlatformView as UIKit.UIView)?.SetupAccessibilityExpectationIfVoiceOverIsOff(); - mapperOverride.Chained[0]!.UpdateProperty(handler, view, nameof(IView.Semantics)); - }); -#endif - } + // Helpers protected void AssertWithinTolerance(double expected, double actual, double tolerance = 0.2, string message = "Value was not within tolerance.") { diff --git a/src/Core/tests/DeviceTests.Shared/HandlerTests/TextInput/TextInputHandlerTests.cs b/src/Core/tests/DeviceTests.Shared/HandlerTests/TextInput/TextInputHandlerTests.cs index 3f50b6588436..2aca3bb04a75 100644 --- a/src/Core/tests/DeviceTests.Shared/HandlerTests/TextInput/TextInputHandlerTests.cs +++ b/src/Core/tests/DeviceTests.Shared/HandlerTests/TextInput/TextInputHandlerTests.cs @@ -9,6 +9,13 @@ public abstract partial class TextInputHandlerTests : HandlerTe where THandler : class, IViewHandler, new() where TStub : IStubBase, ITextInputStub, new() { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(); + }); + [Theory(DisplayName = "TextChanged Events Fire Correctly" #if WINDOWS , Skip = "For some reason, the PlatformView.TextChanged event is not being fired on tests, something is swallowing the event firing. " + diff --git a/src/Core/tests/DeviceTests.Shared/HandlerTests/TextStyle/TextStyleHandlerTests.cs b/src/Core/tests/DeviceTests.Shared/HandlerTests/TextStyle/TextStyleHandlerTests.cs index a8b5278ea847..fa7de3789518 100644 --- a/src/Core/tests/DeviceTests.Shared/HandlerTests/TextStyle/TextStyleHandlerTests.cs +++ b/src/Core/tests/DeviceTests.Shared/HandlerTests/TextStyle/TextStyleHandlerTests.cs @@ -11,6 +11,13 @@ public partial class TextStyleHandlerTests : HandlerTestBasemen where THandler : class, IViewHandler, new() where TStub : IStubBase, IView, ITextStyle, new() { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(); + }); + #if !WINDOWS [Theory(DisplayName = "Font Size Initializes Correctly")] [InlineData(1)] diff --git a/src/Core/tests/DeviceTests/ApplicationTests.Android.cs b/src/Core/tests/DeviceTests/Application/ApplicationTests.Android.cs similarity index 100% rename from src/Core/tests/DeviceTests/ApplicationTests.Android.cs rename to src/Core/tests/DeviceTests/Application/ApplicationTests.Android.cs diff --git a/src/Core/tests/DeviceTests/CoreDeviceTestExtensions.cs b/src/Core/tests/DeviceTests/CoreDeviceTestExtensions.cs deleted file mode 100644 index 5d79f4a34c22..000000000000 --- a/src/Core/tests/DeviceTests/CoreDeviceTestExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using Microsoft.Maui.DeviceTests.Stubs; -using Microsoft.Maui.Hosting; - -namespace Microsoft.Maui.DeviceTests -{ - public static class CoreDeviceTestExtensions - { - public static MauiAppBuilder ConfigureTestBuilder(this MauiAppBuilder mauiAppBuilder) - { - return mauiAppBuilder - .ConfigureMauiHandlers(handlers => - { - handlers.AddHandler(typeof(ButtonWithContainerStub), typeof(ButtonWithContainerStubHandler)); - handlers.AddHandler(typeof(SliderStub), typeof(SliderHandler)); - handlers.AddHandler(typeof(ButtonStub), typeof(ButtonHandler)); - handlers.AddHandler(typeof(ElementStub), typeof(ElementHandlerStub)); - }) - .ConfigureImageSources(services => - { - services.AddService(); - }) - .ConfigureFonts(fonts => - { - fonts.AddFont("dokdo_regular.ttf", "Dokdo"); - fonts.AddFont("LobsterTwo-Regular.ttf", "Lobster Two"); - fonts.AddFont("LobsterTwo-Bold.ttf", "Lobster Two Bold"); - fonts.AddFont("LobsterTwo-Italic.ttf", "Lobster Two Italic"); - fonts.AddFont("LobsterTwo-BoldItalic.ttf", "Lobster Two BoldItalic"); - }); - } - } -} diff --git a/src/Core/tests/DeviceTests/Handlers/Button/ButtonHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/Button/ButtonHandlerTests.cs index 5255ad411038..530d69ba512c 100644 --- a/src/Core/tests/DeviceTests/Handlers/Button/ButtonHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Button/ButtonHandlerTests.cs @@ -74,7 +74,7 @@ public async Task ClickEventFires() [InlineData("black.png", "#000000")] public async Task ImageSourceInitializesCorrectly(string filename, string colorHex) { - var image = new ButtonStub + var button = new ButtonStub { Background = new SolidPaintStub(Colors.Black), ImageSource = new FileImageSourceStub(filename), @@ -82,7 +82,7 @@ public async Task ImageSourceInitializesCorrectly(string filename, string colorH await InvokeOnMainThreadAsync(async () => { - var handler = CreateHandler(image); + var handler = CreateHandler(button); bool imageLoaded = await Wait(() => ImageSourceLoaded(handler)); diff --git a/src/Core/tests/DeviceTests/Handlers/CheckBox/CheckBoxHandlerTests.Android.cs b/src/Core/tests/DeviceTests/Handlers/CheckBox/CheckBoxHandlerTests.Android.cs index e77c5222fa32..4b4aef553aad 100644 --- a/src/Core/tests/DeviceTests/Handlers/CheckBox/CheckBoxHandlerTests.Android.cs +++ b/src/Core/tests/DeviceTests/Handlers/CheckBox/CheckBoxHandlerTests.Android.cs @@ -4,6 +4,7 @@ using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.Graphics; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests @@ -15,6 +16,10 @@ public partial class CheckBoxHandlerTests [InlineData(0xFF0000FF)] public async Task ColorUpdatesCorrectly(uint color) { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + var layout = new LayoutStub(); var checkBox = new CheckBoxStub diff --git a/src/Core/tests/DeviceTests/Handlers/CoreHandlerTestBase.cs b/src/Core/tests/DeviceTests/Handlers/CoreHandlerTestBase.cs index b6ed3a0496a3..48378a48c5c6 100644 --- a/src/Core/tests/DeviceTests/Handlers/CoreHandlerTestBase.cs +++ b/src/Core/tests/DeviceTests/Handlers/CoreHandlerTestBase.cs @@ -6,7 +6,5 @@ namespace Microsoft.Maui.DeviceTests { public abstract class CoreHandlerTestBase : HandlerTestBase, IDisposable { - protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => - mauiAppBuilder.ConfigureTestBuilder(); } -} \ No newline at end of file +} diff --git a/src/Core/tests/DeviceTests/Handlers/CoreHandlerTestBaseOfT.cs b/src/Core/tests/DeviceTests/Handlers/CoreHandlerTestBaseOfT.cs index 434f296f8071..589122c7a9ab 100644 --- a/src/Core/tests/DeviceTests/Handlers/CoreHandlerTestBaseOfT.cs +++ b/src/Core/tests/DeviceTests/Handlers/CoreHandlerTestBaseOfT.cs @@ -8,6 +8,10 @@ public abstract partial class CoreHandlerTestBase : HandlerTest where TStub : StubBase, IView, new() { protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => - mauiAppBuilder.ConfigureTestBuilder(); + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(); + }); } -} \ No newline at end of file +} diff --git a/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.cs index ea69e5944ff9..327c118ed298 100644 --- a/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.cs @@ -1,8 +1,10 @@ -using System.Threading.Tasks; +using System.Linq; +using System.Threading.Tasks; using Microsoft.Maui.Controls; using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.Graphics; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests @@ -24,18 +26,25 @@ public async Task TextInitializesCorrectly() [Fact(DisplayName = "Text Property Initializes Correctly when Keyboard Mapper is Executed Before Text Mapper")] public async Task TextInitializesCorrectlyWhenKeyboardIsBeforeText() { - var editor = new EditorStub() - { - Text = "Test Text Here" - }; - CustomEditorHandler.TestMapper = new PropertyMapper(EditorHandler.Mapper) { // this mapper is run first and then the ones in the ctor arg (EditorHandler.Mapper) [nameof(IEditor.Keyboard)] = EditorHandler.MapKeyboard }; - await ValidatePropertyInitValue(editor, () => editor.Text, GetNativeText, editor.Text); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + + var editor = new EditorStub() + { + Text = "Test Text Here" + }; + + await ValidatePropertyInitValue(editor, () => editor.Text, GetNativeText, editor.Text); + + var handler = Assert.IsType(editor.Handler); + Assert.True(handler._mapper.GetKeys().First() == "Keyboard", "Keyboard was not first in the list."); } [Theory(DisplayName = "Text Updates Correctly")] diff --git a/src/Core/tests/DeviceTests/Handlers/Element/ElementTests.cs b/src/Core/tests/DeviceTests/Handlers/Element/ElementTests.cs index 4aa55ca9a8cf..52402c271915 100644 --- a/src/Core/tests/DeviceTests/Handlers/Element/ElementTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Element/ElementTests.cs @@ -4,12 +4,18 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Maui.DeviceTests.Stubs; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests { public partial class ElementTests : CoreHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + handlers.AddHandler(typeof(ElementStub), typeof(ElementHandlerStub))); + [Fact] public void ElementToHandlerReturnsIElementHandler() { diff --git a/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Android.cs b/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Android.cs index 09529b05a014..6baafd5cb7bb 100644 --- a/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Android.cs +++ b/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Android.cs @@ -8,6 +8,7 @@ using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.Graphics; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Xunit; using AColor = Android.Graphics.Color; @@ -20,6 +21,10 @@ public partial class EntryHandlerTests [InlineData(nameof(Keyboard.Numeric), true)] public async Task ValidateNumericKeyboardUpdatesCorrectlyWithIsPassword(string keyboardName, bool expected) { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handler => + handler.AddHandler())); + var layout = new LayoutStub(); var keyboard = (Keyboard)typeof(Keyboard).GetProperty(keyboardName).GetValue(null); @@ -58,6 +63,10 @@ public async Task ValidateNumericKeyboardUpdatesCorrectlyWithIsPassword(string k [Fact(DisplayName = "Entry Background Updates Correctly")] public async Task BackgroundUpdatesCorrectly() { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handler => + handler.AddHandler())); + var expected = Colors.Red; var layout = new LayoutStub(); diff --git a/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Windows.cs b/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Windows.cs index 268bfa8b2d6a..c138fbe1f182 100644 --- a/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Windows.cs +++ b/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Windows.cs @@ -3,6 +3,7 @@ using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.Graphics; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Microsoft.Maui.Platform; using Microsoft.UI.Xaml.Automation.Peers; using Microsoft.UI.Xaml.Automation.Provider; @@ -24,6 +25,10 @@ public partial class EntryHandlerTests [InlineData(TextAlignment.End)] public async Task VerticalTextAlignmentWorksCorrectlyWithHiddenEntry(TextAlignment textAlignment) { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + var layout = new LayoutStub(); var entry = new EntryStub diff --git a/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.cs index c09453a46cf7..121bfdaa91a8 100644 --- a/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Threading.Tasks; using Microsoft.Maui.Controls; using Microsoft.Maui.DeviceTests.Stubs; @@ -26,52 +27,73 @@ public async Task TextInitializesCorrectly() [Fact(DisplayName = "Text Property Initializes Correctly when Keyboard Mapper is Executed Before Text Mapper")] public async Task TextInitializesCorrectlyWhenKeyboardIsBeforeText() { - var entry = new EntryStub() - { - Text = "Test Text Here" - }; - CustomEntryHandler.TestMapper = new PropertyMapper(EntryHandler.Mapper) { // this mapper is run first and then the ones in the ctor arg (EntryHandler.Mapper) [nameof(IEntry.Keyboard)] = EntryHandler.MapKeyboard }; - await ValidatePropertyInitValue(entry, () => entry.Text, GetNativeText, entry.Text); - } + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); - [Fact(DisplayName = "Text Property Initializes Correctly when IsReadOnly Mapper is Executed Before Text Mapper")] - public async Task TextInitializesCorrectlyWhenIsReadOnlyIsBeforeText() - { var entry = new EntryStub() { Text = "Test Text Here" }; + await ValidatePropertyInitValue(entry, () => entry.Text, GetNativeText, entry.Text); + + var handler = Assert.IsType(entry.Handler); + Assert.True(handler._mapper.GetKeys().First() == "Keyboard", "Keyboard was not first in the list."); + } + + [Fact(DisplayName = "Text Property Initializes Correctly when IsReadOnly Mapper is Executed Before Text Mapper")] + public async Task TextInitializesCorrectlyWhenIsReadOnlyIsBeforeText() + { CustomEntryHandler.TestMapper = new PropertyMapper(EntryHandler.Mapper) { // this mapper is run first and then the ones in the ctor arg (EntryHandler.Mapper) [nameof(IEntry.IsReadOnly)] = EntryHandler.MapIsReadOnly }; - await ValidatePropertyInitValue(entry, () => entry.Text, GetNativeText, entry.Text); - } + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); - [Fact(DisplayName = "Text Property Initializes Correctly when IsPassword Mapper is Executed Before Text Mapper")] - public async Task TextInitializesCorrectlyWhenIsPasswordIsBeforeText() - { var entry = new EntryStub() { Text = "Test Text Here" }; + await ValidatePropertyInitValue(entry, () => entry.Text, GetNativeText, entry.Text); + + var handler = Assert.IsType(entry.Handler); + Assert.True(handler._mapper.GetKeys().First() == "IsReadOnly", "IsReadOnly was not first in the list."); + } + + [Fact(DisplayName = "Text Property Initializes Correctly when IsPassword Mapper is Executed Before Text Mapper")] + public async Task TextInitializesCorrectlyWhenIsPasswordIsBeforeText() + { CustomEntryHandler.TestMapper = new PropertyMapper(EntryHandler.Mapper) { // this mapper is run first and then the ones in the ctor arg (EntryHandler.Mapper) [nameof(IEntry.IsPassword)] = EntryHandler.MapIsPassword }; - await ValidatePropertyInitValue(entry, () => entry.Text, GetNativeText, entry.Text); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + + var entry = new EntryStub() + { + Text = "Test Text Here" + }; + + await ValidatePropertyInitValue(entry, () => entry.Text, GetNativeText, entry.Text); + + var handler = Assert.IsType(entry.Handler); + Assert.True(handler._mapper.GetKeys().First() == "IsPassword", "IsPassword was not first in the list."); } [Fact(DisplayName = "TextColor Initializes Correctly")] diff --git a/src/Core/tests/DeviceTests/Handlers/Image/ImageHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/Image/ImageHandlerTests.cs index e159819e1857..c0ba19243562 100644 --- a/src/Core/tests/DeviceTests/Handlers/Image/ImageHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Image/ImageHandlerTests.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Maui.DeviceTests.Stubs; using Xunit; +using Microsoft.Maui.Hosting; #if ANDROID using Android.Graphics.Drawables; @@ -34,6 +35,11 @@ public abstract partial class ImageHandlerTests : CoreHand const string ImageEventCustomMemberName = "Image"; #endif + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureImageSources(services => + services.AddService()); + [Theory( #if IOS || MACCATALYST Skip = "Test failing on iOS" diff --git a/src/Core/tests/DeviceTests/Handlers/Layout/LayoutHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/Layout/LayoutHandlerTests.cs index d351b79ab580..8b9395de1673 100644 --- a/src/Core/tests/DeviceTests/Handlers/Layout/LayoutHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Layout/LayoutHandlerTests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests.Handlers.Layout @@ -9,6 +10,15 @@ namespace Microsoft.Maui.DeviceTests.Handlers.Layout [Category(TestCategory.Layout)] public partial class LayoutHandlerTests : CoreHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(); + handlers.AddHandler(); + handlers.AddHandler(); + }); + [Fact(DisplayName = "Shadow Initializes Correctly", Skip = "This test is currently invalid https://github.com/dotnet/maui/issues/13692")] public async Task ShadowInitializesCorrectly() diff --git a/src/Core/tests/DeviceTests/Handlers/Navigation/NavigationViewHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/Navigation/NavigationViewHandlerTests.cs index fef04e717078..7521ac01a860 100644 --- a/src/Core/tests/DeviceTests/Handlers/Navigation/NavigationViewHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Navigation/NavigationViewHandlerTests.cs @@ -3,17 +3,22 @@ using System.Threading.Tasks; using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests { [Category(TestCategory.NavigationView)] - public partial class NavigationViewHandlerTests : CoreHandlerTestBase + public partial class NavigationViewHandlerTests : CoreHandlerTestBase { #if ANDROID || WINDOWS [Fact(DisplayName = "Push Multiple Pages At Start")] public async Task PushMultiplePagesAtStart() { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handler => + handler.AddHandler())); + var page1 = new ButtonStub(); var page2 = new ButtonStub(); NavigationViewStub navigationViewStub = new NavigationViewStub() diff --git a/src/Core/tests/DeviceTests/Handlers/Page/PageHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/Page/PageHandlerTests.cs index 3664aa1d92e4..a272e05c0262 100644 --- a/src/Core/tests/DeviceTests/Handlers/Page/PageHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Page/PageHandlerTests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests @@ -9,6 +10,14 @@ namespace Microsoft.Maui.DeviceTests [Category(TestCategory.Page)] public partial class PageHandlerTests : CoreHandlerTestBase { + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(); + handlers.AddHandler(); + }); + [Fact(DisplayName = "Content Initializes Correctly")] public async Task ContentInitializes() { diff --git a/src/Core/tests/DeviceTests/Handlers/ScrollView/ScrollViewHandlerTests.iOS.cs b/src/Core/tests/DeviceTests/Handlers/ScrollView/ScrollViewHandlerTests.iOS.cs index 53eaddf55d5a..49c94995e7f6 100644 --- a/src/Core/tests/DeviceTests/Handlers/ScrollView/ScrollViewHandlerTests.iOS.cs +++ b/src/Core/tests/DeviceTests/Handlers/ScrollView/ScrollViewHandlerTests.iOS.cs @@ -18,7 +18,9 @@ public partial class ScrollViewHandlerTests : CoreHandlerTestBase { builder.ConfigureMauiHandlers(handlers => { handlers.AddHandler(); }); }); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); bool result = await InvokeOnMainThreadAsync(() => { @@ -55,7 +57,9 @@ public async Task ContentInitializesCorrectly() [Fact] public async Task ScrollViewContentSizeSet() { - EnsureHandlerCreated(builder => { builder.ConfigureMauiHandlers(handlers => { handlers.AddHandler(); }); }); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); var scrollView = new ScrollViewStub(); var entry = new EntryStub() { Text = "In a ScrollView" }; diff --git a/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.Android.cs b/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.Android.cs index 4f9f9af09ef6..64e726097648 100644 --- a/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.Android.cs +++ b/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.Android.cs @@ -5,6 +5,7 @@ using Android.Text.Method; using Android.Widget; using Microsoft.Maui.DeviceTests.Stubs; +using Microsoft.Maui.Hosting; using Xunit; using AColor = Android.Graphics.Color; using SearchView = AndroidX.AppCompat.Widget.SearchView; @@ -119,6 +120,10 @@ await InvokeOnMainThreadAsync(() => [Fact] public async Task SearchBarTakesFullWidthByDefault() { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handler => + handler.AddHandler())); + await InvokeOnMainThreadAsync(async () => { var layout = new LayoutStub() @@ -133,7 +138,7 @@ await InvokeOnMainThreadAsync(async () => layout.Add(searchbar); - var layoutHandler = CreateHandler(layout); + var layoutHandler = CreateHandler(layout); await layoutHandler.PlatformView.AttachAndRun(() => { var layoutSize = layout.Measure(double.PositiveInfinity, double.PositiveInfinity); diff --git a/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.cs index 2cdeb12dd882..8e11f866c4f2 100644 --- a/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/SearchBar/SearchBarHandlerTests.cs @@ -1,7 +1,9 @@ -using System.Threading.Tasks; +using System.Linq; +using System.Threading.Tasks; using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.Graphics; using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; using Xunit; namespace Microsoft.Maui.DeviceTests @@ -44,18 +46,25 @@ public async Task TextInitializesCorrectly() [Fact(DisplayName = "Text Property Initializes Correctly when Keyboard Mapper is Executed Before Text Mapper")] public async Task TextInitializesCorrectlyWhenKeyboardIsBeforeText() { - var searchBar = new SearchBarStub() - { - Text = "Test Text Here" - }; - CustomSearchBarHandler.TestMapper = new PropertyMapper(SearchBarHandler.Mapper) { // this mapper is run first and then the ones in the ctor arg (SearchBarHandler.Mapper) [nameof(ISearchBar.Keyboard)] = SearchBarHandler.MapKeyboard }; - await ValidatePropertyInitValue(searchBar, () => searchBar.Text, GetNativeText, searchBar.Text); + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + + var searchBar = new SearchBarStub() + { + Text = "Test Text Here" + }; + + await ValidatePropertyInitValue(searchBar, () => searchBar.Text, GetNativeText, searchBar.Text); + + var handler = Assert.IsType(searchBar.Handler); + Assert.True(handler._mapper.GetKeys().First() == "Keyboard", "Keyboard was not first in the list."); } [Theory(DisplayName = "Query Text Updates Correctly")] diff --git a/src/Core/tests/DeviceTests/Handlers/WebView/WebViewHandlerTests.Android.cs b/src/Core/tests/DeviceTests/Handlers/WebView/WebViewHandlerTests.Android.cs index 616a78b40bcc..973463d4d4ba 100644 --- a/src/Core/tests/DeviceTests/Handlers/WebView/WebViewHandlerTests.Android.cs +++ b/src/Core/tests/DeviceTests/Handlers/WebView/WebViewHandlerTests.Android.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Android.Webkit; using Microsoft.Maui.DeviceTests.Stubs; +using Microsoft.Maui.Hosting; using Xunit; using AWebView = Android.Webkit.WebView; @@ -11,8 +12,13 @@ namespace Microsoft.Maui.DeviceTests public partial class WebViewHandlerTests { [Fact] - public Task EnsureSupportForCustomWebViewClients() => - InvokeOnMainThreadAsync(async () => + public async Task EnsureSupportForCustomWebViewClients() + { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + + await InvokeOnMainThreadAsync(async () => { // create the cross-platform view var webView = new WebViewStub @@ -88,6 +94,7 @@ await AttachAndRun(webView, async webViewHandler => Assert.Equal(1, shouldRequestCount); // only 1 request for the image to load }); }); + } AWebView GetNativeWebView(WebViewHandler webViewHandler) => webViewHandler.PlatformView; @@ -98,10 +105,8 @@ string GetNativeSource(WebViewHandler webViewHandler) => class CustomWebViewHandler : WebViewHandler { // make a copy of the Core mappers because we don't want any Controls changes or to override us - static IPropertyMapper TestMapper = - new PropertyMapper(WebViewHandler.Mapper); - static CommandMapper TestCommandMapper = - new(WebViewHandler.CommandMapper); + static PropertyMapper TestMapper = new (WebViewHandler.Mapper); + static CommandMapper TestCommandMapper = new(WebViewHandler.CommandMapper); static CustomWebViewHandler() { diff --git a/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.Windows.cs b/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.Windows.cs index 5c421be505c5..3d0502e0680a 100644 --- a/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.Windows.cs +++ b/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.Windows.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Microsoft.Maui.Controls; using Microsoft.Maui.DeviceTests.Stubs; +using Microsoft.Maui.Hosting; using Windows.Graphics; using Xunit; using WVisibility = Microsoft.UI.Xaml.Visibility; @@ -13,6 +14,10 @@ public partial class WindowHandlerTests : CoreHandlerTestBase [Fact(DisplayName = "Back Button Not Visible With No Navigation Page")] public async Task BackButtonNotVisibleWithBasicView() { + EnsureHandlerCreated(builder => + builder.ConfigureMauiHandlers(handlers => + handlers.AddHandler())); + var window = new WindowStub() { Content = new ButtonStub() diff --git a/src/Core/tests/DeviceTests/MauiContextTests.Android.cs b/src/Core/tests/DeviceTests/MauiContext/MauiContextTests.Android.cs similarity index 100% rename from src/Core/tests/DeviceTests/MauiContextTests.Android.cs rename to src/Core/tests/DeviceTests/MauiContext/MauiContextTests.Android.cs diff --git a/src/Core/tests/DeviceTests/Memory/MemoryTestTypes.cs b/src/Core/tests/DeviceTests/Memory/MemoryTestTypes.cs index a01c466b4b57..1eed0a59e122 100644 --- a/src/Core/tests/DeviceTests/Memory/MemoryTestTypes.cs +++ b/src/Core/tests/DeviceTests/Memory/MemoryTestTypes.cs @@ -1,20 +1,26 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; using Microsoft.Maui.DeviceTests.Stubs; - namespace Microsoft.Maui.Handlers.Memory { public class MemoryTestTypes : IEnumerable { + public static readonly IReadOnlyDictionary Types = new Dictionary + { + [typeof(DatePickerStub)] = typeof(DatePickerHandler), + [typeof(EditorStub)] = typeof(EditorHandler), + [typeof(EntryStub)] = typeof(EntryHandler), + [typeof(SearchBarStub)] = typeof(SearchBarHandler), + }; + public IEnumerator GetEnumerator() { - yield return new object[] { (typeof(DatePickerStub), typeof(DatePickerHandler)) }; - yield return new object[] { (typeof(EditorStub), typeof(EditorHandler)) }; - yield return new object[] { (typeof(EntryStub), typeof(EntryHandler)) }; - yield return new object[] { (typeof(SearchBarStub), typeof(SearchBarHandler)) }; + foreach (var pair in Types) + yield return new object[] { (pair.Key, pair.Value) }; } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } -} \ No newline at end of file +} diff --git a/src/Core/tests/DeviceTests/Memory/MemoryTests.cs b/src/Core/tests/DeviceTests/Memory/MemoryTests.cs index 854bc10520bc..68b239d774ce 100644 --- a/src/Core/tests/DeviceTests/Memory/MemoryTests.cs +++ b/src/Core/tests/DeviceTests/Memory/MemoryTests.cs @@ -1,19 +1,8 @@ using System; -using System.Collections; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; using System.Threading.Tasks; using Microsoft.Maui.DeviceTests; -using Microsoft.Maui.DeviceTests.Stubs; -using Microsoft.Maui.Graphics; -using Microsoft.Maui.Media; +using Microsoft.Maui.Hosting; using Xunit; -using Xunit.Abstractions; -using Xunit.Sdk; - namespace Microsoft.Maui.Handlers.Memory { @@ -34,6 +23,14 @@ public MemoryTests(MemoryTestFixture fixture) _fixture = fixture; } + protected override MauiAppBuilder ConfigureBuilder(MauiAppBuilder mauiAppBuilder) => + base.ConfigureBuilder(mauiAppBuilder) + .ConfigureMauiHandlers(handlers => + { + foreach (var pair in MemoryTestTypes.Types) + handlers.AddHandler(pair.Key, pair.Value); + }); + [Theory] [ClassData(typeof(MemoryTestTypes))] public async Task Allocate((Type ViewType, Type HandlerType) data) @@ -44,7 +41,8 @@ public async Task Allocate((Type ViewType, Type HandlerType) data) return; #endif - var handler = await InvokeOnMainThreadAsync(() => CreateHandler((IElement)Activator.CreateInstance(data.ViewType), data.HandlerType)); + var handler = await InvokeOnMainThreadAsync(() => CreateHandler((IElement)Activator.CreateInstance(data.ViewType))); + Assert.IsType(data.HandlerType, handler); WeakReference weakHandler = new WeakReference(handler); _fixture.AddReferences(data.HandlerType, (weakHandler, new WeakReference(handler.VirtualView))); handler = null;