Compare commits

...

9 Commits

Author SHA1 Message Date
Zhaopeng Wang (from Dev Box)
879e8fa16d add admin txt 2025-03-11 12:23:40 +08:00
Zhaopeng Wang (from Dev Box)
fe23b1c7b7 fix admin run exe error 2025-03-10 17:23:11 +08:00
Zhaopeng Wang (from Dev Box)
194da1c3ed Merge branch 'dev/zhaopengwang/fix/host-pipeline-error' of https://github.com/microsoft/PowerToys into dev/zhaopengwang/fix/host-pipeline-error 2025-03-10 17:20:17 +08:00
Zhaopeng Wang (from Dev Box)
711b1df517 add Session cleanup function 2025-03-10 17:20:02 +08:00
Xiaofeng Wang (from Dev Box)
b1cbf3b6ba Update IsTrue to alternative methods 2025-03-10 16:50:53 +08:00
Zhaopeng Wang (from Dev Box)
6fccdbf9bf add close scope exe 2025-03-10 16:24:26 +08:00
Zhaopeng Wang (from Dev Box)
5fd757995e change yml 2025-03-10 14:50:35 +08:00
Zhaopeng Wang (from Dev Box)
1b14667390 test file change 2025-03-10 14:44:12 +08:00
Zhaopeng Wang (from Dev Box)
f0d2c209e3 fix UITestCleanup error 2025-03-10 14:40:00 +08:00
7 changed files with 145 additions and 56 deletions

View File

@@ -1,55 +1,51 @@
pr: none
trigger: none
trigger:
batch: true
branches:
include:
- main
- stable
# paths:
# exclude:
# - doc/*
# - temp/*
# - tools/*
# - '**.md'
pr:
branches:
include:
- main
- stable
# paths:
# exclude:
# - '**.md'
# - doc
schedules:
- cron: "0 0 * * 1"
displayName: Weekly fuzzing submission
branches:
include:
- main
always: true
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
parameters:
- name: platform
type: string
default: x64 # for fuzzing, we only use x64 for now
- name: buildPlatforms
type: object
default:
- x64
- arm64
- name: enableMsBuildCaching
type: boolean
displayName: "Enable MSBuild Caching"
default: false
- name: runTests
type: boolean
displayName: "Run Tests"
default: true
- name: useVSPreview
type: boolean
displayName: "Build Using Visual Studio Preview"
default: false
stages:
- stage: Build_${{ parameters.platform }}
displayName: Build ${{ parameters.platform }}
jobs:
- template: templates/job-build-project.yml
parameters:
pool:
${{ if eq(variables['System.CollectionId'], 'cb55739e-4afe-46a3-970f-1b49d8ee7564') }}:
name: SHINE-INT-L
${{ else }}:
name: SHINE-OSS-L
${{ if eq(parameters.useVSPreview, true) }}:
demands: ImageOverride -equals SHINE-VS17-Preview
buildPlatforms:
- ${{ parameters.platform }}
buildConfigurations: [Release]
enablePackageCaching: true
enableMsBuildCaching: ${{ parameters.enableMsBuildCaching }}
runTests: true
useVSPreview: ${{ parameters.useVSPreview }}
- stage: OneFuzz
displayName: Fuzz ${{ parameters.platform }}
dependsOn:
- Build_${{parameters.platform}}
jobs:
- template: templates/job-fuzz.yml
parameters:
platform: ${{ parameters.platform }}
configuration: Release
extends:
template: templates/pipeline-ci-build.yml
parameters:
buildPlatforms: ${{ parameters.buildPlatforms }}
enableMsBuildCaching: ${{ parameters.enableMsBuildCaching }}
runTests: ${{ parameters.runTests }}
useVSPreview: ${{ parameters.useVSPreview }}

View File

@@ -102,7 +102,6 @@ jobs:
uiTests: true
rerunFailedTests: true
testAssemblyVer2: |
**\UITests-FancyZones.dll
**\UITests-FancyZonesEditor.dll
**\*UITest*.dll
!**\obj\**
!**\ref\**

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -20,6 +21,8 @@ namespace Microsoft.PowerToys.UITest
private WindowsDriver<WindowsElement> WindowsDriver { get; set; }
private List<nint> windowList = new List<nint>();
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(nint hWnd);
@@ -29,6 +32,29 @@ namespace Microsoft.PowerToys.UITest
this.WindowsDriver = windowsDriver;
}
/// <summary>
/// Cleans up the Session Exe.
/// </summary>
public void Cleanup()
{
for (var i = 0; i < this.windowList.Count; i++)
{
var windowHandle = this.windowList[i];
if (windowHandle != 0)
{
var process = Process.GetProcessById((int)windowHandle);
if (process != null)
{
process.Kill();
process.WaitForExit();
}
}
}
windowList.Clear();
}
/// <summary>
/// Finds an element by selector.
/// </summary>
@@ -44,7 +70,7 @@ namespace Microsoft.PowerToys.UITest
// leverage findAll to filter out mismatched elements
var collection = this.FindAll<T>(by, timeoutMS);
Assert.IsTrue(collection.Count > 0, $"Element not found using selector: {by}");
Assert.AreNotEqual(0, collection.Count, $"Element not found using selector: {by}");
return collection[0];
}
@@ -166,7 +192,12 @@ namespace Microsoft.PowerToys.UITest
{
if (this.Root != null)
{
var window = this.Root.FindElementByName(windowName);
var window = this.Root.FindElementByName("Administrator: " + windowName);
if (window == null)
{
window = this.Root.FindElementByName(windowName);
}
Assert.IsNotNull(window, $"Failed to attach. Window '{windowName}' not found");
var windowHandle = new nint(int.Parse(window.GetAttribute("NativeWindowHandle")));
@@ -179,6 +210,8 @@ namespace Microsoft.PowerToys.UITest
this.WindowsDriver = new WindowsDriver<WindowsElement>(new Uri(ModuleConfigData.Instance.GetWindowsApplicationDriverUrl()), appCapabilities);
Assert.IsNotNull(this.WindowsDriver, "Attach WindowsDriver is null");
this.windowList.Add(windowHandle);
// Set implicit timeout to make element search retry every 500 ms
this.WindowsDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(3);
}

View File

@@ -35,6 +35,7 @@ namespace Microsoft.PowerToys.UITest
Verb = "runas",
};
this.ExitExe(winAppDriverProcessInfo.FileName);
this.appDriver = Process.Start(winAppDriverProcessInfo);
var desktopCapabilities = new AppiumOptions();
@@ -53,6 +54,7 @@ namespace Microsoft.PowerToys.UITest
public SessionHelper Init()
{
string? path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
this.ExitExe(path + this.sessionPath);
this.StartExe(path + this.sessionPath);
Assert.IsNotNull(this.Driver, $"Failed to initialize the test environment. Driver is null.");
@@ -68,9 +70,11 @@ namespace Microsoft.PowerToys.UITest
/// </summary>
public void Cleanup()
{
this.ExitScopeExe();
try
{
appDriver?.Kill();
appDriver?.WaitForExit();
}
catch (Exception ex)
{
@@ -79,6 +83,39 @@ namespace Microsoft.PowerToys.UITest
}
}
/// <summary>
/// Exit a exe.
/// </summary>
/// <param name="path">The path to the application executable.</param>
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}");
}
}
}
/// <summary>
/// Exit now exe.
/// </summary>
public void ExitScopeExe()
{
this.ExitExe(sessionPath);
}
/// <summary>
/// Starts a new exe and takes control of it.
/// </summary>

View File

@@ -31,11 +31,6 @@ namespace Microsoft.PowerToys.UITest
this.Session = new Session(this.sessionHelper.GetRoot(), this.sessionHelper.GetDriver());
}
~UITestBase()
{
this.sessionHelper.Cleanup();
}
/// <summary>
/// Initializes the test.
/// </summary>
@@ -53,6 +48,16 @@ namespace Microsoft.PowerToys.UITest
}
}
/// <summary>
/// Initializes the test.
/// </summary>
[TestCleanup]
public void TestCleanup()
{
this.Session.Cleanup();
this.sessionHelper.Cleanup();
}
/// <summary>
/// Finds an element by selector.
/// Shortcut for this.Session.Find<T>(by, timeoutMS)

View File

@@ -125,8 +125,9 @@ namespace Hosts.UITests
// Add new URL override and a warning tip should be shown
this.AddEntry("192.168.0.1", "localhost", true);
Assert.IsTrue(
this.FindAll<TextBlock>("The hosts file cannot be saved because the program isn't running as administrator.").Count == 1,
Assert.AreEqual(
1,
this.FindAll<TextBlock>("The hosts file cannot be saved because the program isn't running as administrator.").Count,
"Should display host-file saving error if not run as administrator");
}

View File

@@ -68,7 +68,13 @@ namespace Hosts.UITests
Assert.IsFalse(this.IsHostsFileEditorClosed(), "Hosts File Editor should NOT be closed after click Accept button in Warning Dialog");
// Close Hosts File Editor window
this.Session.Find<Window>("Hosts File Editor").Close();
var hostWindow = this.FindAll<Window>("Hosts File Editor");
if (hostWindow.Count == 0)
{
hostWindow = this.FindAll<Window>("Administrator: Hosts File Editor");
}
hostWindow[0].Close();
// Restore back to PowerToysSettings Session
this.Session.Attach(PowerToysModule.PowerToysSettings);
@@ -82,7 +88,13 @@ namespace Hosts.UITests
Assert.IsFalse(this.IsHostsFileEditorClosed(), "Hosts File Editor should NOT be closed");
// Close Hosts File Editor window
this.Session.Find<Window>("Hosts File Editor").Close();
hostWindow = this.FindAll<Window>("Hosts File Editor");
if (hostWindow.Count == 0)
{
hostWindow = this.FindAll<Window>("Administrator: Hosts File Editor");
}
hostWindow[0].Close();
// Restore back to PowerToysSettings Session
this.Session.Attach(PowerToysModule.PowerToysSettings);
@@ -112,7 +124,13 @@ namespace Hosts.UITests
this.Find<NavigationViewItem>("Advanced").Click();
}
this.Find<NavigationViewItem>("Hosts File Editor").Click();
var hostWindow = this.FindAll<Window>("Hosts File Editor");
if (hostWindow.Count == 0)
{
hostWindow = this.FindAll<Window>("Administrator: Hosts File Editor");
}
hostWindow[0].Click();
this.Find<ToggleSwitch>("Enable Hosts File Editor").Toggle(true);
this.Find<ToggleSwitch>("Launch as administrator").Toggle(launchAsAdmin);