diff --git a/src/Uno.UI.RuntimeTests/IntegrationTests/common/TestServices.InputHelper.cs b/src/Uno.UI.RuntimeTests/IntegrationTests/common/TestServices.InputHelper.cs index 088faf8c2c20..0c90f1c4e79c 100644 --- a/src/Uno.UI.RuntimeTests/IntegrationTests/common/TestServices.InputHelper.cs +++ b/src/Uno.UI.RuntimeTests/IntegrationTests/common/TestServices.InputHelper.cs @@ -95,7 +95,7 @@ public static void Tap(Point point) #endif } - public static void ScrollMouseWheel(CalendarView cv, int i) + public static void ScrollMouseWheel(UIElement cv, int i) { throw new System.NotImplementedException(); } diff --git a/src/Uno.UI.RuntimeTests/IntegrationTests/dxaml/controls/combobox/ComboBoxIntegrationTests.cs b/src/Uno.UI.RuntimeTests/IntegrationTests/dxaml/controls/combobox/ComboBoxIntegrationTests.cs index e200b553fda8..1230f0b98565 100644 --- a/src/Uno.UI.RuntimeTests/IntegrationTests/dxaml/controls/combobox/ComboBoxIntegrationTests.cs +++ b/src/Uno.UI.RuntimeTests/IntegrationTests/dxaml/controls/combobox/ComboBoxIntegrationTests.cs @@ -3,11 +3,16 @@ using System.Diagnostics; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Markup; +using Microsoft.UI.Xaml.Media; using Private.Infrastructure; using Uno.UI.RuntimeTests; +using Uno.UI.RuntimeTests.MUX.Helpers; +using Windows.Foundation; using static Private.Infrastructure.TestServices; using ComboBoxHelper = Microsoft.UI.Xaml.Tests.Common.ComboBoxHelper; @@ -138,6 +143,7 @@ await RunOnUIThread(() => VERIFY_ARE_EQUAL(-1, comboBox.SelectedIndex); VERIFY_IS_NOT_NULL(comboBox.FontFamily); VERIFY_IS_NOT_NULL(comboBox.Foreground); + VERIFY_ARE_EQUAL(comboBox.SelectionChangedTrigger, ComboBoxSelectionChangedTrigger.Committed); }); await TestServices.WindowHelper.WaitForIdle(); } @@ -217,10 +223,10 @@ await RunOnUIThread(() => }); } - // void ValidateUIElementTree() + // [TestMethod] public async Task ValidateUIElementTree() // { - // TestServices.WindowHelper.SetWindowSizeOverride(wf.Size(400, 600)); + // TestServices.WindowHelper.SetWindowSizeOverride(new Size(400, 600)); // // We need a special rule for ComboBox to blacklist IsSelectionBoxHighlighted in // // addition to FocusState. @@ -246,20 +252,20 @@ await RunOnUIThread(() => // ComboBox disabledComboBox = null; // ComboBox openedComboBox = null; - // ComboBoxItem ^ restUnselectedComboBoxItem = null; - // ComboBoxItem ^ pointerOverUnselectedComboBoxItem = null; - // ComboBoxItem ^ pressedUnselectedComboBoxItem = null; - // ComboBoxItem ^ disabledUnselectedComboBoxItem = null; + // ComboBoxItem restUnselectedComboBoxItem = null; + // ComboBoxItem pointerOverUnselectedComboBoxItem = null; + // ComboBoxItem pressedUnselectedComboBoxItem = null; + // ComboBoxItem disabledUnselectedComboBoxItem = null; - // ComboBoxItem ^ restSelectedComboBoxItem = null; - // ComboBoxItem ^ pointerOverSelectedComboBoxItem = null; - // ComboBoxItem ^ pressedSelectedComboBoxItem = null; - // ComboBoxItem ^ focusedSelectedComboBoxItem = null; - // ComboBoxItem ^ disabledSelectedComboBoxItem = null; + // ComboBoxItem restSelectedComboBoxItem = null; + // ComboBoxItem pointerOverSelectedComboBoxItem = null; + // ComboBoxItem pressedSelectedComboBoxItem = null; + // ComboBoxItem focusedSelectedComboBoxItem = null; + // ComboBoxItem disabledSelectedComboBoxItem = null; //#if WI_IS_FEATURE_PRESENT(Feature_HeaderPlacement) - // ComboBox^ topHeaderComboBox = null; - // ComboBox^ leftHeaderComboBox = null; + // ComboBox topHeaderComboBox = null; + // ComboBox leftHeaderComboBox = null; //#endif // StackPanel ^ rootPanel = null; @@ -324,7 +330,7 @@ await RunOnUIThread(() => // openedComboBox = new ComboBox(); // openedComboBox.Items.Add("Opened Combo Box"); - // openedComboBox.Margin = ThicknessHelper.FromLengths(0, 350, 0, 0.0; + // openedComboBox.Margin = ThicknessHelper.FromLengths(0, 350, 0, 0); // openedComboBox.SelectedIndex = 0; // openedComboBox.LightDismissOverlayMode = LightDismissOverlayMode.Off; // rootPanel.Children.Add(openedComboBox); @@ -435,7 +441,7 @@ await RunOnUIThread(() => // { // rootPanel.RequestedTheme = ElementTheme.Light; - // rootPanel.Background = new xaml_media.SolidColorBrush(Microsoft.UI.Colors.White); + // rootPanel.Background = new SolidColorBrush(Microsoft.UI.Colors.White); // }); // await TestServices.WindowHelper.WaitForIdle(); @@ -449,7 +455,7 @@ await RunOnUIThread(() => // { // TestServices.ThemingHelper.HighContrastTheme = HighContrastTheme.Test; - // rootPanel.Background = new xaml_media.SolidColorBrush(mu.Colors.Black); + // rootPanel.Background = new SolidColorBrush(mu.Colors.Black); // }); // await TestServices.WindowHelper.WaitForIdle(); @@ -466,10 +472,6 @@ await RunOnUIThread(() => [TestMethod] public async Task ValidateVeryWideComboBoxItems() { - // Regression coverage for MSFT:1577374 "ComboBox crashes Apps if text in them is wider than the screen resolution for mobile phones" - // We were hitting an issue where a ComboBox that contained an item that was too wide to fit on the screen caused a layout cycle exception. - // To test this we just open a ComboBox containing a very wide ComboBox item and verify that no exceptions get thrown. - var comboBox = await SetupBasicComboBoxTest(); var veryLongString = "Human reason, in one sphere of its cognition, is called upon to consider questions, which it cannot decline, as they are presented by its own nature, but which it cannot answer, as they transcend every faculty of the mind."; @@ -494,9 +496,6 @@ await RunOnUIThread(() => [TestMethod] public async Task ValidateOpenComboBoxWithAllItemsLongWidth() { - - - // This is a regression coverage for bug#6274763 "ComboBox hits a layout cycle crash with having long item width in the all items. // This ComboBox items is the block shape that has all long item width instead of having one item width. // This is the different coverage with above ValidateVeryWideComboBoxItems() by having the all items long width. ComboBox comboBox = null; @@ -548,7 +547,7 @@ await RunOnUIThread(() => //{ - // var comboBox = SetupBasicComboBoxTest(); + // var comboBox = await SetupBasicComboBoxTest(); // var comboBoxClosedEvent = new Event(); // var closedRegistration = CreateSafeEventRegistration>("DropDownClosed"); @@ -579,8 +578,6 @@ await RunOnUIThread(() => [TestMethod] public async Task DropDownClosesOnComboBoxUnloaded() { - - // We need to verify that the DropDown closes when the ComboBox is removed from the visual tree. // If this does not happen, ComobBox is left in an invalid state and so if it gets added back // to the visual tree it does not behave correctly. @@ -608,7 +605,6 @@ await RunOnUIThread(() => await comboBoxClosedEvent.WaitForDefault(); await RunOnUIThread(() => - { VERIFY_IS_FALSE(comboBox.IsDropDownOpen); }); @@ -629,7 +625,7 @@ await RunOnUIThread(() => // UIElement ^ parent = null; - // var comboBox = SetupBasicComboBoxTest(); + // var comboBox = await SetupBasicComboBoxTest(); // var comboBoxClosedEvent = new Event(); // var closedRegistration = CreateSafeEventRegistration>("DropDownClosed"); // var comboBoxParentKeyDownRegistration = CreateSafeEventRegistrationForHandledEvents(Microsoft.UI.Xaml.UIElement, KeyDownEvent); @@ -638,7 +634,7 @@ await RunOnUIThread(() => // await RunOnUIThread(() => // { - // parent = (UIElement ^)(xaml_media.VisualTreeHelper.GetParent(comboBox)); + // parent = (UIElement ^)(VisualTreeHelper.GetParent(comboBox)); // }); // await TestServices.WindowHelper.WaitForIdle(); @@ -649,7 +645,7 @@ await RunOnUIThread(() => // if (verifyKeyDown) // { // comboBoxParentKeyDownRegistration.Attach(parent, - // new xaml_input.KeyEventHandler([expectedKeyDownHandledValue](Platform.Object ^ sender, xaml_input.KeyRoutedEventArgs ^ e) + // new KeyEventHandler([expectedKeyDownHandledValue](Platform.Object ^ sender, KeyRoutedEventArgs ^ e) // { // VERIFY_ARE_EQUAL(e.Handled, expectedKeyDownHandledValue); @@ -659,7 +655,7 @@ await RunOnUIThread(() => // if (verifyKeyUp) // { // comboBoxParentKeyUpRegistration.Attach(parent, - // new xaml_input.KeyEventHandler([expectedKeyUpHandledValue](Platform.Object ^ sender, xaml_input.KeyRoutedEventArgs ^ e) + // new KeyEventHandler([expectedKeyUpHandledValue](Platform.Object ^ sender, KeyRoutedEventArgs ^ e) // { // VERIFY_ARE_EQUAL(e.Handled, expectedKeyUpHandledValue); @@ -700,7 +696,7 @@ await RunOnUIThread(() => //{ // comboBoxParentKeyDownRegistration.Detach(); // comboBoxParentKeyDownRegistration.Attach(parent, - // new xaml_input.KeyEventHandler([](Platform.Object ^ sender, xaml_input.KeyRoutedEventArgs ^ e) + // new KeyEventHandler([](Platform.Object ^ sender, KeyRoutedEventArgs ^ e) // { @@ -712,7 +708,7 @@ await RunOnUIThread(() => //{ // comboBoxParentKeyUpRegistration.Detach(); // comboBoxParentKeyUpRegistration.Attach(parent, - // new xaml_input.KeyEventHandler([](Platform.Object ^ sender, xaml_input.KeyRoutedEventArgs ^ e) + // new KeyEventHandler([](Platform.Object ^ sender, KeyRoutedEventArgs ^ e) // { @@ -739,7 +735,7 @@ await RunOnUIThread(() => // UIElement ^ parent = null; - // var comboBox = SetupBasicComboBoxTest(); + // var comboBox = await SetupBasicComboBoxTest(); // var comboBoxClosedEvent = new Event(); // var comboBoxKeyDownRepeatedEvent = new Event(); // var closedRegistration = CreateSafeEventRegistration>("DropDownClosed"); @@ -751,7 +747,7 @@ await RunOnUIThread(() => // await RunOnUIThread(() => // { - // parent = (UIElement ^)(xaml_media.VisualTreeHelper.GetParent(comboBox)); + // parent = (UIElement ^)(VisualTreeHelper.GetParent(comboBox)); // }); // await TestServices.WindowHelper.WaitForIdle(); @@ -760,7 +756,7 @@ await RunOnUIThread(() => // { // comboBoxParentKeyDownRegistration.Attach(parent, - // new xaml_input.KeyEventHandler([&keyDownCount, comboBoxKeyDownRepeatedEvent](Platform.Object ^ sender, xaml_input.KeyRoutedEventArgs ^ e) + // new KeyEventHandler([&keyDownCount, comboBoxKeyDownRepeatedEvent](Platform.Object ^ sender, KeyRoutedEventArgs ^ e) // { @@ -777,7 +773,7 @@ await RunOnUIThread(() => // })); // comboBoxParentKeyUpRegistration.Attach(parent, - // new xaml_input.KeyEventHandler([](Platform.Object ^ sender, xaml_input.KeyRoutedEventArgs ^ e) + // new KeyEventHandler([](Platform.Object ^ sender, KeyRoutedEventArgs ^ e) // { @@ -795,7 +791,7 @@ await RunOnUIThread(() => //await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); //await TestServices.WindowHelper.WaitForIdle(); - //RunOnUIThread([&]() + //await RunOnUIThread(() => // { // comboBox.Focus(FocusState.Keyboard); @@ -827,11 +823,11 @@ await RunOnUIThread(() => //await TestServices.WindowHelper.WaitForIdle(); // } - //void ValidateResettingSelectedIndexBringsBackPlaceholderText() + //[TestMethod] public async Task ValidateResettingSelectedIndexBringsBackPlaceholderText() //{ - // var comboBox = SetupBasicComboBoxTest(); + // var comboBox = await SetupBasicComboBoxTest(); // TextBlock ^ placeholderTextBlock = null; // await RunOnUIThread(() => @@ -895,7 +891,7 @@ await RunOnUIThread(() => // ComboBox comboBox; - // ScrollViewer ^ scrollViewer; + // ScrollViewer scrollViewer; // var verticalSnapPointsChangedRegistration = CreateSafeEventRegistration(ItemsPresenter, VerticalSnapPointsChanged); // await RunOnUIThread(() => @@ -936,8 +932,8 @@ await RunOnUIThread(() => //await RunOnUIThread(() => // { - // var popup = TreeHelper.GetVisualChildByType(comboBox); - // var popupChild = FrameworkElement ^> (popup.Child); + // var popup = TreeHelper.GetVisualChildByType(comboBox); + // var popupChild = FrameworkElement> (popup.Child); // scrollViewer = TreeHelper.GetVisualChildByType(popupChild); // verticalSnapPointsChangedRegistration.Attach( @@ -957,7 +953,7 @@ await RunOnUIThread(() => //await ComboBoxHelper.CloseComboBox(comboBox); //} - private async Task SetupBasicComboBoxTest(uint numberOfItems = 5, bool adjustMargin = true, bool isEditable = false) + private async Task SetupBasicComboBoxTest(int numberOfItems = 5, bool adjustMargin = true, bool isEditable = false) { ComboBox comboBox = null; @@ -1008,48 +1004,47 @@ await RunOnUIThread(() => return comboBox; } - //// For these purposes, an "Ascending combobox" is a box that has data in a triangular pattern. - //// This forces us to resize the combobox to get bigger every time we navigate down since we realize wider items. - //// It resembles the following: - //// X - //// XX - //// XXX - //// XXXX - //ComboBox SetupAscendingComboBoxTest(uint numberOfItems) - //{ - // ComboBox comboBox = null; - - // await RunOnUIThread(() => + // For these purposes, an "Ascending combobox" is a box that has data in a triangular pattern. + // This forces us to resize the combobox to get bigger every time we navigate down since we realize wider items. + // It resembles the following: + // X + // XX + // XXX + // XXXX + private async Task SetupAscendingComboBoxTest(uint numberOfItems = 50) + { + ComboBox comboBox = null; - // { - // var rootPanel = new Grid(); - // VERIFY_IS_NOT_NULL(rootPanel); + await RunOnUIThread(() => + { + var rootPanel = new Grid(); + VERIFY_IS_NOT_NULL(rootPanel); - // comboBox = new ComboBox(); - // VERIFY_IS_NOT_NULL(comboBox); + comboBox = new ComboBox(); + VERIFY_IS_NOT_NULL(comboBox); - // rootPanel.Children.Add(comboBox); - // TestServices.WindowHelper.WindowContent = rootPanel; + rootPanel.Children.Add(comboBox); + TestServices.WindowHelper.WindowContent = rootPanel; - // for (uint i = 0; i < numberOfItems; i++) - // { - // var item = new ComboBoxItem(); + for (uint i = 0; i < numberOfItems; i++) + { + var item = new ComboBoxItem(); - // var stringItem = ""; - // for (uint j = 1; j <= i + 1; j++) - // { - // stringItem += "X"; - // } + var stringItem = ""; + for (uint j = 1; j <= i + 1; j++) + { + stringItem += "X"; + } - // item.Content = stringItem; - // comboBox.Items.Add(item); - // } - // }); + item.Content = stringItem; + comboBox.Items.Add(item); + } + }); - // await TestServices.WindowHelper.WaitForIdle(); + await TestServices.WindowHelper.WaitForIdle(); - // return comboBox; - //} + return comboBox; + } [TestMethod] public async Task CanOpenWithTouch() @@ -1097,6 +1092,7 @@ await RunOnUIThread(() => } [TestMethod] + [Ignore("The first verify fails as ComboBox pre-selects index 0 due to SelectionChangedTrigger.Always #17988")] public async Task ValidateKeyboardInteraction() { var comboBox = await SetupBasicComboBoxTest(); @@ -1116,11 +1112,10 @@ public async Task ValidateKeyboardInteraction() }); await RunOnUIThread(() => - - { - comboBox.SelectionChangedTrigger = ComboBoxSelectionChangedTrigger.Always; - comboBox.Focus(FocusState.Programmatic); - }); + { + comboBox.SelectionChangedTrigger = ComboBoxSelectionChangedTrigger.Always; + comboBox.Focus(FocusState.Programmatic); + }); await TestServices.WindowHelper.WaitForIdle(); LOG_OUTPUT("Open the ComboBox with the Space key"); @@ -1209,7 +1204,6 @@ await RunOnUIThread(() => await TestServices.WindowHelper.WaitForIdle(); LOG_OUTPUT("Close ComboBox using specified key sequence"); - FocusManager.LosingFocus += (s, e) => Debug.WriteLine("FocusManager.LosingFocus"); TestServices.KeyboardHelper.PressKeySequence(keySequence); await TestServices.WindowHelper.WaitForIdle(); await dropDownClosedEvent.WaitForDefault(); @@ -1217,4 +1211,4760 @@ await RunOnUIThread(() => await ComboBoxHelper.VerifySelectedIndex(comboBox, -1); } + + [TestMethod] + public async Task CanCycleThroughItemsWithMouseWheel() + { + var comboBox = await SetupBasicComboBoxTest(); + + await RunOnUIThread(() => + + { + comboBox.Focus(FocusState.Programmatic); + }); + await TestServices.WindowHelper.WaitForIdle(); + + await ComboBoxHelper.VerifySelectedIndex(comboBox, -1); + + TestServices.InputHelper.MoveMouse(comboBox); + await TestServices.WindowHelper.WaitForIdle(); + + LOG_OUTPUT("Select the first item with the mouse wheel"); + TestServices.InputHelper.ScrollMouseWheel(comboBox, -1); + await TestServices.WindowHelper.WaitForIdle(); + await ComboBoxHelper.VerifySelectedIndex(comboBox, 0); + + LOG_OUTPUT("Select the second item with the mouse wheel"); + TestServices.InputHelper.ScrollMouseWheel(comboBox, -1); + await TestServices.WindowHelper.WaitForIdle(); + await ComboBoxHelper.VerifySelectedIndex(comboBox, 1); + + LOG_OUTPUT("Select the first item again by scrolling the mouse wheel back the other way"); + TestServices.InputHelper.ScrollMouseWheel(comboBox, 1); + await TestServices.WindowHelper.WaitForIdle(); + await ComboBoxHelper.VerifySelectedIndex(comboBox, 0); + } + + [TestMethod] + public async Task CanLightDismissDropdown() + { + ComboBox comboBox = null; + Button button = null; + + await RunOnUIThread(() => + + { + comboBox = new ComboBox(); + + for (int i = 0; i < 5; ++i) + { + var item = new ComboBoxItem(); + item.Content = "Item"; + comboBox.Items.Add(item); + } + + button = new Button(); + button.Width = 222; + // Add a top margin to push the button out from under the status bar on phone. + button.Margin = ThicknessHelper.FromLengths(0, 32, 0, 0); + + var root = new StackPanel(); + root.Children.Add(button); + root.Children.Add(comboBox); + + TestServices.WindowHelper.WindowContent = root; + }); + await TestServices.WindowHelper.WaitForIdle(); + + var dropDownClosedEvent = new Event(); + var dropDownClosedRegistration = CreateSafeEventRegistration>("DropDownClosed"); + dropDownClosedRegistration.Attach(comboBox, (s, e) => { dropDownClosedEvent.Set(); }); + + await RunOnUIThread(() => + + { + comboBox.Focus(FocusState.Programmatic); + comboBox.IsDropDownOpen = true; + }); + await TestServices.WindowHelper.WaitForIdle(); + + // Click the button and see if the drop down light dismisses + TestServices.InputHelper.Tap(button); + await TestServices.WindowHelper.WaitForIdle(); + await dropDownClosedEvent.WaitForDefault(); + } + + [TestMethod] + public async Task ValidateResetItemsSource() + { + var comboBox = await SetupBasicComboBoxTest(); + + // Reset the ComboBox ItemsSource with new items + await RunOnUIThread(() => + { + comboBox.SelectedIndex = 0; + + var itemList = new List(); + + for (int i = 0; i < 5; i++) + { + string itemText = "Item " + i; + itemList.Add(itemText); + } + comboBox.ItemsSource = itemList; + }); + await TestServices.WindowHelper.WaitForIdle(); + + LOG_OUTPUT("ValidateResetItemsSource: Open and Close ComboBox."); + + await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); + await TestServices.WindowHelper.WaitForIdle(); + + await ComboBoxHelper.CloseComboBox(comboBox); + await TestServices.WindowHelper.WaitForIdle(); + + // The selected index must be -1 by reset ItemsSource + await ComboBoxHelper.VerifySelectedIndex(comboBox, -1); + } + + // [TestMethod] + // public async Task ValidateDropdownPlacement() + // { + // TestServices.WindowHelper.SetWindowSizeOverride(new Size(400, 600)); + + // // This test validates that ComboBox can open its Popup outside of the bounds of the window. + // // The test relies on the DoValidateDropdownPlacement helper function to do the validation, passing in various combinations of params to test. + // // + // // All combinations of values for the parameter are valid test cases, but we do not want to execute the full set of all possible combinations (2^5=32 test cases). + // // Instead we: + // // 1. Explicitly test the specific scenarios that we are particularly interested in + // // 2. Ensure pairwise coverage in the parameters by adding a set of test cases with parameters generated by PICT + + // // If a ComboBox is near the Right edge of the window and the ComboBoxItems are wider than the ComboBox, the popup position should be allowed to go outside the window: + // DoValidateDropdownPlacement(VerticalAlignment.Top, HorizontalAlignment.Right, true /*useWideItems*/, 0 /*rotationAngle*/, FlowDirection.LeftToRight, PopupHelper.AreWindowedPopupsEnabled() /* expectOutside */); + + // // If a ComboBox is near the Bottom of the window, the popup position should be allowed to go outside the window: + // DoValidateDropdownPlacement(VerticalAlignment.Bottom, HorizontalAlignment.Right, false /*useWideItems*/, 0 /*rotationAngle*/, FlowDirection.LeftToRight, PopupHelper.AreWindowedPopupsEnabled() /* expectOutside */); + + // // ComboBox popup placement should correctly handle RightToLeft flow direction: + // DoValidateDropdownPlacement(VerticalAlignment.Top, HorizontalAlignment.Left, false /*useWideItems*/, 0 /*rotationAngle*/, FlowDirection.RightToLeft, PopupHelper.AreWindowedPopupsEnabled() /* expectOutside */); + + // // Validate cases where a parent of the ComboBox has a RotateTransform of 90, 180 or 270 degrees. + // // Note: ComboBox does not handle rotation angles other than multiples of 90, so we only test these supported values. + // DoValidateDropdownPlacement(VerticalAlignment.Bottom, HorizontalAlignment.Left, false /*useWideItems*/, 90 /*rotationAngle*/, FlowDirection.LeftToRight, false /* expectOutside */); + // DoValidateDropdownPlacement(VerticalAlignment.Bottom, HorizontalAlignment.Left, false /*useWideItems*/, 180 /*rotationAngle*/, FlowDirection.LeftToRight, false /* expectOutside */); + // DoValidateDropdownPlacement(VerticalAlignment.Top, HorizontalAlignment.Left, false /*useWideItems*/, 270 /*rotationAngle*/, FlowDirection.LeftToRight, false /* expectOutside */); + + // // Extra scenarios from PICT: + // DoValidateDropdownPlacement(VerticalAlignment.Bottom, HorizontalAlignment.Right, true /*useWideItems*/, 180 /*rotationAngle*/, FlowDirection.RightToLeft, false /* expectOutside */); + // DoValidateDropdownPlacement(VerticalAlignment.Top, HorizontalAlignment.Left, true /*useWideItems*/, 180 /*rotationAngle*/, FlowDirection.LeftToRight, false /* expectOutside */); + // DoValidateDropdownPlacement(VerticalAlignment.Bottom, HorizontalAlignment.Right, true /*useWideItems*/, 270 /*rotationAngle*/, FlowDirection.RightToLeft, false /* expectOutside */); + // DoValidateDropdownPlacement(VerticalAlignment.Top, HorizontalAlignment.Right, true /*useWideItems*/, 90 /*rotationAngle*/, FlowDirection.RightToLeft, false /* expectOutside */); + // } + + // private void DoValidateDropdownPlacement(VerticalAlignment verticalAlignment, HorizontalAlignment horizontalAlignment, bool useWideItems, int rotationAngle, FlowDirection flowDirection, bool expectOutside) + // { + // LOG_OUTPUT("DoValidateDropdownPlacement: VerticalAlignment=%s, HorizontalAlignment=%s, useWideItems=%d, rotationAngle=%d, FlowDirection=%s ", verticalAlignment.ToString().Data(), horizontalAlignment.ToString().Data(), useWideItems, rotationAngle, flowDirection.ToString().Data()); + + // ComboBox comboBox; + // Grid rootPanel; + + // await RunOnUIThread(() => + + // { + // // Note: The ComboBox container needs a 6px Margin applied to it due to: + // // WINTH:3722949 "ComboBox dropdown can be placed slightly offscreen when ComboBox is near edge of window". + // // + // // We set ComboBox.SelectedIndex=2 so that there are items both above and below the selected item + // // (ComboBox tries to open the popup with the selected item centered over the ComboBox). + // rootPanel = Grid> (XamlReader.Load( + // LR"( + + // < Grid x: Name = "comboBoxContainer" Width = "300" Height = "300" Background = "Green" Margin = "8" RenderTransformOrigin = "0.5, 0.5" > + + // < Grid.RenderTransform > + + // < RotateTransform Angle = "0" /> + + // + + // < ComboBox x: Name = "comboBox" Width = "300" SelectedIndex = "2" > + + // < ComboBoxItem Content = "item one" /> + + // < ComboBoxItem Content = "item two" /> + + // < ComboBoxItem Content = "item three" /> + + // < ComboBoxItem Content = "item four" /> + + // < ComboBoxItem Content = "item five" /> + + // + + // + + // )")); + + + // comboBox = ComboBox > (rootPanel.FindName("comboBox")); + // comboBox.HorizontalAlignment = horizontalAlignment; + // comboBox.VerticalAlignment = verticalAlignment; + + // var comboBoxContainer = Grid> (rootPanel.FindName("comboBoxContainer")); + // comboBoxContainer.HorizontalAlignment = horizontalAlignment; + // comboBoxContainer.VerticalAlignment = verticalAlignment; + + // var rotateTransform = RotateTransform ^> (comboBoxContainer.RenderTransform); + // rotateTransform.Angle = rotationAngle; + + // if (useWideItems) + // { + // // We set the ComboBoxItems to a width wider than the ComboBox: + // for (var item : comboBox.Items) + // { + // var comboBoxItem = ComboBoxItem> ((Platform.Object ^)(item)); + // comboBoxItem.Width = 380; + // } + // } + + // rootPanel.FlowDirection = flowDirection; + + // TestServices.WindowHelper.WindowContent = rootPanel; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); + + // await RunOnUIThread(() => + + // { + // var dropdownScrollViewer = ScrollViewer> (TreeHelper.GetVisualChildByNameFromOpenPopups("ScrollViewer", rootPanel)); + // Rect dropdownBounds = ControlHelper.GetBounds(dropdownScrollViewer); + // Rect rootBounds = ControlHelper.GetBounds(rootPanel); + + // LOG_OUTPUT("dropdownBounds: (%f, %f, %f, %f)", dropdownBounds.X, dropdownBounds.Y, dropdownBounds.Width, dropdownBounds.Height); + // LOG_OUTPUT("rootBounds: (%f, %f, %f, %f)", rootBounds.X, rootBounds.Y, rootBounds.Width, rootBounds.Height); + + // if (expectOutside) + // { + // // We still expect the ComboBox to be contained within the monitor bounds. + // wf.Point windowPosition = TestServices.WindowHelper.ConvertToPhysicalDisplayLocation({ 0, 0 }); + // Rect monitorBounds = TestServices.WindowHelper.MonitorBounds; + // Rect physicalDropdownBounds = dropdownBounds; + + // // We need to convert the drop-down bounds to screen coordinates here in order to + // // be able to compare them to the monitor bounds. + // physicalDropdownBounds.X += windowPosition.X; + // physicalDropdownBounds.Y += windowPosition.Y; + + // LOG_OUTPUT("windowPosition: (%f, %f)", windowPosition.X, windowPosition.Y); + // LOG_OUTPUT("physicalDropdownBounds: (%f, %f, %f, %f)", physicalDropdownBounds.X, physicalDropdownBounds.Y, physicalDropdownBounds.Width, physicalDropdownBounds.Height); + // LOG_OUTPUT("monitorBounds: (%f, %f, %f, %f)", monitorBounds.X, monitorBounds.Y, monitorBounds.Width, monitorBounds.Height); + + // VERIFY_IS_FALSE(ControlHelper.IsContainedIn(dropdownBounds, rootBounds)); + // VERIFY_IS_TRUE(ControlHelper.IsContainedIn(physicalDropdownBounds, monitorBounds)); + // } + // else + // { + // VERIFY_IS_TRUE(ControlHelper.IsContainedIn(dropdownBounds, rootBounds)); + //} + // }); + //await TestServices.WindowHelper.WaitForIdle(); + // } + + [TestMethod] + public async Task DoesGetFocusWhenProgrammaticallyOpened() + { + + + ComboBox comboBox = null; + Button button = null; + + await RunOnUIThread(() => + + { + comboBox = new ComboBox(); + + for (int i = 0; i < 5; ++i) + { + var item = new ComboBoxItem(); + item.Content = "Item"; + comboBox.Items.Add(item); + } + + button = new Button(); + button.VerticalAlignment = VerticalAlignment.Top; + + var root = new Grid(); + root.Children.Add(button); + root.Children.Add(comboBox); + + TestServices.WindowHelper.WindowContent = root; + }); + await TestServices.WindowHelper.WaitForIdle(); + + await RunOnUIThread(() => + + { + // Explicitly set focus to a button to make sure ComboBox + // is actually grabbing focus rather than just starting + // with focus. + button.Focus(FocusState.Programmatic); + + comboBox.IsDropDownOpen = true; + }); + await TestServices.WindowHelper.WaitForIdle(); + + await RunOnUIThread(() => + { + VERIFY_IS_TRUE(FocusManager.GetFocusedElement(TestServices.WindowHelper.WindowContent.XamlRoot).Equals(comboBox)); + }); + } + + [TestMethod] + public async Task CanNavigateAscendingComboBoxesWithGamepad() + { + await CanNavigateAscendingComboBoxes(InputDevice.Gamepad); + } + + [TestMethod] + public async Task CanNavigateAscendingComboBoxesWithKeyboard() + { + await CanNavigateAscendingComboBoxes(InputDevice.Keyboard); + } + + private async Task CanNavigateAscendingComboBoxes(InputDevice device) + { + var comboBox = await SetupAscendingComboBoxTest(); + await RunOnUIThread(() => + + { + comboBox.SelectedIndex = 0; + }); + await TestServices.WindowHelper.WaitForIdle(); + + var dropDownOpenedEvent = new Event(); + var dropDownOpenedRegistration = CreateSafeEventRegistration>("DropDownOpened"); + dropDownOpenedRegistration.Attach(comboBox, (s, e) => { dropDownOpenedEvent.Set(); }); + + var dropDownClosedEvent = new Event(); + var dropDownClosedRegistration = CreateSafeEventRegistration>("DropDownClosed"); + dropDownClosedRegistration.Attach(comboBox, (s, e) => { dropDownClosedEvent.Set(); }); + + await RunOnUIThread(() => + { + comboBox.Focus(FocusState.Programmatic); + }); + await TestServices.WindowHelper.WaitForIdle(); + + LOG_OUTPUT("Open the ComboBox with the accept button."); + CommonInputHelper.Accept(device); + + await TestServices.WindowHelper.WaitForIdle(); + await dropDownOpenedEvent.WaitForDefault(); + + await ComboBoxHelper.VerifySelectedIndex(comboBox, 0); + + for (int i = 0; i < 10; i++) + { + LOG_OUTPUT("Move focus down."); + CommonInputHelper.Down(device); + + await TestServices.WindowHelper.WaitForIdle(); + } + + LOG_OUTPUT("Close the ComboBox with the accept button."); + CommonInputHelper.Accept(device); + + await dropDownClosedEvent.WaitForDefault(); + await TestServices.WindowHelper.WaitForIdle(); + await ComboBoxHelper.VerifySelectedIndex(comboBox, 10); + } + + [TestMethod] + public async Task SelectionChangedIsNotRaisedUntilClose() + { + InputDevice device = InputDevice.Gamepad; + + var comboBox = await SetupBasicComboBoxTest(); + + var dropDownOpenedEvent = new Event(); + var dropDownOpenedRegistration = CreateSafeEventRegistration>("DropDownOpened"); + dropDownOpenedRegistration.Attach(comboBox, (s, e) => + { + dropDownOpenedEvent.Set(); + }); + + var dropDownClosedEvent = new Event(); + var dropDownClosedRegistration = CreateSafeEventRegistration>("DropDownClosed"); + dropDownClosedRegistration.Attach(comboBox, (s, e) => + { + dropDownClosedEvent.Set(); + }); + + await RunOnUIThread(() => + + { + comboBox.Focus(FocusState.Programmatic); + }); + await TestServices.WindowHelper.WaitForIdle(); + + LOG_OUTPUT("Open the ComboBox with the accept button."); + CommonInputHelper.Accept(device); + + await TestServices.WindowHelper.WaitForIdle(); + await dropDownOpenedEvent.WaitForDefault(); + + await ComboBoxHelper.VerifySelectedIndex(comboBox, -1); + + LOG_OUTPUT("Focus the first item with down button."); + CommonInputHelper.Down(device); + + await TestServices.WindowHelper.WaitForIdle(); + await ComboBoxHelper.VerifySelectedIndex(comboBox, -1); + + LOG_OUTPUT("Focus the first item with down button."); + CommonInputHelper.Down(device); + + await TestServices.WindowHelper.WaitForIdle(); + await ComboBoxHelper.VerifySelectedIndex(comboBox, -1); + + LOG_OUTPUT("Close the ComboBox with the cancel button. No selection change should have happened."); + CommonInputHelper.Cancel(device); + + await dropDownClosedEvent.WaitForDefault(); + await TestServices.WindowHelper.WaitForIdle(); + await ComboBoxHelper.VerifySelectedIndex(comboBox, -1); + + LOG_OUTPUT("Open the ComboBox with the accept button."); + CommonInputHelper.Accept(device); + + await TestServices.WindowHelper.WaitForIdle(); + await dropDownOpenedEvent.WaitForDefault(); + + LOG_OUTPUT("Focus the first item with down button."); + CommonInputHelper.Down(device); + + await TestServices.WindowHelper.WaitForIdle(); + await ComboBoxHelper.VerifySelectedIndex(comboBox, -1); + + LOG_OUTPUT("Focus the first item with down button."); + CommonInputHelper.Down(device); + + await TestServices.WindowHelper.WaitForIdle(); + await ComboBoxHelper.VerifySelectedIndex(comboBox, -1); + + LOG_OUTPUT("Close the ComboBox with the accept button."); + CommonInputHelper.Accept(device); + + await dropDownClosedEvent.WaitForDefault(); + await TestServices.WindowHelper.WaitForIdle(); + await ComboBoxHelper.VerifySelectedIndex(comboBox, 1); + } + + // [TestMethod] + // public async Task ValidateDropdownSizingForDifferentInputModes() + // { + // double expectedDropdownWidth_Touch = 240; + // double expectedDropdownWidth_NonTouch = 80; + // double expectedComboBoxItemHeight_Touch = 40; + // double expectedComboBoxItemHeight_NonTouch = 32; + // Thickness expectedDropdownContentMargin_TouchAndCarousel = new Thickness(0, 0, 0, 0); + // Thickness expectedDropdownContentMargin_NonTouchAndCarousel = new Thickness(0, 4, 0, 4); + + // TestServices.WindowHelper.SetWindowSizeOverride(new Size(400, 600)); + + // ComboBox comboBox; + // ComboBoxItem comboBoxItem; + // FrameworkElement comboBoxDropdownRoot; + // ItemsPresenter comboBoxDropdownItemsPresenter; + + // await RunOnUIThread(() => + + // { + // var root = Grid > (XamlReader.Load( + // LR"( + + + + + // < ComboBox x: Name = "comboBox" Height = "100" > + + + + + // < ComboBoxItem x: Name = "comboBoxItem" Content = "i0" /> + + + + + // + + + + + // )")); + + + + // comboBox = ComboBox > (root.FindName("comboBox")); + // comboBoxItem = (ComboBoxItem)(root.FindName("comboBoxItem")); + + // TestServices.WindowHelper.WindowContent = root; + // }); + //await TestServices.WindowHelper.WaitForIdle(); + + // // Open via Touch. + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Touch); + // await RunOnUIThread(() => + + //{ + // comboBoxDropdownRoot = (FrameworkElement)(TreeHelper.GetVisualChildByNameFromOpenPopups("ScrollViewer", comboBox)); + // comboBoxDropdownItemsPresenter = TreeHelper.GetVisualChildByType(comboBoxDropdownRoot); + // VERIFY_IS_NOT_NULL(comboBoxDropdownRoot); + // VERIFY_IS_NOT_NULL(comboBoxDropdownItemsPresenter); + + // VERIFY_ARE_EQUAL(expectedDropdownWidth_Touch, comboBoxDropdownRoot.MinWidth); + // VERIFY_ARE_EQUAL(expectedDropdownWidth_Touch, comboBoxDropdownRoot.ActualWidth); + // VERIFY_ARE_EQUAL(expectedComboBoxItemHeight_Touch, comboBoxItem.ActualHeight); + // VERIFY_ARE_EQUAL(expectedDropdownContentMargin_NonTouchAndCarousel, comboBoxDropdownItemsPresenter.Margin); + // }); + //await ComboBoxHelper.CloseComboBox(comboBox); + + // // Open via Gamepad. + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Gamepad); + // await RunOnUIThread(() => + + //{ + // comboBoxDropdownRoot = (FrameworkElement)(TreeHelper.GetVisualChildByNameFromOpenPopups("ScrollViewer", comboBox)); + // comboBoxDropdownItemsPresenter = TreeHelper.GetVisualChildByType(comboBoxDropdownRoot); + // VERIFY_ARE_EQUAL(expectedDropdownWidth_Touch, comboBoxDropdownRoot.MinWidth); + // VERIFY_ARE_EQUAL(expectedDropdownWidth_Touch, comboBoxDropdownRoot.ActualWidth); + // VERIFY_ARE_EQUAL(expectedComboBoxItemHeight_Touch, comboBoxItem.ActualHeight); + // VERIFY_ARE_EQUAL(expectedDropdownContentMargin_NonTouchAndCarousel, comboBoxDropdownItemsPresenter.Margin); + // }); + //await ComboBoxHelper.CloseComboBox(comboBox); + + // // Open via Mouse. + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Mouse); + // await RunOnUIThread(() => + + //{ + // VERIFY_ARE_EQUAL(expectedDropdownWidth_NonTouch, comboBoxDropdownRoot.MinWidth); + // VERIFY_ARE_EQUAL(expectedDropdownWidth_NonTouch, comboBoxDropdownRoot.ActualWidth); + // VERIFY_ARE_EQUAL(expectedComboBoxItemHeight_NonTouch, comboBoxItem.ActualHeight); + // VERIFY_ARE_EQUAL(expectedDropdownContentMargin_NonTouchAndCarousel, comboBoxDropdownItemsPresenter.Margin); + // }); + //await ComboBoxHelper.CloseComboBox(comboBox); + + // // Open via Keyboard. + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Keyboard); + // await RunOnUIThread(() => + + //{ + // VERIFY_ARE_EQUAL(expectedDropdownWidth_NonTouch, comboBoxDropdownRoot.MinWidth); + // VERIFY_ARE_EQUAL(expectedDropdownWidth_NonTouch, comboBoxDropdownRoot.ActualWidth); + // VERIFY_ARE_EQUAL(expectedComboBoxItemHeight_NonTouch, comboBoxItem.ActualHeight); + // VERIFY_ARE_EQUAL(expectedDropdownContentMargin_NonTouchAndCarousel, comboBoxDropdownItemsPresenter.Margin); + // }); + //await ComboBoxHelper.CloseComboBox(comboBox); + + // // Open programmatically. + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); + // await RunOnUIThread(() => + + //{ + // VERIFY_ARE_EQUAL(expectedDropdownWidth_NonTouch, comboBoxDropdownRoot.MinWidth); + // VERIFY_ARE_EQUAL(expectedDropdownWidth_NonTouch, comboBoxDropdownRoot.ActualWidth); + // VERIFY_ARE_EQUAL(expectedComboBoxItemHeight_NonTouch, comboBoxItem.ActualHeight); + // VERIFY_ARE_EQUAL(expectedDropdownContentMargin_NonTouchAndCarousel, comboBoxDropdownItemsPresenter.Margin); + // }); + //await ComboBoxHelper.CloseComboBox(comboBox); + + // // Adding 15 more items so that the max limit of ComboBoxItems to show is reached. + // // After 15 items, the Dropdown starts showing a ScrollBar to see other ComboBoxItems. + // await RunOnUIThread(() => + + //{ + // for (uint i = 1; i < 16; ++i) + // { + // var cbItem = new ComboBoxItem(); + // cbItem.Content = "i" + i; + // comboBox.Items.Add(cbItem); + // } + // }); + + //// Open via Touch. Now, since the Dropdown have a ScrollBar, when opened with touch, the Dropdown will Carousel, + //// that is, it loops around the ComboBoxItems. In this case, we want to make sure there is no extra Top/Bottom + //// Padding/Margin on the Content. + //await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Touch); + // await RunOnUIThread(() => + + //{ + // VERIFY_ARE_EQUAL(expectedDropdownWidth_Touch, comboBoxDropdownRoot.MinWidth); + // VERIFY_ARE_EQUAL(expectedDropdownWidth_Touch, comboBoxDropdownRoot.ActualWidth); + // VERIFY_ARE_EQUAL(expectedComboBoxItemHeight_Touch, comboBoxItem.ActualHeight); + // VERIFY_ARE_EQUAL(expectedDropdownContentMargin_TouchAndCarousel, comboBoxDropdownItemsPresenter.Margin); + // }); + //await ComboBoxHelper.CloseComboBox(comboBox); + //} + + //[TestMethod] + //public async Task ValidateFootprint() + //{ + + + // double expectedComboBoxWidth = 64; + // double expectedComboBoxWidth_WithWideContent = 200 + 44; + // double expectedComboBoxWidth_WithWideHeader = 20.0; + + // double expectedComboBoxHeight_NoHeader = 32; + // double expectedComboBoxHeight_WithHeader = 19 + 4 + expectedComboBoxHeight_NoHeader; + + // ComboBox comboBox; + // ComboBox comboBoxWithHeader; + // ComboBox comboBoxWithWideContent; + // ComboBox comboBoxWithWideHeader; + // StackPanel ^ rootPanel; + + // await RunOnUIThread(() => + + // { + // rootPanel = StackPanel ^> (XamlReader.Load( + // LR"( + + + // < ComboBox x: Name = "comboBox" > + + + // < ComboBoxItem Content = "1" /> + + + // < ComboBoxItem Content = "2" /> + + + // < ComboBoxItem Content = "3" /> + + + // + + + // < ComboBox x: Name = "comboBoxWithHeader" Header = "H" > + + + // < ComboBoxItem Content = "1" /> + + + // < ComboBoxItem Content = "2" /> + + + // < ComboBoxItem Content = "3" /> + + + // + + + // < ComboBox x: Name = "comboBoxWithWideContent" > + + + // < ComboBoxItem IsSelected = "True" > + + + // < Rectangle Height = "10" Width = "200" Fill = "Red" /> + + + // + + + // < ComboBoxItem Content = "2" /> + + + // < ComboBoxItem Content = "3" /> + + + // + + + // < ComboBox x: Name = "comboBoxWithWideHeader" > + + + // < ComboBox.Header > + + + // < Rectangle Height = "19" Width = "200" Fill = "Red" /> + + + // + + + // < ComboBoxItem Content = "1" /> + + + // < ComboBoxItem Content = "2" /> + + + // < ComboBoxItem Content = "3" /> + + + // + + + // )")); + + + + // comboBox = ComboBox > (rootPanel.FindName("comboBox")); + // comboBoxWithHeader = ComboBox > (rootPanel.FindName("comboBoxWithHeader")); + // comboBoxWithWideContent = ComboBox > (rootPanel.FindName("comboBoxWithWideContent")); + // comboBoxWithWideHeader = ComboBox > (rootPanel.FindName("comboBoxWithWideHeader")); + + // TestServices.WindowHelper.WindowContent = rootPanel; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + // await RunOnUIThread(() => + + // { + // VERIFY_ARE_EQUAL(expectedComboBoxWidth, comboBox.ActualWidth); + // VERIFY_ARE_EQUAL(expectedComboBoxHeight_NoHeader, comboBox.ActualHeight); + + // VERIFY_ARE_EQUAL(expectedComboBoxWidth, comboBoxWithHeader.ActualWidth); + // VERIFY_ARE_EQUAL(expectedComboBoxHeight_WithHeader, comboBoxWithHeader.ActualHeight); + + // VERIFY_ARE_EQUAL(expectedComboBoxWidth_WithWideContent, comboBoxWithWideContent.ActualWidth); + // VERIFY_ARE_EQUAL(expectedComboBoxHeight_NoHeader, comboBoxWithWideContent.ActualHeight); + + // VERIFY_ARE_EQUAL(expectedComboBoxWidth_WithWideHeader, comboBoxWithWideHeader.ActualWidth); + // VERIFY_ARE_EQUAL(expectedComboBoxHeight_WithHeader, comboBoxWithWideHeader.ActualHeight); + // }); + //} + + [TestMethod] + public async Task CanSelectItemWithTap() + { + ComboBoxItem comboBoxItem = null; + + var comboBox = await SetupBasicComboBoxTest(); + + await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); + await TestServices.WindowHelper.WaitForIdle(); + + await RunOnUIThread(() => + { + comboBoxItem = (ComboBoxItem)(comboBox.ContainerFromIndex(0)); + VERIFY_IS_NOT_NULL(comboBoxItem); + }); + await TestServices.WindowHelper.WaitForIdle(); + + TestServices.InputHelper.Tap(comboBoxItem); + await TestServices.WindowHelper.WaitForIdle(); + + await RunOnUIThread(() => + + { + VERIFY_ARE_EQUAL(comboBox.SelectedIndex, 0); + VERIFY_IS_FALSE(comboBox.IsDropDownOpen); + }); + } + + [TestMethod] + public async Task ValidateMaximumHeightIsHonored() + { + var comboBox = await SetupBasicComboBoxTest(10, true); + + await RunOnUIThread(() => + { + comboBox.MaxDropDownHeight = 10.0; + }); + await TestServices.WindowHelper.WaitForIdle(); + + await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); + await TestServices.WindowHelper.WaitForIdle(); + + await RunOnUIThread(() => + + { + var popupBorder = TreeHelper.GetVisualChildByNameFromOpenPopups("PopupBorder", comboBox); + VERIFY_IS_LESS_THAN(popupBorder.ActualHeight, 100); + }); + } + + //[TestMethod] + //public async Task ValidateSelectedValuePathProperty() + //{ + // ComboBox comboBox = null; + + // await RunOnUIThread(() => + + // { + // var rootPanel = new Grid(); + // VERIFY_IS_NOT_NULL(rootPanel); + + // Platform.Collections.Vector < PersonObject ^> ^itemList = new Platform.Collections.Vector (); + // itemList.Add(new PersonObject("Roger", "Federer")); + // itemList.Add(new PersonObject("Cristiano", "Ronaldo")); + // itemList.Add(new PersonObject("LeBron", "James")); + + // comboBox = new ComboBox(); + // VERIFY_IS_NOT_NULL(comboBox); + + // comboBox.ItemsSource = itemList; + // comboBox.DisplayMemberPath = "FirstName"; + // comboBox.SelectedValuePath = "LastName"; + + // rootPanel.Children.Add(comboBox); + // TestServices.WindowHelper.WindowContent = rootPanel; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // await RunOnUIThread(() => + + // { + // comboBox.SelectedIndex = 1; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // await RunOnUIThread(() => + + // { + // var expectedSelectedValueString = "Ronaldo"; + // var selectedValueString = (string)(comboBox.SelectedValue); + + // VERIFY_IS_NOT_NULL(selectedValueString); + // VERIFY_ARE_EQUAL(expectedSelectedValueString, selectedValueString); + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // await RunOnUIThread(() => + + // { + // // changing the SelectedValue to something invalid (not in collection) + // comboBox.SelectedValue = "Hello"; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // await RunOnUIThread(() => + + // { + // // after changing the SelectedValue to something unrecognizable, SelectedValue should change to null + // VERIFY_IS_NULL(comboBox.SelectedValue); + // }); + // await TestServices.WindowHelper.WaitForIdle(); + //} + + //[TestMethod] + //public async Task ValidateCustomizedPaddingWithTouch() + //{ + + + // ScrollViewer scrollViewer = null; + + // var comboBox = await SetupComboBoxCustomizedPaddingTest(); + + // // Validate the touch input mode padding for each item. + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Touch); + // await RunOnUIThread(() => + + // { + // var popup = TreeHelper.GetVisualChildByType(comboBox); + // var popupChild = (FrameworkElement)(popup.Child); + // scrollViewer = TreeHelper.GetVisualChildByType(popupChild); + // }); + // ValidateComboBoxItemPadding(comboBox, ComboBoxHelper.OpenMethod.Touch); + // for (int i = 0; i < 10; ++i) + // { + // TestServices.InputHelper.Flick(comboBox, FlickDirection.North); + // } + // await TestServices.WindowHelper.WaitForIdle(); + // ValidateComboBoxItemPadding(comboBox, ComboBoxHelper.OpenMethod.Touch); + // for (int i = 0; i < 10; ++i) + // { + // TestServices.InputHelper.Flick(comboBox, FlickDirection.South); + // } + // await TestServices.WindowHelper.WaitForIdle(); + // ValidateComboBoxItemPadding(comboBox, ComboBoxHelper.OpenMethod.Touch); + // await ComboBoxHelper.CloseComboBox(comboBox); + //} + + //[TestMethod] + //public async Task ValidateCustomizedPaddingWithMouseAndKeyboard() + //{ + // ScrollViewer scrollViewer = null; + + // var comboBox = await SetupComboBoxCustomizedPaddingTest(); + + // // Validate the mouse input mode padding for each item. + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Mouse); + // await RunOnUIThread(() => + + // { + // var popup = TreeHelper.GetVisualChildByType(comboBox); + // var popupChild = (FrameworkElement)(popup.Child); + // scrollViewer = TreeHelper.GetVisualChildByType(popupChild); + // }); + // ValidateComboBoxItemPadding(comboBox, ComboBoxHelper.OpenMethod.Mouse); + // TestServices.InputHelper.MoveMouse(scrollViewer); + // await TestServices.WindowHelper.WaitForIdle(); + // TestServices.InputHelper.ScrollMouseWheel(scrollViewer, 10 /* numberOfWheelClicks */); + // await TestServices.WindowHelper.WaitForIdle(); + // ValidateComboBoxItemPadding(comboBox, ComboBoxHelper.OpenMethod.Mouse); + // TestServices.InputHelper.ScrollMouseWheel(scrollViewer, -10 /* numberOfWheelClicks */); + // await TestServices.WindowHelper.WaitForIdle(); + // ValidateComboBoxItemPadding(comboBox, ComboBoxHelper.OpenMethod.Mouse); + // await ComboBoxHelper.CloseComboBox(comboBox); + + // // Validate the keyboard input mode padding for each item. + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Keyboard); + // TestServices.KeyboardHelper.PressKeySequence("$d$_pagedown#$u$_pagedown"); + // await TestServices.WindowHelper.WaitForIdle(); + // TestServices.KeyboardHelper.PressKeySequence("$d$_pagedown#$u$_pagedown"); + // await TestServices.WindowHelper.WaitForIdle(); + // ValidateComboBoxItemPadding(comboBox, ComboBoxHelper.OpenMethod.Keyboard); + // TestServices.KeyboardHelper.PressKeySequence("$d$_pageup#$u$_pageup"); + // await TestServices.WindowHelper.WaitForIdle(); + // TestServices.KeyboardHelper.PressKeySequence("$d$_pageup#$u$_pageup"); + // await TestServices.WindowHelper.WaitForIdle(); + // ValidateComboBoxItemPadding(comboBox, ComboBoxHelper.OpenMethod.Keyboard); + // await ComboBoxHelper.CloseComboBox(comboBox); + //} + + //ComboBox ^ SetupComboBoxCustomizedPaddingTest() + //{ + // ComboBox comboBox = null; + + // await RunOnUIThread(() => + + // { + // var rootPanel = Grid > (XamlReader.Load( + // LR"( + + + + // < Grid.Resources > + + + + + // < Style TargetType = "ComboBoxItem" > + + + + + // < Setter Property = "Background" Value = "Red" /> + + + + + // < Setter Property = "Padding" Value = "21, 22, 23, 24" /> + + + + + // + + + + + // + + + + + // < ComboBox x: Name = 'comboBoxCustomPaddingItem' Background = 'RoyalBlue' SelectedIndex = '0' Width = '350' > + + + + + // < ComboBoxItem Content = 'Apps and Games (1)' /> + + + + + // < ComboBoxItem Content = 'Files, Folders, and Online Storage (2)' /> + + + + + // < ComboBoxItem Content = 'Hardware, Devices, and Drivers (3)' /> + + + + + // < ComboBoxItem Content = 'Windows Installation and Setup (4)' /> + + + + + // < ComboBoxItem Content = 'Microsoft Edge and IE (5)' /> + + + + + // < ComboBoxItem Content = 'Networks (6)' /> + + + + + // < ComboBoxItem Content = 'Personalization and Ease of Access (7)' /> + + + + + // < ComboBoxItem Content = 'Power and Battery (8)' /> + + + + + // < ComboBoxItem Content = 'Windows Recovery (9)' /> + + + + + // < ComboBoxItem Content = 'Cortana and search (10)' /> + + + + + // < ComboBoxItem Content = 'Start (11)' /> + + + + + // < ComboBoxItem Content = 'Desktop (12)' /> + + + + + // < ComboBoxItem Content = 'Security, Privacy, and Accounts (13)' /> + + + + + // < ComboBoxItem Content = 'Input and Interaction Methods (14)' /> + + + + + // < ComboBoxItem Content = 'Store (15)' /> + + + + + // < ComboBoxItem Content = 'Developer Platform (16)' /> + + + + + // < ComboBoxItem Content = 'Internal Feedback Tools (17)' /> + + + + + // < ComboBoxItem Content = 'Preview Programs (18)' /> + + + + + // + + + + + // )")); + + + + + + // comboBox = ComboBox > (TreeHelper.GetVisualChildByName(rootPanel, "comboBoxCustomPaddingItem")); + // TestServices.WindowHelper.WindowContent = rootPanel; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // return comboBox; + //} + + private async Task ValidateComboBoxItemPadding(ComboBox comboBox, ComboBoxHelper.OpenMethod openMethod) + { + await RunOnUIThread(() => + { + foreach (var item in comboBox.Items) + { + var comboBoxItem = (ComboBoxItem)item; + var contentPresenter = (ContentPresenter)TreeHelper.GetVisualChildByName(comboBoxItem, "ContentPresenter"); + + if (contentPresenter is not null) + { + LOG_OUTPUT("Item padding left=%f top=%f right=%f bottom=%f", contentPresenter.Margin.Left, contentPresenter.Margin.Top, contentPresenter.Margin.Right, contentPresenter.Margin.Bottom); + + if (openMethod == ComboBoxHelper.OpenMethod.Touch) + { + Thickness expectedThickness = new Thickness(10, 8, 10, 11); + VERIFY_ARE_EQUAL(expectedThickness, contentPresenter.Margin); + } + else + { + VERIFY_ARE_EQUAL(comboBoxItem.Padding, contentPresenter.Margin); + } + } + else + { + LOG_OUTPUT("Item isn't realized yet!"); + } + } + }); + } + + // [TestMethod] public async Task ValidateItemTemplateSettingWithTouch() + //{ + + + // ComboBox comboBox = null; + // ScrollViewer scrollViewer = null; + + // await RunOnUIThread(() => + + // { + // var rootPanel = Grid > (XamlReader.Load( + // LR"( + + + // < Grid.Resources > + + + + // < Style x: Key = "ContentTextStyle" TargetType = "TextBlock" > + + + + // < Setter Property = "Foreground" Value = "Blue" /> + + + + // < Setter Property = "HorizontalAlignment" Value = "Center" /> + + + + // < Setter Property = "VerticalAlignment" Value = "Center" /> + + + + // < Setter Property = "FontSize" Value = "40" /> + + + + // < Setter Property = "TextWrapping" Value = "NoWrap" /> + + + + // < Setter Property = "FontFamily" Value = "segoeuil.ttf#Segoe UI" /> + + + + // + + + + // + + + + // < StackPanel Orientation = "Horizontal" > + + + + // < ComboBox x: Name = 'comboBoxNotificationSetting' Background = 'RoyalBlue' Width = "200" > + + + + // < ComboBox.ItemTemplate > + + + + // < DataTemplate > + + + + // < Border Height = "60" > + + + + // < Border BorderBrush = "Black" BorderThickness = "0" > + + + + // < TextBlock Text = "{Binding}" Style = "{StaticResource ContentTextStyle}" /> + + + + // + + + + // + + + + // + + + + // + + + + // + + + + // + + + + // )")); + + + // comboBox = ComboBox > (TreeHelper.GetVisualChildByName(rootPanel, "comboBoxNotificationSetting")); + + // // Add the notification setting items + // var itemList = new List(); + // itemList.Add("All settings(1)"); + // itemList.Add("Connect (2)"); + // itemList.Add("Battery saver (3)"); + // itemList.Add("Flashlight (4)"); + // itemList.Add("Note (5)"); + // itemList.Add("VPN (6)"); + // itemList.Add("Location (7)"); + // itemList.Add("Airplane mode (8)"); + // itemList.Add("Bluetooth (9)"); + // itemList.Add("Camera (10)"); + // itemList.Add("Cellular (11)"); + // itemList.Add("Mobile hotspot (12)"); + // itemList.Add("Quiet hours (13)"); + // itemList.Add("Wi-Fi (14)"); + // itemList.Add("Rotation lock (15)"); + // itemList.Add("Brightness (16)"); + // comboBox.ItemsSource = itemList; + + // TestServices.WindowHelper.WindowContent = rootPanel; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // // Validate the touch input mode padding for each item. + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Touch); + + // await RunOnUIThread(() => + + // { + // var popup = TreeHelper.GetVisualChildByType(comboBox); + // scrollViewer = TreeHelper.GetVisualChildByType((FrameworkElement)(popup.Child)); + // }); + + // LOG_OUTPUT("Panning to North."); + + // for (int i = 0; i < 25; ++i) + // { + // TestServices.InputHelper.Flick(comboBox, FlickDirection.North); + // } + // await TestServices.WindowHelper.WaitForIdle(); + + // LOG_OUTPUT("Panning to South."); + + // for (int i = 0; i < 25; ++i) + // { + // TestServices.InputHelper.Flick(comboBox, FlickDirection.South); + // } + // await TestServices.WindowHelper.WaitForIdle(); + + // LOG_OUTPUT("No layout cycle reported!"); + + // await ComboBoxHelper.CloseComboBox(comboBox); + //} + + //[TestMethod] + //public async Task ValidateOpenedComboBoxPositionByTouchInput() + //{ + // await DoValidatePosition(5, ComboBoxHelper.OpenMethod.Touch, false /* addMouseOpenMethod */); + // await DoValidatePosition(50, ComboBoxHelper.OpenMethod.Touch, false /* addMouseOpenMethod */); + //} + + //[TestMethod] + //public async Task ValidateOpenedComboBoxPositionWithDifferentInput() + //{ + // await DoValidatePosition(5, ComboBoxHelper.OpenMethod.Touch, true /* addMouseOpenMethod */); + // await DoValidatePosition(50, ComboBoxHelper.OpenMethod.Touch, true /* addMouseOpenMethod */); + //} + + //private async Task DoValidatePosition(int itemCount, ComboBoxHelper.OpenMethod openMethod, bool addMouseOpenMethod, bool isVerticalAlignment) + //{ + // var comboBox = await SetupBasicComboBoxTest(itemCount /* itemSize */); + + // await RunOnUIThread(() => + // { + // comboBox.Margin = new Thickness(0, 0, 0, 0); + // }); + + // if (isVerticalAlignment) + // { + // LOG_OUTPUT("DoValidatePosition Horizontal:Left Vertical:Top."); + // await ValidatePosition(HorizontalAlignment.Left, VerticalAlignment.Top, comboBox, openMethod); + // if (addMouseOpenMethod) + // { + // await ValidatePosition(HorizontalAlignment.Left, VerticalAlignment.Top, comboBox, ComboBoxHelper.OpenMethod.Mouse); + // } + + // LOG_OUTPUT("DoValidatePosition Horizontal:Left Vertical:Center."); + // await ValidatePosition(HorizontalAlignment.Left, VerticalAlignment.Center, comboBox, openMethod); + // if (addMouseOpenMethod) + // { + // await ValidatePosition(HorizontalAlignment.Left, VerticalAlignment.Center, comboBox, ComboBoxHelper.OpenMethod.Mouse); + // } + + // LOG_OUTPUT("DoValidatePosition Horizontal:Left Vertical:Bottom."); + // await ValidatePosition(HorizontalAlignment.Left, VerticalAlignment.Bottom, comboBox, openMethod); + // if (addMouseOpenMethod) + // { + // await ValidatePosition(HorizontalAlignment.Left, VerticalAlignment.Bottom, comboBox, ComboBoxHelper.OpenMethod.Mouse); + // } + // } + // else + // { + // LOG_OUTPUT("DoValidatePosition Horizontal:Left Vertical:Top."); + // await ValidatePosition(HorizontalAlignment.Left, VerticalAlignment.Top, comboBox, openMethod); + // if (addMouseOpenMethod) + // { + // await ValidatePosition(HorizontalAlignment.Left, VerticalAlignment.Top, comboBox, ComboBoxHelper.OpenMethod.Mouse); + // } + + // LOG_OUTPUT("DoValidatePosition Horizontal:Center Vertical:Top."); + // await ValidatePosition(HorizontalAlignment.Center, VerticalAlignment.Top, comboBox, openMethod); + // if (addMouseOpenMethod) + // { + // await ValidatePosition(HorizontalAlignment.Center, VerticalAlignment.Top, comboBox, ComboBoxHelper.OpenMethod.Mouse); + // } + + // LOG_OUTPUT("DoValidatePosition Horizontal:Right Vertical:Top."); + // await ValidatePosition(HorizontalAlignment.Right, VerticalAlignment.Top, comboBox, openMethod); + // if (addMouseOpenMethod) + // { + // await ValidatePosition(HorizontalAlignment.Right, VerticalAlignment.Top, comboBox, ComboBoxHelper.OpenMethod.Mouse); + // } + // } + //} + + //private async Task ValidatePosition(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, ComboBox comboBox, ComboBoxHelper.OpenMethod openMethod) + //{ + // ScrollViewer scrollViewer = null; + + // await RunOnUIThread(() => + // { + // var rootPanel = (Grid)comboBox.Parent; + // rootPanel.HorizontalAlignment = horizontalAlignment; + // rootPanel.VerticalAlignment = verticalAlignment; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // await ComboBoxHelper.OpenComboBox(comboBox, openMethod); + + // await RunOnUIThread(async () => + + // { + // var popup = TreeHelper.GetVisualChildByType(comboBox); + // var popupChild = (FrameworkElement)popup.Child; + // scrollViewer = (ScrollViewer)(TreeHelper.GetVisualChildByName(popupChild, "ScrollViewer")); + + // Rect scrollViewerBounds = await ControlHelper.GetBounds(scrollViewer); + // Rect visibleBounds = TestServices.WindowHelper.VisibleBounds; + + // LOG_OUTPUT("scrollViewerBounds: (%f, %f, %f, %f)", scrollViewerBounds.X, scrollViewerBounds.Y, scrollViewerBounds.Width, scrollViewerBounds.Height); + // LOG_OUTPUT("visibleBounds: (%f, %f, %f, %f)", visibleBounds.X, visibleBounds.Y, visibleBounds.Width, visibleBounds.Height); + + // Point topLeftCorner = default; + + // // If we're on desktop with windowed popups enabled, then we expect the popup to be able to overlap with the window chrome. + // if (PopupHelper.AreWindowedPopupsEnabled()) + // { + // Rect windowBounds = TestServices.WindowHelper.WindowBounds; + // LOG_OUTPUT("windowBounds: (%f, %f, %f, %f)", windowBounds.X, windowBounds.Y, windowBounds.Width, windowBounds.Height); + + // topLeftCorner.X -= windowBounds.X; + // topLeftCorner.Y -= windowBounds.Y; + // visibleBounds.X += windowBounds.X; + // visibleBounds.Y += windowBounds.Y; + // } + + // VERIFY_IS_TRUE(scrollViewerBounds.X >= topLeftCorner.X); + // VERIFY_IS_TRUE(scrollViewerBounds.X + scrollViewerBounds.Width <= topLeftCorner.X + visibleBounds.X + visibleBounds.Width); + // VERIFY_IS_TRUE(scrollViewerBounds.Y >= topLeftCorner.Y); + // VERIFY_IS_TRUE(scrollViewerBounds.Y + scrollViewerBounds.Height <= topLeftCorner.Y + visibleBounds.Y + visibleBounds.Height); + // }); + + // await ComboBoxHelper.CloseComboBox(comboBox); + // await TestServices.WindowHelper.WaitForIdle(); + //} + + //[TestMethod] + //public async Task ValidateOpenedComboBoxPositionWhenUsingExtendedTitleBar() + //{ + + + // //ExtendViewIntoTitleBar requires that we have a loaded xaml page, so lets load something before we set this flag. + // await RunOnUIThread(() => + + // { + // TestServices.WindowHelper.WindowContent = new Grid(); + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // await RunOnUIThread(() => + + // { + // CoreApplicationViewTitleBar coreApplicationViewTitleBar = null; + + // coreApplicationViewTitleBar = CoreApplication.GetCurrentView().TitleBar; + // coreApplicationViewTitleBar.ExtendViewIntoTitleBar = true; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // // Wait for 2 frame to update the content on the extend title area. + // await TestServices.WindowHelper.SynchronouslyTickUIThread(2); + + // DoValidatePosition(50, ComboBoxHelper.OpenMethod.Touch, false /* addMouseOpenMethod */); + //} + + //[TestMethod] + //public async Task ValidateOpenedComboBoxPositionWhenUsingCoreWindowBounds() + //{ + // TestServices.WindowHelper.SetVisibleBounds(Rect(0, 32, 480, 768)); + + // var comboBox = await SetupBasicComboBoxTest(50.0; + + // await RunOnUIThread(() => + + // { + // comboBox.Margin = { 0,0,0,0 }; + // comboBox.Height = 10.0; + // comboBox.Width = 30.0; + + // wuv.ApplicationView.GetForCurrentView().SetDesiredBoundsMode(wuv.ApplicationViewBoundsMode.UseCoreWindow); + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // DoValidatePosition(50, ComboBoxHelper.OpenMethod.Programmatic, false /* addMouseOpenMethod */, true /* isVerticalAlignment */); + + // // Set the window with the landscape mode with specifying the visible bounds. + // TestServices.WindowHelper.SetWindowSizeOverride(new Size(800, 480)); + // TestServices.WindowHelper.SetVisibleBounds(Rect(44, 0, 756, 480)); + // await TestServices.WindowHelper.WaitForIdle(); + + // DoValidatePosition(50, ComboBoxHelper.OpenMethod.Programmatic, false /* addMouseOpenMethod */, false /* isVerticalAlignment */); + //} + + [TestMethod] + public async Task ValidateLightDismissOverlayMode() + { + var comboBox = await SetupBasicComboBoxTest(); + + await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); + + LOG_OUTPUT("Validate that the default is Auto and the ComboBox's popup is set to Off (or On if on Xbox)"); + { + await RunOnUIThread(() => + + { + VERIFY_ARE_EQUAL(comboBox.LightDismissOverlayMode, LightDismissOverlayMode.Auto); + }); + + await ValidateComboBoxPopupLightDismissOverlayMode( + TestServices.Utilities.IsXBox ? LightDismissOverlayMode.On : LightDismissOverlayMode.Off); + } + + LOG_OUTPUT("Validate that when set to On the ComboBox's popup is also set to On."); + { + await RunOnUIThread(() => + + { + comboBox.LightDismissOverlayMode = LightDismissOverlayMode.On; + }); + + await ValidateComboBoxPopupLightDismissOverlayMode(LightDismissOverlayMode.On); + } + + LOG_OUTPUT("Validate that when set to Off the ComboBox's popup is also set to Off."); + { + await RunOnUIThread(() => + + { + comboBox.LightDismissOverlayMode = LightDismissOverlayMode.Off; + }); + + await ValidateComboBoxPopupLightDismissOverlayMode(LightDismissOverlayMode.Off); + } + + await ComboBoxHelper.CloseComboBox(comboBox); + } + + [TestMethod] + public async Task DoesAutoLightDismissOverlayModeCreateOverlayOnXbox() + { + var comboBox = await SetupBasicComboBoxTest(); + + await RunOnUIThread(() => + + { + comboBox.LightDismissOverlayMode = LightDismissOverlayMode.Auto; + }); + + await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); + + await ValidateComboBoxPopupLightDismissOverlayMode(LightDismissOverlayMode.On); + + await ComboBoxHelper.CloseComboBox(comboBox); + } + + //[TestMethod] + //public async Task ValidateOverlayBrush() + //{ + // var comboBox = await SetupBasicComboBoxTest(); + + // await RunOnUIThread(() => + + // { + // comboBox.LightDismissOverlayMode = LightDismissOverlayMode.On; + // }); + + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); + + // await RunOnUIThread(() => + + // { + // var expectedBrush = SolidColorBrush(Application.Current.Resources.Lookup("ComboBoxLightDismissOverlayBackground")); + + // var popups = VisualTreeHelper.GetOpenPopupsForXamlRoot(comboBox.XamlRoot); + // WEX.Common.Throw.IfFalse(popups.Size == 1, E_FAIL, "Expected exactly one open Popup."); + + // var popup = popups.GetAt(0.0; + + // var overlayElement = TestServices.Utilities.GetPopupOverlayElement(popup); + // THROW_IF_null_WITH_MSG(overlayElement, "An overlay element should exist."); + + // var overlayRect = (xaml_shapes.Rectangle ^)(overlayElement); + // THROW_IF_null_WITH_MSG(overlayRect, "The overlay element should be a rectangle."); + + // var overlayBrush = SolidColorBrush ^> (overlayRect.Fill); + // VERIFY_IS_NOT_NULL(overlayBrush); + // VERIFY_IS_TRUE(overlayBrush.Equals(expectedBrush)); + // }); + + // await ComboBoxHelper.CloseComboBox(comboBox); + //} + + private async Task ValidateComboBoxPopupLightDismissOverlayMode(LightDismissOverlayMode expectedMode) + { + await RunOnUIThread(() => + + { + var popups = VisualTreeHelper.GetOpenPopupsForXamlRoot(TestServices.WindowHelper.WindowContent.XamlRoot); + Assert.AreEqual(1, popups.Count, "Expected exactly one open Popup."); + + var popup = popups[0]; + + VERIFY_ARE_EQUAL(popup.LightDismissOverlayMode, expectedMode); + + if (expectedMode == LightDismissOverlayMode.On) + { + var overlayElement = TestServices.Utilities.GetPopupOverlayElement(popup); + VERIFY_IS_NOT_NULL(overlayElement); + } + }); + } + + [TestMethod] + public async Task ValidateFocusStateForComboBoxOpenedWithTouch() + { + await ValidateFocusStateForComboBoxWorker(ComboBoxHelper.OpenMethod.Touch, FocusState.Pointer); + } + + [TestMethod] + public async Task ValidateFocusStateForComboBoxOpenedWithMouse() + { + await ValidateFocusStateForComboBoxWorker(ComboBoxHelper.OpenMethod.Mouse, FocusState.Pointer); + } + + [TestMethod] + public async Task ValidateFocusStateForComboBoxOpenedWithKeyboard() + { + await ValidateFocusStateForComboBoxWorker(ComboBoxHelper.OpenMethod.Keyboard, FocusState.Keyboard); + } + + [TestMethod] + public async Task ValidateFocusStateForComboBoxOpenedWithGamepad() + { + await ValidateFocusStateForComboBoxWorker(ComboBoxHelper.OpenMethod.Gamepad, FocusState.Keyboard); + } + + private async Task ValidateFocusStateForComboBoxWorker(ComboBoxHelper.OpenMethod openMethod, FocusState expectedFocusState) + { + + + ComboBox comboBox = await SetupBasicComboBoxTest(); + + await RunOnUIThread(() => + { + comboBox.SelectedIndex = 0; + }); + await TestServices.WindowHelper.WaitForIdle(); + + await ComboBoxHelper.OpenComboBox(comboBox, openMethod); + + await RunOnUIThread(() => + + { + var selectedValue = (ComboBoxItem)(comboBox.SelectedValue); + VERIFY_IS_NOT_NULL(selectedValue); + var focusState = selectedValue.FocusState; + VERIFY_ARE_EQUAL(expectedFocusState, focusState); + }); + await TestServices.WindowHelper.WaitForIdle(); + + await ComboBoxHelper.CloseComboBox(comboBox); + await TestServices.WindowHelper.WaitForIdle(); + } + + [TestMethod] + public async Task ValidateFocusStateOfClosedComboBoxWhenOpenedAndClosedWithMouse() + { + await ValidateFocusStateOfClosedComboBoxWorker(ComboBoxHelper.OpenMethod.Mouse, ComboBoxHelper.CloseMethod.Mouse, FocusState.Pointer); + } + + [TestMethod] + public async Task ValidateFocusStateOfClosedComboBoxWhenOpenedAndClosedWithTouch() + { + await ValidateFocusStateOfClosedComboBoxWorker(ComboBoxHelper.OpenMethod.Touch, ComboBoxHelper.CloseMethod.Touch, FocusState.Pointer); + } + + [TestMethod] + public async Task ValidateFocusStateOfClosedComboBoxWhenOpenedAndClosedWithKeyboard() + { + await ValidateFocusStateOfClosedComboBoxWorker(ComboBoxHelper.OpenMethod.Keyboard, ComboBoxHelper.CloseMethod.Keyboard, FocusState.Keyboard); + } + + [TestMethod] + public async Task ValidateFocusStateOfClosedComboBoxWhenOpenedAndClosedWithGamepad() + { + await ValidateFocusStateOfClosedComboBoxWorker(ComboBoxHelper.OpenMethod.Gamepad, ComboBoxHelper.CloseMethod.Gamepad, FocusState.Keyboard); + } + + [TestMethod] + public async Task ValidateFocusStateOfClosedComboBoxWhenOpenedWithTouchAndClosedWithKeyboard() + { + await ValidateFocusStateOfClosedComboBoxWorker(ComboBoxHelper.OpenMethod.Touch, ComboBoxHelper.CloseMethod.Keyboard, FocusState.Keyboard); + } + + [TestMethod] + public async Task ValidateFocusStateOfClosedComboBoxWhenOpenedWithTouchAndClosedWithGamepad() + { + await ValidateFocusStateOfClosedComboBoxWorker(ComboBoxHelper.OpenMethod.Touch, ComboBoxHelper.CloseMethod.Gamepad, FocusState.Keyboard); + } + + [TestMethod] + public async Task ValidateFocusStateOfClosedComboBoxWhenOpenedWithMouseAndClosedWithKeyboard() + { + await ValidateFocusStateOfClosedComboBoxWorker(ComboBoxHelper.OpenMethod.Mouse, ComboBoxHelper.CloseMethod.Keyboard, FocusState.Keyboard); + } + + [TestMethod] + public async Task ValidateFocusStateOfClosedComboBoxWhenOpenedWithMouseAndClosedWithGamepad() + { + await ValidateFocusStateOfClosedComboBoxWorker(ComboBoxHelper.OpenMethod.Mouse, ComboBoxHelper.CloseMethod.Gamepad, FocusState.Keyboard); + } + + private async Task ValidateFocusStateOfClosedComboBoxWorker(ComboBoxHelper.OpenMethod openMethod, ComboBoxHelper.CloseMethod closeMethod, FocusState expectedFocusState) + { + + + ComboBox comboBox = await SetupBasicComboBoxTest(); + + await RunOnUIThread(() => + + { + comboBox.SelectedIndex = 0; + }); + await TestServices.WindowHelper.WaitForIdle(); + + await ComboBoxHelper.OpenComboBox(comboBox, openMethod); + + await ComboBoxHelper.CloseComboBox(comboBox, closeMethod); + + await RunOnUIThread(() => + + { + var focusState = comboBox.FocusState; + VERIFY_ARE_EQUAL(expectedFocusState, focusState); + }); + await TestServices.WindowHelper.WaitForIdle(); + } + + //[TestMethod] + //public async Task ValidatePagingKeyInteraction() + //{ + // int totalNumberOfItems = 20; + // int expectedNumberOfItemsToScrollWithPageKeys = 14; + + // ComboBox comboBox = await SetupBasicComboBoxTest(totalNumberOfItems); + + // await RunOnUIThread(() => + + // { + // comboBox.SelectionChangedTrigger = ComboBoxSelectionChangedTrigger.Always; + // comboBox.SelectedIndex = 0; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); + + // await ComboBoxHelper.VerifySelectedIndex(comboBox, 0); + + // LOG_OUTPUT("Changing selection with PageDown"); + // TestServices.KeyboardHelper.PageDown(); + // await TestServices.WindowHelper.WaitForIdle(); + // await ComboBoxHelper.VerifySelectedIndex(comboBox, expectedNumberOfItemsToScrollWithPageKeys); + + // LOG_OUTPUT("Changing selection with PageUp"); + // TestServices.KeyboardHelper.PageUp(); + // await TestServices.WindowHelper.WaitForIdle(); + // await ComboBoxHelper.VerifySelectedIndex(comboBox, 0); + + // LOG_OUTPUT("Changing selection with End"); + // TestServices.KeyboardHelper.End(); + // await TestServices.WindowHelper.WaitForIdle(); + // await ComboBoxHelper.VerifySelectedIndex(comboBox, totalNumberOfItems - 1); + + // LOG_OUTPUT("Changing selection with Home"); + // TestServices.KeyboardHelper.Home(); + // await TestServices.WindowHelper.WaitForIdle(); + // await ComboBoxHelper.VerifySelectedIndex(comboBox, 0); + + // await ComboBoxHelper.CloseComboBox(comboBox, ComboBoxHelper.CloseMethod.Programmatic); + //} + + // void OpenComboBoxWhileSIPIsUp() + // { + // wf.EventRegistrationToken inputPaneShowingToken = default; + // wf.EventRegistrationToken inputPaneHidingToken = default; + + // // Since InputPane is not agile, we can't use SafeEventRegistration. We need to manage the SIP events manually. + // TestCleanupWrapper cleanup([&inputPaneShowingToken, &inputPaneHidingToken]() + + + + // { + // RunOnUIThread([&inputPaneShowingToken, &inputPaneHidingToken]() + + // { + // InputPane.GetForCurrentView().Showing -= inputPaneShowingToken; + // InputPane.GetForCurrentView().Hiding -= inputPaneHidingToken; + // inputPaneShowingToken = default; + // inputPaneHidingToken = default; + // }); + + // TestServices.WindowHelper.ResetWindowContentAndWaitForIdle(); + // }); + + // ComboBox combobox; + // TextBox ^ textbox; + // ComboBoxItem itemToSelect; + + // await RunOnUIThread(() => + + // { + // var rootPanel = StackPanel ^> (XamlReader.Load( + // LR"( + + + + + + + + + // < ComboBox x: Name = "combobox" Header = "ComboBox Header" Margin = "12" FontSize = "40" SelectedIndex = "0" > + + + + + + + + + // < ComboBoxItem Content = "ComboBoxItem A" /> + + + + + + + + + // < ComboBoxItem Content = "ComboBoxItem B" /> + + + + + + + + + // < ComboBoxItem Content = "ComboBoxItem C" x: Name = "itemToSelect" /> + + + + + + + + + // < ComboBoxItem Content = "ComboBoxItem D" /> + + + + + + + + + // < ComboBoxItem Content = "ComboBoxItem E" /> + + + + + + + + + // < ComboBoxItem Content = "ComboBoxItem F" /> + + + + + + + + + // < ComboBoxItem Content = "ComboBoxItem G" /> + + + + + + + + + // + + + + + + + + + // < TextBox x: Name = "textbox" Header = "TextBox" Width = "200" HorizontalAlignment = "Left" Margin = "12" /> + + + + + + + + + // )")); + + + + + + + + // combobox = ComboBox > (rootPanel.FindName("combobox")); + // textbox = TextBox ^> (rootPanel.FindName("textbox")); + // itemToSelect = (ComboBoxItem)(rootPanel.FindName("itemToSelect")); + + // TestServices.WindowHelper.WindowContent = rootPanel; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // Event selectionChangedEvent; + // var selectionChangedRegistration = CreateSafeEventRegistration(ComboBox, SelectionChanged); + // selectionChangedRegistration.Attach(comboBox, (s, e) => { selectionChangedEvent.Set(); }); + + // var SIPShowingEvent = new Event(); + // var SIPHidingEvent = new Event(); + // await RunOnUIThread(() => + + // { + // InputPane ^ inputPane = InputPane.GetForCurrentView(); + // inputPaneShowingToken = inputPane.Showing += new wf.TypedEventHandler ([&](InputPane ^ pane, InputPaneVisibilityEventArgs ^ e) + + + + + + + // { + // SIPShowingEvent.Set(); + // }); + // inputPaneHidingToken = inputPane.Hiding += new wf.TypedEventHandler ([&](InputPane ^ pane, InputPaneVisibilityEventArgs ^ e) + + + + // { + // SIPHidingEvent.Set(); + // }); + // }); + + //// We want to know the height of the open ComboBox popup (without the SIP being involved). + //double fullHeightOfComboBoxPopup = 0; + // await ComboBoxHelper.OpenComboBox(combobox, ComboBoxHelper.OpenMethod.Touch); + // await RunOnUIThread(() => + + //{ + // var popupBorder = TreeHelper.GetVisualChildByNameFromOpenPopups("PopupBorder", combobox); + // fullHeightOfComboBoxPopup = popupBorder.ActualHeight; + // }); + //await ComboBoxHelper.CloseComboBox(combobox); + + // // Tap the TextBox to bring up the SIP. + // TestServices.InputHelper.Tap(textbox); + //SIPShowingEvent.WaitForDefault(); + //await TestServices.WindowHelper.WaitForIdle(); + + // // We want to test the scenario where the full size of the ComboBox popup would not fit in the window space + // // available when the SIP is up. + // // We verify that this is actually the case (otherwise we are not testing what we want to test). + // await RunOnUIThread(() => + + //{ + // var sipRect = InputPane.GetForCurrentView().OccludedRect; + // var windowBounds = Window.Current.Bounds; + + // var usableHeight = windowBounds.Height - sipRect.Height; + // VERIFY_IS_GREATER_THAN(fullHeightOfComboBoxPopup, usableHeight); + // }); + + //// Tap on the ComboBox when the SIP is up. + //// The ComboBox will open and the SIP will dismiss at the same time. + //await ComboBoxHelper.OpenComboBox(combobox, ComboBoxHelper.OpenMethod.Touch); + // SIPHidingEvent.WaitForDefault(); + //await TestServices.WindowHelper.WaitForIdle(); + + // // Select an item from the open ComboBox. + // TestServices.InputHelper.Tap(itemToSelect); + //selectionChangedEvent.WaitForDefault(); + + //await RunOnUIThread(() => + + // { + // VERIFY_IS_TRUE(itemToSelect.Equals(combobox.SelectedItem)); + // }); + //} + + + [TestMethod] + public async Task ValidatePopupPlacementAtBottomOfScreen() + { + int numberOfItems = 8; + float heightOfWindow = 40; + + Size size = new(400, heightOfWindow); + TestServices.WindowHelper.SetWindowSizeOverride(size); + + ComboBox comboBox = await SetupBasicComboBoxTest(numberOfItems); + + await RunOnUIThread(() => + + { + // Ensure that the combobox is partially off screen + TranslateTransform translateTransform = new Microsoft.UI.Xaml.Media.TranslateTransform(); + translateTransform.Y = 20; + comboBox.RenderTransform = translateTransform; + + comboBox.Margin = ThicknessHelper.FromUniformLength(0); + comboBox.HorizontalAlignment = HorizontalAlignment.Center; + comboBox.VerticalAlignment = VerticalAlignment.Bottom; + + // Select the last item. We will get the bounds of this item and ensure it is rendered on-screen. + comboBox.SelectedIndex = numberOfItems - 1; + }); + await TestServices.WindowHelper.WaitForIdle(); + + await ComboBoxHelper.OpenComboBox(comboBox, ComboBoxHelper.OpenMethod.Programmatic); + + ComboBoxItem selectedItem; + await RunOnUIThread(() => + + { + // Get the selected item + selectedItem = (ComboBoxItem)(comboBox.SelectedItem); + + // Get the bounds of the item + Rect selectedItemBounds = await ControlHelper.GetBounds(selectedItem); + LOG_OUTPUT("selectedItemBounds: (%f, %f, %f, %f)", selectedItemBounds.X, selectedItemBounds.Y, selectedItemBounds.Width, selectedItemBounds.Height); + + // Ensure that the bounds of the item are rendered within the height of the window, + // unless windowed popups are enabled, in which case we're fine with it appearing outside. + if (PopupHelper.AreWindowedPopupsEnabled()) + { + VERIFY_IS_GREATER_THAN(selectedItemBounds.Y + selectedItemBounds.Height, heightOfWindow); + } + else + { + VERIFY_IS_LESS_THAN_OR_EQUAL(selectedItemBounds.Y + selectedItemBounds.Height, heightOfWindow); + } + }); + + await ComboBoxHelper.CloseComboBox(comboBox, ComboBoxHelper.CloseMethod.Programmatic); + } + + //[TestMethod] + //public async Task ValidateOpenedDropDownHeightUsingMouse() + //{ + // ComboBox comboBoxTop; + // ComboBox comboBoxCenter; + // ComboBox comboBoxBottom; + // Rect scrollViewerTopBounds = default; + // Rect scrollViewerCenterBounds = default; + // Rect scrollViewerBottomBounds = default; + + // await RunOnUIThread(() => + + // { + // var rootPanel = Grid > (XamlReader.Load( + // LR"( + + + + // < ComboBox x: Name = "comboBoxTop" Width = "300" HorizontalAlignment = "Center" VerticalAlignment = "Top" > + + + + + + // < ComboBoxItem Content = "item one" /> + + + + + + // < ComboBoxItem Content = "item two" /> + + + + + + // < ComboBoxItem Content = "item three" /> + + + + + + // < ComboBoxItem Content = "item four" /> + + + + + + // < ComboBoxItem Content = "item five" /> + + + + + + // + + + + + + // < ComboBox x: Name = "comboBoxCenter" Width = "300" HorizontalAlignment = "Center" VerticalAlignment = "Center" > + + + + + + // < ComboBoxItem Content = "item one" /> + + + + + + // < ComboBoxItem Content = "item two" /> + + + + + + // < ComboBoxItem Content = "item three" /> + + + + + + // < ComboBoxItem Content = "item four" /> + + + + + + // < ComboBoxItem Content = "item five" /> + + + + + + // + + + + + + // < ComboBox x: Name = "comboBoxBottom" Width = "300" HorizontalAlignment = "Center" VerticalAlignment = "Bottom" > + + + + + + // < ComboBoxItem Content = "item one" /> + + + + + + // < ComboBoxItem Content = "item two" /> + + + + + + // < ComboBoxItem Content = "item three" /> + + + + + + // < ComboBoxItem Content = "item four" /> + + + + + + // < ComboBoxItem Content = "item five" /> + + + + + + // + + + + + + // )")); + + + + + // comboBoxTop = ComboBox > (rootPanel.FindName("comboBoxTop")); + // comboBoxCenter = ComboBox > (rootPanel.FindName("comboBoxCenter")); + // comboBoxBottom = ComboBox > (rootPanel.FindName("comboBoxBottom")); + + // TestServices.WindowHelper.WindowContent = rootPanel; + // }); + // await TestServices.WindowHelper.WaitForIdle(); + + // await ComboBoxHelper.OpenComboBox(comboBoxTop, ComboBoxHelper.OpenMethod.Mouse); + // await RunOnUIThread(() => + + // { + // var popup = TreeHelper.GetVisualChildByType(comboBoxTop); + // var popupChild = (FrameworkElement)(popup.Child); + // var scrollViewer = TreeHelper.GetVisualChildByType(popupChild); + // scrollViewerTopBounds = ControlHelper.GetBounds(scrollViewer); + // }); + // await ComboBoxHelper.CloseComboBox(comboBoxTop); + + // await ComboBoxHelper.OpenComboBox(comboBoxCenter, ComboBoxHelper.OpenMethod.Mouse); + // await RunOnUIThread(() => + + // { + // var popup = TreeHelper.GetVisualChildByType(comboBoxCenter); + // var popupChild = (FrameworkElement)(popup.Child); + // var scrollViewer = TreeHelper.GetVisualChildByType(popupChild); + // scrollViewerCenterBounds = ControlHelper.GetBounds(scrollViewer); + // }); + // await ComboBoxHelper.CloseComboBox(comboBoxCenter); + + // await ComboBoxHelper.OpenComboBox(comboBoxBottom, ComboBoxHelper.OpenMethod.Mouse); + // await RunOnUIThread(() => + + // { + // var popup = TreeHelper.GetVisualChildByType(comboBoxBottom); + // var popupChild = (FrameworkElement)(popup.Child); + // var scrollViewer = TreeHelper.GetVisualChildByType(popupChild); + // scrollViewerBottomBounds = ControlHelper.GetBounds(scrollViewer); + + // VERIFY_IS_TRUE(scrollViewerTopBounds.Height == scrollViewerCenterBounds.Height); + // VERIFY_IS_TRUE(scrollViewerCenterBounds.Height == scrollViewerBottomBounds.Height); + // VERIFY_IS_TRUE(scrollViewerBottomBounds.Height == scrollViewerTopBounds.Height); + // }); + // await ComboBoxHelper.CloseComboBox(comboBoxBottom); + //} + + //[TestMethod] + //public async Task ValidateFocusTrappedWithNoSelectionPressingGamepadUp() + //{ + // Size size = new(400, 400); + // TestServices.WindowHelper.SetWindowSizeOverride(size); + + // ComboBox comboBox = null; + // Button focusableButton = null; + + // await RunOnUIThread(() => + + // { + // var rootPanel = (Grid)(XamlReader.Load( + // "" + + + + + + // " " + + + + + + // " " + + + + + + // "