mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 09:28:03 +08:00
move attach to session.cs
This commit is contained in:
parent
30e32a895a
commit
c91ef00113
@ -11,7 +11,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OpenQA.Selenium.Appium;
|
||||
using OpenQA.Selenium.Appium.Windows;
|
||||
using OpenQA.Selenium.Interactions;
|
||||
using static Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext;
|
||||
using static Microsoft.PowerToys.UITest.WindowHelper;
|
||||
|
||||
namespace Microsoft.PowerToys.UITest
|
||||
@ -23,17 +22,12 @@ namespace Microsoft.PowerToys.UITest
|
||||
{
|
||||
public WindowsDriver<WindowsElement> Root { get; set; }
|
||||
|
||||
private WindowsDriver<WindowsElement> WindowsDriver
|
||||
{
|
||||
get { return sessionHelper.GetDriver(); }
|
||||
}
|
||||
private WindowsDriver<WindowsElement> WindowsDriver { get; set; }
|
||||
|
||||
private List<IntPtr> windowHandlers = new List<IntPtr>();
|
||||
|
||||
private Window? MainWindow { get; set; }
|
||||
|
||||
private SessionHelper sessionHelper;
|
||||
|
||||
/// <summary>
|
||||
/// Gets Main Window Handler
|
||||
/// </summary>
|
||||
@ -52,17 +46,17 @@ namespace Microsoft.PowerToys.UITest
|
||||
/// </summary>
|
||||
public bool? IsElevated { get; private set; }
|
||||
|
||||
public Session(SessionHelper pSessionHelper)
|
||||
public Session(WindowsDriver<WindowsElement> pRoot, WindowsDriver<WindowsElement> pDriver, PowerToysModule scope, WindowSize size)
|
||||
{
|
||||
this.MainWindowHandler = IntPtr.Zero;
|
||||
this.Root = pSessionHelper.GetRoot();
|
||||
this.InitScope = pSessionHelper.Scope;
|
||||
this.sessionHelper = pSessionHelper;
|
||||
this.Root = pRoot;
|
||||
this.WindowsDriver = pDriver;
|
||||
this.InitScope = scope;
|
||||
|
||||
if (pSessionHelper.Size != WindowSize.UnSpecified)
|
||||
if (size != WindowSize.UnSpecified)
|
||||
{
|
||||
// Attach to the scope & reset MainWindowHandler
|
||||
this.Attach(pSessionHelper.Scope, pSessionHelper.Size);
|
||||
this.Attach(scope, size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -482,11 +476,63 @@ namespace Microsoft.PowerToys.UITest
|
||||
{
|
||||
this.IsElevated = null;
|
||||
this.MainWindowHandler = IntPtr.Zero;
|
||||
var windowHandleInfo = sessionHelper.Attach(windowName, size);
|
||||
this.MainWindow = this.Find<Window>(windowHandleInfo.MainWindowTitle);
|
||||
this.MainWindowHandler = windowHandleInfo.MainWindowHandler;
|
||||
this.IsElevated = windowHandleInfo.IsElevated;
|
||||
this.windowHandlers.Add(this.MainWindowHandler);
|
||||
|
||||
if (this.Root != null)
|
||||
{
|
||||
// search window handler by window title (admin and non-admin titles)
|
||||
var timeout = TimeSpan.FromMinutes(2);
|
||||
var retryInterval = TimeSpan.FromSeconds(5);
|
||||
DateTime startTime = DateTime.Now;
|
||||
|
||||
List<(IntPtr HWnd, string Title)>? matchingWindows = null;
|
||||
|
||||
while (DateTime.Now - startTime < timeout)
|
||||
{
|
||||
matchingWindows = WindowHelper.ApiHelper.FindDesktopWindowHandler(
|
||||
new[] { windowName, WindowHelper.AdministratorPrefix + windowName });
|
||||
|
||||
if (matchingWindows.Count > 0 && matchingWindows[0].HWnd != IntPtr.Zero)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Task.Delay(retryInterval).Wait();
|
||||
}
|
||||
|
||||
if (matchingWindows == null || matchingWindows.Count == 0 || matchingWindows[0].HWnd == IntPtr.Zero)
|
||||
{
|
||||
Assert.Fail($"Failed to attach. Window '{windowName}' not found after {timeout.TotalSeconds} seconds.");
|
||||
}
|
||||
|
||||
// pick one from matching windows
|
||||
this.MainWindowHandler = matchingWindows[0].HWnd;
|
||||
this.IsElevated = matchingWindows[0].Title.StartsWith(WindowHelper.AdministratorPrefix);
|
||||
|
||||
ApiHelper.SetForegroundWindow(this.MainWindowHandler);
|
||||
|
||||
var hexWindowHandle = this.MainWindowHandler.ToInt64().ToString("x");
|
||||
|
||||
var appCapabilities = new AppiumOptions();
|
||||
appCapabilities.AddAdditionalCapability("appTopLevelWindow", hexWindowHandle);
|
||||
appCapabilities.AddAdditionalCapability("deviceName", "WindowsPC");
|
||||
this.WindowsDriver = new WindowsDriver<WindowsElement>(new Uri(ModuleConfigData.Instance.GetWindowsApplicationDriverUrl()), appCapabilities);
|
||||
|
||||
this.windowHandlers.Add(this.MainWindowHandler);
|
||||
|
||||
if (size != WindowSize.UnSpecified)
|
||||
{
|
||||
WindowHelper.SetWindowSize(this.MainWindowHandler, size);
|
||||
}
|
||||
|
||||
// Set MainWindow
|
||||
MainWindow = Find<Window>(matchingWindows[0].Title);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsNotNull(this.Root, $"Failed to attach to the window '{windowName}'. Root driver is null");
|
||||
}
|
||||
|
||||
Task.Delay(3000).Wait();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -523,6 +569,35 @@ namespace Microsoft.PowerToys.UITest
|
||||
return WindowHelper.GetWindowRect(this.MainWindowHandler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches the specified executable with optional arguments and simulates a delay before and after execution.
|
||||
/// </summary>
|
||||
/// <param name="executablePath">The full path to the executable to launch.</param>
|
||||
/// <param name="arguments">Optional command-line arguments to pass to the executable.</param>
|
||||
/// <param name="msPreAction">The number of milliseconds to wait before launching the executable. Default is 0 ms.</param>
|
||||
/// <param name="msPostAction">The number of milliseconds to wait after launching the executable. Default is 2000 ms.</param>
|
||||
public void StartExe(string executablePath, string arguments = "", int msPreAction = 0, int msPostAction = 2000)
|
||||
{
|
||||
PerformAction(
|
||||
() =>
|
||||
{
|
||||
StartExeInternal(executablePath, arguments);
|
||||
},
|
||||
msPreAction,
|
||||
msPostAction);
|
||||
}
|
||||
|
||||
private void StartExeInternal(string executablePath, string arguments = "")
|
||||
{
|
||||
var processInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = executablePath,
|
||||
Arguments = arguments,
|
||||
UseShellExecute = true,
|
||||
};
|
||||
Process.Start(processInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Terminates all running processes that match the specified process name.
|
||||
/// Waits for each process to exit after sending the kill signal.
|
||||
|
@ -32,15 +32,12 @@ namespace Microsoft.PowerToys.UITest
|
||||
private Process? appDriver;
|
||||
private Process? runner;
|
||||
|
||||
public PowerToysModule Scope { get; private set; }
|
||||
|
||||
public WindowSize Size { get; private set; }
|
||||
private PowerToysModule scope;
|
||||
|
||||
[UnconditionalSuppressMessage("SingleFile", "IL3000:Avoid accessing Assembly file path when publishing as a single file", Justification = "<Pending>")]
|
||||
public SessionHelper(PowerToysModule scope, WindowSize size)
|
||||
public SessionHelper(PowerToysModule scope)
|
||||
{
|
||||
this.Scope = scope;
|
||||
this.Size = size;
|
||||
this.scope = scope;
|
||||
this.sessionPath = ModuleConfigData.Instance.GetModulePath(scope);
|
||||
this.locationPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
|
||||
@ -88,7 +85,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
{
|
||||
appDriver?.Kill();
|
||||
appDriver?.WaitForExit(); // Optional: Wait for the process to exit
|
||||
if (this.Scope == PowerToysModule.PowerToysSettings)
|
||||
if (this.scope == PowerToysModule.PowerToysSettings)
|
||||
{
|
||||
runner?.Kill();
|
||||
runner?.WaitForExit(); // Optional: Wait for the process to exit
|
||||
@ -167,23 +164,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start scope exe.
|
||||
/// </summary>
|
||||
public void StartScopeExe()
|
||||
{
|
||||
var processInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = this.locationPath + this.sessionPath,
|
||||
Arguments = string.Empty,
|
||||
UseShellExecute = true,
|
||||
};
|
||||
Process.Start(processInfo);
|
||||
string windowName = ModuleConfigData.Instance.GetModuleWindowName(this.Scope);
|
||||
var windowHandleInfo = this.Attach(windowName, this.Size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exit scope exe.
|
||||
/// Exit now exe.
|
||||
/// </summary>
|
||||
public void ExitScopeExe()
|
||||
{
|
||||
@ -201,7 +182,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
public void RestartScopeExe()
|
||||
{
|
||||
ExitScopeExe();
|
||||
StartScopeExe();
|
||||
StartExe(locationPath + sessionPath);
|
||||
}
|
||||
|
||||
public WindowsDriver<WindowsElement> GetRoot() => this.Root;
|
||||
@ -223,78 +204,5 @@ namespace Microsoft.PowerToys.UITest
|
||||
this.ExitExe(winAppDriverProcessInfo.FileName);
|
||||
this.appDriver = Process.Start(winAppDriverProcessInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches to an existing exe by string window name.
|
||||
/// The session should be attached when a new app is started.
|
||||
/// </summary>
|
||||
/// <param name="windowName">The window name to attach to.</param>
|
||||
/// <param name="size">The window size to set. Default is no change to window size</param>
|
||||
public WindowHandleInfo Attach(string windowName, WindowSize size = WindowSize.UnSpecified)
|
||||
{
|
||||
WindowHandleInfo res = new WindowHandleInfo { };
|
||||
if (this.Root != null)
|
||||
{
|
||||
// search window handler by window title (admin and non-admin titles)
|
||||
var timeout = TimeSpan.FromMinutes(2);
|
||||
var retryInterval = TimeSpan.FromSeconds(5);
|
||||
DateTime startTime = DateTime.Now;
|
||||
|
||||
List<(IntPtr HWnd, string Title)>? matchingWindows = null;
|
||||
|
||||
while (DateTime.Now - startTime < timeout)
|
||||
{
|
||||
matchingWindows = WindowHelper.ApiHelper.FindDesktopWindowHandler(
|
||||
new[] { windowName, WindowHelper.AdministratorPrefix + windowName });
|
||||
|
||||
if (matchingWindows.Count > 0 && matchingWindows[0].HWnd != IntPtr.Zero)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Task.Delay(retryInterval).Wait();
|
||||
}
|
||||
|
||||
if (matchingWindows == null || matchingWindows.Count == 0 || matchingWindows[0].HWnd == IntPtr.Zero)
|
||||
{
|
||||
Assert.Fail($"Failed to attach. Window '{windowName}' not found after {timeout.TotalSeconds} seconds.");
|
||||
}
|
||||
|
||||
// pick one from matching windows
|
||||
res.MainWindowHandler = matchingWindows[0].HWnd;
|
||||
res.MainWindowTitle = matchingWindows[0].Title;
|
||||
res.IsElevated = matchingWindows[0].Title.StartsWith(WindowHelper.AdministratorPrefix);
|
||||
|
||||
ApiHelper.SetForegroundWindow(res.MainWindowHandler);
|
||||
|
||||
var hexWindowHandle = res.MainWindowHandler.ToInt64().ToString("x");
|
||||
|
||||
var appCapabilities = new AppiumOptions();
|
||||
appCapabilities.AddAdditionalCapability("appTopLevelWindow", hexWindowHandle);
|
||||
appCapabilities.AddAdditionalCapability("deviceName", "WindowsPC");
|
||||
this.Driver = new WindowsDriver<WindowsElement>(new Uri(ModuleConfigData.Instance.GetWindowsApplicationDriverUrl()), appCapabilities);
|
||||
|
||||
if (size != WindowSize.UnSpecified)
|
||||
{
|
||||
WindowHelper.SetWindowSize(res.MainWindowHandler, size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsNotNull(this.Root, $"Failed to attach to the window '{windowName}'. Root driver is null");
|
||||
}
|
||||
|
||||
Task.Delay(3000).Wait();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public struct WindowHandleInfo
|
||||
{
|
||||
public IntPtr MainWindowHandler { get; set; }
|
||||
|
||||
public string MainWindowTitle { get; set; }
|
||||
|
||||
public bool IsElevated { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +75,8 @@ namespace Microsoft.PowerToys.UITest
|
||||
System.Windows.Forms.SendKeys.SendWait("{ESC}");
|
||||
}
|
||||
|
||||
this.sessionHelper = new SessionHelper(scope, size).Init();
|
||||
this.Session = new Session(this.sessionHelper);
|
||||
this.sessionHelper = new SessionHelper(scope).Init();
|
||||
this.Session = new Session(this.sessionHelper.GetRoot(), this.sessionHelper.GetDriver(), scope, size);
|
||||
|
||||
if (this.scope == PowerToysModule.PowerToysSettings)
|
||||
{
|
||||
@ -447,7 +447,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
public void RestartScopeExe()
|
||||
{
|
||||
this.sessionHelper!.RestartScopeExe();
|
||||
this.Session = new Session(sessionHelper);
|
||||
this.Session = new Session(this.sessionHelper.GetRoot(), this.sessionHelper.GetDriver(), this.scope, this.size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user