// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; using OpenQA.Selenium.Appium; using OpenQA.Selenium.Appium.Windows; namespace Microsoft.PowerToys.UITest { /// /// Nested class for test initialization. /// internal class SessionHelper { // Default session path is PowerToys settings dashboard private readonly string sessionPath = ModuleConfigData.Instance.GetModulePath(PowerToysModule.PowerToysSettings); private string? locationPath; private WindowsDriver Root { get; set; } private WindowsDriver? Driver { get; set; } private Process? appDriver; [UnconditionalSuppressMessage("SingleFile", "IL3000:Avoid accessing Assembly file path when publishing as a single file", Justification = "")] public SessionHelper(PowerToysModule scope) { this.sessionPath = ModuleConfigData.Instance.GetModulePath(scope); this.locationPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var winAppDriverProcessInfo = new ProcessStartInfo { FileName = "C:\\Program Files (x86)\\Windows Application Driver\\WinAppDriver.exe", Verb = "runas", }; this.appDriver = Process.Start(winAppDriverProcessInfo); var desktopCapabilities = new AppiumOptions(); desktopCapabilities.AddAdditionalCapability("app", "Root"); this.Root = new WindowsDriver(new Uri(ModuleConfigData.Instance.GetWindowsApplicationDriverUrl()), desktopCapabilities); // Set default timeout to 5 seconds this.Root.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5); } /// /// Initializes the test environment. /// /// The PowerToys module to start. public SessionHelper Init() { this.StartExe(locationPath + this.sessionPath); Assert.IsNotNull(this.Driver, $"Failed to initialize the test environment. Driver is null."); return this; } /// /// Cleans up the test environment. /// public void Cleanup() { ExitScopeExe(); try { appDriver?.Kill(); appDriver?.WaitForExit(); // Optional: Wait for the process to exit } catch (Exception ex) { // Handle exceptions if needed Debug.WriteLine($"Exception during Cleanup: {ex.Message}"); } } /// /// Starts a new exe and takes control of it. /// /// The path to the application executable. public void StartExe(string appPath) { var opts = new AppiumOptions(); opts.AddAdditionalCapability("app", appPath); Console.WriteLine($"appPath: {appPath}"); this.Driver = new WindowsDriver(new Uri(ModuleConfigData.Instance.GetWindowsApplicationDriverUrl()), opts); // Set default timeout to 5 seconds this.Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5); } /// /// Exit a exe. /// /// The path to the application executable. public void ExitExe(string path) { // Exit Exe string exeName = Path.GetFileNameWithoutExtension(path); // PowerToys.FancyZonesEditor Process[] processes = Process.GetProcessesByName(exeName); foreach (Process process in processes) { try { process.Kill(); process.WaitForExit(); // Optional: Wait for the process to exit } catch (Exception ex) { Assert.Fail($"Failed to terminate process {process.ProcessName} (ID: {process.Id}): {ex.Message}"); } } } /// /// Exit now exe. /// public void ExitScopeExe() { ExitExe(sessionPath); } /// /// Restarts now exe and takes control of it. /// public void RestartScopeExe() { ExitExe(sessionPath); StartExe(locationPath + sessionPath); } public WindowsDriver GetRoot() => this.Root; public WindowsDriver GetDriver() { Assert.IsNotNull(this.Driver, $"Failed to get driver. Driver is null."); return this.Driver; } } }