public static void AreEqual(Bitmap expected, Bitmap actual, Action <Bitmap> onFail) { if (expected.Size != actual.Size) { if (Debugger.IsAttached) { ImageDiffWindow.Show(expected, actual); } onFail(actual); throw AssertException.Create( "Sizes did not match\r\n" + $"Expected: {expected.Size}\r\n" + $"Actual: {actual.Size}"); } for (var x = 0; x < expected.Size.Width; x++) { for (var y = 0; y < expected.Size.Height; y++) { if (expected.GetPixel(x, y).Name == actual.GetPixel(x, y).Name) { continue; } if (Debugger.IsAttached) { ImageDiffWindow.Show(expected, actual); } onFail(actual); throw AssertException.Create("Images do not match."); } } }
/// <summary> /// Assert that <paramref name="expected"/> is equal to <paramref name="element"/> by comparing pixels. /// </summary> /// <param name="expected">The expected <see cref="Bitmap"/>.</param> /// <param name="element">The actual <see cref="UiElement"/>.</param> public static void AreEqual(Bitmap expected, UiElement element) { if (expected is null) { throw new ArgumentNullException(nameof(expected)); } if (element is null) { throw new ArgumentNullException(nameof(element)); } if (Equal(expected, element, RetryTime)) { return; } using var actual = Capture.Rectangle(element.Bounds); if (Debugger.IsAttached) { ImageDiffWindow.Show(expected, actual); } throw ImageMatchException(expected, actual, null); }
/// <summary> /// Compare Capture.Rectangle(element.Bounds) to the expected image. /// </summary> /// <param name="fileName">Can be a full file name relative filename or the name of a resource.</param> /// <param name="element">The automation element.</param> /// <param name="onFail">Useful for saving the actual image on error for example.</param> public static void AreEqual(string fileName, UiElement element, OnImageAssertFail onFail) { if (fileName is null) { throw new ArgumentNullException(nameof(fileName)); } if (element is null) { throw new ArgumentNullException(nameof(element)); } if (onFail is null) { throw new ArgumentNullException(nameof(onFail)); } if (TryGetStream(fileName, Assembly.GetCallingAssembly(), out var stream)) { using (stream) { using var expected = (Bitmap)Image.FromStream(stream); if (Equal(expected, element, RetryTime)) { return; } using var actual = Capture.Rectangle(element.Bounds); if (Debugger.IsAttached) { ImageDiffWindow.Show(expected, actual); } onFail(expected, actual, fileName); throw ImageMatchException(expected, actual, fileName); } } else { using var actual = Capture.Rectangle(element.Bounds); if (Debugger.IsAttached) { ImageDiffWindow.Show(null, actual); } onFail(null, actual, fileName); throw MissingResourceException(actual, fileName); } }
public static void Show(Bitmap?expected, Bitmap actual) { if (actual is null) { throw new System.ArgumentNullException(nameof(actual)); } var dispatcher = WpfDispatcher.Create(); dispatcher !.Invoke(() => { var window = new ImageDiffWindow(expected, actual); _ = window.ShowDialog(); }); dispatcher.InvokeShutdown(); _ = dispatcher.Thread.Join(1000); }
/// <summary> /// Assert that <paramref name="expected"/> is equal to <paramref name="actual"/> by comparing pixels. /// </summary> /// <param name="expected">The expected <see cref="Bitmap"/>.</param> /// <param name="actual">The actual <see cref="Bitmap"/>.</param> public static void AreEqual(Bitmap expected, Bitmap actual) { if (expected is null) { throw new ArgumentNullException(nameof(expected)); } if (actual is null) { throw new ArgumentNullException(nameof(actual)); } if (!Equal(expected, actual)) { if (Debugger.IsAttached) { ImageDiffWindow.Show(expected, actual); } throw ImageMatchException(expected, actual, null); } }
public static void Show(Bitmap expected, Bitmap actual) { using (var startedEvent = new ManualResetEventSlim(initialState: false)) { System.Windows.Threading.Dispatcher dispatcher = null; var uiThread = new Thread(() => { // Create and install a new dispatcher context SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher)); dispatcher = Dispatcher.CurrentDispatcher; // Signal that it is initialized // ReSharper disable once AccessToDisposedClosure startedEvent.Set(); // Start the dispatcher processing Dispatcher.Run(); }); // Set the apartment state uiThread.SetApartmentState(ApartmentState.STA); // Make the thread a background thread uiThread.IsBackground = true; // Start the thread uiThread.Start(); startedEvent.Wait(); dispatcher.Invoke(() => { var window = new ImageDiffWindow(expected, actual); window.ShowDialog().IgnoreReturnValue(); }); dispatcher.InvokeShutdown(); uiThread.Join(1000).IgnoreReturnValue(); } }