mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-23 03:30:02 +01:00
Compare commits
34 Commits
async-cpp-
...
gleb/pipel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d88930b5e3 | ||
|
|
b1db93d97b | ||
|
|
40c61c92bb | ||
|
|
632b2f7fb9 | ||
|
|
d21446b0f7 | ||
|
|
a9b97b1f8a | ||
|
|
1d0ef233c9 | ||
|
|
12c84b19c9 | ||
|
|
501ff5690d | ||
|
|
38acf1a6bc | ||
|
|
cb70e1dbfd | ||
|
|
df750394db | ||
|
|
9bcba8cb8b | ||
|
|
00457b2933 | ||
|
|
2b0b80c63a | ||
|
|
d42df8392c | ||
|
|
c6033bc8e5 | ||
|
|
69c206e85e | ||
|
|
0afb91b71d | ||
|
|
f926a5ece9 | ||
|
|
b9e66cca26 | ||
|
|
c4dd213712 | ||
|
|
2808f65d7f | ||
|
|
0e61b28571 | ||
|
|
ce406892b3 | ||
|
|
f619334ff2 | ||
|
|
142f09459d | ||
|
|
f42115bc4f | ||
|
|
36764487c5 | ||
|
|
218cb473c1 | ||
|
|
f0b674763a | ||
|
|
cf0264e9b9 | ||
|
|
be7098c267 | ||
|
|
3f486ea3db |
@@ -46,20 +46,7 @@ jobs:
|
|||||||
SrcPath: $(Build.Repository.LocalPath)
|
SrcPath: $(Build.Repository.LocalPath)
|
||||||
TestArtifactsName: build-${{ variables.BuildPlatform }}-${{ parameters.configuration }}${{ parameters.inputArtifactStem }}
|
TestArtifactsName: build-${{ variables.BuildPlatform }}-${{ parameters.configuration }}${{ parameters.inputArtifactStem }}
|
||||||
pool:
|
pool:
|
||||||
${{ if eq(variables['System.CollectionId'], 'cb55739e-4afe-46a3-970f-1b49d8ee7564') }}:
|
name: testing-arm64-selfhost
|
||||||
${{ if ne(parameters.platform, 'ARM64') }}:
|
|
||||||
name: SHINE-INT-Testing-x64
|
|
||||||
${{ if eq(parameters.platform, 'x64Win11') }}:
|
|
||||||
demands: ImageOverride -equals SHINE-W11-Testing
|
|
||||||
${{ else }}:
|
|
||||||
name: SHINE-INT-Testing-arm64
|
|
||||||
${{ else }}:
|
|
||||||
${{ if ne(parameters.platform, 'ARM64') }}:
|
|
||||||
name: SHINE-OSS-Testing-x64
|
|
||||||
${{ if eq(parameters.platform, 'x64Win11') }}:
|
|
||||||
demands: ImageOverride -equals SHINE-W11-Testing
|
|
||||||
${{ else }}:
|
|
||||||
name: SHINE-OSS-Testing-arm64
|
|
||||||
steps:
|
steps:
|
||||||
- checkout: self
|
- checkout: self
|
||||||
submodules: false
|
submodules: false
|
||||||
@@ -67,41 +54,41 @@ jobs:
|
|||||||
fetchDepth: 1
|
fetchDepth: 1
|
||||||
fetchTags: false
|
fetchTags: false
|
||||||
|
|
||||||
- ${{ if eq(parameters.useLatestWebView2, true) }}:
|
# - ${{ if eq(parameters.useLatestWebView2, true) }}:
|
||||||
- powershell: |
|
# - powershell: |
|
||||||
$edge_url = 'https://go.microsoft.com/fwlink/?linkid=2084649&Channel=Canary&language=en'
|
# $edge_url = 'https://go.microsoft.com/fwlink/?linkid=2084649&Channel=Canary&language=en'
|
||||||
$timeout = New-TimeSpan -Minutes 6
|
# $timeout = New-TimeSpan -Minutes 6
|
||||||
$timeoutSeconds = [int]$timeout.TotalSeconds
|
# $timeoutSeconds = [int]$timeout.TotalSeconds
|
||||||
$command = {
|
# $command = {
|
||||||
Invoke-WebRequest -Uri $using:edge_url -OutFile $(Pipeline.Workspace)\MicrosoftEdgeSetup.exe
|
# Invoke-WebRequest -Uri $using:edge_url -OutFile $(Pipeline.Workspace)\MicrosoftEdgeSetup.exe
|
||||||
Write-Host "##[command]Installing Canary channel of Microsoft Edge"
|
# Write-Host "##[command]Installing Canary channel of Microsoft Edge"
|
||||||
Start-Process $(Pipeline.Workspace)\MicrosoftEdgeSetup.exe -ArgumentList '/silent /install' -Wait
|
# Start-Process $(Pipeline.Workspace)\MicrosoftEdgeSetup.exe -ArgumentList '/silent /install' -Wait
|
||||||
}
|
# }
|
||||||
|
|
||||||
$job = Start-Job -ScriptBlock $command
|
# $job = Start-Job -ScriptBlock $command
|
||||||
Wait-Job $job -Timeout $timeoutSeconds
|
# Wait-Job $job -Timeout $timeoutSeconds
|
||||||
if ($job.State -eq "Running") {
|
# if ($job.State -eq "Running") {
|
||||||
Stop-Job $job
|
# Stop-Job $job
|
||||||
Write-Host "##[warning]The job was stopped because it exceeded the time limit."
|
# Write-Host "##[warning]The job was stopped because it exceeded the time limit."
|
||||||
}
|
# }
|
||||||
displayName: "Install the latest MSEdge Canary"
|
# displayName: "Install the latest MSEdge Canary"
|
||||||
|
|
||||||
- script:
|
# - script:
|
||||||
reg add "HKLM\Software\Policies\Microsoft\Edge\WebView2\ReleaseChannels" /v PowerToys.exe /t REG_SZ /d "3"
|
# reg add "HKLM\Software\Policies\Microsoft\Edge\WebView2\ReleaseChannels" /v PowerToys.exe /t REG_SZ /d "3"
|
||||||
displayName: "Enable WebView2 Canary Channel"
|
# displayName: "Enable WebView2 Canary Channel"
|
||||||
|
|
||||||
- ${{ if ne(parameters.platform, 'arm64') }}:
|
# - ${{ if ne(parameters.platform, 'arm64') }}:
|
||||||
- download: current
|
# - download: current
|
||||||
displayName: Download artifacts
|
# displayName: Download artifacts
|
||||||
artifact: $(TestArtifactsName)
|
# artifact: $(TestArtifactsName)
|
||||||
patterns: |-
|
# patterns: |-
|
||||||
**
|
# **
|
||||||
!**\*.pdb
|
# !**\*.pdb
|
||||||
!**\*.lib
|
# !**\*.lib
|
||||||
- ${{ else }}:
|
# - ${{ else }}:
|
||||||
- template: steps-download-artifacts-with-azure-cli.yml
|
# - template: steps-download-artifacts-with-azure-cli.yml
|
||||||
parameters:
|
# parameters:
|
||||||
artifactName: $(TestArtifactsName)
|
# artifactName: $(TestArtifactsName)
|
||||||
|
|
||||||
- template: steps-ensure-dotnet-version.yml
|
- template: steps-ensure-dotnet-version.yml
|
||||||
parameters:
|
parameters:
|
||||||
@@ -111,9 +98,9 @@ jobs:
|
|||||||
- task: VisualStudioTestPlatformInstaller@1
|
- task: VisualStudioTestPlatformInstaller@1
|
||||||
displayName: Ensure VSTest Platform
|
displayName: Ensure VSTest Platform
|
||||||
|
|
||||||
- pwsh: |-
|
# - pwsh: |-
|
||||||
& '$(build.sourcesdirectory)\.pipelines\InstallWinAppDriver.ps1'
|
# & '$(build.sourcesdirectory)\.pipelines\InstallWinAppDriver.ps1'
|
||||||
displayName: Download and install WinAppDriver
|
# displayName: Download and install WinAppDriver
|
||||||
|
|
||||||
- ${{ if ne(parameters.buildSource, 'buildNow') }}:
|
- ${{ if ne(parameters.buildSource, 'buildNow') }}:
|
||||||
- task: DownloadPipelineArtifact@2
|
- task: DownloadPipelineArtifact@2
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ parameters:
|
|||||||
- name: uiTestModules
|
- name: uiTestModules
|
||||||
type: object
|
type: object
|
||||||
default: []
|
default: []
|
||||||
|
- name: pool
|
||||||
|
type: string
|
||||||
|
default: 'SHINE-OSS-Testing-arm64-selfhost'
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- ${{ each platform in parameters.buildPlatforms }}:
|
- ${{ each platform in parameters.buildPlatforms }}:
|
||||||
@@ -46,6 +49,7 @@ stages:
|
|||||||
useVSPreview: ${{ parameters.useVSPreview }}
|
useVSPreview: ${{ parameters.useVSPreview }}
|
||||||
useLatestWebView2: ${{ parameters.useLatestWebView2 }}
|
useLatestWebView2: ${{ parameters.useLatestWebView2 }}
|
||||||
uiTestModules: ${{ parameters.uiTestModules }}
|
uiTestModules: ${{ parameters.uiTestModules }}
|
||||||
|
pool: ${{ parameters.pool }}
|
||||||
|
|
||||||
# Official build path: build UI tests only + download official build + run tests
|
# Official build path: build UI tests only + download official build + run tests
|
||||||
- ${{ if ne(parameters.buildSource, 'buildNow') }}:
|
- ${{ if ne(parameters.buildSource, 'buildNow') }}:
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ parameters:
|
|||||||
- name: uiTestModules
|
- name: uiTestModules
|
||||||
type: object
|
type: object
|
||||||
default: []
|
default: []
|
||||||
|
- name: pool
|
||||||
|
type: string
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
# Stage 1: Build full PowerToys project
|
# Stage 1: Build full PowerToys project
|
||||||
@@ -23,13 +25,7 @@ stages:
|
|||||||
jobs:
|
jobs:
|
||||||
- template: job-build-project.yml
|
- template: job-build-project.yml
|
||||||
parameters:
|
parameters:
|
||||||
pool:
|
pool: [ ${{ 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:
|
buildPlatforms:
|
||||||
- ${{ parameters.platform }}
|
- ${{ parameters.platform }}
|
||||||
buildConfigurations: [Release]
|
buildConfigurations: [Release]
|
||||||
|
|||||||
@@ -793,6 +793,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Window
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.UnitTestBase", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.UnitTestsBase\Microsoft.CmdPal.Ext.UnitTestBase.csproj", "{00D8659C-2068-40B6-8B86-759CD6284BBB}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.UnitTestBase", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.UnitTestsBase\Microsoft.CmdPal.Ext.UnitTestBase.csproj", "{00D8659C-2068-40B6-8B86-759CD6284BBB}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{E11826E1-76DF-42AC-985C-164CC2EE57A1}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScreenRuler.UITests", "src\modules\MeasureTool\Tests\ScreenRuler.UITests\ScreenRuler.UITests.csproj", "{66C069F8-C548-4CA6-8CDE-239104D68E88}"
|
||||||
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Apps.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.Apps.UnitTests\Microsoft.CmdPal.Ext.Apps.UnitTests.csproj", "{E816D7B1-4688-4ECB-97CC-3D8E798F3830}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Apps.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.Apps.UnitTests\Microsoft.CmdPal.Ext.Apps.UnitTests.csproj", "{E816D7B1-4688-4ECB-97CC-3D8E798F3830}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Bookmarks.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.Bookmarks.UnitTests\Microsoft.CmdPal.Ext.Bookmarks.UnitTests.csproj", "{E816D7B3-4688-4ECB-97CC-3D8E798F3832}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Bookmarks.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.Bookmarks.UnitTests\Microsoft.CmdPal.Ext.Bookmarks.UnitTests.csproj", "{E816D7B3-4688-4ECB-97CC-3D8E798F3832}"
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ You can build the entire solution from the command line, which is sometimes fast
|
|||||||
1. Open Developer Command Prompt for VS 2022
|
1. Open Developer Command Prompt for VS 2022
|
||||||
2. Navigate to the repository root directory
|
2. Navigate to the repository root directory
|
||||||
3. Run the following command(don't forget to set the correct platform):
|
3. Run the following command(don't forget to set the correct platform):
|
||||||
```
|
```pwsh
|
||||||
msbuild -restore -p:RestorePackagesConfig=true -p:Platform=ARM64 -m PowerToys.sln
|
msbuild -restore -p:RestorePackagesConfig=true -p:Platform=ARM64 -m PowerToys.sln /tl /p:NuGetInteractive="true"
|
||||||
```
|
```
|
||||||
4. This process should complete in approximately 13-14 minutes for a full build
|
4. This process should complete in approximately 13-14 minutes for a full build
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ namespace Microsoft.PowerToys.UITest
|
|||||||
Workspaces,
|
Workspaces,
|
||||||
PowerRename,
|
PowerRename,
|
||||||
CommandPalette,
|
CommandPalette,
|
||||||
|
ScreenRuler,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -104,6 +105,7 @@ namespace Microsoft.PowerToys.UITest
|
|||||||
[PowerToysModule.Workspaces] = new ModuleInfo("PowerToys.WorkspacesEditor.exe", "Workspaces Editor"),
|
[PowerToysModule.Workspaces] = new ModuleInfo("PowerToys.WorkspacesEditor.exe", "Workspaces Editor"),
|
||||||
[PowerToysModule.PowerRename] = new ModuleInfo("PowerToys.PowerRename.exe", "PowerRename", "WinUI3Apps"),
|
[PowerToysModule.PowerRename] = new ModuleInfo("PowerToys.PowerRename.exe", "PowerRename", "WinUI3Apps"),
|
||||||
[PowerToysModule.CommandPalette] = new ModuleInfo("Microsoft.CmdPal.UI.exe", "PowerToys Command Palette", "WinUI3Apps\\CmdPal"),
|
[PowerToysModule.CommandPalette] = new ModuleInfo("Microsoft.CmdPal.UI.exe", "PowerToys Command Palette", "WinUI3Apps\\CmdPal"),
|
||||||
|
[PowerToysModule.ScreenRuler] = new ModuleInfo("PowerToys.MeasureToolUI.exe", "PowerToys.ScreenRuler", "WinUI3Apps"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:winuiex="using:WinUIEx"
|
xmlns:winuiex="using:WinUIEx"
|
||||||
|
Title="PowerToys.ScreenRuler"
|
||||||
IsAlwaysOnTop="True"
|
IsAlwaysOnTop="True"
|
||||||
IsMaximizable="False"
|
IsMaximizable="False"
|
||||||
IsMinimizable="False"
|
IsMinimizable="False"
|
||||||
@@ -250,6 +251,7 @@
|
|||||||
<ToggleButton
|
<ToggleButton
|
||||||
Name="btnBounds"
|
Name="btnBounds"
|
||||||
x:Uid="BtnBounds"
|
x:Uid="BtnBounds"
|
||||||
|
AutomationProperties.AutomationId="Button_Bounds"
|
||||||
Click="BoundsTool_Click"
|
Click="BoundsTool_Click"
|
||||||
Content=""
|
Content=""
|
||||||
KeyboardAcceleratorPlacementMode="Auto"
|
KeyboardAcceleratorPlacementMode="Auto"
|
||||||
@@ -267,6 +269,7 @@
|
|||||||
<ToggleButton
|
<ToggleButton
|
||||||
Name="btnSpacing"
|
Name="btnSpacing"
|
||||||
x:Uid="BtnSpacing"
|
x:Uid="BtnSpacing"
|
||||||
|
AutomationProperties.AutomationId="Button_Spacing"
|
||||||
Click="MeasureTool_Click"
|
Click="MeasureTool_Click"
|
||||||
Style="{StaticResource ToggleButtonRadioButtonStyle}">
|
Style="{StaticResource ToggleButtonRadioButtonStyle}">
|
||||||
<ToolTipService.ToolTip>
|
<ToolTipService.ToolTip>
|
||||||
@@ -284,6 +287,7 @@
|
|||||||
<ToggleButton
|
<ToggleButton
|
||||||
Name="btnHorizontalSpacing"
|
Name="btnHorizontalSpacing"
|
||||||
x:Uid="BtnHorizontalSpacing"
|
x:Uid="BtnHorizontalSpacing"
|
||||||
|
AutomationProperties.AutomationId="Button_SpacingHorizontal"
|
||||||
Click="HorizontalMeasureTool_Click"
|
Click="HorizontalMeasureTool_Click"
|
||||||
Style="{StaticResource ToggleButtonRadioButtonStyle}">
|
Style="{StaticResource ToggleButtonRadioButtonStyle}">
|
||||||
<ToolTipService.ToolTip>
|
<ToolTipService.ToolTip>
|
||||||
@@ -304,6 +308,7 @@
|
|||||||
<ToggleButton
|
<ToggleButton
|
||||||
Name="btnVerticalSpacing"
|
Name="btnVerticalSpacing"
|
||||||
x:Uid="BtnVerticalSpacing"
|
x:Uid="BtnVerticalSpacing"
|
||||||
|
AutomationProperties.AutomationId="Button_SpacingVertical"
|
||||||
Click="VerticalMeasureTool_Click"
|
Click="VerticalMeasureTool_Click"
|
||||||
Style="{StaticResource ToggleButtonRadioButtonStyle}">
|
Style="{StaticResource ToggleButtonRadioButtonStyle}">
|
||||||
<ToolTipService.ToolTip>
|
<ToolTipService.ToolTip>
|
||||||
@@ -324,6 +329,7 @@
|
|||||||
<AppBarSeparator />
|
<AppBarSeparator />
|
||||||
<Button
|
<Button
|
||||||
x:Uid="BtnClosePanel"
|
x:Uid="BtnClosePanel"
|
||||||
|
AutomationProperties.AutomationId="Button_Close"
|
||||||
Click="ClosePanelTool_Click"
|
Click="ClosePanelTool_Click"
|
||||||
Content=""
|
Content=""
|
||||||
Foreground="{StaticResource CloseButtonBackgroundPointerOver}">
|
Foreground="{StaticResource CloseButtonBackgroundPointerOver}">
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<Package
|
||||||
|
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||||
|
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||||
|
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||||
|
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||||
|
IgnorableNamespaces="uap rescap">
|
||||||
|
|
||||||
|
<Identity
|
||||||
|
Name="d4d0f157-5c12-4390-9689-152b0c86a582"
|
||||||
|
Publisher="CN=gkhmyznikov"
|
||||||
|
Version="1.0.0.0" />
|
||||||
|
|
||||||
|
<mp:PhoneIdentity PhoneProductId="d4d0f157-5c12-4390-9689-152b0c86a582" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||||
|
|
||||||
|
<Properties>
|
||||||
|
<DisplayName>ScreenRuler.UITests</DisplayName>
|
||||||
|
<PublisherDisplayName>gkhmyznikov</PublisherDisplayName>
|
||||||
|
<Logo>Assets\StoreLogo.png</Logo>
|
||||||
|
</Properties>
|
||||||
|
|
||||||
|
<Dependencies>
|
||||||
|
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
|
||||||
|
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
|
||||||
|
</Dependencies>
|
||||||
|
|
||||||
|
<Resources>
|
||||||
|
<Resource Language="x-generate"/>
|
||||||
|
</Resources>
|
||||||
|
|
||||||
|
<Applications>
|
||||||
|
<Application Id="App"
|
||||||
|
Executable="$targetnametoken$.exe"
|
||||||
|
EntryPoint="$targetentrypoint$">
|
||||||
|
<uap:VisualElements
|
||||||
|
DisplayName="ScreenRuler.UITests"
|
||||||
|
Description="ScreenRuler.UITests"
|
||||||
|
BackgroundColor="transparent"
|
||||||
|
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||||
|
Square44x44Logo="Assets\Square44x44Logo.png">
|
||||||
|
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
|
||||||
|
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||||
|
</uap:VisualElements>
|
||||||
|
</Application>
|
||||||
|
</Applications>
|
||||||
|
|
||||||
|
<Capabilities>
|
||||||
|
<rescap:Capability Name="runFullTrust" />
|
||||||
|
</Capabilities>
|
||||||
|
</Package>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<Import Project="..\..\..\..\Common.Dotnet.CsWinRT.props" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<RootNamespace>PowerToys.ScreenRuler.UITests</RootNamespace>
|
||||||
|
<AssemblyName>ScreenRuler.UITests</AssemblyName>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
|
||||||
|
<!-- This is a UI test, so don't run as part of MSBuild -->
|
||||||
|
<RunVSTest>false</RunVSTest>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\tests\ScreenRuler.UITests\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="MSTest" />
|
||||||
|
<ProjectReference Include="..\..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// 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 Microsoft.PowerToys.UITest;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace ScreenRuler.UITests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class TestBounds : UITestBase
|
||||||
|
{
|
||||||
|
public TestBounds()
|
||||||
|
: base(PowerToysModule.PowerToysSettings, WindowSize.Large)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod("ScreenRuler.BoundsTool")]
|
||||||
|
[TestCategory("Spacing")]
|
||||||
|
public void TestScreenRulerBoundsTool()
|
||||||
|
{
|
||||||
|
TestHelper.InitializeTest(this, "bounds test");
|
||||||
|
TestHelper.PerformBoundsToolTest(this);
|
||||||
|
TestHelper.CleanupTest(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
466
src/modules/MeasureTool/Tests/ScreenRuler.UITests/TestHelper.cs
Normal file
466
src/modules/MeasureTool/Tests/ScreenRuler.UITests/TestHelper.cs
Normal file
@@ -0,0 +1,466 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.PowerToys.UITest;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace ScreenRuler.UITests
|
||||||
|
{
|
||||||
|
public static class TestHelper
|
||||||
|
{
|
||||||
|
private static readonly string[] ShortcutSeparators = { " + ", "+", " " };
|
||||||
|
|
||||||
|
// Button automation names from Resources.resw
|
||||||
|
public const string BoundsButtonId = "Button_Bounds";
|
||||||
|
public const string SpacingButtonName = "Button_Spacing";
|
||||||
|
public const string HorizontalSpacingButtonName = "Button_SpacingHorizontal";
|
||||||
|
public const string VerticalSpacingButtonName = "Button_SpacingVertical";
|
||||||
|
public const string CloseButtonId = "Button_Close";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs common test initialization: navigate to settings, enable toggle, verify shortcut
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="testBase">The test base instance</param>
|
||||||
|
/// <param name="testName">Name of the test for assertions</param>
|
||||||
|
/// <returns>The activation keys for the test</returns>
|
||||||
|
public static Key[] InitializeTest(UITestBase testBase, string testName)
|
||||||
|
{
|
||||||
|
LaunchFromSetting(testBase);
|
||||||
|
|
||||||
|
var toggleSwitch = SetScreenRulerToggle(testBase, enable: true);
|
||||||
|
Assert.IsTrue(
|
||||||
|
toggleSwitch.IsOn,
|
||||||
|
$"Screen Ruler toggle switch should be ON for {testName}");
|
||||||
|
|
||||||
|
var activationKeys = ReadActivationShortcut(testBase);
|
||||||
|
Assert.IsNotNull(activationKeys, "Should be able to read activation shortcut");
|
||||||
|
Assert.IsTrue(activationKeys.Length > 0, "Activation shortcut should contain at least one key");
|
||||||
|
|
||||||
|
return activationKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs common test cleanup: close ScreenRuler UI
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="testBase">The test base instance</param>
|
||||||
|
public static void CleanupTest(UITestBase testBase)
|
||||||
|
{
|
||||||
|
CloseScreenRulerUI(testBase);
|
||||||
|
|
||||||
|
// Ensure we're attached to settings after cleanup
|
||||||
|
try
|
||||||
|
{
|
||||||
|
testBase.Session.Attach(PowerToysModule.PowerToysSettings);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore attachment errors - this is just cleanup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Navigate to the Screen Ruler (Measure Tool) settings page
|
||||||
|
/// </summary>
|
||||||
|
public static void LaunchFromSetting(UITestBase testBase)
|
||||||
|
{
|
||||||
|
var screenRulers = testBase.Session.FindAll<NavigationViewItem>(By.AccessibilityId("Shell_Nav_ScreenRuler"));
|
||||||
|
|
||||||
|
if (screenRulers.Count == 0)
|
||||||
|
{
|
||||||
|
testBase.Session.Find<NavigationViewItem>(By.AccessibilityId("Shell_Nav_TopLevelSystemTools"), 5000).Click(msPostAction: 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
testBase.Session.Find<NavigationViewItem>(By.AccessibilityId("Shell_Nav_ScreenRuler"), 5000).Click(msPostAction: 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the Screen Ruler toggle switch to the specified state
|
||||||
|
/// </summary>
|
||||||
|
public static ToggleSwitch SetScreenRulerToggle(UITestBase testBase, bool enable)
|
||||||
|
{
|
||||||
|
var toggleSwitch = testBase.Session.Find<ToggleSwitch>(By.AccessibilityId("Toggle_ScreenRuler"), 5000);
|
||||||
|
|
||||||
|
if (toggleSwitch.IsOn != enable)
|
||||||
|
{
|
||||||
|
toggleSwitch.Click(msPreAction: 1000, msPostAction: 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toggleSwitch.IsOn != enable)
|
||||||
|
{
|
||||||
|
testBase.Session.SendKey(Key.Space, msPreAction: 0, msPostAction: 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toggleSwitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the Screen Ruler toggle and verify its state
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="testBase">The test base instance</param>
|
||||||
|
/// <param name="enable">True to enable, false to disable</param>
|
||||||
|
/// <param name="testName">Name of the test for assertion messages</param>
|
||||||
|
public static void SetAndVerifyScreenRulerToggle(UITestBase testBase, bool enable, string testName)
|
||||||
|
{
|
||||||
|
var toggleSwitch = SetScreenRulerToggle(testBase, enable);
|
||||||
|
Assert.AreEqual(
|
||||||
|
enable,
|
||||||
|
toggleSwitch.IsOn,
|
||||||
|
$"Screen Ruler toggle switch should be {(enable ? "ON" : "OFF")} for {testName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read the current activation shortcut from the ShortcutControl
|
||||||
|
/// </summary>
|
||||||
|
public static Key[] ReadActivationShortcut(UITestBase testBase)
|
||||||
|
{
|
||||||
|
var shortcutCard = testBase.Session.Find<Element>(By.AccessibilityId("Shortcut_ScreenRuler"), 5000);
|
||||||
|
var shortcutButton = shortcutCard.Find<Element>(By.AccessibilityId("EditButton"), 5000);
|
||||||
|
return ParseShortcutText(shortcutButton.HelpText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse shortcut text like "Win + Ctrl + Shift + M" into Key array
|
||||||
|
/// </summary>
|
||||||
|
private static Key[] ParseShortcutText(string shortcutText)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(shortcutText))
|
||||||
|
{
|
||||||
|
return new Key[] { Key.Win, Key.Ctrl, Key.Shift, Key.M };
|
||||||
|
}
|
||||||
|
|
||||||
|
var keys = new List<Key>();
|
||||||
|
var parts = shortcutText.Split(ShortcutSeparators, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
foreach (var part in parts)
|
||||||
|
{
|
||||||
|
var cleanPart = part.Trim().ToLowerInvariant();
|
||||||
|
var key = cleanPart switch
|
||||||
|
{
|
||||||
|
"win" or "windows" => Key.Win,
|
||||||
|
"ctrl" or "control" => Key.Ctrl,
|
||||||
|
"shift" => Key.Shift,
|
||||||
|
"alt" => Key.Alt,
|
||||||
|
_ when cleanPart.Length == 1 && char.IsLetter(cleanPart[0]) &&
|
||||||
|
cleanPart[0] >= 'a' && cleanPart[0] <= 'z' =>
|
||||||
|
(Key)Enum.Parse(typeof(Key), cleanPart.ToUpperInvariant()),
|
||||||
|
_ => (Key?)null,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (key.HasValue)
|
||||||
|
{
|
||||||
|
keys.Add(key.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys.Count > 0 ? keys.ToArray() : new Key[] { Key.Win, Key.Ctrl, Key.Shift, Key.M };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if ScreenRulerUI window is open
|
||||||
|
/// </summary>
|
||||||
|
public static bool IsScreenRulerUIOpen(UITestBase testBase) => testBase.IsWindowOpen("PowerToys.ScreenRuler");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wait for ScreenRulerUI to reach the specified state within the timeout
|
||||||
|
/// </summary>
|
||||||
|
public static bool WaitForScreenRulerUIState(UITestBase testBase, bool shouldBeOpen, int timeoutMs = 5000, int pollingIntervalMs = 100)
|
||||||
|
{
|
||||||
|
var endTime = DateTime.Now.AddMilliseconds(timeoutMs);
|
||||||
|
|
||||||
|
while (DateTime.Now < endTime)
|
||||||
|
{
|
||||||
|
if (IsScreenRulerUIOpen(testBase) == shouldBeOpen)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Task.Delay(pollingIntervalMs).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wait for ScreenRulerUI to appear within the specified timeout
|
||||||
|
/// </summary>
|
||||||
|
public static bool WaitForScreenRulerUI(UITestBase testBase, int timeoutMs = 5000) =>
|
||||||
|
WaitForScreenRulerUIState(testBase, shouldBeOpen: true, timeoutMs);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wait for ScreenRulerUI to disappear within the specified timeout
|
||||||
|
/// </summary>
|
||||||
|
public static bool WaitForScreenRulerUIToDisappear(UITestBase testBase, int timeoutMs = 5000) =>
|
||||||
|
WaitForScreenRulerUIState(testBase, shouldBeOpen: false, timeoutMs);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Close ScreenRulerUI if it's open
|
||||||
|
/// </summary>
|
||||||
|
public static void CloseScreenRulerUI(UITestBase testBase)
|
||||||
|
{
|
||||||
|
if (IsScreenRulerUIOpen(testBase))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Attach to ScreenRuler window before trying to find and click close button
|
||||||
|
testBase.Session.Attach(PowerToysModule.ScreenRuler);
|
||||||
|
var closeButton = testBase.Session.Find<Element>(By.AccessibilityId(CloseButtonId), 15000, true);
|
||||||
|
closeButton?.Click();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// If we can't find the close button, ignore - the window might have closed already
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Attach back to settings after closing
|
||||||
|
try
|
||||||
|
{
|
||||||
|
testBase.Session.Attach(PowerToysModule.PowerToysSettings);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore attachment errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a specific ScreenRulerUI button by its automation name
|
||||||
|
/// </summary>
|
||||||
|
public static Element? GetScreenRulerButton(UITestBase testBase, string buttonName, int timeoutMs = 1000)
|
||||||
|
{
|
||||||
|
return testBase.Session.Find<Element>(By.AccessibilityId(buttonName), timeoutMs, true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Attach to ScreenRuler window before trying to find buttons
|
||||||
|
testBase.Session.Attach(PowerToysModule.ScreenRuler);
|
||||||
|
return testBase.Session.Find<Element>(By.AccessibilityId(buttonName), timeoutMs, true);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Attach back to settings if needed for further operations
|
||||||
|
// This ensures we don't break the test flow
|
||||||
|
try
|
||||||
|
{
|
||||||
|
testBase.Session.Attach(PowerToysModule.PowerToysSettings);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore attachment errors - the calling code will handle as needed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clear the clipboard content using STA thread
|
||||||
|
/// </summary>
|
||||||
|
public static void ClearClipboard()
|
||||||
|
{
|
||||||
|
ExecuteInSTAThread(() => System.Windows.Forms.Clipboard.Clear());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get text content from clipboard using STA thread
|
||||||
|
/// </summary>
|
||||||
|
public static string GetClipboardText()
|
||||||
|
{
|
||||||
|
string result = string.Empty;
|
||||||
|
ExecuteInSTAThread(() =>
|
||||||
|
{
|
||||||
|
if (System.Windows.Forms.Clipboard.ContainsText())
|
||||||
|
{
|
||||||
|
result = System.Windows.Forms.Clipboard.GetText();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute an action in an STA thread with error handling
|
||||||
|
/// </summary>
|
||||||
|
private static void ExecuteInSTAThread(Action action)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var staThread = new Thread(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore clipboard errors
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
staThread.SetApartmentState(ApartmentState.STA);
|
||||||
|
staThread.Start();
|
||||||
|
staThread.Join(TimeSpan.FromSeconds(5));
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore clipboard errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate clipboard content contains valid spacing measurement for the specified type
|
||||||
|
/// </summary>
|
||||||
|
public static bool ValidateSpacingClipboardContent(string clipboardText, string spacingType)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(clipboardText))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return spacingType switch
|
||||||
|
{
|
||||||
|
"Spacing" => Regex.IsMatch(clipboardText, @"\d+\s*[<5B>x]\s*\d+"),
|
||||||
|
"Horizontal Spacing" or "Vertical Spacing" => Regex.IsMatch(clipboardText, @"^\d+$"),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Perform a complete spacing tool test operation
|
||||||
|
/// </summary>
|
||||||
|
public static void PerformSpacingToolTest(UITestBase testBase, string buttonId, string testName)
|
||||||
|
{
|
||||||
|
ClearClipboard();
|
||||||
|
|
||||||
|
// Launch ScreenRuler UI
|
||||||
|
var activationKeys = ReadActivationShortcut(testBase);
|
||||||
|
testBase.SendKeys(activationKeys);
|
||||||
|
|
||||||
|
Assert.IsTrue(
|
||||||
|
WaitForScreenRulerUI(testBase, 2000),
|
||||||
|
$"ScreenRulerUI should appear after pressing activation shortcut for {testName}: {string.Join(" + ", activationKeys)}");
|
||||||
|
|
||||||
|
// Attach to ScreenRuler window and click spacing button
|
||||||
|
// testBase.Session.Attach(PowerToysModule.ScreenRuler);
|
||||||
|
var spacingButton = testBase.Session.Find<Element>(By.AccessibilityId(buttonId), 15000, true);
|
||||||
|
Assert.IsNotNull(spacingButton, $"{testName} button should be found");
|
||||||
|
|
||||||
|
spacingButton!.Click();
|
||||||
|
Task.Delay(500).Wait();
|
||||||
|
|
||||||
|
// Perform measurement action (stay attached to ScreenRuler for this)
|
||||||
|
PerformMeasurementAction(testBase);
|
||||||
|
|
||||||
|
// Validate results
|
||||||
|
ValidateClipboardResults(testName);
|
||||||
|
|
||||||
|
// Cleanup - this will handle session attachment properly
|
||||||
|
CloseScreenRulerUI(testBase);
|
||||||
|
Assert.IsTrue(
|
||||||
|
WaitForScreenRulerUIToDisappear(testBase, 2000),
|
||||||
|
$"{testName}: ScreenRulerUI should close after calling CloseScreenRulerUI");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Perform a bounds tool test operation
|
||||||
|
/// </summary>
|
||||||
|
public static void PerformBoundsToolTest(UITestBase testBase)
|
||||||
|
{
|
||||||
|
ClearClipboard();
|
||||||
|
|
||||||
|
var activationKeys = ReadActivationShortcut(testBase);
|
||||||
|
testBase.SendKeys(activationKeys);
|
||||||
|
|
||||||
|
Assert.IsTrue(
|
||||||
|
WaitForScreenRulerUI(testBase, 2000),
|
||||||
|
$"ScreenRulerUI should appear after pressing activation shortcut: {string.Join(" + ", activationKeys)}");
|
||||||
|
|
||||||
|
// Attach to ScreenRuler window and click bounds button
|
||||||
|
// testBase.Session.Attach(PowerToysModule.ScreenRuler);
|
||||||
|
var boundsButton = testBase.Session.Find<Element>(By.AccessibilityId(BoundsButtonId), 15000, true);
|
||||||
|
Assert.IsNotNull(boundsButton, "Bounds button should be found");
|
||||||
|
|
||||||
|
boundsButton.Click();
|
||||||
|
Task.Delay(500).Wait();
|
||||||
|
|
||||||
|
// Perform drag operation to create 100x100 box (stay attached to ScreenRuler)
|
||||||
|
var currentPos = testBase.GetMousePosition();
|
||||||
|
int startX = currentPos.Item1;
|
||||||
|
int startY = currentPos.Item2 + 200;
|
||||||
|
|
||||||
|
testBase.MoveMouseTo(startX, startY);
|
||||||
|
Task.Delay(200).Wait();
|
||||||
|
|
||||||
|
// Drag operation
|
||||||
|
testBase.Session.PerformMouseAction(MouseActionType.LeftDown);
|
||||||
|
Task.Delay(100).Wait();
|
||||||
|
|
||||||
|
testBase.MoveMouseTo(startX + 99, startY + 99);
|
||||||
|
Task.Delay(200).Wait();
|
||||||
|
|
||||||
|
testBase.Session.PerformMouseAction(MouseActionType.LeftUp);
|
||||||
|
Task.Delay(500).Wait();
|
||||||
|
|
||||||
|
// Dismiss selection
|
||||||
|
testBase.Session.PerformMouseAction(MouseActionType.RightClick);
|
||||||
|
Task.Delay(500).Wait();
|
||||||
|
|
||||||
|
// Validate results
|
||||||
|
string clipboardText = GetClipboardText();
|
||||||
|
Assert.IsFalse(string.IsNullOrEmpty(clipboardText), "Clipboard should contain measurement data");
|
||||||
|
Assert.IsTrue(
|
||||||
|
clipboardText.Contains("100 <20> 100"),
|
||||||
|
$"Clipboard should contain '100 <20> 100', but contained: '{clipboardText}'");
|
||||||
|
|
||||||
|
// Cleanup - this will handle session attachment properly
|
||||||
|
CloseScreenRulerUI(testBase);
|
||||||
|
Assert.IsTrue(
|
||||||
|
WaitForScreenRulerUIToDisappear(testBase, 2000),
|
||||||
|
"ScreenRulerUI should close after calling CloseScreenRulerUI");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Perform a measurement action (move mouse and click)
|
||||||
|
/// </summary>
|
||||||
|
private static void PerformMeasurementAction(UITestBase testBase)
|
||||||
|
{
|
||||||
|
var currentPos = testBase.GetMousePosition();
|
||||||
|
int startX = currentPos.Item1;
|
||||||
|
int startY = currentPos.Item2 + 200;
|
||||||
|
|
||||||
|
testBase.MoveMouseTo(startX, startY);
|
||||||
|
Task.Delay(200).Wait();
|
||||||
|
|
||||||
|
testBase.Session.PerformMouseAction(MouseActionType.LeftClick);
|
||||||
|
Task.Delay(500).Wait();
|
||||||
|
|
||||||
|
testBase.Session.PerformMouseAction(MouseActionType.RightClick);
|
||||||
|
Task.Delay(500).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate clipboard results for spacing tests
|
||||||
|
/// </summary>
|
||||||
|
private static void ValidateClipboardResults(string testName)
|
||||||
|
{
|
||||||
|
string clipboardText = GetClipboardText();
|
||||||
|
Assert.IsFalse(string.IsNullOrEmpty(clipboardText), $"{testName}: Clipboard should contain measurement data");
|
||||||
|
|
||||||
|
bool containsValidPattern = ValidateSpacingClipboardContent(clipboardText, testName);
|
||||||
|
Assert.IsTrue(
|
||||||
|
containsValidPattern,
|
||||||
|
$"{testName}: Clipboard should contain valid spacing measurement, but contained: '{clipboardText}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
// 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.Threading.Tasks;
|
||||||
|
using Microsoft.PowerToys.UITest;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace ScreenRuler.UITests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class TestShortcutActivation : UITestBase
|
||||||
|
{
|
||||||
|
public TestShortcutActivation()
|
||||||
|
: base(PowerToysModule.PowerToysSettings, WindowSize.Large)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod("ScreenRuler.ShortcutActivation")]
|
||||||
|
[TestCategory("Activation")]
|
||||||
|
public void TestScreenRulerShortcutActivation()
|
||||||
|
{
|
||||||
|
var activationKeys = TestHelper.InitializeTest(this, "activation test");
|
||||||
|
|
||||||
|
// Test 1: Press the activation shortcut and verify the toolbar appears
|
||||||
|
SendKeys(activationKeys);
|
||||||
|
bool screenRulerAppeared = TestHelper.WaitForScreenRulerUI(this, 1000);
|
||||||
|
Assert.IsTrue(
|
||||||
|
screenRulerAppeared,
|
||||||
|
$"ScreenRulerUI should appear after pressing activation shortcut: {string.Join(" + ", activationKeys)}");
|
||||||
|
|
||||||
|
// Test 2: Press the activation shortcut again and verify the toolbar disappears
|
||||||
|
SendKeys(activationKeys);
|
||||||
|
bool screenRulerDisappeared = TestHelper.WaitForScreenRulerUIToDisappear(this, 1000);
|
||||||
|
Assert.IsTrue(
|
||||||
|
screenRulerDisappeared,
|
||||||
|
$"ScreenRulerUI should disappear after pressing activation shortcut again: {string.Join(" + ", activationKeys)}");
|
||||||
|
|
||||||
|
// Test 3: Disable Screen Ruler and verify that the activation shortcut no longer activates the utility
|
||||||
|
// Ensure we're attached to settings UI before toggling
|
||||||
|
Session.Attach(PowerToysModule.PowerToysSettings);
|
||||||
|
TestHelper.SetAndVerifyScreenRulerToggle(this, enable: false, "disabled state test");
|
||||||
|
|
||||||
|
// Try to activate with shortcut while disabled
|
||||||
|
SendKeys(activationKeys);
|
||||||
|
Task.Delay(1000).Wait();
|
||||||
|
Assert.IsFalse(
|
||||||
|
TestHelper.IsScreenRulerUIOpen(this),
|
||||||
|
"ScreenRulerUI should not appear when Screen Ruler is disabled");
|
||||||
|
|
||||||
|
// Test 4: Enable Screen Ruler and press the activation shortcut and verify the toolbar appears
|
||||||
|
// Ensure we're attached to settings UI before toggling
|
||||||
|
Session.Attach(PowerToysModule.PowerToysSettings);
|
||||||
|
TestHelper.SetAndVerifyScreenRulerToggle(this, enable: true, "re-enabled state test");
|
||||||
|
|
||||||
|
SendKeys(activationKeys);
|
||||||
|
screenRulerAppeared = TestHelper.WaitForScreenRulerUI(this, 1000);
|
||||||
|
Assert.IsTrue(
|
||||||
|
screenRulerAppeared,
|
||||||
|
$"ScreenRulerUI should appear after re-enabling and pressing activation shortcut: {string.Join(" + ", activationKeys)}");
|
||||||
|
|
||||||
|
// Test 5: Verify the utility can be closed via the cleanup method
|
||||||
|
TestHelper.CloseScreenRulerUI(this);
|
||||||
|
bool screenRulerClosed = TestHelper.WaitForScreenRulerUIToDisappear(this, 1000);
|
||||||
|
Assert.IsTrue(
|
||||||
|
screenRulerClosed,
|
||||||
|
"ScreenRulerUI should close after calling CloseScreenRulerUI");
|
||||||
|
|
||||||
|
TestHelper.CleanupTest(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// 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 Microsoft.PowerToys.UITest;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace ScreenRuler.UITests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class TestSpacing : UITestBase
|
||||||
|
{
|
||||||
|
public TestSpacing()
|
||||||
|
: base(PowerToysModule.PowerToysSettings, WindowSize.Large)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod("ScreenRuler.SpacingTool")]
|
||||||
|
[TestCategory("Spacing")]
|
||||||
|
public void TestScreenRulerSpacingTool()
|
||||||
|
{
|
||||||
|
TestHelper.InitializeTest(this, "spacing test");
|
||||||
|
TestHelper.PerformSpacingToolTest(this, TestHelper.SpacingButtonName, "Spacing");
|
||||||
|
TestHelper.CleanupTest(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// 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 Microsoft.PowerToys.UITest;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace ScreenRuler.UITests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class TestSpacingHorizontal : UITestBase
|
||||||
|
{
|
||||||
|
public TestSpacingHorizontal()
|
||||||
|
: base(PowerToysModule.PowerToysSettings, WindowSize.Large)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod("ScreenRuler.HorizontalSpacingTool")]
|
||||||
|
[TestCategory("Spacing")]
|
||||||
|
public void TestScreenRulerHorizontalSpacingTool()
|
||||||
|
{
|
||||||
|
TestHelper.InitializeTest(this, "horizontal spacing test");
|
||||||
|
TestHelper.PerformSpacingToolTest(this, TestHelper.HorizontalSpacingButtonName, "Horizontal Spacing");
|
||||||
|
TestHelper.CleanupTest(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// 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 Microsoft.PowerToys.UITest;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace ScreenRuler.UITests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class TestSpacingVertical : UITestBase
|
||||||
|
{
|
||||||
|
public TestSpacingVertical()
|
||||||
|
: base(PowerToysModule.PowerToysSettings, WindowSize.Large)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod("ScreenRuler.VerticalSpacingTool")]
|
||||||
|
[TestCategory("Spacing")]
|
||||||
|
public void TestScreenRulerVerticalSpacingTool()
|
||||||
|
{
|
||||||
|
TestHelper.InitializeTest(this, "vertical spacing test");
|
||||||
|
TestHelper.PerformSpacingToolTest(this, TestHelper.VerticalSpacingButtonName, "Vertical Spacing");
|
||||||
|
TestHelper.CleanupTest(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<assemblyIdentity version="1.0.0.0" name="ScreenRuler.UITests.app"/>
|
||||||
|
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<!-- The ID below informs the system that this application is compatible with OS features first introduced in Windows 10.
|
||||||
|
It is necessary to support features in unpackaged applications, for example the custom titlebar implementation.
|
||||||
|
For more info see https://docs.microsoft.com/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time#declare-os-compatibility-in-your-application-manifest -->
|
||||||
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
|
||||||
|
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<windowsSettings>
|
||||||
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||||
|
</windowsSettings>
|
||||||
|
</application>
|
||||||
|
</assembly>
|
||||||
@@ -19,7 +19,10 @@
|
|||||||
x:Uid="MeasureTool_EnableMeasureTool"
|
x:Uid="MeasureTool_EnableMeasureTool"
|
||||||
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ScreenRuler.png}"
|
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ScreenRuler.png}"
|
||||||
IsEnabled="{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}">
|
IsEnabled="{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}">
|
||||||
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
|
<ToggleSwitch
|
||||||
|
x:Uid="ToggleSwitch"
|
||||||
|
AutomationProperties.AutomationId="Toggle_ScreenRuler"
|
||||||
|
IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
|
||||||
</tkcontrols:SettingsCard>
|
</tkcontrols:SettingsCard>
|
||||||
<InfoBar
|
<InfoBar
|
||||||
x:Uid="GPO_SettingIsManaged"
|
x:Uid="GPO_SettingIsManaged"
|
||||||
@@ -36,7 +39,10 @@
|
|||||||
Name="MeasureToolActivationShortcut"
|
Name="MeasureToolActivationShortcut"
|
||||||
x:Uid="MeasureTool_ActivationShortcut"
|
x:Uid="MeasureTool_ActivationShortcut"
|
||||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||||
<controls:ShortcutControl MinWidth="{StaticResource SettingActionControlMinWidth}" HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" />
|
<controls:ShortcutControl
|
||||||
|
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||||
|
AutomationProperties.AutomationId="Shortcut_ScreenRuler"
|
||||||
|
HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" />
|
||||||
</tkcontrols:SettingsCard>
|
</tkcontrols:SettingsCard>
|
||||||
<tkcontrols:SettingsCard Name="MeasureToolDefaultMeasureStyle" x:Uid="MeasureTool_DefaultMeasureStyle">
|
<tkcontrols:SettingsCard Name="MeasureToolDefaultMeasureStyle" x:Uid="MeasureTool_DefaultMeasureStyle">
|
||||||
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.DefaultMeasureStyle, Mode=TwoWay}">
|
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.DefaultMeasureStyle, Mode=TwoWay}">
|
||||||
|
|||||||
@@ -174,6 +174,7 @@
|
|||||||
<!-- System Tools -->
|
<!-- System Tools -->
|
||||||
<NavigationViewItem
|
<NavigationViewItem
|
||||||
x:Uid="Shell_TopLevelSystemTools"
|
x:Uid="Shell_TopLevelSystemTools"
|
||||||
|
AutomationProperties.AutomationId="Shell_Nav_TopLevelSystemTools"
|
||||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/SystemTools.png}"
|
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/SystemTools.png}"
|
||||||
SelectsOnInvoked="False">
|
SelectsOnInvoked="False">
|
||||||
<NavigationViewItem.MenuItems>
|
<NavigationViewItem.MenuItems>
|
||||||
@@ -200,6 +201,7 @@
|
|||||||
<NavigationViewItem
|
<NavigationViewItem
|
||||||
x:Uid="Shell_MeasureTool"
|
x:Uid="Shell_MeasureTool"
|
||||||
helpers:NavHelper.NavigateTo="views:MeasureToolPage"
|
helpers:NavHelper.NavigateTo="views:MeasureToolPage"
|
||||||
|
AutomationProperties.AutomationId="Shell_Nav_ScreenRuler"
|
||||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ScreenRuler.png}" />
|
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ScreenRuler.png}" />
|
||||||
<NavigationViewItem
|
<NavigationViewItem
|
||||||
x:Uid="Shell_ShortcutGuide"
|
x:Uid="Shell_ShortcutGuide"
|
||||||
|
|||||||
Reference in New Issue
Block a user