public void WhenFluentClick_04_DisabledChecked() { NavigateToSample("CheckBox", "Fluent"); TakeScreenshot("Before Checked"); var fluentDisabledCheckedBox = new QueryEx(x => x.All().Marked("Fluent_Disabled_Checked")); App.ScrollDownTo("Fluent_Disabled_Checked"); fluentDisabledCheckedBox.Tap(); TakeScreenshot("After UnChecked"); Assert.IsFalse(fluentDisabledCheckedBox.GetDependencyPropertyValue <bool>("IsEnabled")); Assert.IsTrue(fluentDisabledCheckedBox.GetDependencyPropertyValue <bool>("IsChecked")); }
public void WhenCupertinoClick_02_DisabledUnChecked() { NavigateToSample("CheckBox", "Cupertino"); TakeScreenshot("Before Checked"); var cupertinoDisabledUncheckedBox = new QueryEx(x => x.All().Marked("Cupertino_Disabled_Unchecked")); App.ScrollDownTo("Cupertino_Disabled_Unchecked"); cupertinoDisabledUncheckedBox.Tap(); TakeScreenshot("After Checked"); Assert.IsFalse(cupertinoDisabledUncheckedBox.GetDependencyPropertyValue <bool>("IsEnabled")); Assert.IsFalse(cupertinoDisabledUncheckedBox.GetDependencyPropertyValue <bool>("IsChecked")); }
public void WhenMaterialClickSecondary_04_DisabledChecked() { NavigateToSample("CheckBox", "Material"); TakeScreenshot("Before Checked"); var materialSecondaryDisabledCheckedBox = new QueryEx(x => x.All().Marked("Material_Secondary_Disabled_Checked")); App.ScrollDownTo("Material_Secondary_Disabled_Checked"); materialSecondaryDisabledCheckedBox.Tap(); TakeScreenshot("After UnChecked"); Assert.IsFalse(materialSecondaryDisabledCheckedBox.GetDependencyPropertyValue <bool>("IsEnabled")); Assert.IsTrue(materialSecondaryDisabledCheckedBox.GetDependencyPropertyValue <bool>("IsChecked")); }
private void ChangeFocusAndAssertBeforeAfter(IApp app, Action <IApp> changeFocus, QueryEx target, string initialText, string finalText) { // Focus target changeFocus(app); // Assert initial state Assert.AreEqual(initialText, target.GetDependencyPropertyValue("Text")?.ToString()); // Update text content _app.ClearText(); _app.EnterText(finalText); // Assert final state Assert.AreEqual(finalText, target.GetDependencyPropertyValue("Text")?.ToString()); }
public void WhenCupertinoClick_06_DisabledIndeterminate() { NavigateToSample("CheckBox", "Cupertino"); TakeScreenshot("Before Checked"); var cupertinoDisabledIndeterminateBox = new QueryEx(x => x.All().Marked("Cupertino_Disabled_Indeterminate")); App.ScrollDownTo("Cupertino_Disabled_Indeterminate"); cupertinoDisabledIndeterminateBox.Tap(); TakeScreenshot("After Checked"); Assert.IsFalse(cupertinoDisabledIndeterminateBox.GetDependencyPropertyValue <bool>("IsEnabled")); var isChecked = cupertinoDisabledIndeterminateBox.GetDependencyPropertyValue("IsChecked"); Assert.IsTrue(isChecked == null || string.IsNullOrWhiteSpace(isChecked as string)); }
private void ChangeTextAndAssertBeforeAfter(QueryEx textbox, string initialTextAlignment, string finalText, string finalTextAlignment) { // Focus textbox textbox.Tap(); // Assert initial state Assert.AreEqual(initialTextAlignment, textbox.GetDependencyPropertyValue("TextAlignment")?.ToString()); // Update text content _app.ClearText(); _app.EnterText(finalText); // Assert final state Assert.AreEqual(finalTextAlignment, textbox.GetDependencyPropertyValue("TextAlignment")?.ToString()); }
private int GetSliderValue(QueryEx mark) { _app.Wait(0.15f); // give time to app to execute the action var valueString = mark.GetDependencyPropertyValue("Text") as string; return(int.TryParse(valueString, out var c) ? c : -1); }
public void CommandTest() { Run("UITests.Microsoft_UI_Xaml_Controls.SplitButtonTests.SplitButtonPage"); var splitButton = new QueryEx(q => q.All().Marked("CommandSplitButton")); var canExecuteCheckBox = new QueryEx(q => q.All().Marked("CanExecuteCheckBox")); var executeCountTextBlock = new QueryEx(q => q.All().Marked("ExecuteCountTextBlock")); Console.WriteLine("Assert that the control starts out enabled"); Assert.IsTrue("true".Equals(canExecuteCheckBox.GetDependencyPropertyValue("IsChecked").ToString(), StringComparison.InvariantCultureIgnoreCase)); Assert.IsTrue("true".Equals(splitButton.GetDependencyPropertyValue("IsEnabled").ToString(), StringComparison.InvariantCultureIgnoreCase)); Assert.AreEqual("0", executeCountTextBlock.GetText()); Console.WriteLine("Click primary button to execute command"); TapPrimaryButton(splitButton); Assert.AreEqual("1", executeCountTextBlock.GetText()); Console.WriteLine("Assert that setting CanExecute to false disables the primary button"); canExecuteCheckBox.FastTap(); //Wait.ForIdle(); TapPrimaryButton(splitButton); Assert.AreEqual("1", executeCountTextBlock.GetText()); }
public void WhenFluentClick_01_Unchecked() { NavigateToSample("CheckBox", "Fluent"); TakeScreenshot("Before Checked"); var FluentUncheckedBox = new QueryEx(x => x.All().Marked("Fluent_Unchecked")); App.ScrollDownTo("Fluent_Unchecked"); FluentUncheckedBox.Tap(); TakeScreenshot("After Checked"); Assert.IsTrue(FluentUncheckedBox.GetDependencyPropertyValue <bool>("IsChecked")); }
public void When_MultipleItems() { Run("UITests.Windows_UI_Xaml_Controls.SwipeControlTests.SwipeControl_Automated"); QueryEx sut = "SUT"; QueryEx output = new QueryEx(q => q.All().Marked("Output")); var sutRect = _app.Query(sut).Single().Rect; _app.DragCoordinates(sutRect.CenterX, sutRect.CenterY, sutRect.X + 10, sutRect.CenterY); var result = output.GetDependencyPropertyValue <string>("Text"); Assert.IsTrue(string.IsNullOrWhiteSpace(result)); _app.TapCoordinates(sutRect.Right - 10, sutRect.CenterY); result = output.GetDependencyPropertyValue <string>("Text"); Assert.AreEqual("Right_3", result); }
public void TestSetup() { Run("UITests.Shared.Microsoft_UI_Xaml_Controls.TwoPaneViewTests.TwoPaneViewPage"); Query myQuery = q => q.All().Marked("ControlWidthText"); var controlWidthText = new QueryEx(myQuery); // _app.Repl(); Assert.IsTrue(controlWidthText.GetDependencyPropertyValue <int>("Text") > 641, "The window size must be large enough for the control Width to be larger than 641"); }
public void WhenMaterialClick_03_Checked() { NavigateToSample("CheckBox", "Material"); TakeScreenshot("Before UnChecked"); var checkedBox = new QueryEx(x => x.All().Marked("Material_Checked")); App.ScrollDownTo("Material_Checked"); checkedBox.Tap(); TakeScreenshot("After UnChecked"); Assert.IsFalse(checkedBox.GetDependencyPropertyValue <bool>("IsChecked")); }
private static string ArchiveResults(QueryEx benchmarkControl) { var base64 = benchmarkControl.GetDependencyPropertyValue <string>("ResultsAsBase64"); var file = Path.GetTempFileName(); File.WriteAllBytes(file, Convert.FromBase64String(base64)); if (Environment.GetEnvironmentVariable(BenchmarkOutputPath) is { } path) { ZipFile.ExtractToDirectory(file, path); }
private static string ArchiveResults(QueryEx unitTestsControl) { var document = unitTestsControl.GetDependencyPropertyValue <string>("NUnitTestResultsDocument"); var file = Path.GetTempFileName(); File.WriteAllText(file, document, Encoding.Unicode); if (Environment.GetEnvironmentVariable(TestResultsOutputFilePath) is { } path) { File.Copy(file, path); }
public void WhenFluentClick_05_Indeterminate() { NavigateToSample("CheckBox", "Fluent"); TakeScreenshot("Before UnChecked"); var fluentCheckedIndeterminateBox = new QueryEx(x => x.All().Marked("Fluent_Indeterminate")); App.ScrollDownTo("Fluent_Indeterminate"); fluentCheckedIndeterminateBox.Tap(); TakeScreenshot("After UnChecked"); Assert.IsFalse(fluentCheckedIndeterminateBox.GetDependencyPropertyValue <bool>("IsChecked")); fluentCheckedIndeterminateBox.Tap(); TakeScreenshot("After Checked"); Assert.IsTrue(fluentCheckedIndeterminateBox.GetDependencyPropertyValue <bool>("IsChecked")); fluentCheckedIndeterminateBox.Tap(); TakeScreenshot("After Checked"); var isChecked = fluentCheckedIndeterminateBox.GetDependencyPropertyValue("IsChecked"); Assert.IsTrue(isChecked == null || string.IsNullOrWhiteSpace(isChecked as string)); }
public void WhenMaterialClickSecondary_05_Indeterminate() { NavigateToSample("CheckBox", "Material"); TakeScreenshot("Before UnChecked"); var materialSecondaryCheckedIndeterminateBox = new QueryEx(x => x.All().Marked("Material_Secondary_Indeterminate")); App.ScrollDownTo("Material_Secondary_Indeterminate"); materialSecondaryCheckedIndeterminateBox.Tap(); TakeScreenshot("After UnChecked"); Assert.IsFalse(materialSecondaryCheckedIndeterminateBox.GetDependencyPropertyValue <bool>("IsChecked")); materialSecondaryCheckedIndeterminateBox.Tap(); TakeScreenshot("After Checked"); Assert.IsTrue(materialSecondaryCheckedIndeterminateBox.GetDependencyPropertyValue <bool>("IsChecked")); materialSecondaryCheckedIndeterminateBox.Tap(); TakeScreenshot("After Checked"); var isChecked = materialSecondaryCheckedIndeterminateBox.GetDependencyPropertyValue("IsChecked"); Assert.IsTrue(isChecked == null || string.IsNullOrWhiteSpace(isChecked as string)); }
private async Task When_InScrollableContainer(string testName) { QueryEx sut = new QueryEx(q => q.All().Marked("SUT")); QueryEx output = new QueryEx(q => q.All().Marked("Output")); Run(testName, skipInitialScreenshot: true); var sutPhyRect = _app.GetPhysicalRect(sut); var item2PhyPosition = new Point((int)sutPhyRect.X + 150, (int)sutPhyRect.Y + 150).LogicalToPhysicalPixels(_app); // Validate initial state var initial = TakeScreenshot("initial"); ImageAssert.HasColorAt(initial, item2PhyPosition.X, item2PhyPosition.Y, "#FFFFA52C"); // Execute left command on item 2 _app.DragCoordinates(item2PhyPosition.X, item2PhyPosition.Y, item2PhyPosition.X + 300.LogicalToPhysicalPixels(_app), item2PhyPosition.Y); await Task.Delay(1000); // We cannot detect the animation ... var swippedItem = output.GetDependencyPropertyValue <string>("Text"); Assert.AreEqual("#FFFFA52C", swippedItem); // Scroll up _app.DragCoordinates(sutPhyRect.CenterX, sutPhyRect.Bottom - 10.LogicalToPhysicalPixels(_app), sutPhyRect.CenterX, sutPhyRect.Y + 10.LogicalToPhysicalPixels(_app)); // Validate scrolled successfully var postScroll = TakeScreenshot("after scroll"); ImageAssert.DoesNotHaveColorAt(postScroll, item2PhyPosition.X, item2PhyPosition.Y, "#FFFFA52C"); // Execute left command on item that is now at item 2 location _app.DragCoordinates(item2PhyPosition.X, item2PhyPosition.Y, item2PhyPosition.X + 300.LogicalToPhysicalPixels(_app), item2PhyPosition.Y); await Task.Delay(1000); // We cannot detect the animation ... swippedItem = output.GetDependencyPropertyValue <string>("Text"); Assert.AreNotEqual("#FFFFA52C", swippedItem); }
public async Task When_MultipleItems() { Run("UITests.Windows_UI_Xaml_Controls.SwipeControlTests.SwipeControl_Automated"); QueryEx sut = "SUT"; QueryEx output = new QueryEx(q => q.All().Marked("Output")); var sutRect = _app.Query(sut).Single().Rect; _app.DragCoordinates(sutRect.Right - 10, sutRect.CenterY, sutRect.X + 10, sutRect.CenterY); var result = output.GetDependencyPropertyValue <string>("Text"); await Task.Delay(1000); // We cannot detect the animation ... Assert.AreEqual("** none **", result); _app.TapCoordinates(sutRect.Right - 10, sutRect.CenterY); result = output.GetDependencyPropertyValue <string>("Text"); Assert.AreEqual("Right_3", result); }
public void When_SingleItem() { Run("UITests.Windows_UI_Xaml_Controls.SwipeControlTests.SwipeControl_Automated"); QueryEx sut = "SUT"; QueryEx output = "Output"; var sutRect = _app.Query(sut).Single().Rect; _app.DragCoordinates(sutRect.CenterX, sutRect.CenterY, sutRect.Right - 10, sutRect.CenterY); var result = output.GetDependencyPropertyValue <string>("Text"); Assert.AreEqual("Left_1", result); }
public void When_Tap_PressedReleasedAreHandled() { Run("UITests.Windows_UI_Xaml_Controls.ComboBox.ComboBox_Pointers"); QueryEx combo = "_combo"; QueryEx output = "_output"; _app.FastTap(combo); // Test sanity: close the combo _app.FastTap(combo); var rawOutput = output.GetDependencyPropertyValue <string>("Text"); var outputParser = new Regex(@"\[(?<event>\w+)\]\s+(?<params>\|\s*(?<key>\w+)\s*=\s*(?<value>[\w\d]+))*"); var parsedOutput = rawOutput .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries) .Select(outputLine => outputParser.Match(outputLine)) .Where(match => match.Success) .Select(match => { using var keys = match.Groups["key"].Captures.Cast <Capture>().GetEnumerator(); using var values = match.Groups["value"].Captures.Cast <Capture>().GetEnumerator(); IEnumerable <(string key, string value)> GetParameters() { while (keys.MoveNext() && values.MoveNext()) { yield return(keys.Current !.Value, values.Current !.Value); } } return(evt: match.Groups["event"].Value, @params: GetParameters().ToDictionary(pair => pair.key, pair => pair.value, StringComparer.OrdinalIgnoreCase)); }) .ToArray(); Assert.IsTrue( parsedOutput.Any(o => o.evt == "PRESSED"), "At least one pressed"); Assert.IsTrue( parsedOutput.Where(o => o.evt == "PRESSED").All(o => o.@params["handled"].Equals("True", StringComparison.OrdinalIgnoreCase)), "Pressed must be flagged as handled"); Assert.IsTrue( parsedOutput.Any(o => o.evt == "RELEASED"), "At least one release"); Assert.IsTrue( parsedOutput.Where(o => o.evt == "RELEASED").All(o => o.@params["handled"].Equals("True", StringComparison.OrdinalIgnoreCase)), "Pressed must be flagged as handled"); }
// This class contains **ASYNC** extensions method that match a sync version of the Uno.UITest.Helpers.Queries.QueryExtensions contract. // When a method is added here, a correspondent version should be added in \src\SamplesApp\SamplesApp.UITests\Extensions\QueryExtensions.async.cs // to allow usage in the Xamarin / Selenium UI tests. public static async Task WaitForDependencyPropertyValueAsync(this IApp app, QueryEx element, string dependencyPropertyName, string value) { const int interval = 25; const int attemps = 3000 / interval; for (var i = 0; i < attemps; i++) { var actual = element.GetDependencyPropertyValue <string>(dependencyPropertyName); if (actual?.Equals(value) ?? value is null) { return; } await Task.Delay(interval); } Assert.Fail($"Failed to get '{value}' for '{dependencyPropertyName}'."); }
public void When_PageHasNoContent_Then_PointerPassThrough() { Run("UITests.Windows_UI_Xaml_Controls.FrameTests.Frame_PageStacking", skipInitialScreenshot: true); _app.Marked("NavRed").FastTap(); _app.Marked("NavTransparent").FastTap(); _app.FastTap("MyFrame"); QueryEx output = "TappedResult"; var result = output.GetDependencyPropertyValue<string>("Text"); // We expect a "tapped" as: // 1. The red should be collapsed so it should not have receive the tapped event, so it has not flagged it as handled. // 2. Even if the bg of the TransparentPage is not null (i.e. Transparent), // the Page should not get any pointer event as its content is completely empty. result.Should().Be("tapped"); }
public async Task When_TapInListView_Then_TriggerClickAndSelection() { await RunAsync("UITests.Windows_UI_Xaml_Controls.SwipeControlTests.SwipeControl_ListView_ItemClick"); QueryEx sut = "SUT"; QueryEx clicked = "LastClicked"; QueryEx selected = "LastSelected"; QueryEx swiped = "LastSwipeInvoked"; var sutRect = App.GetPhysicalRect(sut); App.TapCoordinates(sutRect.X + 100, sutRect.Y + 20); await Task.Delay(1000); // We cannot detect the animation ... Assert.AreEqual("0", clicked.GetDependencyPropertyValue <string>("Text")); Assert.AreEqual("0", selected.GetDependencyPropertyValue <string>("Text")); Assert.AreEqual("** none **", swiped.GetDependencyPropertyValue <string>("Text")); }
/// <summary> /// Get the value of the Text property for an element. /// </summary> public static string GetText(this QueryEx element) => element.GetDependencyPropertyValue <string>("Text");
public static GestureResult Get(QueryEx textBlock) => Parse(textBlock.GetDependencyPropertyValue <string>("Text"));
// [Timeout(3000000)] // Timeout is now moved to individual platorms runners configuration in CI public async Task RunRuntimeTests() { Run("SamplesApp.Samples.UnitTests.UnitTestsPage"); IAppQuery AllQuery(IAppQuery query) // .All() is not yet supported for wasm. => AppInitializer.GetLocalPlatform() == Platform.Browser ? query : query.All(); var runButton = new QueryEx(q => AllQuery(q).Marked("runButton")); var failedTests = new QueryEx(q => AllQuery(q).Marked("failedTests")); var failedTestsDetails = new QueryEx(q => AllQuery(q).Marked("failedTestDetails")); var unitTestsControl = new QueryEx(q => AllQuery(q).Marked("UnitTestsRootControl")); async Task <bool> IsTestExecutionDone() { return(await GetWithRetry("IsTestExecutionDone", () => unitTestsControl.GetDependencyPropertyValue("RunningStateForUITest")?.ToString().Equals("Finished", StringComparison.OrdinalIgnoreCase) ?? false)); } _app.WaitForElement(runButton); _app.FastTap(runButton); var lastChange = DateTimeOffset.Now; var lastValue = ""; while (DateTimeOffset.Now - lastChange < TestRunTimeout) { var newValue = await GetWithRetry("GetRunTestCount", () => unitTestsControl.GetDependencyPropertyValue("RunTestCountForUITest")?.ToString()); if (lastValue != newValue) { lastChange = DateTimeOffset.Now; } await Task.Delay(TimeSpan.FromSeconds(.5)); if (await IsTestExecutionDone()) { break; } } if (!await IsTestExecutionDone()) { Assert.Fail("A test run timed out"); } TestContext.AddTestAttachment(ArchiveResults(unitTestsControl), "runtimetests-results.zip"); var count = GetValue(nameof(unitTestsControl), unitTestsControl, "FailedTestCountForUITest"); if (count != "0") { var tests = GetValue(nameof(failedTests), failedTests) .Split(new char[] { '§' }, StringSplitOptions.RemoveEmptyEntries) .Select((x, i) => $"\t{i + 1}. {x}\n") .ToArray(); var details = GetValue(nameof(failedTestsDetails), failedTestsDetails); Assert.Fail($"{tests.Length} unit test(s) failed (count={count}).\n\tFailing Tests:\n{string.Join("", tests)}\n\n---\n\tDetails:\n{details}"); } TakeScreenshot("Runtime Tests Results", ignoreInSnapshotCompare: true); }
public void ValidateShape(string shapeName, PixelTolerance?tolerance = null) { Run("UITests.Windows_UI_Xaml_Shapes.Basic_Shapes", skipInitialScreenshot: true); var ctrl = new QueryEx(q => q.Marked("_basicShapesTestRoot")); var expectedDirectory = Path.Combine( TestContext.CurrentContext.TestDirectory, "Windows_UI_Xaml_Shapes/Basics_Shapes_Tests_EpectedResults"); var actualDirectory = Path.Combine( TestContext.CurrentContext.WorkDirectory, nameof(Windows_UI_Xaml_Shapes), nameof(Basics_Shapes_Tests), shapeName); tolerance = tolerance ?? (new PixelTolerance() .WithColor(132) // We are almost only trying to detect edges .WithOffset(3, 3, LocationToleranceKind.PerPixel) .Discrete(2)); var failures = new List <(string test, Exception error)>(); // To improve performance, we run all test for a given stretch at once. var testGroups = _tests .Where(t => t.StartsWith(shapeName)) .GroupBy(t => string.Join("_", t.Split(new[] { '_' }, 3, StringSplitOptions.RemoveEmptyEntries).Take(2))); foreach (var testGroup in testGroups) { ctrl.SetDependencyPropertyValue("RunTest", string.Join(";", testGroup)); _app.WaitFor(() => !string.IsNullOrWhiteSpace(ctrl.GetDependencyPropertyValue <string>("TestResult")), timeout: TimeSpan.FromMinutes(1)); var testResultsRaw = ctrl.GetDependencyPropertyValue <string>("TestResult"); var testResults = testResultsRaw .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries) .Select(line => line.Split(new[] { ';' }, 3, StringSplitOptions.RemoveEmptyEntries)) .Where(line => line.Length == 3) .ToDictionary( line => line[0], line => { var testName = line[0]; var isSuccess = line[1] == "SUCCESS"; var data = Convert.FromBase64String(line[2]); var target = Path .Combine(actualDirectory, testName + (isSuccess ? ".png" : ".txt")) .GetNormalizedLongPath(); var targetFile = new FileInfo(target); targetFile.Directory.Create(); File.WriteAllBytes(target, data); SetOptions(targetFile, new ScreenshotOptions { IgnoreInSnapshotCompare = true }); TestContext.AddTestAttachment(target, testName); return(isSuccess ? new Bitmap(new MemoryStream(Convert.FromBase64String(line[2]))) : new Exception(Encoding.UTF8.GetString(Convert.FromBase64String(line[2]))) as object); }); foreach (var test in testGroup) { try { var expected = new FileInfo(Path.Combine(expectedDirectory, $"{test}.png")); if (!expected.Exists) { Assert.Fail($"Expected screenshot does not exists ({expected.FullName})"); } if (!testResults.TryGetValue(test, out var testResult)) { Assert.Fail($"No test result for {test}."); } if (testResult is Exception error) { Assert.Fail($"Test failed: {error.Message}"); } using (var actual = (Bitmap)testResult) { var scale = 2.0; ImageAssert.AreAlmostEqual(expected, ImageAssert.FirstQuadrant, actual, ImageAssert.FirstQuadrant, scale, tolerance.Value); } } catch (Exception e) { Console.Error.WriteLine(e); // Ease debug while reading log from CI failures.Add((test, e)); } } } if (failures.Any()) { throw new AggregateException( $"Failed tests ({failures.Count} of {testGroups.Sum(g => g.Count())}):\r\n{string.Join("\r\n", failures.Select(t => t.test))}\r\n", failures.Select(t => t.error)); } else { Console.WriteLine($"All {testGroups.Sum(g => g.Count())} ran successfully."); } }
public static T GetDependencyPropertyValue <T>(this QueryEx query, string propertyName) => (T)query.GetDependencyPropertyValue(propertyName);
private string GetText(QueryEx textBlock) => textBlock.GetDependencyPropertyValue <string>("Text");
[Timeout(600000)] // Adjust this timeout based on average test run duration public async Task RunRuntimeTests() { Run("SamplesApp.Samples.UnitTests.UnitTestsPage"); IAppQuery AllQuery(IAppQuery query) // .All() is not yet supported for wasm. => AppInitializer.GetLocalPlatform() == Platform.Browser ? query : query.All(); var runButton = new QueryEx(q => AllQuery(q).Marked("runButton")); var failedTestsCount = new QueryEx(q => AllQuery(q).Marked("failedTestCount")); var failedTests = new QueryEx(q => AllQuery(q).Marked("failedTests")); var runningState = new QueryEx(q => AllQuery(q).Marked("runningState")); var runTestCount = new QueryEx(q => AllQuery(q).Marked("runTestCount")); bool IsTestExecutionDone() => runningState.GetDependencyPropertyValue("Text")?.ToString().Equals("Finished", StringComparison.OrdinalIgnoreCase) ?? false; _app.WaitForElement(runButton); _app.FastTap(runButton); var lastChange = DateTimeOffset.Now; var lastValue = ""; while (DateTimeOffset.Now - lastChange < TestRunTimeout) { var newValue = runTestCount.GetDependencyPropertyValue("Text")?.ToString(); if (lastValue != newValue) { lastChange = DateTimeOffset.Now; } await Task.Delay(TimeSpan.FromSeconds(.5)); if (IsTestExecutionDone()) { break; } } if (!IsTestExecutionDone()) { Assert.Fail("A test run timed out"); } var count = failedTestsCount.GetDependencyPropertyValue("Text").ToString(); if (count != "0") { var tests = failedTests.GetDependencyPropertyValue <string>("Text") .Split(new char[] { '§' }, StringSplitOptions.RemoveEmptyEntries) .Select((x, i) => $"\t{i + 1}. {x}\n") .ToArray(); var details = _app.Marked("failedTestDetails").GetDependencyPropertyValue("Text"); Assert.Fail( $"{tests.Length} unit test(s) failed.\n\tFailing Tests:\n{string.Join("", tests)}\n\n---\n\tDetails:\n{details}"); } TakeScreenshot("Runtime Tests Results", ignoreInSnapshotCompare: true); }