diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/BorderBackgroundSizeUpdatesWhenRotatingScreen.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/BorderBackgroundSizeUpdatesWhenRotatingScreen.png new file mode 100644 index 000000000000..07d5370f608b Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/BorderBackgroundSizeUpdatesWhenRotatingScreen.png differ diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/Issue22606_SetHeightTo200.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/Issue22606_SetHeightTo200.png new file mode 100644 index 000000000000..adeca3d3f732 Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/Issue22606_SetHeightTo200.png differ diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/Issue22606_SetHeightTo500.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/Issue22606_SetHeightTo500.png new file mode 100644 index 000000000000..11a377c7b69d Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/Issue22606_SetHeightTo500.png differ diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22606.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22606.cs new file mode 100644 index 000000000000..44345f00a117 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22606.cs @@ -0,0 +1,35 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues +{ + public class Issue22606 : _IssuesUITest + { + public Issue22606(TestDevice device) : base(device) { } + + public override string Issue => "Border does not expand on Content size changed"; + + [Test] + public void BorderBackgroundExpandsOnContentSizeChanged() + { + App.WaitForElement("SetHeightTo200"); + App.Tap("SetHeightTo200"); + VerifyScreenshot("Issue22606_SetHeightTo200"); + + App.Tap("SetHeightTo500"); + VerifyScreenshot("Issue22606_SetHeightTo500"); + } + +#if ANDROID || IOS + [Test] + public void BorderBackgroundSizeUpdatesWhenRotatingScreen() + { + App.WaitForElement("SetHeightTo200"); + App.Tap("SetHeightTo200"); + App.SetOrientationLandscape(); + VerifyScreenshot(); + } +#endif + } +} \ No newline at end of file diff --git a/src/Controls/tests/TestCases.Shared.Tests/UITest.cs b/src/Controls/tests/TestCases.Shared.Tests/UITest.cs index 6c0f45651786..672f84ef1c6b 100644 --- a/src/Controls/tests/TestCases.Shared.Tests/UITest.cs +++ b/src/Controls/tests/TestCases.Shared.Tests/UITest.cs @@ -16,11 +16,6 @@ namespace Microsoft.Maui.TestCases.Tests [TestFixture(TestDevice.Mac)] #elif WINTEST [TestFixture(TestDevice.Windows)] -#else - [TestFixture(TestDevice.iOS)] - [TestFixture(TestDevice.Mac)] - [TestFixture(TestDevice.Windows)] - [TestFixture(TestDevice.Android)] #endif public abstract class UITest : UITestBase { @@ -98,109 +93,133 @@ public override void Reset() public void VerifyScreenshot(string? name = null) { - string deviceName = GetTestConfig().GetProperty("DeviceName") ?? string.Empty; - // Remove the XHarness suffix if present - deviceName = deviceName.Replace(" - created by XHarness", "", StringComparison.Ordinal); - - /* - Determine the environmentName, used as the directory name for visual testing snaphots. Here are the rules/conventions: - - Names are lower case, no spaces. - - By default, the name matches the platform (android, ios, windows, or mac). - - Each platform has a default device (or set of devices) - if the snapshot matches the default no suffix is needed (e.g. just ios). - - If tests are run on secondary devices that produce different snapshots, the device name is used as suffix (e.g. ios-iphonex). - - If tests are run on secondary devices with multiple OS versions that produce different snapshots, both device name and os version are - used as a suffix (e.g. ios-iphonex-16_4). We don't have any cases of this today but may eventually. The device name comes first here, - before os version, because most visual testing differences come from different sceen size (a device thing), not OS version differences, - but both can happen. - */ - string environmentName = ""; - switch (_testDevice) + // Retry the verification once in case the app is in a transient state + try { - case TestDevice.Android: - if (deviceName == "Nexus 5X") - { - environmentName = "android"; - } - else - { - Assert.Fail($"Android visual tests should be run on an Nexus 5X (API 30) emulator image, but the current device is '{deviceName}'. Follow the steps on the MAUI UI testing wiki."); - } - break; - - case TestDevice.iOS: - if (deviceName == "iPhone Xs (iOS 17.2)") - { - environmentName = "ios"; - } - else if (deviceName == "iPhone X (iOS 16.4)") - { - environmentName = "ios-iphonex"; - } - else - { - Assert.Fail($"iOS visual tests should be run on iPhone Xs (iOS 17.2) or iPhone X (iOS 16.4) simulator images, but the current device is '{deviceName}'. Follow the steps on the MAUI UI testing wiki."); - } - break; - - case TestDevice.Windows: - environmentName = "windows"; - break; - - case TestDevice.Mac: - // For now, ignore visual tests on Mac Catalyst since the Appium screenshot on Mac (unlike Windows) - // is of the entire screen, not just the app. Later when xharness relay support is in place to - // send a message to the MAUI app to get the screenshot, we can use that to just screenshot - // the app. - Assert.Ignore("MacCatalyst isn't supported yet for visual tests"); - break; - - default: - throw new NotImplementedException($"Unknown device type {_testDevice}"); + Verify(name); } - - name ??= TestContext.CurrentContext.Test.MethodName ?? TestContext.CurrentContext.Test.Name; - - // Currently Android is the OS with the ripple animations, but Windows may also have some animations - // that need to finish before taking a screenshot. - if (_testDevice == TestDevice.Android) + catch { - Thread.Sleep(350); + Thread.Sleep(500); + Verify(name); } - byte[] screenshotPngBytes = App.Screenshot() ?? throw new InvalidOperationException("Failed to get screenshot"); - - var actualImage = new ImageSnapshot(screenshotPngBytes, ImageSnapshotFormat.PNG); - - // For Android and iOS, crop off the OS status bar at the top since it's not part of the - // app itself and contains the time, which always changes. For WinUI, crop off the title - // bar at the top as it varies slightly based on OS theme and is also not part of the app. - int cropFromTop = _testDevice switch - { - TestDevice.Android => 60, - TestDevice.iOS => environmentName == "ios-iphonex" ? 90 : 110, - TestDevice.Windows => 32, - _ => 0, - }; - - // For Android also crop the 3 button nav from the bottom, since it's not part of the - // app itself and the button color can vary (the buttons change clear briefly when tapped) - int cropFromBottom = _testDevice switch + void Verify(string? name) { - TestDevice.Android => 125, - _ => 0, - }; + string deviceName = GetTestConfig().GetProperty("DeviceName") ?? string.Empty; + // Remove the XHarness suffix if present + deviceName = deviceName.Replace(" - created by XHarness", "", StringComparison.Ordinal); + + /* + Determine the environmentName, used as the directory name for visual testing snaphots. Here are the rules/conventions: + - Names are lower case, no spaces. + - By default, the name matches the platform (android, ios, windows, or mac). + - Each platform has a default device (or set of devices) - if the snapshot matches the default no suffix is needed (e.g. just ios). + - If tests are run on secondary devices that produce different snapshots, the device name is used as suffix (e.g. ios-iphonex). + - If tests are run on secondary devices with multiple OS versions that produce different snapshots, both device name and os version are + used as a suffix (e.g. ios-iphonex-16_4). We don't have any cases of this today but may eventually. The device name comes first here, + before os version, because most visual testing differences come from different sceen size (a device thing), not OS version differences, + but both can happen. + */ + string environmentName = ""; + switch (_testDevice) + { + case TestDevice.Android: + if (deviceName == "Nexus 5X") + { + environmentName = "android"; + } + else + { + Assert.Fail($"Android visual tests should be run on an Nexus 5X (API 30) emulator image, but the current device is '{deviceName}'. Follow the steps on the MAUI UI testing wiki."); + } + break; + + case TestDevice.iOS: + if (deviceName == "iPhone Xs (iOS 17.2)") + { + environmentName = "ios"; + } + else if (deviceName == "iPhone X (iOS 16.4)") + { + environmentName = "ios-iphonex"; + } + else + { + Assert.Fail($"iOS visual tests should be run on iPhone Xs (iOS 17.2) or iPhone X (iOS 16.4) simulator images, but the current device is '{deviceName}'. Follow the steps on the MAUI UI testing wiki."); + } + break; + + case TestDevice.Windows: + environmentName = "windows"; + break; + + case TestDevice.Mac: + // For now, ignore visual tests on Mac Catalyst since the Appium screenshot on Mac (unlike Windows) + // is of the entire screen, not just the app. Later when xharness relay support is in place to + // send a message to the MAUI app to get the screenshot, we can use that to just screenshot + // the app. + Assert.Ignore("MacCatalyst isn't supported yet for visual tests"); + break; + + default: + throw new NotImplementedException($"Unknown device type {_testDevice}"); + } + + name ??= TestContext.CurrentContext.Test.MethodName ?? TestContext.CurrentContext.Test.Name; + + // Currently Android is the OS with the ripple animations, but Windows may also have some animations + // that need to finish before taking a screenshot. + if (_testDevice == TestDevice.Android) + { + Thread.Sleep(350); + } + + byte[] screenshotPngBytes = App.Screenshot() ?? throw new InvalidOperationException("Failed to get screenshot"); + + var actualImage = new ImageSnapshot(screenshotPngBytes, ImageSnapshotFormat.PNG); + + // For Android and iOS, crop off the OS status bar at the top since it's not part of the + // app itself and contains the time, which always changes. For WinUI, crop off the title + // bar at the top as it varies slightly based on OS theme and is also not part of the app. + int cropFromTop = _testDevice switch + { + TestDevice.Android => 60, + TestDevice.iOS => environmentName == "ios-iphonex" ? 90 : 110, + TestDevice.Windows => 32, + _ => 0, + }; + + // For Android also crop the 3 button nav from the bottom, since it's not part of the + // app itself and the button color can vary (the buttons change clear briefly when tapped) + int cropFromBottom = _testDevice switch + { + TestDevice.Android => 125, + _ => 0, + }; + + if (cropFromTop > 0 || cropFromBottom > 0) + { + IImageEditor imageEditor = _imageEditorFactory.CreateImageEditor(actualImage); + (int width, int height) = imageEditor.GetSize(); + + imageEditor.Crop(0, cropFromTop, width, height - cropFromTop - cropFromBottom); + + actualImage = imageEditor.GetUpdatedImage(); + } + + _visualRegressionTester.VerifyMatchesSnapshot(name!, actualImage, environmentName: environmentName, testContext: _visualTestContext); + } + } - if (cropFromTop > 0 || cropFromBottom > 0) + [SetUp] + public void TestSetup() + { + var device = App.GetTestDevice(); + if(device == TestDevice.Android || device == TestDevice.iOS) { - IImageEditor imageEditor = _imageEditorFactory.CreateImageEditor(actualImage); - (int width, int height) = imageEditor.GetSize(); - - imageEditor.Crop(0, cropFromTop, width, height - cropFromTop - cropFromBottom); - - actualImage = imageEditor.GetUpdatedImage(); + App.SetOrientationPortrait(); } - - _visualRegressionTester.VerifyMatchesSnapshot(name!, actualImage, environmentName: environmentName, testContext: _visualTestContext); } } } diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue22606_SetHeightTo200.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue22606_SetHeightTo200.png new file mode 100644 index 000000000000..051e37200c33 Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue22606_SetHeightTo200.png differ diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue22606_SetHeightTo500.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue22606_SetHeightTo500.png new file mode 100644 index 000000000000..f04d9d7d7fee Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue22606_SetHeightTo500.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BorderBackgroundSizeUpdatesWhenRotatingScreen.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BorderBackgroundSizeUpdatesWhenRotatingScreen.png new file mode 100644 index 000000000000..ade193be1acb Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/BorderBackgroundSizeUpdatesWhenRotatingScreen.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue22606_SetHeightTo200.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue22606_SetHeightTo200.png new file mode 100644 index 000000000000..93feb64e4ddf Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue22606_SetHeightTo200.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue22606_SetHeightTo500.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue22606_SetHeightTo500.png new file mode 100644 index 000000000000..39861e96b65b Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/Issue22606_SetHeightTo500.png differ diff --git a/src/Controls/tests/TestCases/Issues/Issue22606.xaml b/src/Controls/tests/TestCases/Issues/Issue22606.xaml new file mode 100644 index 000000000000..7f8085ea3801 --- /dev/null +++ b/src/Controls/tests/TestCases/Issues/Issue22606.xaml @@ -0,0 +1,23 @@ + + + + + + +