diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/FlipViewTests/FlipView_Tests.FlipView.cs b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/FlipViewTests/FlipView_Tests.FlipView.cs index c6285687dc2b..5d9b3ba4f32f 100644 --- a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/FlipViewTests/FlipView_Tests.FlipView.cs +++ b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/FlipViewTests/FlipView_Tests.FlipView.cs @@ -14,53 +14,66 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Controls.FlipViewTests [TestFixture] public partial class FlipView_Tests : SampleControlUITestBase { + // Green, Blue, Red, Fuchsia, Orange + const string ButtonColors = "#008000,#0000FF,#FF0000,#FF00FF,#FFA500"; + [Test] [AutoRetry] [ActivePlatforms(Platform.Browser)] public void FlipView_WithButtons_FlipForward() { - Run("UITests.Windows_UI_Xaml_Controls.FlipView.FlipView_Buttons"); - - _app.WaitForElement("NextButtonHorizontal"); - - _app.WaitForElement("Button1"); - - _app.WaitForElement("NextButtonHorizontal"); - - // FlipView buttons are Collapsed by default. - var nextButton = _app.Marked("NextButtonHorizontal"); - nextButton.SetDependencyPropertyValue("Visibility", "Visible"); - - _app.FastTap("NextButtonHorizontal"); - - _app.WaitForElement("Button2"); + FlipView_WithButtons_BtnNavTest(1, true); } [Test] - [AutoRetry] + [AutoRetry(tryCount: 1)] [ActivePlatforms(Platform.Browser)] public void FlipView_WithButtons_FlipBackward() { - Run("UITests.Windows_UI_Xaml_Controls.FlipView.FlipView_Buttons"); + FlipView_WithButtons_BtnNavTest(0, true, false); + } - _app.WaitForElement("NextButtonHorizontal"); + private void FlipView_WithButtons_BtnNavTest(int expectedIndex, params bool[] forwardNavigations) + { + Run("UITests.Windows_UI_Xaml_Controls.FlipView.FlipView_Buttons"); - // FlipView buttons are Collapsed by default. + var flipview = _app.Marked("SUT"); var nextButton = _app.Marked("NextButtonHorizontal"); - nextButton.SetDependencyPropertyValue("Visibility", "Visible"); - - _app.FastTap("NextButtonHorizontal"); - - _app.WaitForElement("Button2"); - - _app.WaitForElement("PreviousButtonHorizontal"); - - var backButton = _app.Marked("PreviousButtonHorizontal"); - backButton.SetDependencyPropertyValue("Visibility", "Visible"); - - _app.FastTap("PreviousButtonHorizontal"); - - _app.WaitForElement("Button1"); + var previousButton = _app.Marked("PreviousButtonHorizontal"); + + // using tap to ensure navigation buttons are visible, since we cant mouse-over + _app.WaitForElement(flipview); + _app.FastTap(flipview); + + // perform navigations + foreach (var navigation in forwardNavigations.Select((x, i) => new { Step = i, Forward = x })) + { + string GetCurrentNavigationContext() => + $"step#{navigation.Step} of" + new string(forwardNavigations + .Select(x => x ? 'N' : 'P').ToArray()) + .Insert(navigation.Step, "*"); + + // tap previous or next + var targetButton = navigation.Forward ? nextButton : previousButton; + _app.WaitForElement(targetButton, $"Timeout waiting for the {(navigation.Forward ? "next" : "previous")} button in {GetCurrentNavigationContext()}"); + _app.FastTap(targetButton); + } + + var flipviewRect = _app.GetPhysicalRect(flipview); + var navigationContext = new string(forwardNavigations.Select(x => x ? 'N' : 'P').ToArray()); + var previousButtonRect = _app.GetPhysicalRect(previousButton); + + // check for selection index && content + Assert.AreEqual(expectedIndex, flipview.GetDependencyPropertyValue("SelectedIndex")); + using (var screenshot = TakeScreenshot($"Post_{navigationContext}_Navigation", ignoreInSnapshotCompare: true)) + { + ImageAssert.HasColorAt( + screenshot, + flipviewRect.X + previousButtonRect.Width + 2, + flipviewRect.CenterY, + ButtonColors.Split(',').ElementAtOrDefault(expectedIndex) ?? throw new IndexOutOfRangeException($"{nameof(expectedIndex)} is out of range") + ); + } } [Test] diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_FlipView.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_FlipView.cs index 0530429ea19a..dae4c4568b9d 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_FlipView.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_FlipView.cs @@ -15,8 +15,8 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls public class Given_FlipView { [TestMethod] -#if !__IOS__ && !__ANDROID__ - [Ignore] // Test fails on Skia and WASM: https://github.com/unoplatform/uno/issues/7671 +#if !__IOS__ && !__ANDROID__ && !__WASM__ + [Ignore] // Test fails on Skia: https://github.com/unoplatform/uno/issues/7671 #endif public async Task When_Observable_ItemsSource_And_Added() { diff --git a/src/Uno.UI/UI/Xaml/Controls/FlipView/FlipView.managed.cs b/src/Uno.UI/UI/Xaml/Controls/FlipView/FlipView.managed.cs index d08a95fb8345..3e59935f7bee 100644 --- a/src/Uno.UI/UI/Xaml/Controls/FlipView/FlipView.managed.cs +++ b/src/Uno.UI/UI/Xaml/Controls/FlipView/FlipView.managed.cs @@ -474,6 +474,11 @@ void InitializeScrollViewer() m_tpScrollViewer.VerticalScrollMode = ScrollMode.Disabled; m_tpScrollViewer.HorizontalScrollMode = ScrollMode.Enabled; } +#if HAS_UNO && __WASM__ + // UNO workaround: the scrollability depends on both the ScrollMode and the ScrollBarVisibility, and by default the latter is Disabled. + m_tpScrollViewer.HorizontalScrollBarVisibility = m_tpScrollViewer.HorizontalScrollMode == ScrollMode.Enabled ? ScrollBarVisibility.Hidden : ScrollBarVisibility.Disabled; + m_tpScrollViewer.VerticalScrollBarVisibility = m_tpScrollViewer.VerticalScrollMode == ScrollMode.Enabled ? ScrollBarVisibility.Hidden : ScrollBarVisibility.Disabled; +#endif m_tpScrollViewer.SizeChanged += OnScrollingHostPartSizeChanged; @@ -1517,6 +1522,9 @@ internal override void OnSelectedIndexChanged(int oldSelectedIndex, int newSelec m_tpFixOffsetTimer?.Stop(); + // UNO: force previous/next buttons' visibility to update immediately + UpdateVisualState(); + //m_tpScrollViewer?.InvalidateScrollInfo(); // When the application is not being rendered, there is no need to animate // the view change. Instead, a view jump is performed to minimize the CPU cost. diff --git a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs index f771fe915152..65f76abf9e7c 100644 --- a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs +++ b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs @@ -158,16 +158,6 @@ protected override Size MeasureOverride(Size size) { var slotSize = size; -#if __WASM__ - if (CanVerticallyScroll || _forceChangeToCurrentView) - { - slotSize.Height = double.PositiveInfinity; - } - if (CanHorizontallyScroll || _forceChangeToCurrentView) - { - slotSize.Width = double.PositiveInfinity; - } -#else if (CanVerticallyScroll) { slotSize.Height = double.PositiveInfinity; @@ -176,7 +166,6 @@ protected override Size MeasureOverride(Size size) { slotSize.Width = double.PositiveInfinity; } -#endif child.Measure(slotSize); diff --git a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.wasm.cs b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.wasm.cs index 138d6b1458e7..51a438883338 100644 --- a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.wasm.cs +++ b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.wasm.cs @@ -127,16 +127,18 @@ internal ScrollBarVisibility HorizontalScrollBarVisibility } } + private bool _canHorizontallyScroll; public bool CanHorizontallyScroll { - get => HorizontalScrollBarVisibility != ScrollBarVisibility.Disabled || _forceChangeToCurrentView; - set { } + get => _canHorizontallyScroll || _forceChangeToCurrentView; + set => _canHorizontallyScroll = value; } + private bool _canVerticallyScroll; public bool CanVerticallyScroll { - get => VerticalScrollBarVisibility != ScrollBarVisibility.Disabled || _forceChangeToCurrentView; - set { } + get => _canVerticallyScroll || _forceChangeToCurrentView; + set => _canVerticallyScroll = value; } public double HorizontalOffset { get; private set; }