Merge pull request #2276 from unoplatform/dev/jela/ios-snapshots

Restore iOS Snapshot Tests
This commit is contained in:
Jérôme Laban 2019-12-09 10:43:44 -05:00 коммит произвёл GitHub
Родитель a159b0edd5 c85bebb589
Коммит bd7f4d3042
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
25 изменённых файлов: 183 добавлений и 52 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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=" \

Просмотреть файл

@ -17,8 +17,8 @@
<PackageReference Update="Uno.SourceGeneration" Version="1.32.0" />
<PackageReference Update="Uno.Core" Version="1.29.0-dev.93" />
<PackageReference Update="Uno.Core.Build" Version="1.29.0" />
<PackageReference Update="Uno.Wasm.Bootstrap" Version="1.0.5" />
<DotNetCliToolReference Update="Uno.Wasm.Bootstrap.Cli" Version="1.0.5" />
<PackageReference Update="Uno.Wasm.Bootstrap" Version="1.0.10" />
<DotNetCliToolReference Update="Uno.Wasm.Bootstrap.Cli" Version="1.0.10" />
<PackageReference Update="xamarin.build.download" Version="0.4.11" />
<PackageReference Update="Uno.MonoAnalyzers" Version="1.0.0-dev.4" PrivateAssets="all" />
<PackageReference Update="System.Memory" Version="4.5.2" />

Просмотреть файл

@ -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);");
}
}
}

Просмотреть файл

@ -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<TestAppModeAttribute>().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<AutoRetryAttribute>().Length == 0)
{
Assert.Fail($"The AutoRetryAttribute is not defined for this test");
}
}
private static T[] GetCurrentFixtureAttributes<T>() 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<T>() 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(".", "_"));
}

Просмотреть файл

@ -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
{
/// <summary>
/// Builds TestMode attribute
/// </summary>
/// <param name="cleanEnvironment">
/// Determines if the app should be restarted to get a clean environment before the fixture tests are started.
/// </param>
/// <param name="platform">Determines the target platform to be used for this attribute</param>
public TestAppModeAttribute(bool cleanEnvironment, Platform platform)
{
CleanEnvironment = cleanEnvironment;
Platform = platform;
}
/// <summary>
/// Determines if the app should be restarted to get a clean environment before the fixture tests are started.
/// </summary>
public bool CleanEnvironment { get; }
/// <summary>
/// Determines the target platform to be used for this attribute
/// </summary>
public Platform Platform { get; }
}
}

Просмотреть файл

@ -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()
{

Просмотреть файл

@ -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()
{

Просмотреть файл

@ -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");

Просмотреть файл

@ -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");

Просмотреть файл

@ -53,6 +53,7 @@ namespace SamplesApp.UITests.Windows_UI_Xaml_Controls.ListViewTests
}
[Test]
[AutoRetry]
[ActivePlatforms(Platform.Android)]
public void ListView_ItemPanel_HotSwapTest()
{

Просмотреть файл

@ -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");

Просмотреть файл

@ -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()

Просмотреть файл

@ -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()
{

Просмотреть файл

@ -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);

Просмотреть файл

@ -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");

Просмотреть файл

@ -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",

Просмотреть файл

@ -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;

Просмотреть файл

@ -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()

Просмотреть файл

@ -21,7 +21,7 @@ namespace SamplesApp.Samples.Progress
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
[SampleControlInfo("Progress", "ProgressRing")]
[SampleControlInfo("Progress", "ProgressRing", ignoreInSnapshotTests: true)]
public sealed partial class ProgressRing : Page
{
public ProgressRing()

Просмотреть файл

@ -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;

Просмотреть файл

@ -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<T> LogForeach<T>(IEnumerable<T> q, Action<T> action)

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);
}
}

Просмотреть файл

@ -773,6 +773,10 @@
</Setter>
</xamarin:Style>
<xamarin:Style x:Key="XamlDefaultComboBox"
TargetType="ComboBox"
BasedOn="{StaticResource DefaultComboBoxStyle}" />
<Style TargetType="ComboBox"
BasedOn="{StaticResource DefaultComboBoxStyle}" />