public void SetUp() { WinAppDriverHelper.CheckIsInstalled(); WinAppDriverHelper.StartIfNotRunning(); VirtualKeyboard.MinimizeAllWindows(); }
public async Task EnsureFrameworksProduceIdenticalOutputForEachPageInNavViewAsync() { var genIdentities = AllPagesThatSupportSimpleTesting(); ExecutionEnvironment.CheckRunningAsAdmin(); WinAppDriverHelper.CheckIsInstalled(); var app1Details = await SetUpProjectForUiTestComparisonAsync(ProgrammingLanguages.CSharp, "SplitView", "MVVMBasic", genIdentities); var errors = new List <string>(); foreach (var framework in GetAdditionalCsFrameworks()) { var app2Details = await SetUpProjectForUiTestComparisonAsync(ProgrammingLanguages.CSharp, "SplitView", framework[0].ToString(), genIdentities); var pageExclusions = new Dictionary <string, string>(); pageExclusions.Add("Settings", "new ImageComparer.ExclusionArea(new Rectangle(480, 360, 450, 40), 1.25f)"); var testProjectDetails = SetUpTestProjectForAllNavViewPagesComparison(app1Details, app2Details, pageExclusions); var(testSuccess, testOutput) = RunWinAppDriverTests(testProjectDetails); // Note that failing tests will leave the projects behind, plus the apps and test certificates installed if (testSuccess) { UninstallAppx(app2Details.PackageFullName); RemoveCertificate(app2Details.CertificatePath); // Parent of images folder also contains the test project Fs.SafeDeleteDirectory(Path.Combine(testProjectDetails.imagesFolder, "..")); } else { errors.AddRange(testOutput); // A diff image is automatically created if the outputs differ if (Directory.GetFiles(testProjectDetails.imagesFolder, "DIFF-*.png").Any()) { errors.Add($"Failing test images in {testProjectDetails.imagesFolder}"); } } } var outputMessages = string.Join(Environment.NewLine, errors); if (outputMessages.Any()) { Assert.True(false, $"{Environment.NewLine}{Environment.NewLine}{outputMessages}"); } else { UninstallAppx(app1Details.PackageFullName); RemoveCertificate(app1Details.CertificatePath); } }
// There are tests with hardcoded projectType and framework values to make rerunning/debugging only some of the tests easier private async Task EnsureLanguageLaunchPageVisualsAreEquivalentAsync(string projectType, string framework, string page) { var genIdentities = new[] { page }; ExecutionEnvironment.CheckRunningAsAdmin(); WinAppDriverHelper.CheckIsInstalled(); var app1Details = await SetUpProjectForUiTestComparisonAsync(ProgrammingLanguages.CSharp, projectType, framework, genIdentities, lastPageIsHome : true, createForScreenshots : true); var app2Details = await SetUpProjectForUiTestComparisonAsync(ProgrammingLanguages.VisualBasic, projectType, framework, genIdentities, lastPageIsHome : true, createForScreenshots : true); var noClickCount = 0; if (page == "wts.Page.Map") { noClickCount = 1; } else if (page == "wts.Page.Camera") { noClickCount = 2; } var longPause = page.EndsWith(".WebView") || page.EndsWith(".MediaPlayer"); var testProjectDetails = SetUpTestProjectForInitialScreenshotComparison(app1Details, app2Details, GetExclusionAreasForVisualEquivalencyTest(projectType, page), noClickCount, longPause); var(testSuccess, testOutput) = RunWinAppDriverTests(testProjectDetails); // Note that failing tests will leave the projects behind, plus the apps and test certificates installed if (testSuccess) { UninstallAppx(app1Details.PackageFullName); UninstallAppx(app2Details.PackageFullName); RemoveCertificate(app1Details.CertificatePath); RemoveCertificate(app2Details.CertificatePath); // Parent of images folder also contains the test project Fs.SafeDeleteDirectory(Path.Combine(testProjectDetails.imagesFolder, "..")); } var outputMessages = string.Join(Environment.NewLine, testOutput); // A diff image is automatically created if the outputs differ if (Directory.Exists(testProjectDetails.imagesFolder) && Directory.GetFiles(testProjectDetails.imagesFolder, "*.*-Diff.png").Any()) { Assert.True( testSuccess, $"Failing test images in {testProjectDetails.imagesFolder}{Environment.NewLine}{Environment.NewLine}{outputMessages}"); } else { Assert.True(testSuccess, outputMessages); } }
/// <summary> /// Stops the application. /// </summary> public static void StopApp() { if (WebApp != null) { WebApp.Quit(); WebApp = null; } WinAppDriverHelper.Stop(); }
public async Task CompareInitialScreenshots() { WinAppDriverHelper.StartIfNotRunning(); if (!Directory.Exists(TestAppInfo.ScreenshotsFolder)) { Directory.CreateDirectory(TestAppInfo.ScreenshotsFolder); } // Hide other apps to give a consistent backdrop for acrylic textures VirtualKeyboard.MinimizeAllWindows(); async Task GetScreenshot(string pfn, string fileName) { using (var session = WinAppDriverHelper.LaunchAppx(pfn)) { if (TestAppInfo.NoClickCount > 0) { await Task.Delay(TimeSpan.FromSeconds(2)); for (var i = 0; i < TestAppInfo.NoClickCount; i++) { await ClickNoOnPopUpAsync(session); } } session.Manage().Window.Maximize(); if (TestAppInfo.LongPauseAfterLaunch) { await Task.Delay(TimeSpan.FromSeconds(30)); // Because loading the first frame of the video can sometimes take this long } else { await Task.Delay(TimeSpan.FromSeconds(2)); } var screenshot = session.GetScreenshot(); screenshot.SaveAsFile(Path.Combine(TestAppInfo.ScreenshotsFolder, fileName), ImageFormat.Png); // Don't leave the app maximized in case we want to open the app again. // Some controls handle layout differently when the app is first opened maximized VirtualKeyboard.RestoreMaximizedWindow(); } } await GetScreenshot(TestAppInfo.AppPfn1, App1Filename); await GetScreenshot(TestAppInfo.AppPfn2, App2Filename); var imageCompareResult = CheckImagesAreTheSame(TestAppInfo.ScreenshotsFolder, App1Filename, App2Filename); Assert.IsTrue(imageCompareResult, $"Images do not match.{Environment.NewLine}App1: {App1Filename}{Environment.NewLine}App2: {App2Filename}{Environment.NewLine}See results in '{TestAppInfo.ScreenshotsFolder}'"); }
public async Task RunBasicAccessibilityChecksAgainstEachPageWpfAsync() { // This test does not run against all combinations but relies on other tests to ensure output is the same for each combination. // In theory this means that there should be no need to repeat tests as they would find the same things. // As this is a slow test to run we do not want to increase overall execution time unnecessarily. ExecutionEnvironment.CheckRunningAsAdmin(); WinAppDriverHelper.CheckIsInstalled(); WinAppDriverHelper.StartIfNotRunning(); var pagesFoundWithIssues = 0; var rootFolder = $"{Path.GetPathRoot(Environment.CurrentDirectory)}UIT\\ALLY\\{DateTime.Now:dd_HHmmss}\\"; var reportFolder = Path.Combine(rootFolder, "Reports"); void ForOpenedPage(string projectName) { var processes = Process.GetProcessesByName(projectName); var config = Axe.Windows.Automation.Config.Builder.ForProcessId(processes[0].Id); config.WithOutputFileFormat(Axe.Windows.Automation.OutputFileFormat.A11yTest); config.WithOutputDirectory(reportFolder); var scanner = Axe.Windows.Automation.ScannerFactory.CreateScanner(config.Build()); try { var scanResults = scanner.Scan(); if (scanResults.ErrorCount > 0) { pagesFoundWithIssues++; } } catch (Axe.Windows.Automation.AxeWindowsAutomationException exc) { Assert.True(exc == null, exc.ToString()); } } try { var wpfTestPages = new List <string> { "wts.Wpf.Page.Blank", "wts.Wpf.Page.ListDetails", "wts.Wpf.Page.Settings", "wts.Wpf.Page.WebView", }; var appDetails = await SetUpWpfProjectForUiTestComparisonAsync(ProgrammingLanguages.CSharp, ProjectTypes.SplitView, Frameworks.MVVMLight, wpfTestPages); var exePath = Path.Combine(appDetails.ProjectPath, appDetails.ProjectName, "bin", "Release", "netcoreapp3.1", $"{appDetails.ProjectName}.exe"); using (var appSession = WinAppDriverHelper.LaunchExe(exePath)) { appSession.Manage().Window.Maximize(); await Task.Delay(TimeSpan.FromSeconds(2)); var menuItems = appSession.FindElementsByClassName("ListBoxItem"); foreach (var menuItem in menuItems) { menuItem.Click(); await Task.Delay(TimeSpan.FromMilliseconds(1500)); // Allow page to load and animations to complete ForOpenedPage(appDetails.ProjectName); } } // Don't leave the app maximized in case we want to open the app again. // Some controls handle layout differently when the app is first opened maximized VirtualKeyboard.RestoreMaximizedWindow(); } finally { WinAppDriverHelper.StopIfRunning(); } Assert.True(0 == pagesFoundWithIssues, $"Accessibility issues found. For details, see reports in '{reportFolder}'."); }
private async Task EnsureCanNavigateToEveryPageWithoutErrorAsync(string framework, string language, string projectType) { var pageIdentities = AllTestablePages(); ExecutionEnvironment.CheckRunningAsAdmin(); WinAppDriverHelper.CheckIsInstalled(); WinAppDriverHelper.StartIfNotRunning(); VisualComparisonTestDetails appDetails = null; int pagesOpenedSuccessfully = 0; try { appDetails = await SetUpProjectForUiTestComparisonAsync(language, projectType, framework, pageIdentities); using (var appSession = WinAppDriverHelper.LaunchAppx(appDetails.PackageFamilyName)) { appSession.Manage().Window.Maximize(); await Task.Delay(TimeSpan.FromSeconds(2)); var menuItems = appSession.FindElementsByClassName("ListViewItem"); foreach (var menuItem in menuItems) { menuItem.Click(); Debug.WriteLine("Opened: " + menuItem.Text); await Task.Delay(TimeSpan.FromMilliseconds(1500)); // Allow page to load and animations to complete if (menuItem.Text == "Map") { // For location permission if (await ClickYesOnPopUpAsync(appSession)) { await Task.Delay(TimeSpan.FromSeconds(2)); // Allow page to load after accepting prompt pagesOpenedSuccessfully++; } else { Assert.True(false, "Failed to click \"Yes\" on popup for Map permission."); } } else if (menuItem.Text == "Camera") { var cameraPermission = await ClickYesOnPopUpAsync(appSession); // For camera permission var microphonePermission = await ClickYesOnPopUpAsync(appSession); // For microphone permission if (cameraPermission && microphonePermission) { await Task.Delay(TimeSpan.FromSeconds(2)); // Allow page to load after accepting prompts pagesOpenedSuccessfully++; } else { Assert.True(false, "Failed to click \"Yes\" on popups for Camera page permissions."); } } else { pagesOpenedSuccessfully++; } } // Don't leave the app maximized in case we want to open the app again. // Some controls handle layout differently when the app is first opened maximized VirtualKeyboard.RestoreMaximizedWindow(); } } finally { if (appDetails != null) { UninstallAppx(appDetails.PackageFullName); RemoveCertificate(appDetails.CertificatePath); } WinAppDriverHelper.StopIfRunning(); } var expectedPageCount = pageIdentities.Length + 1; // Add 1 for"Main page" added as well by default Assert.True(expectedPageCount == pagesOpenedSuccessfully, "Not all pages were opened successfully."); }
public async Task EnsureFrameworkLaunchPageVisualsAreEquivalentAsync(string projectType, string page, string[] frameworks) { var genIdentities = new[] { page }; var noClickCount = 0; if (page == "wts.Page.Map") { noClickCount = 1; } else if (page == "wts.Page.Camera") { noClickCount = 2; } ExecutionEnvironment.CheckRunningAsAdmin(); WinAppDriverHelper.CheckIsInstalled(); // MVVMBasic is considered the reference version. Compare generated apps with equivalent in other frameworks var refAppDetails = await SetUpProjectForUiTestComparisonAsync(ProgrammingLanguages.CSharp, projectType, "MVVMBasic", genIdentities, lastPageIsHome : true, createForScreenshots : true); var otherProjDetails = new VisualComparisonTestDetails[frameworks.Length]; bool allTestsPassed = true; var outputMessages = string.Empty; for (int i = 0; i < frameworks.Length; i++) { string framework = frameworks[i]; otherProjDetails[i] = await SetUpProjectForUiTestComparisonAsync(ProgrammingLanguages.CSharp, projectType, framework, genIdentities, lastPageIsHome : true, createForScreenshots : true); var testProjectDetails = SetUpTestProjectForInitialScreenshotComparison(refAppDetails, otherProjDetails[i], GetExclusionAreasForVisualEquivalencyTest(projectType, page), noClickCount); var(testSuccess, testOutput) = RunWinAppDriverTests(testProjectDetails); if (testSuccess) { UninstallAppx(otherProjDetails[i].PackageFullName); RemoveCertificate(otherProjDetails[i].CertificatePath); // Parent of images folder also contains the test project Fs.SafeDeleteDirectory(Path.Combine(testProjectDetails.imagesFolder, "..")); } else { allTestsPassed = false; if (Directory.Exists(testProjectDetails.imagesFolder) && Directory.GetFiles(testProjectDetails.imagesFolder, "*.*-Diff.png").Any()) { outputMessages += $"Failing test images in {testProjectDetails.imagesFolder}{Environment.NewLine}{Environment.NewLine}{outputMessages}"; } else { outputMessages += $"{Environment.NewLine}{string.Join(Environment.NewLine, testOutput)}"; } } } if (allTestsPassed) { UninstallAppx(refAppDetails.PackageFullName); RemoveCertificate(refAppDetails.CertificatePath); } Assert.True(allTestsPassed, outputMessages.TrimStart()); }
public void TearDown() { WinAppDriverHelper.StopIfRunning(); }
public async Task AllTextVisibleInHighContrastModesAsync() { if (!Directory.Exists(ArtifactDir)) { Directory.CreateDirectory(ArtifactDir); } string imagePathFormat = ArtifactDir + "{0}_{1}.png"; async Task GetScreenshotImagesAsync(string identifier) { async Task TakeScreenshotThenExtractTextAsync(WindowsDriver <WindowsElement> session, string imageId) { var imgFile = string.Format(imagePathFormat, imageId, identifier); var linesFile = $"{imgFile}.lines.txt"; var wordsFile = $"{imgFile}.words.txt"; CursorHelper.MoveToTopLeftOfScreen(); // To avoid cursor being over any controls that changes their visuals session.SaveScreenshot(imgFile); if (this.testSettings.IsFreeSubscription) { // Therefore rate limited await Task.Delay(30000); // This pause to avoid querying the server too often } var(lines, words) = await CognitiveServicesHelpers.GetTextFromImageAsync(imgFile, this.testSettings.SubscriptionKey, this.testSettings.AzureRegion); File.WriteAllLines(linesFile, lines); File.WriteAllLines(wordsFile, words); } var appSession = WinAppDriverHelper.LaunchExe(PathToExe); await TakeScreenshotThenExtractTextAsync(appSession, "Settings"); appSession.FindElementByName("Profile").Click(); await Task.Delay(1000); await TakeScreenshotThenExtractTextAsync(appSession, "Profile"); appSession.FindElementByName("Mappings").Click(); await Task.Delay(1000); await TakeScreenshotThenExtractTextAsync(appSession, "Mappings"); appSession.FindElementByName("Datacontext").Click(); await Task.Delay(1000); await TakeScreenshotThenExtractTextAsync(appSession, "Datacontext"); appSession.FindElementByName("General").Click(); await Task.Delay(1000); await TakeScreenshotThenExtractTextAsync(appSession, "General"); appSession.ClickElement("Close"); } var sysSettings = new SystemSettingsHelper(); await sysSettings.TurnOffHighContrastAsync(); VirtualKeyboard.MinimizeAllWindows(); await GetScreenshotImagesAsync("normal"); await sysSettings.SwitchToHighContrastNumber1Async(); VirtualKeyboard.MinimizeAllWindows(); await GetScreenshotImagesAsync("HiContrast1"); await sysSettings.SwitchToHighContrastNumber2Async(); VirtualKeyboard.MinimizeAllWindows(); await GetScreenshotImagesAsync("HiContrast2"); await sysSettings.SwitchToHighContrastBlackAsync(); VirtualKeyboard.MinimizeAllWindows(); await GetScreenshotImagesAsync("HiContrastBlack"); await sysSettings.SwitchToHighContrastWhiteAsync(); VirtualKeyboard.MinimizeAllWindows(); await GetScreenshotImagesAsync("HiContrastWhite"); void CompareWordsText(string refIdentifier, string compIdentifier) { // These pages have text that goes beyond the TextBox bounds // - as text size changes this affects the number of lines shown which results in different text on the screen var pagesToIgnore = new[] { "Mapping", "Profile" }; foreach (var refFile in Directory.EnumerateFiles(ArtifactDir, $"*{refIdentifier}*.words.txt")) { bool skipCheck = false; foreach (var toIgnore in pagesToIgnore) { if (refFile.Contains(toIgnore)) { skipCheck = true; break; } } if (skipCheck) { continue; } var compFile = refFile.Replace(refIdentifier, compIdentifier); if (!File.Exists(compFile)) { Assert.Fail($"Expected file not found: '{compFile}'"); } else { var refText = File.ReadAllLines(refFile); var compText = File.ReadAllLines(compFile); List <string> RemoveKnownExceptions(string[] origin) { // Close and Maximize buttons are sometimes detected as text return(origin.Where(t => t != "X" && t != "O").ToList()); } var filteredRefText = RemoveKnownExceptions(refText); var filteredCompText = RemoveKnownExceptions(compText); List <string> TrimNonAlphaNumerics(List <string> origin) { string TrimNANStart(string source) { var trimIndex = 0; for (int i = 0; i < source.Length; i++) { if (char.IsLetterOrDigit(source[i])) { trimIndex = i; break; } } return(source.Substring(trimIndex)); } string TrimNANEnd(string source) { var trimIndex = -1; for (int i = source.Length - 1; i >= 0; i--) { if (char.IsLetterOrDigit(source[i])) { trimIndex = i; break; } } return(source.Substring(0, trimIndex + 1)); } return(origin.Select(o => TrimNANStart(TrimNANEnd(o))).Where(t => !string.IsNullOrWhiteSpace(t)).ToList()); } // Allow for text detection being inconsistent with punctuation var trimmedRefText = TrimNonAlphaNumerics(filteredRefText); var trimmedCompText = TrimNonAlphaNumerics(filteredCompText); List <string> AccountForKnownExceptions(List <string> origin) { string RemoveKnownSubstringExceptions(string source) { if (source.EndsWith("$()")) { return(source.Substring(0, source.Length - 3)); } if (source.EndsWith("$0")) { return(source.Substring(0, source.Length - 2)); } return(source); } return(origin.Select(t => RemoveKnownSubstringExceptions(t)).ToList()); } var testableRefText = AccountForKnownExceptions(trimmedRefText); var testableCompText = AccountForKnownExceptions(trimmedCompText); ListOfStringAssert.AssertAreEqualIgnoringOrder( testableRefText, testableCompText, caseSensitive: false, message: $"Difference between '{refFile}' and '{compFile}'."); } } } // Now we've got all images and extracted the text, actually do the comparison // It's easier to restart the tests and just do these checks if something fails. // It's also easier to have all versions available if needing to do manual checks. CompareWordsText("normal", "HiContrast1"); CompareWordsText("normal", "HiContrast2"); CompareWordsText("normal", "HiContrastBlack"); CompareWordsText("normal", "HiContrastWhite"); }
public async Task RunBasicAccessibilityChecksAgainstEachPageUwpAsync() { // This test does not run against all combinations as other tests ensure output is the same for each combination. // In theory this means that there should be no need to repeat tests as they would find the same things. // As this is a slow test to run we do not want to increase overall execution time unnecessarily. ExecutionEnvironment.CheckRunningAsAdmin(); WinAppDriverHelper.CheckIsInstalled(); WinAppDriverHelper.StartIfNotRunning(); var pagesFoundWithIssues = 0; var rootFolder = $"{Path.GetPathRoot(Environment.CurrentDirectory)}UIT\\ALLY\\{DateTime.Now:dd_HHmmss}\\"; var reportFolder = Path.Combine(rootFolder, "Reports"); var pageIdentities = AllTestablePages(Frameworks.CodeBehind); VisualComparisonTestDetails appDetails = null; async Task ForOpenedPage(string pageName, WindowsDriver <WindowsElement> session, string projectName) { if (pageName == "Map") { // For location permission if (await ClickYesOnPopUpAsync(session)) { await Task.Delay(TimeSpan.FromSeconds(2)); // Allow page to load after accepting prompt } } else if (pageName == "Camera") { var cameraPermission = await ClickYesOnPopUpAsync(session); // For camera permission var microphonePermission = await ClickYesOnPopUpAsync(session); // For microphone permission if (cameraPermission && microphonePermission) { await Task.Delay(TimeSpan.FromSeconds(2)); // Allow page to load after accepting prompts } } var processes = Process.GetProcessesByName(projectName); var config = Axe.Windows.Automation.Config.Builder.ForProcessId(processes[0].Id); config.WithOutputFileFormat(Axe.Windows.Automation.OutputFileFormat.A11yTest); config.WithOutputDirectory(reportFolder); var scanner = Axe.Windows.Automation.ScannerFactory.CreateScanner(config.Build()); try { var scanResults = scanner.Scan(); if (scanResults.ErrorCount > 0) { pagesFoundWithIssues++; } } catch (Axe.Windows.Automation.AxeWindowsAutomationException exc) { Assert.True(exc == null, exc.ToString()); } } try { appDetails = await SetUpProjectForUiTestComparisonAsync(ProgrammingLanguages.CSharp, ProjectTypes.SplitView, Frameworks.CodeBehind, pageIdentities); using (var appSession = WinAppDriverHelper.LaunchAppx(appDetails.PackageFamilyName)) { appSession.Manage().Window.Maximize(); await Task.Delay(TimeSpan.FromSeconds(2)); var menuItems = appSession.FindElementsByClassName("Microsoft.UI.Xaml.Controls.NavigationViewItem"); foreach (var menuItem in menuItems) { menuItem.Click(); await Task.Delay(TimeSpan.FromMilliseconds(1500)); // Allow page to load and animations to complete await ForOpenedPage(menuItem.Text, appSession, appDetails.ProjectName); } } // Don't leave the app maximized in case we want to open the app again. // Some controls handle layout differently when the app is first opened maximized VirtualKeyboard.RestoreMaximizedWindow(); } finally { if (appDetails != null) { UninstallAppx(appDetails.PackageFullName); RemoveCertificate(appDetails.CertificatePath); } WinAppDriverHelper.StopIfRunning(); } Assert.True(0 == pagesFoundWithIssues, $"Accessibility issues found. For details, see reports in '{reportFolder}'."); }
public void CompareScreenshotsOfAllPages() { WinAppDriverHelper.StartIfNotRunning(); if (!Directory.Exists(TestAppInfo.ScreenshotsFolder)) { Directory.CreateDirectory(TestAppInfo.ScreenshotsFolder); } // Hide other apps to all a consistent backdrop for acrylic textures VirtualKeyboard.MinimizeAllWindows(); using (var appSession1 = WinAppDriverHelper.LaunchAppx(TestAppInfo.AppPfn1)) { appSession1.Manage().Window.Maximize(); Task.Delay(TimeSpan.FromSeconds(2)).Wait(); var menuItems = appSession1.FindElementsByClassName("ListViewItem"); foreach (var menuItem in menuItems) { menuItem.Click(); Task.Delay(TimeSpan.FromMilliseconds(1500)).Wait(); // Allow page to load and animations to complete var screenshot = appSession1.GetScreenshot(); var fileName = string.Format(AppFileNameFormat, TestAppInfo.AppName1, menuItem.Text); screenshot.SaveAsFile(Path.Combine(TestAppInfo.ScreenshotsFolder, fileName), ImageFormat.Png); } // Don't leave the app maximized in case we want to open the app again. // Some controls handle layout differently when the app is first opened maximized VirtualKeyboard.RestoreMaximizedWindow(); } using (var appSession2 = WinAppDriverHelper.LaunchAppx(TestAppInfo.AppPfn2)) { appSession2.Manage().Window.Maximize(); Task.Delay(TimeSpan.FromSeconds(2)).Wait(); var menuItems = appSession2.FindElementsByClassName("ListViewItem"); foreach (var menuItem in menuItems) { menuItem.Click(); Task.Delay(TimeSpan.FromMilliseconds(1500)).Wait(); // Allow page to load and animations to complete var screenshot = appSession2.GetScreenshot(); var fileName = string.Format(AppFileNameFormat, TestAppInfo.AppName2, menuItem.Text); screenshot.SaveAsFile(Path.Combine(TestAppInfo.ScreenshotsFolder, fileName), ImageFormat.Png); } // Don't leave the app maximized in case we want to open the app again. // Some controls handle layout differently when the app is first opened maximized VirtualKeyboard.RestoreMaximizedWindow(); } var app1Images = Directory.GetFiles(TestAppInfo.ScreenshotsFolder, $"*-{TestAppInfo.AppName1}*.png"); var allImagesCount = Directory.GetFiles(TestAppInfo.ScreenshotsFolder, "*.png").Length; if (allImagesCount != app1Images.Length * 2) { Assert.Fail($"Did not produce equal number of page screenshots for each app. {TestAppInfo.ScreenshotsFolder}"); } var nonMatchingImages = new List <string>(); var toDelete = new List <string>(); foreach (var file in app1Images) { var equivFile = file.Replace(TestAppInfo.AppName1, TestAppInfo.AppName2); var imagesAreTheSame = CheckImagesAreTheSame(TestAppInfo.ScreenshotsFolder, file, equivFile); if (imagesAreTheSame) { toDelete.Add(file); toDelete.Add(equivFile); } else { nonMatchingImages.Add(equivFile); } } foreach (var fileToDelete in toDelete) { Task.Run(() => { try { File.Delete(fileToDelete); } catch (Exception) { Task.Delay(TimeSpan.FromSeconds(5)).Wait(); File.Delete(fileToDelete); } }); } Assert.IsFalse(nonMatchingImages.Any(), string.Join(Environment.NewLine, nonMatchingImages)); }
/// <summary> /// Starts the application ready for testing. /// </summary> /// <param name="opts"> /// The options to configure the driver with. /// </param> /// <exception cref="DriverLoadFailedException"> /// Thrown if the application is null or the session ID is null once initialized. /// </exception> /// <exception cref="T:Legerity.Windows.Exceptions.WinAppDriverNotFoundException">Thrown if the WinAppDriver could not be found when running with <see cref="WindowsAppManagerOptions.LaunchWinAppDriver"/> true.</exception> /// <exception cref="T:Legerity.Windows.Exceptions.WinAppDriverLoadFailedException">Thrown if the WinAppDriver failed to load when running with <see cref="WindowsAppManagerOptions.LaunchWinAppDriver"/> true.</exception> public static void StartApp(AppManagerOptions opts) { StopApp(); switch (opts) { case WebAppManagerOptions webOpts: { WebApp = webOpts.DriverType switch { WebAppDriverType.Chrome => new ChromeDriver(webOpts.DriverUri), WebAppDriverType.Firefox => new FirefoxDriver(webOpts.DriverUri), WebAppDriverType.Opera => new OperaDriver(webOpts.DriverUri), WebAppDriverType.Safari => new SafariDriver(webOpts.DriverUri), WebAppDriverType.Edge => new EdgeDriver(webOpts.DriverUri), WebAppDriverType.InternetExplorer => new InternetExplorerDriver(webOpts.DriverUri), _ => WebApp }; VerifyAppDriver(WebApp, webOpts); if (webOpts.Maximize) { WebApp.Manage().Window.Maximize(); } else { WebApp.Manage().Window.Size = webOpts.DesiredSize; } WebApp.Url = webOpts.Url; break; } case WindowsAppManagerOptions winOpts: { if (winOpts.LaunchWinAppDriver) { WinAppDriverHelper.Run(); } WebApp = new WindowsDriver <WindowsElement>( new Uri(winOpts.DriverUri), winOpts.AppiumOptions); VerifyAppDriver(WindowsApp, winOpts); if (winOpts.Maximize) { WebApp.Manage().Window.Maximize(); } break; } case AndroidAppManagerOptions androidOpts: { WebApp = new AndroidDriver <AndroidElement>( new Uri(androidOpts.DriverUri), androidOpts.AppiumOptions); VerifyAppDriver(AndroidApp, androidOpts); break; } case IOSAppManagerOptions iosOpts: { WebApp = new IOSDriver <IOSElement>(new Uri(iosOpts.DriverUri), iosOpts.AppiumOptions); VerifyAppDriver(IOSApp, iosOpts); break; } } }