2025-02-20 13:25:20 +08:00
|
|
|
|
// 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.Collections.ObjectModel;
|
|
|
|
|
|
using System.Diagnostics;
|
2025-06-17 17:56:48 +08:00
|
|
|
|
using System.Runtime.InteropServices;
|
2025-02-20 13:25:20 +08:00
|
|
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
2025-06-17 17:56:48 +08:00
|
|
|
|
using OpenQA.Selenium;
|
2025-02-20 13:25:20 +08:00
|
|
|
|
|
|
|
|
|
|
namespace Microsoft.PowerToys.UITest
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Base class that should be inherited by all Test Classes.
|
|
|
|
|
|
/// </summary>
|
2025-02-28 03:08:08 -08:00
|
|
|
|
[TestClass]
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public class UITestBase : IDisposable
|
2025-02-20 13:25:20 +08:00
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public required TestContext TestContext { get; set; }
|
2025-02-20 13:25:20 +08:00
|
|
|
|
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public required Session Session { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsInPipeline { get; }
|
|
|
|
|
|
|
[UI tests] Add full UI test coverage for Peek based on release checklist (#40734)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Add full UI test coverage for Peek based on release checklist
### Peek
* Open different files to check that they're shown properly
- [x] Image
- [x] Text or dev file
- [x] Markdown file
- [ ] PDF
- [x] Archive files (.zip, .tar, .rar)
- [x] Any other not mentioned file (.exe for example) to verify the
unsupported file view is shown
* Pinning/unpinning
- [x] Pin the window, switch between images of different size, verify
the window stays at the same place and the same size.
- [x] Pin the window, close and reopen Peek, verify the new window is
opened at the same place and the same size as before.
- [x] Unpin the window, switch to a different file, verify the window is
moved to the default place.
- [x] Unpin the window, close and reopen Peek, verify the new window is
opened on the default place.
* Open with a default program
- [x] By clicking a button.
- [x] By pressing enter.
- [x] Switch between files in the folder using `LeftArrow` and
`RightArrow`, verify you can switch between all files in the folder.
- [x] Open multiple files, verify you can switch only between selected
files.
<img width="519" height="266" alt="image"
src="https://github.com/user-attachments/assets/f27c555d-9939-476f-9ecc-50d598285aef"
/>
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] **Closes:**
#[40676](https://github.com/microsoft/PowerToys/issues/40676)
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-07-22 09:00:39 +08:00
|
|
|
|
public string? ScreenshotDirectory { get; set; }
|
|
|
|
|
|
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public static MonitorInfoData.ParamsWrapper MonitorInfoData { get; set; } = new MonitorInfoData.ParamsWrapper() { Monitors = new List<MonitorInfoData.MonitorInfoDataWrapper>() };
|
2025-02-28 03:08:08 -08:00
|
|
|
|
|
|
|
|
|
|
private readonly PowerToysModule scope;
|
2025-06-17 17:56:48 +08:00
|
|
|
|
private readonly WindowSize size;
|
2025-07-09 14:32:40 +08:00
|
|
|
|
private readonly string[]? commandLineArgs;
|
2025-06-17 17:56:48 +08:00
|
|
|
|
private SessionHelper? sessionHelper;
|
|
|
|
|
|
private System.Threading.Timer? screenshotTimer;
|
2025-02-20 13:25:20 +08:00
|
|
|
|
|
2025-07-09 14:32:40 +08:00
|
|
|
|
public UITestBase(PowerToysModule scope = PowerToysModule.PowerToysSettings, WindowSize size = WindowSize.UnSpecified, string[]? commandLineArgs = null)
|
2025-02-20 13:25:20 +08:00
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
this.IsInPipeline = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("platform"));
|
|
|
|
|
|
Console.WriteLine($"Running tests on platform: {Environment.GetEnvironmentVariable("platform")}");
|
|
|
|
|
|
if (IsInPipeline)
|
|
|
|
|
|
{
|
|
|
|
|
|
NativeMethods.ChangeDisplayResolution(1920, 1080);
|
|
|
|
|
|
NativeMethods.GetMonitorInfo();
|
|
|
|
|
|
|
|
|
|
|
|
// Escape Popups before starting
|
|
|
|
|
|
System.Windows.Forms.SendKeys.SendWait("{ESC}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-28 03:08:08 -08:00
|
|
|
|
this.scope = scope;
|
2025-06-17 17:56:48 +08:00
|
|
|
|
this.size = size;
|
2025-07-09 14:32:40 +08:00
|
|
|
|
this.commandLineArgs = commandLineArgs;
|
2025-02-20 13:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Initializes the test.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[TestInitialize]
|
|
|
|
|
|
public void TestInit()
|
|
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
CloseOtherApplications();
|
|
|
|
|
|
if (IsInPipeline)
|
|
|
|
|
|
{
|
[UI tests] Add full UI test coverage for Peek based on release checklist (#40734)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Add full UI test coverage for Peek based on release checklist
### Peek
* Open different files to check that they're shown properly
- [x] Image
- [x] Text or dev file
- [x] Markdown file
- [ ] PDF
- [x] Archive files (.zip, .tar, .rar)
- [x] Any other not mentioned file (.exe for example) to verify the
unsupported file view is shown
* Pinning/unpinning
- [x] Pin the window, switch between images of different size, verify
the window stays at the same place and the same size.
- [x] Pin the window, close and reopen Peek, verify the new window is
opened at the same place and the same size as before.
- [x] Unpin the window, switch to a different file, verify the window is
moved to the default place.
- [x] Unpin the window, close and reopen Peek, verify the new window is
opened on the default place.
* Open with a default program
- [x] By clicking a button.
- [x] By pressing enter.
- [x] Switch between files in the folder using `LeftArrow` and
`RightArrow`, verify you can switch between all files in the folder.
- [x] Open multiple files, verify you can switch only between selected
files.
<img width="519" height="266" alt="image"
src="https://github.com/user-attachments/assets/f27c555d-9939-476f-9ecc-50d598285aef"
/>
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] **Closes:**
#[40676](https://github.com/microsoft/PowerToys/issues/40676)
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-07-22 09:00:39 +08:00
|
|
|
|
ScreenshotDirectory = Path.Combine(this.TestContext.TestResultsDirectory ?? string.Empty, "UITestScreenshots_" + Guid.NewGuid().ToString());
|
|
|
|
|
|
Directory.CreateDirectory(ScreenshotDirectory);
|
2025-06-17 17:56:48 +08:00
|
|
|
|
|
|
|
|
|
|
// Take screenshot every 1 second
|
[UI tests] Add full UI test coverage for Peek based on release checklist (#40734)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Add full UI test coverage for Peek based on release checklist
### Peek
* Open different files to check that they're shown properly
- [x] Image
- [x] Text or dev file
- [x] Markdown file
- [ ] PDF
- [x] Archive files (.zip, .tar, .rar)
- [x] Any other not mentioned file (.exe for example) to verify the
unsupported file view is shown
* Pinning/unpinning
- [x] Pin the window, switch between images of different size, verify
the window stays at the same place and the same size.
- [x] Pin the window, close and reopen Peek, verify the new window is
opened at the same place and the same size as before.
- [x] Unpin the window, switch to a different file, verify the window is
moved to the default place.
- [x] Unpin the window, close and reopen Peek, verify the new window is
opened on the default place.
* Open with a default program
- [x] By clicking a button.
- [x] By pressing enter.
- [x] Switch between files in the folder using `LeftArrow` and
`RightArrow`, verify you can switch between all files in the folder.
- [x] Open multiple files, verify you can switch only between selected
files.
<img width="519" height="266" alt="image"
src="https://github.com/user-attachments/assets/f27c555d-9939-476f-9ecc-50d598285aef"
/>
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] **Closes:**
#[40676](https://github.com/microsoft/PowerToys/issues/40676)
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-07-22 09:00:39 +08:00
|
|
|
|
screenshotTimer = new System.Threading.Timer(ScreenCapture.TimerCallback, ScreenshotDirectory, TimeSpan.Zero, TimeSpan.FromMilliseconds(1000));
|
2025-06-17 17:56:48 +08:00
|
|
|
|
|
|
|
|
|
|
// Escape Popups before starting
|
|
|
|
|
|
System.Windows.Forms.SendKeys.SendWait("{ESC}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-09 14:32:40 +08:00
|
|
|
|
this.sessionHelper = new SessionHelper(scope, commandLineArgs).Init();
|
2025-06-17 17:56:48 +08:00
|
|
|
|
this.Session = new Session(this.sessionHelper.GetRoot(), this.sessionHelper.GetDriver(), scope, size);
|
2025-02-20 13:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-14 17:04:23 +08:00
|
|
|
|
/// <summary>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// Cleanups the test.
|
2025-03-14 17:04:23 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
[TestCleanup]
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public void TestCleanup()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsInPipeline)
|
|
|
|
|
|
{
|
|
|
|
|
|
screenshotTimer?.Change(Timeout.Infinite, Timeout.Infinite);
|
|
|
|
|
|
Dispose();
|
|
|
|
|
|
if (TestContext.CurrentTestOutcome is UnitTestOutcome.Failed
|
|
|
|
|
|
or UnitTestOutcome.Error
|
|
|
|
|
|
or UnitTestOutcome.Unknown)
|
|
|
|
|
|
{
|
|
|
|
|
|
Task.Delay(1000).Wait();
|
|
|
|
|
|
AddScreenShotsToTestResultsDirectory();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.Session.Cleanup();
|
|
|
|
|
|
this.sessionHelper!.Cleanup();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
2025-03-14 17:04:23 +08:00
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
screenshotTimer?.Dispose();
|
|
|
|
|
|
GC.SuppressFinalize(this);
|
2025-03-14 17:04:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-24 02:05:55 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Finds an element by selector.
|
|
|
|
|
|
/// Shortcut for this.Session.Find<T>(by, timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T">The class of the element, should be Element or its derived class.</typeparam>
|
|
|
|
|
|
/// <param name="by">The selector to find the element.</param>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
2025-02-24 02:05:55 -08:00
|
|
|
|
/// <returns>The found element.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
protected T Find<T>(By by, int timeoutMS = 5000, bool global = false)
|
2025-02-24 02:05:55 -08:00
|
|
|
|
where T : Element, new()
|
|
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
return this.Session.Find<T>(by, timeoutMS, global);
|
2025-02-24 02:05:55 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <summary>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// Shortcut for this.Session.Find<Element>(name, timeoutMS)
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T">The class of the element, should be Element or its derived class.</typeparam>
|
|
|
|
|
|
/// <param name="name">The name of the element.</param>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <returns>The found element.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
protected T Find<T>(string name, int timeoutMS = 5000, bool global = false)
|
2025-02-28 03:08:08 -08:00
|
|
|
|
where T : Element, new()
|
|
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
return this.Session.Find<T>(By.Name(name), timeoutMS, global);
|
2025-02-28 03:08:08 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Shortcut for this.Session.Find<Element>(by, timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="by">The selector to find the element.</param>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <returns>The found element.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
protected Element Find(By by, int timeoutMS = 5000, bool global = false)
|
2025-02-28 03:08:08 -08:00
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
return this.Session.Find(by, timeoutMS, global);
|
2025-02-28 03:08:08 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// Shortcut for this.Session.Find<Element>(name, timeoutMS)
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="name">The name of the element.</param>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <returns>The found element.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
protected Element Find(string name, int timeoutMS = 5000, bool global = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.Session.Find(name, timeoutMS, global);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Has only one Element or its derived class by selector.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T">The class of the element, should be Element or its derived class.</typeparam>
|
|
|
|
|
|
/// <param name="by">The name of the element.</param>
|
|
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
Updates for check-spelling v0.0.25 (#40386)
## Summary of the Pull Request
- #39572 updated check-spelling but ignored:
> 🐣 Breaking Changes
[Code Scanning action requires a Code Scanning
Ruleset](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset)
If you use SARIF reporting, then instead of the workflow yielding an ❌
when it fails, it will rely on [github-advanced-security
🤖](https://github.com/apps/github-advanced-security) to report the
failure. You will need to adjust your checks for PRs.
This means that check-spelling hasn't been properly doing its job 😦.
I'm sorry, I should have pushed a thing to this repo earlier,...
Anyway, as with most refreshes, this comes with a number of fixes, some
are fixes for typos that snuck in before the 0.0.25 upgrade, some are
for things that snuck in after, some are based on new rules in
spell-check-this, and some are hand written patterns based on running
through this repository a few times.
About the 🐣 **breaking change**: someone needs to create a ruleset for
this repository (see [Code Scanning action requires a Code Scanning
Ruleset: Sample ruleset
](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset#sample-ruleset)).
The alternative to adding a ruleset is to change the condition to not
use sarif for this repository. In general, I think the github
integration from sarif is prettier/more helpful, so I think that it's
the better choice.
You can see an example of it working in:
- https://github.com/check-spelling-sandbox/PowerToys/pull/23
---------
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2025-07-08 18:16:52 -04:00
|
|
|
|
/// <returns>True if only has one element; otherwise, false.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public bool HasOne<T>(By by, int timeoutMS = 5000, bool global = false)
|
|
|
|
|
|
where T : Element, new()
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.FindAll<T>(by, timeoutMS, global).Count == 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Shortcut for this.Session.HasOne<Element>(by, timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="by">The name of the element.</param>
|
|
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
Updates for check-spelling v0.0.25 (#40386)
## Summary of the Pull Request
- #39572 updated check-spelling but ignored:
> 🐣 Breaking Changes
[Code Scanning action requires a Code Scanning
Ruleset](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset)
If you use SARIF reporting, then instead of the workflow yielding an ❌
when it fails, it will rely on [github-advanced-security
🤖](https://github.com/apps/github-advanced-security) to report the
failure. You will need to adjust your checks for PRs.
This means that check-spelling hasn't been properly doing its job 😦.
I'm sorry, I should have pushed a thing to this repo earlier,...
Anyway, as with most refreshes, this comes with a number of fixes, some
are fixes for typos that snuck in before the 0.0.25 upgrade, some are
for things that snuck in after, some are based on new rules in
spell-check-this, and some are hand written patterns based on running
through this repository a few times.
About the 🐣 **breaking change**: someone needs to create a ruleset for
this repository (see [Code Scanning action requires a Code Scanning
Ruleset: Sample ruleset
](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset#sample-ruleset)).
The alternative to adding a ruleset is to change the condition to not
use sarif for this repository. In general, I think the github
integration from sarif is prettier/more helpful, so I think that it's
the better choice.
You can see an example of it working in:
- https://github.com/check-spelling-sandbox/PowerToys/pull/23
---------
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2025-07-08 18:16:52 -04:00
|
|
|
|
/// <returns>True if only has one element; otherwise, false.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public bool HasOne(By by, int timeoutMS = 5000, bool global = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.Session.HasOne<Element>(by, timeoutMS, global);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Shortcut for this.Session.HasOne<T>(name, timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T">The class of the element, should be Element or its derived class.</typeparam>
|
|
|
|
|
|
/// <param name="name">The name of the element.</param>
|
|
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
Updates for check-spelling v0.0.25 (#40386)
## Summary of the Pull Request
- #39572 updated check-spelling but ignored:
> 🐣 Breaking Changes
[Code Scanning action requires a Code Scanning
Ruleset](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset)
If you use SARIF reporting, then instead of the workflow yielding an ❌
when it fails, it will rely on [github-advanced-security
🤖](https://github.com/apps/github-advanced-security) to report the
failure. You will need to adjust your checks for PRs.
This means that check-spelling hasn't been properly doing its job 😦.
I'm sorry, I should have pushed a thing to this repo earlier,...
Anyway, as with most refreshes, this comes with a number of fixes, some
are fixes for typos that snuck in before the 0.0.25 upgrade, some are
for things that snuck in after, some are based on new rules in
spell-check-this, and some are hand written patterns based on running
through this repository a few times.
About the 🐣 **breaking change**: someone needs to create a ruleset for
this repository (see [Code Scanning action requires a Code Scanning
Ruleset: Sample ruleset
](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset#sample-ruleset)).
The alternative to adding a ruleset is to change the condition to not
use sarif for this repository. In general, I think the github
integration from sarif is prettier/more helpful, so I think that it's
the better choice.
You can see an example of it working in:
- https://github.com/check-spelling-sandbox/PowerToys/pull/23
---------
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2025-07-08 18:16:52 -04:00
|
|
|
|
/// <returns>True if only has one element; otherwise, false.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public bool HasOne<T>(string name, int timeoutMS = 5000, bool global = false)
|
|
|
|
|
|
where T : Element, new()
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.Session.HasOne<T>(By.Name(name), timeoutMS, global);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Shortcut for this.Session.HasOne<Element>(name, timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="name">The name of the element.</param>
|
|
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
Updates for check-spelling v0.0.25 (#40386)
## Summary of the Pull Request
- #39572 updated check-spelling but ignored:
> 🐣 Breaking Changes
[Code Scanning action requires a Code Scanning
Ruleset](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset)
If you use SARIF reporting, then instead of the workflow yielding an ❌
when it fails, it will rely on [github-advanced-security
🤖](https://github.com/apps/github-advanced-security) to report the
failure. You will need to adjust your checks for PRs.
This means that check-spelling hasn't been properly doing its job 😦.
I'm sorry, I should have pushed a thing to this repo earlier,...
Anyway, as with most refreshes, this comes with a number of fixes, some
are fixes for typos that snuck in before the 0.0.25 upgrade, some are
for things that snuck in after, some are based on new rules in
spell-check-this, and some are hand written patterns based on running
through this repository a few times.
About the 🐣 **breaking change**: someone needs to create a ruleset for
this repository (see [Code Scanning action requires a Code Scanning
Ruleset: Sample ruleset
](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset#sample-ruleset)).
The alternative to adding a ruleset is to change the condition to not
use sarif for this repository. In general, I think the github
integration from sarif is prettier/more helpful, so I think that it's
the better choice.
You can see an example of it working in:
- https://github.com/check-spelling-sandbox/PowerToys/pull/23
---------
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2025-07-08 18:16:52 -04:00
|
|
|
|
/// <returns>True if only has one element; otherwise, false.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public bool HasOne(string name, int timeoutMS = 5000, bool global = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.Session.HasOne<Element>(name, timeoutMS, global);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Shortcut for this.Session.Has<T>(by, timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T">The class of the element, should be Element or its derived class.</typeparam>
|
|
|
|
|
|
/// <param name="by">The selector to find the element.</param>
|
|
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
Updates for check-spelling v0.0.25 (#40386)
## Summary of the Pull Request
- #39572 updated check-spelling but ignored:
> 🐣 Breaking Changes
[Code Scanning action requires a Code Scanning
Ruleset](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset)
If you use SARIF reporting, then instead of the workflow yielding an ❌
when it fails, it will rely on [github-advanced-security
🤖](https://github.com/apps/github-advanced-security) to report the
failure. You will need to adjust your checks for PRs.
This means that check-spelling hasn't been properly doing its job 😦.
I'm sorry, I should have pushed a thing to this repo earlier,...
Anyway, as with most refreshes, this comes with a number of fixes, some
are fixes for typos that snuck in before the 0.0.25 upgrade, some are
for things that snuck in after, some are based on new rules in
spell-check-this, and some are hand written patterns based on running
through this repository a few times.
About the 🐣 **breaking change**: someone needs to create a ruleset for
this repository (see [Code Scanning action requires a Code Scanning
Ruleset: Sample ruleset
](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset#sample-ruleset)).
The alternative to adding a ruleset is to change the condition to not
use sarif for this repository. In general, I think the github
integration from sarif is prettier/more helpful, so I think that it's
the better choice.
You can see an example of it working in:
- https://github.com/check-spelling-sandbox/PowerToys/pull/23
---------
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2025-07-08 18:16:52 -04:00
|
|
|
|
/// <returns>True if has one or more element; otherwise, false.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public bool Has<T>(By by, int timeoutMS = 5000, bool global = false)
|
|
|
|
|
|
where T : Element, new()
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.Session.FindAll<T>(by, timeoutMS, global).Count >= 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Shortcut for this.Session.Has<Element>(by, timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="by">The selector to find the element.</param>
|
|
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
Updates for check-spelling v0.0.25 (#40386)
## Summary of the Pull Request
- #39572 updated check-spelling but ignored:
> 🐣 Breaking Changes
[Code Scanning action requires a Code Scanning
Ruleset](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset)
If you use SARIF reporting, then instead of the workflow yielding an ❌
when it fails, it will rely on [github-advanced-security
🤖](https://github.com/apps/github-advanced-security) to report the
failure. You will need to adjust your checks for PRs.
This means that check-spelling hasn't been properly doing its job 😦.
I'm sorry, I should have pushed a thing to this repo earlier,...
Anyway, as with most refreshes, this comes with a number of fixes, some
are fixes for typos that snuck in before the 0.0.25 upgrade, some are
for things that snuck in after, some are based on new rules in
spell-check-this, and some are hand written patterns based on running
through this repository a few times.
About the 🐣 **breaking change**: someone needs to create a ruleset for
this repository (see [Code Scanning action requires a Code Scanning
Ruleset: Sample ruleset
](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset#sample-ruleset)).
The alternative to adding a ruleset is to change the condition to not
use sarif for this repository. In general, I think the github
integration from sarif is prettier/more helpful, so I think that it's
the better choice.
You can see an example of it working in:
- https://github.com/check-spelling-sandbox/PowerToys/pull/23
---------
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2025-07-08 18:16:52 -04:00
|
|
|
|
/// <returns>True if has one or more element; otherwise, false.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public bool Has(By by, int timeoutMS = 5000, bool global = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.Session.Has<Element>(by, timeoutMS, global);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Shortcut for this.Session.Has<T>(By.Name(name), timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T">The class of the element, should be Element or its derived class.</typeparam>
|
|
|
|
|
|
/// <param name="name">The name of the element.</param>
|
|
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
Updates for check-spelling v0.0.25 (#40386)
## Summary of the Pull Request
- #39572 updated check-spelling but ignored:
> 🐣 Breaking Changes
[Code Scanning action requires a Code Scanning
Ruleset](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset)
If you use SARIF reporting, then instead of the workflow yielding an ❌
when it fails, it will rely on [github-advanced-security
🤖](https://github.com/apps/github-advanced-security) to report the
failure. You will need to adjust your checks for PRs.
This means that check-spelling hasn't been properly doing its job 😦.
I'm sorry, I should have pushed a thing to this repo earlier,...
Anyway, as with most refreshes, this comes with a number of fixes, some
are fixes for typos that snuck in before the 0.0.25 upgrade, some are
for things that snuck in after, some are based on new rules in
spell-check-this, and some are hand written patterns based on running
through this repository a few times.
About the 🐣 **breaking change**: someone needs to create a ruleset for
this repository (see [Code Scanning action requires a Code Scanning
Ruleset: Sample ruleset
](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset#sample-ruleset)).
The alternative to adding a ruleset is to change the condition to not
use sarif for this repository. In general, I think the github
integration from sarif is prettier/more helpful, so I think that it's
the better choice.
You can see an example of it working in:
- https://github.com/check-spelling-sandbox/PowerToys/pull/23
---------
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2025-07-08 18:16:52 -04:00
|
|
|
|
/// <returns>True if has one or more element; otherwise, false.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public bool Has<T>(string name, int timeoutMS = 5000, bool global = false)
|
|
|
|
|
|
where T : Element, new()
|
2025-02-28 03:08:08 -08:00
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
return this.Session.Has<T>(By.Name(name), timeoutMS, global);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Shortcut for this.Session.Has<Element>(name, timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="name">The name of the element.</param>
|
|
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
Updates for check-spelling v0.0.25 (#40386)
## Summary of the Pull Request
- #39572 updated check-spelling but ignored:
> 🐣 Breaking Changes
[Code Scanning action requires a Code Scanning
Ruleset](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset)
If you use SARIF reporting, then instead of the workflow yielding an ❌
when it fails, it will rely on [github-advanced-security
🤖](https://github.com/apps/github-advanced-security) to report the
failure. You will need to adjust your checks for PRs.
This means that check-spelling hasn't been properly doing its job 😦.
I'm sorry, I should have pushed a thing to this repo earlier,...
Anyway, as with most refreshes, this comes with a number of fixes, some
are fixes for typos that snuck in before the 0.0.25 upgrade, some are
for things that snuck in after, some are based on new rules in
spell-check-this, and some are hand written patterns based on running
through this repository a few times.
About the 🐣 **breaking change**: someone needs to create a ruleset for
this repository (see [Code Scanning action requires a Code Scanning
Ruleset: Sample ruleset
](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset#sample-ruleset)).
The alternative to adding a ruleset is to change the condition to not
use sarif for this repository. In general, I think the github
integration from sarif is prettier/more helpful, so I think that it's
the better choice.
You can see an example of it working in:
- https://github.com/check-spelling-sandbox/PowerToys/pull/23
---------
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2025-07-08 18:16:52 -04:00
|
|
|
|
/// <returns>True if has one or more element; otherwise, false.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
public bool Has(string name, int timeoutMS = 5000, bool global = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.Session.Has<Element>(name, timeoutMS, global);
|
2025-02-28 03:08:08 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-24 02:05:55 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Finds all elements by selector.
|
|
|
|
|
|
/// Shortcut for this.Session.FindAll<T>(by, timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T">The class of the elements, should be Element or its derived class.</typeparam>
|
|
|
|
|
|
/// <param name="by">The selector to find the elements.</param>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
2025-02-24 02:05:55 -08:00
|
|
|
|
/// <returns>A read-only collection of the found elements.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
protected ReadOnlyCollection<T> FindAll<T>(By by, int timeoutMS = 5000, bool global = false)
|
2025-02-24 02:05:55 -08:00
|
|
|
|
where T : Element, new()
|
|
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
return this.Session.FindAll<T>(by, timeoutMS, global);
|
2025-02-24 02:05:55 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-20 13:25:20 +08:00
|
|
|
|
/// <summary>
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// Finds all elements by selector.
|
|
|
|
|
|
/// Shortcut for this.Session.FindAll<Element>(By.Name(name), timeoutMS)
|
2025-02-20 13:25:20 +08:00
|
|
|
|
/// </summary>
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <typeparam name="T">The class of the elements, should be Element or its derived class.</typeparam>
|
|
|
|
|
|
/// <param name="name">The name of the elements.</param>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <returns>A read-only collection of the found elements.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
protected ReadOnlyCollection<T> FindAll<T>(string name, int timeoutMS = 5000, bool global = false)
|
2025-02-28 03:08:08 -08:00
|
|
|
|
where T : Element, new()
|
2025-02-20 13:25:20 +08:00
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
return this.Session.FindAll<T>(By.Name(name), timeoutMS, global);
|
2025-02-28 03:08:08 -08:00
|
|
|
|
}
|
2025-02-20 13:25:20 +08:00
|
|
|
|
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Finds all elements by selector.
|
|
|
|
|
|
/// Shortcut for this.Session.FindAll<Element>(by, timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="by">The selector to find the elements.</param>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <returns>A read-only collection of the found elements.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
protected ReadOnlyCollection<Element> FindAll(By by, int timeoutMS = 5000, bool global = false)
|
2025-02-28 03:08:08 -08:00
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
return this.Session.FindAll<Element>(by, timeoutMS, global);
|
2025-02-28 03:08:08 -08:00
|
|
|
|
}
|
2025-02-20 13:25:20 +08:00
|
|
|
|
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Finds all elements by selector.
|
|
|
|
|
|
/// Shortcut for this.Session.FindAll<Element>(By.Name(name), timeoutMS)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="name">The name of the elements.</param>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
/// <param name="timeoutMS">The timeout in milliseconds (default is 5000).</param>
|
2025-02-28 03:08:08 -08:00
|
|
|
|
/// <returns>A read-only collection of the found elements.</returns>
|
2025-06-17 17:56:48 +08:00
|
|
|
|
protected ReadOnlyCollection<Element> FindAll(string name, int timeoutMS = 5000, bool global = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.Session.FindAll<Element>(By.Name(name), timeoutMS, global);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Scrolls the page
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="scrollCount">The number of scroll attempts.</param>
|
|
|
|
|
|
/// <param name="direction">The direction to scroll.</param>
|
|
|
|
|
|
/// <param name="msPreAction">Pre-action delay in milliseconds.</param>
|
|
|
|
|
|
/// <param name="msPostAction">Post-action delay in milliseconds.</param>
|
|
|
|
|
|
public void Scroll(int scrollCount = 5, string direction = "Up", int msPreAction = 500, int msPostAction = 500)
|
2025-02-28 03:08:08 -08:00
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
MouseActionType mouseAction = direction == "Up" ? MouseActionType.ScrollUp : MouseActionType.ScrollDown;
|
|
|
|
|
|
for (int i = 0; i < scrollCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
Session.PerformMouseAction(mouseAction, msPreAction, msPostAction); // Ensure settings are visible
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Captures the last screenshot when the test fails.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
protected void CaptureLastScreenshot()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Implement your screenshot capture logic here
|
|
|
|
|
|
// For example, save a screenshot to a file and return the file path
|
|
|
|
|
|
string screenshotPath = Path.Combine(this.TestContext.TestResultsDirectory ?? string.Empty, "last_screenshot.png");
|
|
|
|
|
|
|
|
|
|
|
|
this.Session.Root.GetScreenshot().SaveAsFile(screenshotPath, ScreenshotImageFormat.Png);
|
|
|
|
|
|
|
|
|
|
|
|
// Save screenshot to screenshotPath & upload to test attachment
|
|
|
|
|
|
this.TestContext.AddResultFile(screenshotPath);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Retrieves the color of the pixel at the specified screen coordinates.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="x">The X coordinate on the screen.</param>
|
|
|
|
|
|
/// <param name="y">The Y coordinate on the screen.</param>
|
|
|
|
|
|
/// <returns>The color of the pixel at the specified coordinates.</returns>
|
|
|
|
|
|
public Color GetPixelColor(int x, int y)
|
|
|
|
|
|
{
|
|
|
|
|
|
return WindowHelper.GetPixelColor(x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Retrieves the color of the pixel at the specified screen coordinates as a string.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="x">The X coordinate on the screen.</param>
|
|
|
|
|
|
/// <param name="y">The Y coordinate on the screen.</param>
|
|
|
|
|
|
/// <returns>The color of the pixel at the specified coordinates.</returns>
|
|
|
|
|
|
public string GetPixelColorString(int x, int y)
|
|
|
|
|
|
{
|
|
|
|
|
|
return WindowHelper.GetPixelColorString(x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Gets the size of the display.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>
|
|
|
|
|
|
/// A tuple containing the width and height of the display.
|
|
|
|
|
|
/// </returns
|
|
|
|
|
|
public Tuple<int, int> GetDisplaySize()
|
|
|
|
|
|
{
|
|
|
|
|
|
return WindowHelper.GetDisplaySize();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Sends a combination of keys.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="keys">The keys to send.</param>
|
|
|
|
|
|
public void SendKeys(params Key[] keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.Session.SendKeys(keys);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Sends a sequence of keys.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="keys">An array of keys to send.</param>
|
|
|
|
|
|
public void SendKeySequence(params Key[] keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.Session.SendKeySequence(keys);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Gets the current position of the mouse cursor as a tuple.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>A tuple containing the X and Y coordinates of the cursor.</returns>
|
|
|
|
|
|
public Tuple<int, int> GetMousePosition()
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.Session.GetMousePosition();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Gets the screen center coordinates.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>(x, y)</returns>
|
|
|
|
|
|
public (int CenterX, int CenterY) GetScreenCenter()
|
|
|
|
|
|
{
|
|
|
|
|
|
return WindowHelper.GetScreenCenter();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsWindowOpen(string windowName)
|
|
|
|
|
|
{
|
|
|
|
|
|
return WindowHelper.IsWindowOpen(windowName);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Moves the mouse cursor to the specified screen coordinates.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="x">The new x-coordinate of the cursor.</param>
|
|
|
|
|
|
/// <param name="y">The new y-coordinate of the cursor.</param
|
|
|
|
|
|
public void MoveMouseTo(int x, int y)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.Session.MoveMouseTo(x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected void AddScreenShotsToTestResultsDirectory()
|
|
|
|
|
|
{
|
[UI tests] Add full UI test coverage for Peek based on release checklist (#40734)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Add full UI test coverage for Peek based on release checklist
### Peek
* Open different files to check that they're shown properly
- [x] Image
- [x] Text or dev file
- [x] Markdown file
- [ ] PDF
- [x] Archive files (.zip, .tar, .rar)
- [x] Any other not mentioned file (.exe for example) to verify the
unsupported file view is shown
* Pinning/unpinning
- [x] Pin the window, switch between images of different size, verify
the window stays at the same place and the same size.
- [x] Pin the window, close and reopen Peek, verify the new window is
opened at the same place and the same size as before.
- [x] Unpin the window, switch to a different file, verify the window is
moved to the default place.
- [x] Unpin the window, close and reopen Peek, verify the new window is
opened on the default place.
* Open with a default program
- [x] By clicking a button.
- [x] By pressing enter.
- [x] Switch between files in the folder using `LeftArrow` and
`RightArrow`, verify you can switch between all files in the folder.
- [x] Open multiple files, verify you can switch only between selected
files.
<img width="519" height="266" alt="image"
src="https://github.com/user-attachments/assets/f27c555d-9939-476f-9ecc-50d598285aef"
/>
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] **Closes:**
#[40676](https://github.com/microsoft/PowerToys/issues/40676)
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-07-22 09:00:39 +08:00
|
|
|
|
if (ScreenshotDirectory != null)
|
2025-06-17 17:56:48 +08:00
|
|
|
|
{
|
[UI tests] Add full UI test coverage for Peek based on release checklist (#40734)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Add full UI test coverage for Peek based on release checklist
### Peek
* Open different files to check that they're shown properly
- [x] Image
- [x] Text or dev file
- [x] Markdown file
- [ ] PDF
- [x] Archive files (.zip, .tar, .rar)
- [x] Any other not mentioned file (.exe for example) to verify the
unsupported file view is shown
* Pinning/unpinning
- [x] Pin the window, switch between images of different size, verify
the window stays at the same place and the same size.
- [x] Pin the window, close and reopen Peek, verify the new window is
opened at the same place and the same size as before.
- [x] Unpin the window, switch to a different file, verify the window is
moved to the default place.
- [x] Unpin the window, close and reopen Peek, verify the new window is
opened on the default place.
* Open with a default program
- [x] By clicking a button.
- [x] By pressing enter.
- [x] Switch between files in the folder using `LeftArrow` and
`RightArrow`, verify you can switch between all files in the folder.
- [x] Open multiple files, verify you can switch only between selected
files.
<img width="519" height="266" alt="image"
src="https://github.com/user-attachments/assets/f27c555d-9939-476f-9ecc-50d598285aef"
/>
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] **Closes:**
#[40676](https://github.com/microsoft/PowerToys/issues/40676)
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-07-22 09:00:39 +08:00
|
|
|
|
foreach (string file in Directory.GetFiles(ScreenshotDirectory))
|
2025-06-17 17:56:48 +08:00
|
|
|
|
{
|
|
|
|
|
|
this.TestContext.AddResultFile(file);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-02-20 13:25:20 +08:00
|
|
|
|
}
|
2025-03-14 17:04:23 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Restart scope exe.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void RestartScopeExe()
|
|
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
this.sessionHelper!.RestartScopeExe();
|
|
|
|
|
|
this.Session = new Session(this.sessionHelper.GetRoot(), this.sessionHelper.GetDriver(), this.scope, this.size);
|
2025-03-14 17:04:23 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Restart scope exe.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void ExitScopeExe()
|
|
|
|
|
|
{
|
2025-06-17 17:56:48 +08:00
|
|
|
|
this.sessionHelper!.ExitScopeExe();
|
2025-03-14 17:04:23 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-06-17 17:56:48 +08:00
|
|
|
|
|
|
|
|
|
|
private void CloseOtherApplications()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Close other applications
|
|
|
|
|
|
var processNamesToClose = new List<string>
|
|
|
|
|
|
{
|
|
|
|
|
|
"PowerToys",
|
|
|
|
|
|
"PowerToys.Settings",
|
|
|
|
|
|
"PowerToys.FancyZonesEditor",
|
|
|
|
|
|
};
|
|
|
|
|
|
foreach (var processName in processNamesToClose)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var process in Process.GetProcessesByName(processName))
|
|
|
|
|
|
{
|
|
|
|
|
|
process.Kill();
|
|
|
|
|
|
process.WaitForExit();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class NativeMethods
|
|
|
|
|
|
{
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
|
|
|
|
|
public struct DISPLAY_DEVICE
|
|
|
|
|
|
{
|
|
|
|
|
|
public int cb;
|
|
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
|
|
|
|
|
public string DeviceName;
|
|
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
|
|
|
|
|
|
public string DeviceString;
|
|
|
|
|
|
public int StateFlags;
|
|
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
|
|
|
|
|
|
public string DeviceID;
|
|
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
|
|
|
|
|
|
public string DeviceKey;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport("user32.dll")]
|
|
|
|
|
|
private static extern int EnumDisplaySettings(IntPtr deviceName, int modeNum, ref DEVMODE devMode);
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport("user32.dll")]
|
|
|
|
|
|
private static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
|
|
|
|
|
|
private static extern bool EnumDisplayDevices(IntPtr lpDevice, int iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, int dwFlags);
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport("user32.dll")]
|
|
|
|
|
|
private static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags);
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
|
|
|
|
|
|
private static extern int ChangeDisplaySettingsEx(IntPtr lpszDeviceName, ref DEVMODE lpDevMode, IntPtr hwnd, uint dwflags, IntPtr lParam);
|
|
|
|
|
|
|
|
|
|
|
|
private const int DM_PELSWIDTH = 0x80000;
|
|
|
|
|
|
private const int DM_PELSHEIGHT = 0x100000;
|
|
|
|
|
|
|
|
|
|
|
|
public const int ENUM_CURRENT_SETTINGS = -1;
|
|
|
|
|
|
public const int CDS_TEST = 0x00000002;
|
|
|
|
|
|
public const int CDS_UPDATEREGISTRY = 0x01;
|
|
|
|
|
|
public const int DISP_CHANGE_SUCCESSFUL = 0;
|
|
|
|
|
|
public const int DISP_CHANGE_RESTART = 1;
|
|
|
|
|
|
public const int DISP_CHANGE_FAILED = -1;
|
|
|
|
|
|
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
|
|
public struct DEVMODE
|
|
|
|
|
|
{
|
|
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
|
|
|
|
|
public string DmDeviceName;
|
|
|
|
|
|
public short DmSpecVersion;
|
|
|
|
|
|
public short DmDriverVersion;
|
|
|
|
|
|
public short DmSize;
|
|
|
|
|
|
public short DmDriverExtra;
|
|
|
|
|
|
public int DmFields;
|
|
|
|
|
|
public int DmPositionX;
|
|
|
|
|
|
public int DmPositionY;
|
|
|
|
|
|
public int DmDisplayOrientation;
|
|
|
|
|
|
public int DmDisplayFixedOutput;
|
|
|
|
|
|
public short DmColor;
|
|
|
|
|
|
public short DmDuplex;
|
|
|
|
|
|
public short DmYResolution;
|
|
|
|
|
|
public short DmTTOption;
|
|
|
|
|
|
public short DmCollate;
|
|
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
|
|
|
|
|
public string DmFormName;
|
|
|
|
|
|
public short DmLogPixels;
|
|
|
|
|
|
public int DmBitsPerPel;
|
|
|
|
|
|
public int DmPelsWidth;
|
|
|
|
|
|
public int DmPelsHeight;
|
|
|
|
|
|
public int DmDisplayFlags;
|
|
|
|
|
|
public int DmDisplayFrequency;
|
|
|
|
|
|
public int DmICMMethod;
|
|
|
|
|
|
public int DmICMIntent;
|
|
|
|
|
|
public int DmMediaType;
|
|
|
|
|
|
public int DmDitherType;
|
|
|
|
|
|
public int DmReserved1;
|
|
|
|
|
|
public int DmReserved2;
|
|
|
|
|
|
public int DmPanningWidth;
|
|
|
|
|
|
public int DmPanningHeight;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void GetMonitorInfo()
|
|
|
|
|
|
{
|
|
|
|
|
|
int deviceIndex = 0;
|
|
|
|
|
|
DISPLAY_DEVICE d = default(DISPLAY_DEVICE);
|
|
|
|
|
|
d.cb = Marshal.SizeOf(d);
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("monitor list :");
|
|
|
|
|
|
while (EnumDisplayDevices(IntPtr.Zero, deviceIndex, ref d, 0))
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"monitor {deviceIndex + 1}:");
|
|
|
|
|
|
Console.WriteLine($" name: {d.DeviceName}");
|
|
|
|
|
|
Console.WriteLine($" string: {d.DeviceString}");
|
|
|
|
|
|
Console.WriteLine($" ID: {d.DeviceID}");
|
|
|
|
|
|
Console.WriteLine($" key: {d.DeviceKey}");
|
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
|
|
|
|
|
|
DEVMODE dm = default(DEVMODE);
|
|
|
|
|
|
dm.DmSize = (short)Marshal.SizeOf<DEVMODE>();
|
|
|
|
|
|
int modeNum = 0;
|
|
|
|
|
|
while (EnumDisplaySettings(d.DeviceName, modeNum, ref dm) > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
MonitorInfoData.Monitors.Add(new MonitorInfoData.MonitorInfoDataWrapper()
|
|
|
|
|
|
{
|
|
|
|
|
|
DeviceName = d.DeviceName,
|
|
|
|
|
|
DeviceString = d.DeviceString,
|
|
|
|
|
|
DeviceID = d.DeviceID,
|
|
|
|
|
|
DeviceKey = d.DeviceKey,
|
|
|
|
|
|
PelsWidth = dm.DmPelsWidth,
|
|
|
|
|
|
PelsHeight = dm.DmPelsHeight,
|
|
|
|
|
|
DisplayFrequency = dm.DmDisplayFrequency,
|
|
|
|
|
|
});
|
|
|
|
|
|
Console.WriteLine($" mode {modeNum}: {dm.DmPelsWidth}x{dm.DmPelsHeight} @ {dm.DmDisplayFrequency}Hz");
|
|
|
|
|
|
modeNum++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
deviceIndex++;
|
|
|
|
|
|
d.cb = Marshal.SizeOf(d); // Reset the size for the next device
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void ChangeDisplayResolution(int PelsWidth, int PelsHeight)
|
|
|
|
|
|
{
|
|
|
|
|
|
Screen screen = Screen.PrimaryScreen!;
|
|
|
|
|
|
if (screen.Bounds.Width == PelsWidth && screen.Bounds.Height == PelsHeight)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEVMODE devMode = default(DEVMODE);
|
|
|
|
|
|
devMode.DmDeviceName = new string(new char[32]);
|
|
|
|
|
|
devMode.DmFormName = new string(new char[32]);
|
|
|
|
|
|
devMode.DmSize = (short)Marshal.SizeOf<DEVMODE>();
|
|
|
|
|
|
|
|
|
|
|
|
int modeNum = 0;
|
|
|
|
|
|
while (EnumDisplaySettings(IntPtr.Zero, modeNum, ref devMode) > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"Mode {modeNum}: {devMode.DmPelsWidth}x{devMode.DmPelsHeight} @ {devMode.DmDisplayFrequency}Hz");
|
|
|
|
|
|
modeNum++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
devMode.DmPelsWidth = PelsWidth;
|
|
|
|
|
|
devMode.DmPelsHeight = PelsHeight;
|
|
|
|
|
|
|
|
|
|
|
|
int result = NativeMethods.ChangeDisplaySettings(ref devMode, NativeMethods.CDS_TEST);
|
|
|
|
|
|
|
|
|
|
|
|
if (result == DISP_CHANGE_SUCCESSFUL)
|
|
|
|
|
|
{
|
|
|
|
|
|
result = ChangeDisplaySettings(ref devMode, CDS_UPDATEREGISTRY);
|
|
|
|
|
|
if (result == DISP_CHANGE_SUCCESSFUL)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"Changing display resolution to {devMode.DmPelsWidth}x{devMode.DmPelsHeight}");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"Failed to change display resolution. Error code: {result}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (result == DISP_CHANGE_RESTART)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"Changing display resolution to {devMode.DmPelsWidth}x{devMode.DmPelsHeight} requires a restart");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"Failed to change display resolution. Error code: {result}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
[UI tests] Add full UI test coverage for Peek based on release checklist (#40734)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Add full UI test coverage for Peek based on release checklist
### Peek
* Open different files to check that they're shown properly
- [x] Image
- [x] Text or dev file
- [x] Markdown file
- [ ] PDF
- [x] Archive files (.zip, .tar, .rar)
- [x] Any other not mentioned file (.exe for example) to verify the
unsupported file view is shown
* Pinning/unpinning
- [x] Pin the window, switch between images of different size, verify
the window stays at the same place and the same size.
- [x] Pin the window, close and reopen Peek, verify the new window is
opened at the same place and the same size as before.
- [x] Unpin the window, switch to a different file, verify the window is
moved to the default place.
- [x] Unpin the window, close and reopen Peek, verify the new window is
opened on the default place.
* Open with a default program
- [x] By clicking a button.
- [x] By pressing enter.
- [x] Switch between files in the folder using `LeftArrow` and
`RightArrow`, verify you can switch between all files in the folder.
- [x] Open multiple files, verify you can switch only between selected
files.
<img width="519" height="266" alt="image"
src="https://github.com/user-attachments/assets/f27c555d-9939-476f-9ecc-50d598285aef"
/>
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] **Closes:**
#[40676](https://github.com/microsoft/PowerToys/issues/40676)
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-07-22 09:00:39 +08:00
|
|
|
|
|
|
|
|
|
|
// Windows API for moving windows
|
|
|
|
|
|
[DllImport("user32.dll")]
|
|
|
|
|
|
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
|
|
|
|
|
|
|
|
|
|
|
|
private const uint SWPNOSIZE = 0x0001;
|
|
|
|
|
|
private const uint SWPNOZORDER = 0x0004;
|
|
|
|
|
|
|
|
|
|
|
|
public static void MoveWindow(Element window, int x, int y)
|
|
|
|
|
|
{
|
|
|
|
|
|
var windowHandle = IntPtr.Parse(window.GetAttribute("NativeWindowHandle") ?? "0", System.Globalization.CultureInfo.InvariantCulture);
|
|
|
|
|
|
if (windowHandle != IntPtr.Zero)
|
|
|
|
|
|
{
|
|
|
|
|
|
SetWindowPos(windowHandle, IntPtr.Zero, x, y, 0, 0, SWPNOSIZE | SWPNOZORDER);
|
|
|
|
|
|
Task.Delay(500).Wait();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-06-17 17:56:48 +08:00
|
|
|
|
}
|
2025-02-20 13:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|