diff --git a/.azure-devops-ios-tests.yml b/.azure-devops-ios-tests.yml
index 43278eadca..e2c8af2924 100644
--- a/.azure-devops-ios-tests.yml
+++ b/.azure-devops-ios-tests.yml
@@ -2,14 +2,20 @@ jobs:
- job: iOS_Tests
+ timeoutInMinutes: 120
+
strategy:
matrix:
Automated:
UITEST_SNAPSHOTS_ONLY: false
- # Tests are failing, to be enabled in later PR
- #Snapshots:
- # UITEST_SNAPSHOTS_ONLY: true
+ Snapshots_Group00:
+ UITEST_SNAPSHOTS_ONLY: true
+ UITEST_SNAPSHOTS_GROUP: 00
+
+ Snapshots_Group01:
+ UITEST_SNAPSHOTS_ONLY: true
+ UITEST_SNAPSHOTS_GROUP: 01
variables:
CI_Build: true
@@ -47,12 +53,13 @@ jobs:
BUILD_SOURCESDIRECTORY: "$(build.sourcesdirectory)"
BUILD_ARTIFACTSTAGINGDIRECTORY: "$(build.artifactstagingdirectory)"
UITEST_SNAPSHOTS_ONLY: "$(UITEST_SNAPSHOTS_ONLY)"
+ UITEST_SNAPSHOTS_GROUP: "$(UITEST_SNAPSHOTS_GROUP)"
- task: PublishTestResults@2
condition: always()
inputs:
- testRunTitle: 'iOS Test Run'
+ testRunTitle: 'iOS Test Run ($(Agent.JobName ))'
testResultsFormat: 'NUnit'
testResultsFiles: '$(build.sourcesdirectory)/build/TestResult.xml'
failTaskOnFailedTests: true
diff --git a/build/ios-uitest-run.sh b/build/ios-uitest-run.sh
index 16b3abcca5..15965a7d97 100755
--- a/build/ios-uitest-run.sh
+++ b/build/ios-uitest-run.sh
@@ -19,7 +19,14 @@ mono nuget/nuget.exe install NUnit.ConsoleRunner -Version 3.10.0
if [ "$UITEST_SNAPSHOTS_ONLY" == 'true' ];
then
export SCREENSHOTS_FOLDERNAME=ios-Snap
- export TEST_FILTERS="namespace == 'SamplesApp.UITests.Snap'"
+
+ # CommandBar disabled: https://github.com/unoplatform/uno/issues/1955
+ # runGroup is used to parallelize the snapshots tests on multiple agents
+ export TEST_FILTERS=" \
+ namespace == 'SamplesApp.UITests.Snap' \
+ and Description !~ 'automated:Uno.UI.Samples.Content.UITests.CommandBar.*' \
+ and Description =~ 'runGroup:$UITEST_SNAPSHOTS_GROUP' \
+ "
else
export SCREENSHOTS_FOLDERNAME=ios
export TEST_FILTERS=" \
diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets
index fe65435a82..c18d0424f0 100644
--- a/src/Directory.Build.targets
+++ b/src/Directory.Build.targets
@@ -17,8 +17,8 @@
-
-
+
+
diff --git a/src/SamplesApp/SamplesApp.UITests.Generator/SnapShotTestGenerator.cs b/src/SamplesApp/SamplesApp.UITests.Generator/SnapShotTestGenerator.cs
index 594fe888e6..ce4828dd5a 100644
--- a/src/SamplesApp/SamplesApp.UITests.Generator/SnapShotTestGenerator.cs
+++ b/src/SamplesApp/SamplesApp.UITests.Generator/SnapShotTestGenerator.cs
@@ -89,25 +89,29 @@ namespace Uno.Samples.UITest.Generator
using (builder.BlockInvariant($"namespace {context.GetProjectInstance().GetPropertyValue("RootNamespace")}.Snap"))
{
- builder.AppendLineInvariant("[NUnit.Framework.TestFixture]");
+ builder.AppendLineInvariant("[global::NUnit.Framework.TestFixture]");
+
+ // Required for https://github.com/unoplatform/uno/issues/1955
+ builder.AppendLineInvariant("[global::SamplesApp.UITests.TestFramework.TestAppModeAttribute(cleanEnvironment: true, platform: Uno.UITest.Helpers.Queries.Platform.iOS)]");
using (builder.BlockInvariant($"public partial class {groupName} : SampleControlUITestBase"))
{
- foreach (var test in group.Symbols) // .Where(s => s.symbol.ToString()).Contains("Border_Simple")))
+ foreach (var test in group.Symbols)
{
var info = GetSampleInfo(test.symbol, test.symbol.FindAttributeFlattened(_sampleControlInfoSymbol));
- builder.AppendLineInvariant("[NUnit.Framework.Test]");
+ builder.AppendLineInvariant("[global::NUnit.Framework.Test]");
+ builder.AppendLineInvariant($"[global::NUnit.Framework.Description(\"runGroup:{group.Index % 2:00}, automated:{test.symbol.ToDisplayString()}\")]");
if (info.ignoreInSnapshotTests)
{
- builder.AppendLineInvariant("[NUnit.Framework.Ignore(\"ignoreInSnapshotTests is set for attribute\")]");
+ builder.AppendLineInvariant("[global::NUnit.Framework.Ignore(\"ignoreInSnapshotTests is set for attribute\")]");
}
- builder.AppendLineInvariant("[SamplesApp.UITests.TestFramework.AutoRetry]");
+ builder.AppendLineInvariant("[global::SamplesApp.UITests.TestFramework.AutoRetry]");
using (builder.BlockInvariant($"public void {Sanitize(test.category)}_{Sanitize(info.name)}()"))
{
- builder.AppendLineInvariant($"Run(\"{test.symbol}\");");
+ builder.AppendLineInvariant($"Run(\"{test.symbol}\", waitForSampleControl: false);");
}
}
}
diff --git a/src/SamplesApp/SamplesApp.UITests/SampleControlUITestBase.cs b/src/SamplesApp/SamplesApp.UITests/SampleControlUITestBase.cs
index 91713df807..e84742b036 100644
--- a/src/SamplesApp/SamplesApp.UITests/SampleControlUITestBase.cs
+++ b/src/SamplesApp/SamplesApp.UITests/SampleControlUITestBase.cs
@@ -15,11 +15,18 @@ namespace SamplesApp.UITests
public class SampleControlUITestBase
{
protected IApp _app;
+ private static int _totalTestFixtureCount;
public SampleControlUITestBase()
{
}
+ [OneTimeSetUp]
+ public void SingleSetup()
+ {
+ ValidateAppMode();
+ }
+
static SampleControlUITestBase()
{
AppInitializer.TestEnvironment.AndroidAppName = Constants.AndroidAppName;
@@ -38,6 +45,25 @@ namespace SamplesApp.UITests
AppInitializer.ColdStartApp();
}
+ public void ValidateAppMode()
+ {
+ if(GetCurrentFixtureAttributes().FirstOrDefault() is TestAppModeAttribute testAppMode)
+ {
+ if(
+ _totalTestFixtureCount != 0
+ && testAppMode.CleanEnvironment
+ && testAppMode.Platform == AppInitializer.GetLocalPlatform()
+ )
+ {
+ // If this is not the first run, and the fixture requested a clean environment, request a cold start.
+ // If this is the first run, as the app is cold-started during the type constructor, we can skip this.
+ _app = AppInitializer.ColdStartApp();
+ }
+ }
+
+ _totalTestFixtureCount++;
+ }
+
[SetUp]
[AutoRetry]
public void BeforeEachTest()
@@ -194,14 +220,25 @@ namespace SamplesApp.UITests
private static void ValidateAutoRetry()
{
- var testType = Type.GetType(TestContext.CurrentContext.Test.ClassName);
- var methodInfo = testType?.GetMethod(TestContext.CurrentContext.Test.MethodName);
- if (methodInfo?.GetCustomAttributes(typeof(AutoRetryAttribute), true).Length == 0 && false)
+ if (GetCurrentTestAttributes().Length == 0)
{
Assert.Fail($"The AutoRetryAttribute is not defined for this test");
}
}
+ private static T[] GetCurrentFixtureAttributes() where T : Attribute
+ {
+ var testType = Type.GetType(TestContext.CurrentContext.Test.ClassName);
+ return testType?.GetCustomAttributes(typeof(T), true) is T[] array ? array : new T[0];
+ }
+
+ private static T[] GetCurrentTestAttributes() where T : Attribute
+ {
+ var testType = Type.GetType(TestContext.CurrentContext.Test.ClassName);
+ var methodInfo = testType?.GetMethod(TestContext.CurrentContext.Test.MethodName);
+ return methodInfo?.GetCustomAttributes(typeof(T), true) is T[] array ? array : new T[0];
+ }
+
private Platform[] GetActivePlatforms()
{
if (TestContext.CurrentContext.Test.Properties["ActivePlatforms"].FirstOrDefault() is Platform[] platforms)
@@ -246,7 +283,7 @@ namespace SamplesApp.UITests
{
var result = _app.InvokeGeneric("browser:SampleRunner|IsTestDone", testRunId).ToString();
return bool.TryParse(result, out var testDone) && testDone;
- }, retryFrequency: TimeSpan.FromMilliseconds(250));
+ }, retryFrequency: TimeSpan.FromMilliseconds(50));
TakeScreenshot(metadataName.Replace(".", "_"));
}
diff --git a/src/SamplesApp/SamplesApp.UITests/TestFramework/TestAppMode.cs b/src/SamplesApp/SamplesApp.UITests/TestFramework/TestAppMode.cs
new file mode 100644
index 0000000000..037c872243
--- /dev/null
+++ b/src/SamplesApp/SamplesApp.UITests/TestFramework/TestAppMode.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Uno.UITest.Helpers.Queries;
+
+namespace SamplesApp.UITests.TestFramework
+{
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple=true, Inherited = true)]
+ public class TestAppModeAttribute : Attribute
+ {
+ ///
+ /// Builds TestMode attribute
+ ///
+ ///
+ /// Determines if the app should be restarted to get a clean environment before the fixture tests are started.
+ ///
+ /// Determines the target platform to be used for this attribute
+ public TestAppModeAttribute(bool cleanEnvironment, Platform platform)
+ {
+ CleanEnvironment = cleanEnvironment;
+ Platform = platform;
+ }
+
+ ///
+ /// Determines if the app should be restarted to get a clean environment before the fixture tests are started.
+ ///
+ public bool CleanEnvironment { get; }
+
+ ///
+ /// Determines the target platform to be used for this attribute
+ ///
+ public Platform Platform { get; }
+ }
+}
diff --git a/src/SamplesApp/SamplesApp.UITests/Toolkit/UnoSamples_Tests.Elevation.cs b/src/SamplesApp/SamplesApp.UITests/Toolkit/UnoSamples_Tests.Elevation.cs
index 344404e85a..53803b16d1 100644
--- a/src/SamplesApp/SamplesApp.UITests/Toolkit/UnoSamples_Tests.Elevation.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Toolkit/UnoSamples_Tests.Elevation.cs
@@ -17,6 +17,7 @@ namespace SamplesApp.UITests.Toolkit
{
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS)] // Android is disabled https://github.com/unoplatform/uno/issues/1635
public void Elevation_Validation()
{
diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_Devices/GyrometerTests.cs b/src/SamplesApp/SamplesApp.UITests/Windows_Devices/GyrometerTests.cs
index 17c14588bf..109371dccf 100644
--- a/src/SamplesApp/SamplesApp.UITests/Windows_Devices/GyrometerTests.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Windows_Devices/GyrometerTests.cs
@@ -14,6 +14,7 @@ namespace SamplesApp.UITests.Windows_Devices
public class GyrometerTests : SampleControlUITestBase
{
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void When_Gyrometer_Is_Retrived_With_GetDefault()
{
@@ -23,6 +24,7 @@ namespace SamplesApp.UITests.Windows_Devices
}
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void When_Reading_Is_Attached()
{
@@ -51,6 +53,7 @@ namespace SamplesApp.UITests.Windows_Devices
}
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void When_Reading_Is_Attached_And_Waits()
{
@@ -78,6 +81,7 @@ namespace SamplesApp.UITests.Windows_Devices
}
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void When_Reading_Is_Attached_And_Detaches()
{
diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Automation/AutomationId_Tests.cs b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Automation/AutomationId_Tests.cs
index 7309d16880..00920af971 100644
--- a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Automation/AutomationId_Tests.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Automation/AutomationId_Tests.cs
@@ -15,6 +15,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Automation
public class AutomationId_Tests : SampleControlUITestBase
{
[Test]
+ [AutoRetry]
public void TestSimple()
{
Run("UITests.Shared.Windows_UI.Xaml_Automation.AutomationProperties_AutomationId");
diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/FlyoutTests/UnoSamples_Tests.Flyout.cs b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/FlyoutTests/UnoSamples_Tests.Flyout.cs
index 5a33f883b3..b51af22d18 100644
--- a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/FlyoutTests/UnoSamples_Tests.Flyout.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/FlyoutTests/UnoSamples_Tests.Flyout.cs
@@ -16,6 +16,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Controls.FlyoutTests
public partial class Flyout_Tests : SampleControlUITestBase
{
[Test]
+ [AutoRetry]
[Ignore("Not available yet")]
public void FlyoutTest_BottomPlacement_WithSmallerAnchor_DoesntDefaultToFull()
{
@@ -36,6 +37,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Controls.FlyoutTests
}
[Test]
+ [AutoRetry]
public void FlyoutTest_Target()
{
Run("Uno.UI.Samples.Content.UITests.Flyout.Flyout_Target");
@@ -94,6 +96,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Controls.FlyoutTests
}
[Test]
+ [AutoRetry]
public void FlyoutTest_Unloaded()
{
Run("UITests.Shared.Windows_UI_Xaml_Controls.Flyout.Flyout_Unloaded");
diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/ListViewTests/UnoSamples_Tests.ListView.cs b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/ListViewTests/UnoSamples_Tests.ListView.cs
index 92ecd8cc19..4e76aada30 100644
--- a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/ListViewTests/UnoSamples_Tests.ListView.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/ListViewTests/UnoSamples_Tests.ListView.cs
@@ -53,6 +53,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Controls.ListViewTests
}
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.Android)]
public void ListView_ItemPanel_HotSwapTest()
{
diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/ToggleSwitchTests/UnoSamples_Tests.ToggleSwitch.cs b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/ToggleSwitchTests/UnoSamples_Tests.ToggleSwitch.cs
index 6a2ed32695..6774d849ad 100644
--- a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/ToggleSwitchTests/UnoSamples_Tests.ToggleSwitch.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Controls/ToggleSwitchTests/UnoSamples_Tests.ToggleSwitch.cs
@@ -3,6 +3,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
+using SamplesApp.UITests.TestFramework;
using Uno.UITest.Helpers;
using Uno.UITest.Helpers.Queries;
@@ -12,6 +13,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Controls.ToggleSwitchTests
public partial class ToggleSwitch_Tests : SampleControlUITestBase
{
[Test]
+ [AutoRetry]
public void ToggleSwitch_TemplateReuseTest()
{
Run("UITests.Shared.Windows_UI_Xaml_Controls.ToggleSwitchControl.ToggleSwitch_TemplateReuse");
diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/Capture_Tests.cs b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/Capture_Tests.cs
index 2b5739a6b3..f874bdbea1 100644
--- a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/Capture_Tests.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/Capture_Tests.cs
@@ -13,24 +13,29 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
public class Capture_Tests : SampleControlUITestBase
{
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS | Platform.Android)] // This fails with unit test
public void TestSimple()
=> RunTest("Simple", TouchAndMoveOut);
[Test]
+ [AutoRetry]
public void TestVisibility()
=> RunTest("Visibility");
[Test]
+ [AutoRetry]
public void TestNestedVisibility()
=> RunTest("NestedVisibility");
[Test]
+ [AutoRetry]
[Ignore("Inconsistent behavior between manual and unit test")]
public void TestIsEnabled()
=> RunTest("IsEnabled");
[Test]
+ [AutoRetry]
[Ignore("Inconsistent behavior between manual and unit test")]
[ActivePlatforms(Platform.Browser)] // The IsEnabled property is not inherited on other platforms yet.
public void TestNestedIsEnabled()
diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/DragCoordinates_Tests.cs b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/DragCoordinates_Tests.cs
index 9de82aae44..45fd13e68c 100644
--- a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/DragCoordinates_Tests.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/DragCoordinates_Tests.cs
@@ -14,6 +14,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Controls.TimePickerTests
public class DragCoordinates_Tests : SampleControlUITestBase
{
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Browser)] // Android is disabled https://github.com/unoplatform/uno/issues/1257
public void DragBorder01()
{
diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/EventSequence_Tests.cs b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/EventSequence_Tests.cs
index d23cd61e14..8a689a58ab 100644
--- a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/EventSequence_Tests.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/EventSequence_Tests.cs
@@ -13,26 +13,32 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
public class EventSequence_Tests : SampleControlUITestBase
{
[Test]
+ [AutoRetry]
public void TestTap()
=> RunSequence("Tap");
[Test]
+ [AutoRetry]
public void TestClick()
=> RunSequence("Click");
[Test]
+ [AutoRetry]
public void TestTranslatedTap()
=> RunSequence("TranslatedTap", TranslateOverElement);
[Test]
+ [AutoRetry]
public void TestTranslatedClick()
=> RunSequence("TranslatedClick", TranslateOverElement);
[Test]
+ [AutoRetry]
public void TestHyperlink()
=> RunSequence("Hyperlink", TapSomewhereInElement);
[Test]
+ [AutoRetry]
public void TestListView()
=> RunSequence("ListView", TapSomewhereInElement);
diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/Manipulation_Tests.cs b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/Manipulation_Tests.cs
index 164dd6f337..4a5902ed4e 100644
--- a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/Manipulation_Tests.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/Manipulation_Tests.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
+using SamplesApp.UITests.TestFramework;
using Uno.UITest.Helpers;
using Uno.UITest.Helpers.Queries;
@@ -12,6 +13,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
public class Manipulation_Tests : SampleControlUITestBase
{
[Test]
+ [AutoRetry]
public void TestManipulation()
{
Run("UITests.Shared.Windows_UI_Input.GestureRecognizerTests.ManipulationEvents");
diff --git a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/VisualState_Tests.cs b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/VisualState_Tests.cs
index d784fdc175..ec074628af 100644
--- a/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/VisualState_Tests.cs
+++ b/src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/VisualState_Tests.cs
@@ -16,6 +16,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
public class VisualState_Tests : SampleControlUITestBase
{
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void TestButtonReleasedOut() => TestButtonReleasedOutState(
"MyButton",
@@ -24,6 +25,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
"CommonStates.Normal");
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void TestIndeterminateToggleButtonReleasedOut() => TestButtonReleasedOutState(
"MyIndeterminateToggleButton",
@@ -32,6 +34,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
"CommonStates.Indeterminate");
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void TestCheckedToggleButtonReleasedOut() => TestButtonReleasedOutState(
"MyCheckedToggleButton",
@@ -40,6 +43,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
"CommonStates.Checked");
[Test]
+ [AutoRetry]
[Ignore("We get an invalid 'PointerOver' on release, a fix in pending in another PR")]
public void TestUncheckedToggleButtonReleasedOut() => TestButtonReleasedOutState(
"MyUncheckedToggleButton",
@@ -48,6 +52,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
"CommonStates.Unchecked");
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void TestRadioButtonReleasedOut() => TestButtonReleasedOutState(
"MyRadioButton",
@@ -56,6 +61,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
"CommonStates.Normal");
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void TestHyperlinkButtonReleasedOut() => TestButtonReleasedOutState(
"MyHyperlinkButton",
@@ -64,6 +70,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
"CommonStates.Normal");
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void TestIndeterminateCheckboxReleasedOut() => TestButtonReleasedOutState(
"MyIndeterminateCheckbox",
@@ -72,6 +79,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
"CombinedStates.IndeterminateNormal");
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void TestCheckedCheckboxReleasedOut() => TestButtonReleasedOutState(
"MyCheckedCheckbox",
@@ -80,6 +88,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
"CombinedStates.CheckedNormal");
[Test]
+ [AutoRetry]
[ActivePlatforms(Platform.iOS, Platform.Android)]
public void TestUncheckedCheckboxReleasedOut() => TestButtonReleasedOutState(
"MyUncheckedCheckbox",
@@ -88,10 +97,12 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
"CombinedStates.UncheckedNormal");
[Test]
+ [AutoRetry]
public void TestHyperlinkReleasedOut() => TestButtonReleasedOutState(
"MyHyperlink"); // There is no "VisualState" for Hyperlink, only a hardcoded opacity of .5 (kind-of like UWP)
[Test]
+ [AutoRetry]
public void TestListViewReleasedOut()
{
Run("UITests.Shared.Windows_UI_Input.VisualStatesTests.ListViewItem");
@@ -107,12 +118,14 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Input
}
[Test]
+ [AutoRetry]
public void TestTextBoxReleaseOut() => TestTextBoxReleasedOutState(
"MyTextBox",
"CommonStates.PointerOver",
"CommonStates.Focused");
[Test]
+ [AutoRetry]
public void TestTextBoxTap() => TestTextBoxTappedState(
"MyTextBox",
"CommonStates.PointerOver",
diff --git a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml/UIElementTests/TransformToVisual_ScrollViewer.xaml.cs b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml/UIElementTests/TransformToVisual_ScrollViewer.xaml.cs
index be7c84a603..36e1b3ad21 100644
--- a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml/UIElementTests/TransformToVisual_ScrollViewer.xaml.cs
+++ b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml/UIElementTests/TransformToVisual_ScrollViewer.xaml.cs
@@ -9,7 +9,7 @@ using Uno.UI.Samples.Controls;
namespace UITests.Shared.Windows_UI_Xaml.UIElementTests
{
- [SampleControlInfo("UIElement")]
+ [SampleControlInfo("UIElement", ignoreInSnapshotTests: true)]
public sealed partial class TransformToVisual_ScrollViewer : Page
{
private readonly TestRunner _tests;
diff --git a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/ListView/ListView_CacheLength_Slow_Load.xaml.cs b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/ListView/ListView_CacheLength_Slow_Load.xaml.cs
index 5efe516e3c..4dc214daa2 100644
--- a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/ListView/ListView_CacheLength_Slow_Load.xaml.cs
+++ b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/ListView/ListView_CacheLength_Slow_Load.xaml.cs
@@ -4,7 +4,7 @@ using Windows.UI.Xaml.Controls;
namespace SamplesApp.Windows_UI_Xaml_Controls.ListView
{
- [SampleControlInfo("ListView", "ListView_CacheLength_Slow_Load", description: "ListView with slow-loading images, illustrating caching behaviour.")]
+ [SampleControlInfo("ListView", "ListView_CacheLength_Slow_Load", ignoreInSnapshotTests: true, description: "ListView with slow-loading images, illustrating caching behaviour.")]
public sealed partial class ListView_CacheLength_Slow_Load : UserControl
{
public ListView_CacheLength_Slow_Load()
diff --git a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/Progress/ProgressRing.xaml.cs b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/Progress/ProgressRing.xaml.cs
index 52cd2dca44..849b29640f 100644
--- a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/Progress/ProgressRing.xaml.cs
+++ b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/Progress/ProgressRing.xaml.cs
@@ -21,7 +21,7 @@ namespace SamplesApp.Samples.Progress
///
/// An empty page that can be used on its own or navigated to within a Frame.
///
- [SampleControlInfo("Progress", "ProgressRing")]
+ [SampleControlInfo("Progress", "ProgressRing", ignoreInSnapshotTests: true)]
public sealed partial class ProgressRing : Page
{
public ProgressRing()
diff --git a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Media/Transform/Transformed_Ancestor_And_UI_Blocked.xaml.cs b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Media/Transform/Transformed_Ancestor_And_UI_Blocked.xaml.cs
index 2c16776c0f..db5b0e5022 100644
--- a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Media/Transform/Transformed_Ancestor_And_UI_Blocked.xaml.cs
+++ b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Media/Transform/Transformed_Ancestor_And_UI_Blocked.xaml.cs
@@ -21,7 +21,7 @@ using Windows.UI.Xaml.Navigation;
namespace UITests.Shared.Windows_UI_Xaml_Media.Transform
{
- [SampleControlInfo("Transform", "Transformed_Ancestor_And_UI_Blocked", description: "Animation in transformed hierarchy, under simulated heavy UI load. Animation should remain smooth on Android 8+ devices.")]
+ [SampleControlInfo("Transform", "Transformed_Ancestor_And_UI_Blocked", ignoreInSnapshotTests: true, description: "Animation in transformed hierarchy, under simulated heavy UI load. Animation should remain smooth on Android 8+ devices.")]
public sealed partial class Transformed_Ancestor_And_UI_Blocked : UserControl
{
private bool _isLoaded;
diff --git a/src/Uno.UI.TestComparer/Comparer/TestFilesComparer.cs b/src/Uno.UI.TestComparer/Comparer/TestFilesComparer.cs
index f5da497836..ccfedcc104 100644
--- a/src/Uno.UI.TestComparer/Comparer/TestFilesComparer.cs
+++ b/src/Uno.UI.TestComparer/Comparer/TestFilesComparer.cs
@@ -147,10 +147,10 @@ namespace Uno.UI.TestComparer.Comparer
var currentImage = DecodeImage(folderInfo.Path);
var previousImage = DecodeImage(previousFolderInfo.Path);
- var diff = DiffImages(currentImage.pixels, previousImage.pixels);
+ var diff = DiffImages(currentImage.pixels, previousImage.pixels, currentImage.frame.Format.BitsPerPixel / 8);
var diffFilePath = Path.Combine(diffPath, $"{folderInfo.Id}-{folderInfo.CompareeId}.png");
- WriteImage(diffFilePath, diff, currentImage.frame);
+ WriteImage(diffFilePath, diff, currentImage.frame, currentImage.stride);
compareResultFileRun.DiffResultImage = diffFilePath;
@@ -220,7 +220,7 @@ namespace Uno.UI.TestComparer.Comparer
}
}
- private void WriteImage(string diffPath, byte[] diff, BitmapFrame frameInfo)
+ private void WriteImage(string diffPath, byte[] diff, BitmapFrame frameInfo, int stride)
{
using (var stream = new FileStream(diffPath, FileMode.Create))
{
@@ -229,14 +229,14 @@ namespace Uno.UI.TestComparer.Comparer
encoder.Interlace = PngInterlaceOption.On;
var frame = BitmapSource.Create(
- pixelWidth: (int)frameInfo.Width,
- pixelHeight: (int)frameInfo.Height,
+ pixelWidth: (int)frameInfo.PixelWidth,
+ pixelHeight: (int)frameInfo.PixelHeight,
dpiX: frameInfo.DpiX,
dpiY: frameInfo.DpiY,
pixelFormat: frameInfo.Format,
palette: frameInfo.Palette,
pixels: diff,
- stride: (int)(frameInfo.Width * 4)
+ stride: stride
);
encoder.Frames.Add(BitmapFrame.Create(frame));
@@ -244,7 +244,7 @@ namespace Uno.UI.TestComparer.Comparer
}
}
- private byte[] DiffImages(byte[] currentImage, byte[] previousImage)
+ private byte[] DiffImages(byte[] currentImage, byte[] previousImage, int pixelSize)
{
var result = new byte[currentImage.Length];
@@ -253,37 +253,34 @@ namespace Uno.UI.TestComparer.Comparer
result[i] = (byte)(currentImage[i] ^ previousImage[i]);
}
- // Force result to be opaque
- for (int i = 0; i < result.Length; i += 4)
+ if (pixelSize == 4)
{
- result[i+3] = 0xFF;
+ // Force result to be opaque
+ for (int i = 0; i < result.Length; i += 4)
+ {
+ result[i + 3] = 0xFF;
+ }
}
return result;
}
- private (BitmapFrame frame, byte[] pixels) DecodeImage(string path1)
+ private (BitmapFrame frame, byte[] pixels, int stride) DecodeImage(string path1)
{
- Stream imageStreamSource = new FileStream(@"\\?\" + path1, FileMode.Open, FileAccess.Read, FileShare.Read);
- var decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.None, BitmapCacheOption.Default);
-
- var f = decoder.Frames[0];
- var sourceStride = f.PixelWidth * (f.Format.BitsPerPixel / 8);
- sourceStride += (4 - sourceStride % 4);
-
- var image = new byte[sourceStride * (f.PixelHeight * 4)];
- decoder.Frames[0].CopyPixels(image, (int)sourceStride, 0);
-
- // Remove the stride
- var targetImage = new byte[f.PixelWidth * f.PixelHeight * 4];
- var targetStride = f.PixelWidth * 4;
-
- for (int i = 0; i < f.PixelHeight; i++)
+ using (Stream imageStreamSource = new FileStream(@"\\?\" + path1, FileMode.Open, FileAccess.Read, FileShare.Read))
{
- Buffer.BlockCopy(image, i * sourceStride, targetImage, i * targetStride, targetStride);
- }
+ var decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
- return (decoder.Frames[0], targetImage);
+ var f = decoder.Frames[0];
+ var sourceBytesPerPixels = f.Format.BitsPerPixel / 8;
+ var sourceStride = f.PixelWidth * sourceBytesPerPixels;
+ sourceStride += (4 - sourceStride % 4);
+
+ var image = new byte[sourceStride * (f.PixelHeight * sourceBytesPerPixels)];
+ decoder.Frames[0].CopyPixels(image, (int)sourceStride, 0);
+
+ return (decoder.Frames[0], image, sourceStride);
+ }
}
private static IEnumerable LogForeach(IEnumerable q, Action action)
diff --git a/src/Uno.UI.TestComparer/Program.cs b/src/Uno.UI.TestComparer/Program.cs
index 4303e72ac6..4b95708be0 100644
--- a/src/Uno.UI.TestComparer/Program.cs
+++ b/src/Uno.UI.TestComparer/Program.cs
@@ -166,7 +166,7 @@ namespace Umbrella.UI.TestComparer
return;
}
- if (string.IsNullOrEmpty(githubPAT.Trim()))
+ if (string.IsNullOrEmpty(githubPAT.Trim()) || githubPAT.StartsWith("$("))
{
Console.WriteLine($"No GitHub PAT, no PR comment will be posted.");
return;
diff --git a/src/Uno.UI/UI/Xaml/Controls/TextBlock/TextBlock.iOS.cs b/src/Uno.UI/UI/Xaml/Controls/TextBlock/TextBlock.iOS.cs
index afa2ff522c..6bbdce9e6c 100644
--- a/src/Uno.UI/UI/Xaml/Controls/TextBlock/TextBlock.iOS.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/TextBlock/TextBlock.iOS.cs
@@ -312,7 +312,7 @@ namespace Windows.UI.Xaml.Controls
}
else
{
- return _attributedString.GetBoundingRect(size, NSStringDrawingOptions.UsesLineFragmentOrigin, null).Size;
+ return _attributedString?.GetBoundingRect(size, NSStringDrawingOptions.UsesLineFragmentOrigin, null).Size ?? new CGSize(0,0);
}
}
diff --git a/src/Uno.UI/UI/Xaml/Style/Generic/Generic.xaml b/src/Uno.UI/UI/Xaml/Style/Generic/Generic.xaml
index 5cd171b17d..fb0cd606b9 100644
--- a/src/Uno.UI/UI/Xaml/Style/Generic/Generic.xaml
+++ b/src/Uno.UI/UI/Xaml/Style/Generic/Generic.xaml
@@ -773,6 +773,10 @@
+
+