mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-11-27 14:59:16 +08:00
[FancyZones]UI testing that works in CI (#29453)
* added test project * run fz test * rename proj * editor test project * check if FZ is running * rename * added assert messages * spelling * dev docs * spelling * update to latest stable * exclude ui tests deps * update packages list in notice.md * added sample tests * added file for tests run * removed unrecognized * removed run * fix test configuration * rename job * change dependance * run test template * removed condition * tabulation fix * removed arg * removed dependance * removed log * removed parameters * test * test * added parameters * pool * pool * vs test * dependance * download artifact * publish artifact * artifact publish conditions * artifact name, default download path * set folders * prepare dotnet and vstest platform * copy all * target dotnet8 * test build agents * set vs test version * spellcheck * set test platform version * package feed selector * hardcoded vstest location * are other tests running? * location * vstest.console * upd command * script path * search vstest.console * vs path * tools dir * check files * try full path * try vstest task * try full path in vstest task * change path, remove unnecessary * test with full vsconsole path * winappdriver task * changed args and condition * default address * added start operation type * task name * remove resolution * Update run-ui-tests-ci.yml * Update run-ui-tests-ci.yml * Update run-ui-tests-ci.yml * Update run-ui-tests-ci.yml * AgentResolution should be a string * Update run-ui-tests-ci.yml testing against what WinUI gallery has for agent * Update run-ui-tests-ci.yml * Update run-ui-tests-ci.yml * added WinAppDriver.exe * spellcheck * remove task * checkout * path * src dir variable * added init to the second project * set longer timeout * try waiting * rerun * log session info * exclude WinAppDriver files from spell-check * split io class: editor params * remove unnecessary * move data to the common project * io test helper * write retry * Moved constants * file utils * prepare editor files before launch * remove unused file * spellcheck * create directory * fixed cleaning up * remove WinAppDriver from deps * start WinAppDriver from the default installation path * installation script * Revert "spellcheck" This reverts commit4bdc395730
. * Revert "exclude WinAppDriver files from spell-check" This reverts commit21ee6db3f5
. * install * installation argument * spellcheck * change winappdriver path in fz tests * delete iohelper * update docs * deleted obsolete winappdriver tests * net version * try without vstest location * spellcheck * Revert "try without vstest location" This reverts commit7cd39f3ae6
. * moved json tag constants to the common project
This commit is contained in:
parent
c39e306784
commit
f6e7635a4e
4
.github/actions/spell-check/expect.txt
vendored
4
.github/actions/spell-check/expect.txt
vendored
@ -54,7 +54,7 @@ Apm
|
|||||||
APPBARDATA
|
APPBARDATA
|
||||||
appdata
|
appdata
|
||||||
APPEXECLINK
|
APPEXECLINK
|
||||||
appium
|
Appium
|
||||||
Applicationcan
|
Applicationcan
|
||||||
appmanifest
|
appmanifest
|
||||||
APPNAME
|
APPNAME
|
||||||
@ -929,6 +929,7 @@ mscorlib
|
|||||||
msdata
|
msdata
|
||||||
msedge
|
msedge
|
||||||
MSGFLT
|
MSGFLT
|
||||||
|
msiexec
|
||||||
MSIFASTINSTALL
|
MSIFASTINSTALL
|
||||||
MSIHANDLE
|
MSIHANDLE
|
||||||
msiquery
|
msiquery
|
||||||
@ -1716,6 +1717,7 @@ VSM
|
|||||||
vso
|
vso
|
||||||
vsonline
|
vsonline
|
||||||
vstemplate
|
vstemplate
|
||||||
|
vstest
|
||||||
VSTHRD
|
VSTHRD
|
||||||
VSTT
|
VSTT
|
||||||
vswhere
|
vswhere
|
||||||
|
15
.pipelines/InstallWinAppDriver.ps1
Normal file
15
.pipelines/InstallWinAppDriver.ps1
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
$ProgressPreference = 'SilentlyContinue'
|
||||||
|
|
||||||
|
$WinAppDriverDownloadUrl = "https://github.com/microsoft/WinAppDriver/releases/download/v1.2.1/WindowsApplicationDriver_1.2.1.msi"
|
||||||
|
|
||||||
|
# Download WinAppDriver and verify their hash sums
|
||||||
|
Invoke-WebRequest -Uri $WinAppDriverDownloadUrl -OutFile "$($ENV:Temp)\WindowsApplicationDriver_1.2.1.msi"
|
||||||
|
$Hash = (Get-FileHash -Algorithm SHA256 "$($ENV:Temp)\WindowsApplicationDriver_1.2.1.msi").Hash
|
||||||
|
if ($Hash -ne 'a76a8f4e44b29bad331acf6b6c248fcc65324f502f28826ad2acd5f3c80857fe')
|
||||||
|
{
|
||||||
|
Write-Error "$WinAppDriverHash"
|
||||||
|
throw "WindowsApplicationDriver_1.2.1.msi has unexpected SHA256 hash: $Hash"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install WinAppDriver
|
||||||
|
Start-Process msiexec.exe -Wait -ArgumentList "/I $($ENV:Temp)\WindowsApplicationDriver_1.2.1.msi /quiet /passive"
|
@ -33,4 +33,7 @@ jobs:
|
|||||||
platform: x64
|
platform: x64
|
||||||
- template: ./templates/build-powertoys-ci.yml
|
- template: ./templates/build-powertoys-ci.yml
|
||||||
parameters:
|
parameters:
|
||||||
platform: arm64
|
platform: arm64
|
||||||
|
- template: ./templates/run-ui-tests-ci.yml
|
||||||
|
parameters:
|
||||||
|
platform: x64
|
||||||
|
@ -299,3 +299,18 @@ steps:
|
|||||||
displayName: Publish Logs
|
displayName: Publish Logs
|
||||||
artifact: '$(System.JobDisplayName) logs'
|
artifact: '$(System.JobDisplayName) logs'
|
||||||
condition: always()
|
condition: always()
|
||||||
|
|
||||||
|
- task: CopyFiles@2
|
||||||
|
displayName: Copy Build Files
|
||||||
|
condition: and(succeeded(), ne(variables['BuildPlatform'],'arm64'))
|
||||||
|
inputs:
|
||||||
|
sourceFolder: '$(Build.SourcesDirectory)'
|
||||||
|
contents: '$(BuildPlatform)/$(BuildConfiguration)/**/*'
|
||||||
|
targetFolder: '$(Build.ArtifactStagingDirectory)\$(BuildPlatform)\$(BuildConfiguration)'
|
||||||
|
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
displayName: Publish Build Artifacts
|
||||||
|
condition: and(succeeded(), ne(variables['BuildPlatform'],'arm64'))
|
||||||
|
inputs:
|
||||||
|
pathToPublish: '$(Build.ArtifactStagingDirectory)\$(BuildPlatform)\$(BuildConfiguration)'
|
||||||
|
artifactName: build-$(BuildPlatform)-$(BuildConfiguration)
|
||||||
|
72
.pipelines/ci/templates/run-ui-tests-ci.yml
Normal file
72
.pipelines/ci/templates/run-ui-tests-ci.yml
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
parameters:
|
||||||
|
configuration: 'Release'
|
||||||
|
platform: ''
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: UITest
|
||||||
|
displayName: UI Test ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||||
|
dependsOn: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||||
|
variables:
|
||||||
|
SrcPath: $(Build.Repository.LocalPath)
|
||||||
|
pool:
|
||||||
|
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||||
|
name: SHINE-OSS-Testing-x64
|
||||||
|
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||||
|
name: SHINE-INT-Testing-x64
|
||||||
|
steps:
|
||||||
|
- checkout: self
|
||||||
|
fetchDepth: 1
|
||||||
|
submodules: false
|
||||||
|
clean: true
|
||||||
|
fetchTags: false
|
||||||
|
|
||||||
|
- task: DownloadPipelineArtifact@2
|
||||||
|
displayName: Download artifacts
|
||||||
|
inputs:
|
||||||
|
artifact: build-${{ parameters.platform }}-${{ parameters.configuration }}
|
||||||
|
path: $(Build.ArtifactStagingDirectory)
|
||||||
|
|
||||||
|
- task: UseDotNet@2
|
||||||
|
displayName: 'Use .NET 6 SDK'
|
||||||
|
inputs:
|
||||||
|
packageType: sdk
|
||||||
|
version: '6.x'
|
||||||
|
|
||||||
|
- task: UseDotNet@2
|
||||||
|
displayName: 'Use .NET 8 SDK'
|
||||||
|
inputs:
|
||||||
|
packageType: sdk
|
||||||
|
version: '8.x'
|
||||||
|
includePreviewVersions: true
|
||||||
|
|
||||||
|
- task: VisualStudioTestPlatformInstaller@1
|
||||||
|
displayName: Ensure VSTest Platform
|
||||||
|
|
||||||
|
- task: PowerShell@2
|
||||||
|
displayName: Download and install WinAppDriver
|
||||||
|
inputs:
|
||||||
|
targetType: filePath
|
||||||
|
filePath: '$(build.sourcesdirectory)\.pipelines\InstallWinAppDriver.ps1'
|
||||||
|
|
||||||
|
- task: ScreenResolutionUtility@1
|
||||||
|
inputs:
|
||||||
|
displaySettings: 'optimal'
|
||||||
|
|
||||||
|
- task: VSTest@2
|
||||||
|
displayName: 'UI Tests'
|
||||||
|
condition: and(succeeded(), ne(variables['BuildPlatform'],'arm64')) # No arm64 agents to run the tests.
|
||||||
|
inputs:
|
||||||
|
platform: '$(BuildPlatform)'
|
||||||
|
configuration: '$(BuildConfiguration)'
|
||||||
|
testSelector: 'testAssemblies'
|
||||||
|
searchFolder: '$(Build.ArtifactStagingDirectory)'
|
||||||
|
vstestLocationMethod: 'location' # otherwise fails to find vstest.console.exe
|
||||||
|
#vstestLocation: '$(Agent.ToolsDirectory)\VsTest\**\${{ parameters.platform }}\tools\net462\Common7\IDE\Extensions\TestPlatform'
|
||||||
|
vstestLocation: '$(Agent.ToolsDirectory)\VsTest\17.10.0-preview-24080-01\x64\tools\net462\Common7\IDE\Extensions\TestPlatform'
|
||||||
|
uiTests: true
|
||||||
|
rerunFailedTests: true
|
||||||
|
testAssemblyVer2: |
|
||||||
|
**\UITests-FancyZones.dll
|
||||||
|
**\UITests-FancyZonesEditor.dll
|
||||||
|
!**\obj\**
|
||||||
|
!**\ref\**
|
@ -15,7 +15,8 @@ Param(
|
|||||||
$referencedFileVersionsPerDll = @{}
|
$referencedFileVersionsPerDll = @{}
|
||||||
$totalFailures = 0
|
$totalFailures = 0
|
||||||
|
|
||||||
Get-ChildItem $targetDir -Recurse -Filter *.deps.json | ForEach-Object {
|
Get-ChildItem $targetDir -Recurse -Filter *.deps.json -Exclude UITests-FancyZones* | ForEach-Object {
|
||||||
|
# Temporarily exclude FancyZones UI tests because of Appium.WebDriver dependencies
|
||||||
$depsJsonFullFileName = $_.FullName
|
$depsJsonFullFileName = $_.FullName
|
||||||
$depsJsonFileName = $_.Name
|
$depsJsonFileName = $_.Name
|
||||||
$depsJson = Get-Content $depsJsonFullFileName | ConvertFrom-Json
|
$depsJson = Get-Content $depsJsonFullFileName | ConvertFrom-Json
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Appium.WebDriver" Version="4.2.1" />
|
<PackageVersion Include="Appium.WebDriver" Version="4.4.5" />
|
||||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||||
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.0.240109" />
|
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.0.240109" />
|
||||||
<PackageVersion Include="CommunityToolkit.WinUI.Collections" Version="8.0.240109" />
|
<PackageVersion Include="CommunityToolkit.WinUI.Collections" Version="8.0.240109" />
|
||||||
|
@ -1296,6 +1296,7 @@ EXHIBIT A -Mozilla Public License.
|
|||||||
|
|
||||||
## NuGet Packages used by PowerToys
|
## NuGet Packages used by PowerToys
|
||||||
|
|
||||||
|
- Appium.WebDriver 4.4.5
|
||||||
- CommunityToolkit.Mvvm 8.2.2
|
- CommunityToolkit.Mvvm 8.2.2
|
||||||
- CommunityToolkit.WinUI.Animations 8.0.240109
|
- CommunityToolkit.WinUI.Animations 8.0.240109
|
||||||
- CommunityToolkit.WinUI.Collections 8.0.240109
|
- CommunityToolkit.WinUI.Collections 8.0.240109
|
||||||
|
@ -568,6 +568,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithContextMenu",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithLib", "src\modules\FileLocksmith\FileLocksmithLib\FileLocksmithLib.vcxproj", "{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithLib", "src\modules\FileLocksmith\FileLocksmithLib\FileLocksmithLib.vcxproj", "{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UITests-FancyZones", "src\modules\fancyzones\UITests-FancyZones\UITests-FancyZones.csproj", "{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UITests-FancyZonesEditor", "src\modules\fancyzones\UITests-FancyZonesEditor\UITests-FancyZonesEditor.csproj", "{3A9A791E-94A9-49F8-8401-C11CE288D5FB}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FancyZonesEditorCommon", "src\modules\fancyzones\FancyZonesEditorCommon\FancyZonesEditorCommon.csproj", "{C0974915-8A1D-4BF0-977B-9587D3807AB7}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|ARM64 = Debug|ARM64
|
Debug|ARM64 = Debug|ARM64
|
||||||
@ -2494,6 +2500,42 @@ Global
|
|||||||
{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}.Release|x64.Build.0 = Release|x64
|
{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}.Release|x64.Build.0 = Release|x64
|
||||||
{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}.Release|x86.ActiveCfg = Release|x64
|
{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}.Release|x86.ActiveCfg = Release|x64
|
||||||
{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}.Release|x86.Build.0 = Release|x64
|
{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}.Release|x86.Build.0 = Release|x64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|x86.Build.0 = Debug|x64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|x64.Build.0 = Release|x64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|x86.Build.0 = Release|x64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|x86.Build.0 = Debug|x64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|x64.Build.0 = Release|x64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|x86.Build.0 = Release|x64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|x86.Build.0 = Debug|x64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Release|x64.Build.0 = Release|x64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Release|x86.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -2703,6 +2745,9 @@ Global
|
|||||||
{0014D652-901F-4456-8D65-06FC5F997FB0} = {4C0D0746-BE5B-49EE-BD5D-A7811628AE8B}
|
{0014D652-901F-4456-8D65-06FC5F997FB0} = {4C0D0746-BE5B-49EE-BD5D-A7811628AE8B}
|
||||||
{799A50D8-DE89-4ED1-8FF8-AD5A9ED8C0CA} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
{799A50D8-DE89-4ED1-8FF8-AD5A9ED8C0CA} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
||||||
{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
||||||
|
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||||
|
{3A9A791E-94A9-49F8-8401-C11CE288D5FB} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||||
|
{C0974915-8A1D-4BF0-977B-9587D3807AB7} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||||
|
@ -1,85 +1,26 @@
|
|||||||
## FancyZones Lib
|
# FancyZones UI tests
|
||||||
|
|
||||||
#### [`FancyZones.cpp`](/src/modules/fancyzones/lib/FancyZones.cpp)
|
UI tests are implemented using [Windows Application Driver](https://github.com/microsoft/WinAppDriver).
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`Settings.cpp`](/src/modules/fancyzones/lib/Settings.cpp)
|
## Before running tests
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`trace.cpp`](/src/modules/fancyzones/lib/trace.cpp)
|
- Install Windows Application Driver v1.2.1 from https://github.com/microsoft/WinAppDriver/releases/tag/v1.2.1.
|
||||||
TODO
|
- Enable Developer Mode in Windows settings
|
||||||
|
|
||||||
#### [`Zone.cpp`](/src/modules/fancyzones/lib/Zone.cpp)
|
## Running tests
|
||||||
TODO
|
|
||||||
|
- Exit PowerToys if it's running
|
||||||
|
- Run WinAppDriver.exe from the installation directory. Skip this step if installed in the default directory (`C:\Program Files (x86)\Windows Application Driver`); in this case, it'll be launched automatically during tests.
|
||||||
|
- Open `PowerToys.sln` in Visual Studio and build the solution.
|
||||||
|
- Run tests in the Test Explorer (`Test > Test Explorer` or `Ctrl+E, T`).
|
||||||
|
|
||||||
#### [`ZoneSet.cpp`](/src/modules/fancyzones/lib/ZoneSet.cpp)
|
>Note: notifications or other application windows, that are shown above the window under test, can disrupt the testing process.
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`WorkArea.cpp`](/src/modules/fancyzones/lib/WorkArea.cpp)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
## FancyZones Editor
|
## Extra tools and information
|
||||||
|
|
||||||
#### [`App.xaml.cs`](/src/modules/fancyzones/editor/App.xaml.cs)
|
**Test samples**: https://github.com/microsoft/WinAppDriver/tree/master/Samples
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`Properties\AssemblyInfo.cs`](/src/modules/fancyzones/editor/Properties\AssemblyInfo.cs)
|
While working on tests, you may need a tool that helps you to view the element's accessibility data, e.g. for finding the button to click. For this purpose, you could use [AccessibilityInsights](https://accessibilityinsights.io/docs/windows/overview) or [WinAppDriver UI Recorder](https://github.com/microsoft/WinAppDriver/wiki/WinAppDriver-UI-Recorder).
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`CanvasEditor.xaml.cs`](/src/modules/fancyzones/editor/CanvasEditor.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`CanvasEditorWindow.xaml.cs`](/src/modules/fancyzones/editor/CanvasEditorWindow.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`Models\CanvasLayoutModel.cs`](/src/modules/fancyzones/editor/Models\CanvasLayoutModel.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`CanvasZone.xaml.cs`](/src/modules/fancyzones/editor/CanvasZone.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`EditorOverlay.xaml.cs`](/src/modules/fancyzones/editor/EditorOverlay.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`EditorWindow.cs`](/src/modules/fancyzones/editor/EditorWindow.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`GridEditor.xaml.cs`](/src/modules/fancyzones/editor/GridEditor.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`GridEditorWindow.xaml.cs`](/src/modules/fancyzones/editor/GridEditorWindow.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`Models\GridLayoutModel.cs`](/src/modules/fancyzones/editor/Models\GridLayoutModel.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`GridResizer.xaml.cs`](/src/modules/fancyzones/editor/GridResizer.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`GridZone.xaml.cs`](/src/modules/fancyzones/editor/GridZone.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`Models\LayoutModel.cs`](/src/modules/fancyzones/editor/Models/LayoutModel.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`LayoutPreview.xaml.cs`](/src/modules/fancyzones/editor/LayoutPreview.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`MainWindow.xaml.cs`](/src/modules/fancyzones/editor/MainWindow.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`Properties\Resources.Designer.cs`](/src/modules/fancyzones/editor/Properties/Resources.Designer.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`RowColInfo.cs`](/src/modules/fancyzones/editor/RowColInfo.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`Models\Settings.cs`](/src/modules/fancyzones/editor/Models/Settings.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`Properties\Settings.Designer.cs`](/src/modules/fancyzones/editor/Properties/Settings.Designer.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
#### [`WindowLayout.xaml.cs`](/src/modules/fancyzones/editor/WindowLayout.xaml.cs)
|
|
||||||
TODO
|
|
||||||
|
|
||||||
|
>Note: close helper tools while running tests. Overlapping windows can affect test results.
|
@ -0,0 +1,59 @@
|
|||||||
|
// 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.Generic;
|
||||||
|
|
||||||
|
namespace FancyZonesEditorCommon.Data
|
||||||
|
{
|
||||||
|
public class AppliedLayouts : EditorData<AppliedLayouts.AppliedLayoutsListWrapper>
|
||||||
|
{
|
||||||
|
public string File
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetDataFolder() + "\\Microsoft\\PowerToys\\FancyZones\\applied-layouts.json";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct AppliedLayoutWrapper
|
||||||
|
{
|
||||||
|
public struct DeviceIdWrapper
|
||||||
|
{
|
||||||
|
public string Monitor { get; set; }
|
||||||
|
|
||||||
|
public string MonitorInstance { get; set; }
|
||||||
|
|
||||||
|
public int MonitorNumber { get; set; }
|
||||||
|
|
||||||
|
public string SerialNumber { get; set; }
|
||||||
|
|
||||||
|
public string VirtualDesktop { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct LayoutWrapper
|
||||||
|
{
|
||||||
|
public string Uuid { get; set; }
|
||||||
|
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
public bool ShowSpacing { get; set; }
|
||||||
|
|
||||||
|
public int Spacing { get; set; }
|
||||||
|
|
||||||
|
public int ZoneCount { get; set; }
|
||||||
|
|
||||||
|
public int SensitivityRadius { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceIdWrapper Device { get; set; }
|
||||||
|
|
||||||
|
public LayoutWrapper AppliedLayout { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct AppliedLayoutsListWrapper
|
||||||
|
{
|
||||||
|
public List<AppliedLayoutWrapper> AppliedLayouts { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
// 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.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
|
namespace FancyZonesEditorCommon.Data
|
||||||
|
{
|
||||||
|
public static class Constants
|
||||||
|
{
|
||||||
|
public enum TemplateLayout
|
||||||
|
{
|
||||||
|
Empty,
|
||||||
|
Focus,
|
||||||
|
Rows,
|
||||||
|
Columns,
|
||||||
|
Grid,
|
||||||
|
PriorityGrid,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly ReadOnlyDictionary<TemplateLayout, string> TemplateLayoutJsonTags = new ReadOnlyDictionary<TemplateLayout, string>(
|
||||||
|
new Dictionary<TemplateLayout, string>()
|
||||||
|
{
|
||||||
|
{ TemplateLayout.Empty, "blank" },
|
||||||
|
{ TemplateLayout.Focus, "focus" },
|
||||||
|
{ TemplateLayout.Rows, "rows" },
|
||||||
|
{ TemplateLayout.Columns, "columns" },
|
||||||
|
{ TemplateLayout.Grid, "grid" },
|
||||||
|
{ TemplateLayout.PriorityGrid, "priority-grid" },
|
||||||
|
});
|
||||||
|
|
||||||
|
public const string CustomLayoutJsonTag = "custom";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
// 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.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
|
using static FancyZonesEditorCommon.Data.CustomLayouts;
|
||||||
|
|
||||||
|
namespace FancyZonesEditorCommon.Data
|
||||||
|
{
|
||||||
|
public class CustomLayouts : EditorData<CustomLayoutListWrapper>
|
||||||
|
{
|
||||||
|
public string File
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetDataFolder() + "\\Microsoft\\PowerToys\\FancyZones\\custom-layouts.json";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class CanvasInfoWrapper
|
||||||
|
{
|
||||||
|
public struct CanvasZoneWrapper
|
||||||
|
{
|
||||||
|
public int X { get; set; }
|
||||||
|
|
||||||
|
public int Y { get; set; }
|
||||||
|
|
||||||
|
public int Width { get; set; }
|
||||||
|
|
||||||
|
public int Height { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RefWidth { get; set; }
|
||||||
|
|
||||||
|
public int RefHeight { get; set; }
|
||||||
|
|
||||||
|
public List<CanvasZoneWrapper> Zones { get; set; }
|
||||||
|
|
||||||
|
public int SensitivityRadius { get; set; } = LayoutDefaultSettings.DefaultSensitivityRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class GridInfoWrapper
|
||||||
|
{
|
||||||
|
public int Rows { get; set; }
|
||||||
|
|
||||||
|
public int Columns { get; set; }
|
||||||
|
|
||||||
|
public List<int> RowsPercentage { get; set; }
|
||||||
|
|
||||||
|
public List<int> ColumnsPercentage { get; set; }
|
||||||
|
|
||||||
|
public int[][] CellChildMap { get; set; }
|
||||||
|
|
||||||
|
public bool ShowSpacing { get; set; } = LayoutDefaultSettings.DefaultShowSpacing;
|
||||||
|
|
||||||
|
public int Spacing { get; set; } = LayoutDefaultSettings.DefaultSpacing;
|
||||||
|
|
||||||
|
public int SensitivityRadius { get; set; } = LayoutDefaultSettings.DefaultSensitivityRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct CustomLayoutWrapper
|
||||||
|
{
|
||||||
|
public string Uuid { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
public JsonElement Info { get; set; } // CanvasInfoWrapper or GridInfoWrapper
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct CustomLayoutListWrapper
|
||||||
|
{
|
||||||
|
public List<CustomLayoutWrapper> CustomLayouts { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonElement ToJsonElement(CanvasInfoWrapper info)
|
||||||
|
{
|
||||||
|
string json = JsonSerializer.Serialize(info, this.JsonOptions);
|
||||||
|
return JsonSerializer.Deserialize<JsonElement>(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonElement ToJsonElement(GridInfoWrapper info)
|
||||||
|
{
|
||||||
|
string json = JsonSerializer.Serialize(info, this.JsonOptions);
|
||||||
|
return JsonSerializer.Deserialize<JsonElement>(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CanvasInfoWrapper CanvasFromJsonElement(string json)
|
||||||
|
{
|
||||||
|
return JsonSerializer.Deserialize<CanvasInfoWrapper>(json, this.JsonOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridInfoWrapper GridFromJsonElement(string json)
|
||||||
|
{
|
||||||
|
return JsonSerializer.Deserialize<GridInfoWrapper>(json, this.JsonOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
// 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.Generic;
|
||||||
|
using static FancyZonesEditorCommon.Data.DefaultLayouts;
|
||||||
|
|
||||||
|
namespace FancyZonesEditorCommon.Data
|
||||||
|
{
|
||||||
|
public class DefaultLayouts : EditorData<DefaultLayoutsListWrapper>
|
||||||
|
{
|
||||||
|
public string File
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetDataFolder() + "\\Microsoft\\PowerToys\\FancyZones\\default-layouts.json";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct DefaultLayoutWrapper
|
||||||
|
{
|
||||||
|
public struct LayoutWrapper
|
||||||
|
{
|
||||||
|
public string Uuid { get; set; }
|
||||||
|
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
public bool ShowSpacing { get; set; }
|
||||||
|
|
||||||
|
public int Spacing { get; set; }
|
||||||
|
|
||||||
|
public int ZoneCount { get; set; }
|
||||||
|
|
||||||
|
public int SensitivityRadius { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MonitorConfiguration { get; set; }
|
||||||
|
|
||||||
|
public LayoutWrapper Layout { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct DefaultLayoutsListWrapper
|
||||||
|
{
|
||||||
|
public List<DefaultLayoutWrapper> DefaultLayouts { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
// 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.Text.Json;
|
||||||
|
using FancyZonesEditorCommon.Utils;
|
||||||
|
|
||||||
|
namespace FancyZonesEditorCommon.Data
|
||||||
|
{
|
||||||
|
public class EditorData<T>
|
||||||
|
{
|
||||||
|
public string GetDataFolder()
|
||||||
|
{
|
||||||
|
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JsonSerializerOptions JsonOptions
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = new DashCaseNamingPolicy(),
|
||||||
|
WriteIndented = true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Read(string file)
|
||||||
|
{
|
||||||
|
IOUtils ioUtils = new IOUtils();
|
||||||
|
string data = ioUtils.ReadFile(file);
|
||||||
|
return JsonSerializer.Deserialize<T>(data, JsonOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Serialize(T data)
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(data, JsonOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
// 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.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace FancyZonesEditorCommon.Data
|
||||||
|
{
|
||||||
|
public class EditorParameters : EditorData<EditorParameters.ParamsWrapper>
|
||||||
|
{
|
||||||
|
public string File
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetDataFolder() + "\\Microsoft\\PowerToys\\FancyZones\\editor-parameters.json";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct NativeMonitorDataWrapper
|
||||||
|
{
|
||||||
|
public string Monitor { get; set; }
|
||||||
|
|
||||||
|
public string MonitorInstanceId { get; set; }
|
||||||
|
|
||||||
|
public string MonitorSerialNumber { get; set; }
|
||||||
|
|
||||||
|
public int MonitorNumber { get; set; }
|
||||||
|
|
||||||
|
public string VirtualDesktop { get; set; }
|
||||||
|
|
||||||
|
public int Dpi { get; set; }
|
||||||
|
|
||||||
|
public int LeftCoordinate { get; set; }
|
||||||
|
|
||||||
|
public int TopCoordinate { get; set; }
|
||||||
|
|
||||||
|
public int WorkAreaWidth { get; set; }
|
||||||
|
|
||||||
|
public int WorkAreaHeight { get; set; }
|
||||||
|
|
||||||
|
public int MonitorWidth { get; set; }
|
||||||
|
|
||||||
|
public int MonitorHeight { get; set; }
|
||||||
|
|
||||||
|
public bool IsSelected { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
// using CultureInfo.InvariantCulture since this is internal data
|
||||||
|
sb.Append("Monitor: ");
|
||||||
|
sb.AppendLine(Monitor);
|
||||||
|
sb.Append("Virtual desktop: ");
|
||||||
|
sb.AppendLine(VirtualDesktop);
|
||||||
|
sb.Append("DPI: ");
|
||||||
|
sb.AppendLine(Dpi.ToString(CultureInfo.InvariantCulture));
|
||||||
|
|
||||||
|
sb.Append("X: ");
|
||||||
|
sb.AppendLine(LeftCoordinate.ToString(CultureInfo.InvariantCulture));
|
||||||
|
sb.Append("Y: ");
|
||||||
|
sb.AppendLine(TopCoordinate.ToString(CultureInfo.InvariantCulture));
|
||||||
|
|
||||||
|
sb.Append("Width: ");
|
||||||
|
sb.AppendLine(MonitorWidth.ToString(CultureInfo.InvariantCulture));
|
||||||
|
sb.Append("Height: ");
|
||||||
|
sb.AppendLine(MonitorHeight.ToString(CultureInfo.InvariantCulture));
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ParamsWrapper
|
||||||
|
{
|
||||||
|
public int ProcessId { get; set; }
|
||||||
|
|
||||||
|
public bool SpanZonesAcrossMonitors { get; set; }
|
||||||
|
|
||||||
|
public List<NativeMonitorDataWrapper> Monitors { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public EditorParameters()
|
||||||
|
: base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace FancyZonesEditorCommon.Data
|
||||||
|
{
|
||||||
|
public class LayoutDefaultSettings
|
||||||
|
{
|
||||||
|
// TODO: share the constants b/w C# Editor and FancyZoneLib
|
||||||
|
public const bool DefaultShowSpacing = true;
|
||||||
|
|
||||||
|
public const int DefaultSpacing = 16;
|
||||||
|
|
||||||
|
public const int DefaultZoneCount = 3;
|
||||||
|
|
||||||
|
public const int DefaultSensitivityRadius = 20;
|
||||||
|
|
||||||
|
public const int MaxZones = 128;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
// 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.Generic;
|
||||||
|
using static FancyZonesEditorCommon.Data.LayoutHotkeys;
|
||||||
|
|
||||||
|
namespace FancyZonesEditorCommon.Data
|
||||||
|
{
|
||||||
|
public class LayoutHotkeys : EditorData<LayoutHotkeysWrapper>
|
||||||
|
{
|
||||||
|
public string File
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetDataFolder() + "\\Microsoft\\PowerToys\\FancyZones\\layout-hotkeys.json";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct LayoutHotkeyWrapper
|
||||||
|
{
|
||||||
|
public int Key { get; set; }
|
||||||
|
|
||||||
|
public string LayoutId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct LayoutHotkeysWrapper
|
||||||
|
{
|
||||||
|
public List<LayoutHotkeyWrapper> LayoutHotkeys { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
// 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.Generic;
|
||||||
|
using static FancyZonesEditorCommon.Data.LayoutTemplates;
|
||||||
|
|
||||||
|
namespace FancyZonesEditorCommon.Data
|
||||||
|
{
|
||||||
|
public class LayoutTemplates : EditorData<TemplateLayoutsListWrapper>
|
||||||
|
{
|
||||||
|
public string File
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetDataFolder() + "\\Microsoft\\PowerToys\\FancyZones\\layout-templates.json";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct TemplateLayoutWrapper
|
||||||
|
{
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
public bool ShowSpacing { get; set; }
|
||||||
|
|
||||||
|
public int Spacing { get; set; }
|
||||||
|
|
||||||
|
public int ZoneCount { get; set; }
|
||||||
|
|
||||||
|
public int SensitivityRadius { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct TemplateLayoutsListWrapper
|
||||||
|
{
|
||||||
|
public List<TemplateLayoutWrapper> LayoutTemplates { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<Import Project="..\..\..\Version.props" />
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows10.0.20348.0</TargetFramework>
|
||||||
|
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
|
||||||
|
<Version>$(Version).0</Version>
|
||||||
|
<Authors>Microsoft Corporation</Authors>
|
||||||
|
<Product>PowerToys</Product>
|
||||||
|
<Description>PowerToys FancyZonesEditorCommon</Description>
|
||||||
|
<AssemblyName>PowerToys.FancyZonesEditorCommon</AssemblyName>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.IO.Abstractions" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\FancyZonesEditorCommon\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
@ -4,9 +4,7 @@
|
|||||||
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
using FancyZonesEditor.Utils;
|
namespace FancyZonesEditorCommon.Utils
|
||||||
|
|
||||||
namespace FancyZonesEditor
|
|
||||||
{
|
{
|
||||||
public class DashCaseNamingPolicy : JsonNamingPolicy
|
public class DashCaseNamingPolicy : JsonNamingPolicy
|
||||||
{
|
{
|
@ -0,0 +1,54 @@
|
|||||||
|
// 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.IO;
|
||||||
|
using System.IO.Abstractions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FancyZonesEditorCommon.Utils
|
||||||
|
{
|
||||||
|
public class IOUtils
|
||||||
|
{
|
||||||
|
private readonly IFileSystem _fileSystem = new FileSystem();
|
||||||
|
|
||||||
|
public IOUtils()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteFile(string fileName, string data)
|
||||||
|
{
|
||||||
|
_fileSystem.File.WriteAllText(fileName, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ReadFile(string fileName)
|
||||||
|
{
|
||||||
|
if (_fileSystem.File.Exists(fileName))
|
||||||
|
{
|
||||||
|
var attempts = 0;
|
||||||
|
while (attempts < 10)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Stream inputStream = _fileSystem.File.Open(fileName, FileMode.Open))
|
||||||
|
using (StreamReader reader = new StreamReader(inputStream))
|
||||||
|
{
|
||||||
|
string data = reader.ReadToEnd();
|
||||||
|
inputStream.Close();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Task.Delay(10).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
attempts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace FancyZonesEditor.Utils
|
namespace FancyZonesEditorCommon.Utils
|
||||||
{
|
{
|
||||||
public static class StringUtils
|
public static class StringUtils
|
||||||
{
|
{
|
35
src/modules/fancyzones/UITests-FancyZones/Init.cs
Normal file
35
src/modules/fancyzones/UITests-FancyZones/Init.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// 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.Diagnostics;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace Microsoft.FancyZonesEditor.UITests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class Init
|
||||||
|
{
|
||||||
|
private static Process? appDriver;
|
||||||
|
|
||||||
|
[AssemblyInitialize]
|
||||||
|
public static void SetupAll(TestContext context)
|
||||||
|
{
|
||||||
|
string winAppDriverPath = "C:\\Program Files (x86)\\Windows Application Driver\\WinAppDriver.exe";
|
||||||
|
context.WriteLine($"Attempting to launch WinAppDriver at: {winAppDriverPath}");
|
||||||
|
appDriver = Process.Start(winAppDriverPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
[AssemblyCleanup]
|
||||||
|
public static void CleanupAll()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
appDriver?.Kill();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
// 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.FancyZones.UnitTests.Utils;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace UITests_FancyZones
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class RunFancyZonesTest
|
||||||
|
{
|
||||||
|
private static FancyZonesSession? _session;
|
||||||
|
|
||||||
|
[ClassInitialize]
|
||||||
|
public static void ClassInitialize(TestContext testContext)
|
||||||
|
{
|
||||||
|
_session = new FancyZonesSession(testContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ClassCleanup]
|
||||||
|
public static void ClassCleanup()
|
||||||
|
{
|
||||||
|
_session?.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RunFancyZones()
|
||||||
|
{
|
||||||
|
Assert.IsNotNull(_session?.FancyZonesProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<Import Project="..\..\..\Version.props" />
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows10.0.20348.0</TargetFramework>
|
||||||
|
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||||
|
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||||
|
<ProjectGuid>{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.FancyZones.UITests</RootNamespace>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<Version>$(Version).0</Version>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\UITests-FancyZones\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Appium.WebDriver" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -0,0 +1,66 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace Microsoft.FancyZones.UnitTests.Utils
|
||||||
|
{
|
||||||
|
public class FancyZonesSession
|
||||||
|
{
|
||||||
|
private const string FancyZonesPath = @"\..\..\..\PowerToys.FancyZones.exe";
|
||||||
|
private const string FancyZonesProcessName = "PowerToys.FancyZones";
|
||||||
|
|
||||||
|
private bool stopFancyZones = true;
|
||||||
|
|
||||||
|
public Process? FancyZonesProcess { get; }
|
||||||
|
|
||||||
|
public FancyZonesSession(TestContext testContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Check if FancyZones is already running
|
||||||
|
Process[] runningFZ = Process.GetProcessesByName(FancyZonesProcessName);
|
||||||
|
if (runningFZ.Length > 0)
|
||||||
|
{
|
||||||
|
FancyZonesProcess = runningFZ[0];
|
||||||
|
stopFancyZones = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Launch FancyZones
|
||||||
|
string? path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
|
path += FancyZonesPath;
|
||||||
|
|
||||||
|
ProcessStartInfo info = new ProcessStartInfo(path);
|
||||||
|
FancyZonesProcess = Process.Start(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
testContext.WriteLine(ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.IsNotNull(FancyZonesProcess, "FancyZones process not started");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
// Close the application
|
||||||
|
if (FancyZonesProcess != null)
|
||||||
|
{
|
||||||
|
if (stopFancyZones)
|
||||||
|
{
|
||||||
|
FancyZonesProcess.Kill();
|
||||||
|
}
|
||||||
|
|
||||||
|
FancyZonesProcess.Close();
|
||||||
|
FancyZonesProcess.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
src/modules/fancyzones/UITests-FancyZonesEditor/Init.cs
Normal file
35
src/modules/fancyzones/UITests-FancyZonesEditor/Init.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// 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.Diagnostics;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace Microsoft.FancyZonesEditor.UITests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class Init
|
||||||
|
{
|
||||||
|
private static Process? appDriver;
|
||||||
|
|
||||||
|
[AssemblyInitialize]
|
||||||
|
public static void SetupAll(TestContext context)
|
||||||
|
{
|
||||||
|
string winAppDriverPath = "C:\\Program Files (x86)\\Windows Application Driver\\WinAppDriver.exe";
|
||||||
|
context.WriteLine($"Attempting to launch WinAppDriver at: {winAppDriverPath}");
|
||||||
|
appDriver = Process.Start(winAppDriverPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
[AssemblyCleanup]
|
||||||
|
public static void CleanupAll()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
appDriver?.Kill();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,177 @@
|
|||||||
|
// 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.Generic;
|
||||||
|
using FancyZonesEditorCommon.Data;
|
||||||
|
using Microsoft.FancyZonesEditor.UITests;
|
||||||
|
using Microsoft.FancyZonesEditor.UnitTests.Utils;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace UITests_FancyZonesEditor
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class RunFancyZonesEditorTest
|
||||||
|
{
|
||||||
|
private static FancyZonesEditorSession? _session;
|
||||||
|
private static TestContext? _context;
|
||||||
|
|
||||||
|
[ClassInitialize]
|
||||||
|
public static void ClassInitialize(TestContext testContext)
|
||||||
|
{
|
||||||
|
_context = testContext;
|
||||||
|
|
||||||
|
// prepare files to launch Editor without errors
|
||||||
|
EditorParameters editorParameters = new EditorParameters();
|
||||||
|
EditorParameters.ParamsWrapper parameters = new EditorParameters.ParamsWrapper
|
||||||
|
{
|
||||||
|
ProcessId = 1,
|
||||||
|
SpanZonesAcrossMonitors = false,
|
||||||
|
Monitors = new List<EditorParameters.NativeMonitorDataWrapper>
|
||||||
|
{
|
||||||
|
new EditorParameters.NativeMonitorDataWrapper
|
||||||
|
{
|
||||||
|
Monitor = "monitor-1",
|
||||||
|
MonitorInstanceId = "instance-id-1",
|
||||||
|
MonitorSerialNumber = "serial-number-1",
|
||||||
|
MonitorNumber = 1,
|
||||||
|
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
|
||||||
|
Dpi = 96,
|
||||||
|
LeftCoordinate = 0,
|
||||||
|
TopCoordinate = 0,
|
||||||
|
WorkAreaHeight = 1040,
|
||||||
|
WorkAreaWidth = 1920,
|
||||||
|
MonitorHeight = 1080,
|
||||||
|
MonitorWidth = 1920,
|
||||||
|
IsSelected = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
|
||||||
|
|
||||||
|
LayoutTemplates layoutTemplates = new LayoutTemplates();
|
||||||
|
LayoutTemplates.TemplateLayoutsListWrapper templateLayoutsListWrapper = new LayoutTemplates.TemplateLayoutsListWrapper
|
||||||
|
{
|
||||||
|
LayoutTemplates = new List<LayoutTemplates.TemplateLayoutWrapper>
|
||||||
|
{
|
||||||
|
new LayoutTemplates.TemplateLayoutWrapper
|
||||||
|
{
|
||||||
|
Type = Constants.TemplateLayoutJsonTags[Constants.TemplateLayout.Empty],
|
||||||
|
},
|
||||||
|
new LayoutTemplates.TemplateLayoutWrapper
|
||||||
|
{
|
||||||
|
Type = Constants.TemplateLayoutJsonTags[Constants.TemplateLayout.Focus],
|
||||||
|
ZoneCount = 10,
|
||||||
|
},
|
||||||
|
new LayoutTemplates.TemplateLayoutWrapper
|
||||||
|
{
|
||||||
|
Type = Constants.TemplateLayoutJsonTags[Constants.TemplateLayout.Rows],
|
||||||
|
ZoneCount = 2,
|
||||||
|
ShowSpacing = true,
|
||||||
|
Spacing = 10,
|
||||||
|
SensitivityRadius = 10,
|
||||||
|
},
|
||||||
|
new LayoutTemplates.TemplateLayoutWrapper
|
||||||
|
{
|
||||||
|
Type = Constants.TemplateLayoutJsonTags[Constants.TemplateLayout.Columns],
|
||||||
|
ZoneCount = 2,
|
||||||
|
ShowSpacing = true,
|
||||||
|
Spacing = 20,
|
||||||
|
SensitivityRadius = 20,
|
||||||
|
},
|
||||||
|
new LayoutTemplates.TemplateLayoutWrapper
|
||||||
|
{
|
||||||
|
Type = Constants.TemplateLayoutJsonTags[Constants.TemplateLayout.Grid],
|
||||||
|
ZoneCount = 4,
|
||||||
|
ShowSpacing = false,
|
||||||
|
Spacing = 10,
|
||||||
|
SensitivityRadius = 30,
|
||||||
|
},
|
||||||
|
new LayoutTemplates.TemplateLayoutWrapper
|
||||||
|
{
|
||||||
|
Type = Constants.TemplateLayoutJsonTags[Constants.TemplateLayout.PriorityGrid],
|
||||||
|
ZoneCount = 3,
|
||||||
|
ShowSpacing = true,
|
||||||
|
Spacing = 1,
|
||||||
|
SensitivityRadius = 40,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
FancyZonesEditorSession.Files.LayoutTemplatesIOHelper.WriteData(layoutTemplates.Serialize(templateLayoutsListWrapper));
|
||||||
|
|
||||||
|
CustomLayouts customLayouts = new CustomLayouts();
|
||||||
|
CustomLayouts.CustomLayoutListWrapper customLayoutListWrapper = new CustomLayouts.CustomLayoutListWrapper
|
||||||
|
{
|
||||||
|
CustomLayouts = new List<CustomLayouts.CustomLayoutWrapper> { },
|
||||||
|
};
|
||||||
|
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(customLayoutListWrapper));
|
||||||
|
|
||||||
|
DefaultLayouts defaultLayouts = new DefaultLayouts();
|
||||||
|
DefaultLayouts.DefaultLayoutsListWrapper defaultLayoutsListWrapper = new DefaultLayouts.DefaultLayoutsListWrapper
|
||||||
|
{
|
||||||
|
DefaultLayouts = new List<DefaultLayouts.DefaultLayoutWrapper> { },
|
||||||
|
};
|
||||||
|
FancyZonesEditorSession.Files.DefaultLayoutsIOHelper.WriteData(defaultLayouts.Serialize(defaultLayoutsListWrapper));
|
||||||
|
|
||||||
|
LayoutHotkeys layoutHotkeys = new LayoutHotkeys();
|
||||||
|
LayoutHotkeys.LayoutHotkeysWrapper layoutHotkeysWrapper = new LayoutHotkeys.LayoutHotkeysWrapper
|
||||||
|
{
|
||||||
|
LayoutHotkeys = new List<LayoutHotkeys.LayoutHotkeyWrapper> { },
|
||||||
|
};
|
||||||
|
FancyZonesEditorSession.Files.LayoutHotkeysIOHelper.WriteData(layoutHotkeys.Serialize(layoutHotkeysWrapper));
|
||||||
|
|
||||||
|
AppliedLayouts appliedLayouts = new AppliedLayouts();
|
||||||
|
AppliedLayouts.AppliedLayoutsListWrapper appliedLayoutsWrapper = new AppliedLayouts.AppliedLayoutsListWrapper
|
||||||
|
{
|
||||||
|
AppliedLayouts = new List<AppliedLayouts.AppliedLayoutWrapper> { },
|
||||||
|
};
|
||||||
|
FancyZonesEditorSession.Files.AppliedLayoutsIOHelper.WriteData(appliedLayouts.Serialize(appliedLayoutsWrapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
[ClassCleanup]
|
||||||
|
public static void ClassCleanup()
|
||||||
|
{
|
||||||
|
FancyZonesEditorSession.Files.Restore();
|
||||||
|
_context = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestInitialize]
|
||||||
|
public void TestInitialize()
|
||||||
|
{
|
||||||
|
_session = new FancyZonesEditorSession(_context!);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCleanup]
|
||||||
|
public void TestCleanup()
|
||||||
|
{
|
||||||
|
_session?.Close(_context!);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void OpenEditorWindow() // verify the session is initialized
|
||||||
|
{
|
||||||
|
Assert.IsNotNull(_session?.Session);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void OpenNewLayoutDialog() // verify the new layout dialog is opened
|
||||||
|
{
|
||||||
|
_session?.Click_CreateNewLayout();
|
||||||
|
Assert.IsNotNull(_session?.Session?.FindElementsByName("Choose layout type")); // check the pane header
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void OpenEditLayoutDialog() // verify the edit layout dialog is opened
|
||||||
|
{
|
||||||
|
_session?.Click_EditLayout(TestConstants.TemplateLayoutNames[Constants.TemplateLayout.Grid]);
|
||||||
|
Assert.IsNotNull(_session?.Session?.FindElementByAccessibilityId("EditLayoutDialogTitle")); // check the pane header
|
||||||
|
Assert.IsNotNull(_session?.Session?.FindElementsByName("Edit 'Grid'")); // verify it's opened for the correct layout
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void OpenContextMenu() // verify the context menu is opened
|
||||||
|
{
|
||||||
|
Assert.IsNotNull(_session?.OpenContextMenu(TestConstants.TemplateLayoutNames[Constants.TemplateLayout.Columns]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
// 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.Generic;
|
||||||
|
using static FancyZonesEditorCommon.Data.Constants;
|
||||||
|
|
||||||
|
namespace Microsoft.FancyZonesEditor.UITests
|
||||||
|
{
|
||||||
|
public static class TestConstants
|
||||||
|
{
|
||||||
|
public static readonly Dictionary<TemplateLayout, string> TemplateLayoutNames = new Dictionary<TemplateLayout, string>()
|
||||||
|
{
|
||||||
|
{ TemplateLayout.Empty, "No layout" },
|
||||||
|
{ TemplateLayout.Focus, "Focus" },
|
||||||
|
{ TemplateLayout.Rows, "Rows" },
|
||||||
|
{ TemplateLayout.Columns, "Columns" },
|
||||||
|
{ TemplateLayout.Grid, "Grid" },
|
||||||
|
{ TemplateLayout.PriorityGrid, "PriorityGrid" },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<Import Project="..\..\..\Version.props" />
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows10.0.20348.0</TargetFramework>
|
||||||
|
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||||
|
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||||
|
<ProjectGuid>{3A9A791E-94A9-49F8-8401-C11CE288D5FB}</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.FancyZonesEditor.UITests</RootNamespace>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<Version>$(Version).0</Version>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\UITests-FancyZonesEditor\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Appium.WebDriver" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" />
|
||||||
|
<PackageReference Include="System.IO.Abstractions" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\FancyZonesEditorCommon\FancyZonesEditorCommon.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -0,0 +1,43 @@
|
|||||||
|
// 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 FancyZonesEditorCommon.Data;
|
||||||
|
|
||||||
|
namespace Microsoft.FancyZonesEditor.UITests.Utils
|
||||||
|
{
|
||||||
|
public class FancyZonesEditorFiles
|
||||||
|
{
|
||||||
|
public IOTestHelper ParamsIOHelper { get; }
|
||||||
|
|
||||||
|
public IOTestHelper AppliedLayoutsIOHelper { get; }
|
||||||
|
|
||||||
|
public IOTestHelper CustomLayoutsIOHelper { get; }
|
||||||
|
|
||||||
|
public IOTestHelper DefaultLayoutsIOHelper { get; }
|
||||||
|
|
||||||
|
public IOTestHelper LayoutHotkeysIOHelper { get; }
|
||||||
|
|
||||||
|
public IOTestHelper LayoutTemplatesIOHelper { get; }
|
||||||
|
|
||||||
|
public FancyZonesEditorFiles()
|
||||||
|
{
|
||||||
|
ParamsIOHelper = new IOTestHelper(new EditorParameters().File);
|
||||||
|
AppliedLayoutsIOHelper = new IOTestHelper(new AppliedLayouts().File);
|
||||||
|
CustomLayoutsIOHelper = new IOTestHelper(new CustomLayouts().File);
|
||||||
|
DefaultLayoutsIOHelper = new IOTestHelper(new DefaultLayouts().File);
|
||||||
|
LayoutHotkeysIOHelper = new IOTestHelper(new LayoutHotkeys().File);
|
||||||
|
LayoutTemplatesIOHelper = new IOTestHelper(new LayoutTemplates().File);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Restore()
|
||||||
|
{
|
||||||
|
ParamsIOHelper.RestoreData();
|
||||||
|
AppliedLayoutsIOHelper.RestoreData();
|
||||||
|
CustomLayoutsIOHelper.RestoreData();
|
||||||
|
DefaultLayoutsIOHelper.RestoreData();
|
||||||
|
LayoutHotkeysIOHelper.RestoreData();
|
||||||
|
LayoutTemplatesIOHelper.RestoreData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,137 @@
|
|||||||
|
// 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.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.FancyZonesEditor.UITests.Utils;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using OpenQA.Selenium;
|
||||||
|
using OpenQA.Selenium.Appium;
|
||||||
|
using OpenQA.Selenium.Appium.Windows;
|
||||||
|
using OpenQA.Selenium.Interactions;
|
||||||
|
|
||||||
|
namespace Microsoft.FancyZonesEditor.UnitTests.Utils
|
||||||
|
{
|
||||||
|
public class FancyZonesEditorSession
|
||||||
|
{
|
||||||
|
protected const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
|
||||||
|
private const string FancyZonesEditorPath = @"\..\..\..\PowerToys.FancyZonesEditor.exe";
|
||||||
|
|
||||||
|
private static FancyZonesEditorFiles? _files;
|
||||||
|
|
||||||
|
public static FancyZonesEditorFiles Files
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_files == null)
|
||||||
|
{
|
||||||
|
_files = new FancyZonesEditorFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _files;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public WindowsDriver<WindowsElement>? Session { get; }
|
||||||
|
|
||||||
|
public WindowsElement? MainEditorWindow { get; }
|
||||||
|
|
||||||
|
public FancyZonesEditorSession(TestContext testContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Launch FancyZonesEditor
|
||||||
|
string? path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
|
path += FancyZonesEditorPath;
|
||||||
|
|
||||||
|
AppiumOptions opts = new AppiumOptions();
|
||||||
|
opts.AddAdditionalCapability("app", path);
|
||||||
|
Session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), opts);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
testContext.WriteLine(ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.IsNotNull(Session, "Session not initialized");
|
||||||
|
|
||||||
|
testContext.WriteLine("Session: " + Session.SessionId.ToString());
|
||||||
|
testContext.WriteLine("Title: " + Session.Title);
|
||||||
|
|
||||||
|
// Set implicit timeout to make element search to retry every 500 ms
|
||||||
|
Session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(3);
|
||||||
|
|
||||||
|
// Find main editor window
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MainEditorWindow = Session.FindElementByAccessibilityId("MainWindow1");
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Assert.IsNotNull(MainEditorWindow, "Main editor window not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close(TestContext testContext)
|
||||||
|
{
|
||||||
|
// Close the session
|
||||||
|
if (Session != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// FZEditor application can be closed by explicitly closing main editor window
|
||||||
|
MainEditorWindow?.SendKeys(Keys.Alt + Keys.F4);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
testContext.WriteLine(ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Session.Quit();
|
||||||
|
Session.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private WindowsElement? GetLayout(string layoutName)
|
||||||
|
{
|
||||||
|
var listItem = Session?.FindElementByName(layoutName);
|
||||||
|
Assert.IsNotNull(listItem, "Layout " + layoutName + " not found");
|
||||||
|
return listItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WindowsElement? OpenContextMenu(string layoutName)
|
||||||
|
{
|
||||||
|
RightClick_Layout(layoutName);
|
||||||
|
var menu = Session?.FindElementByClassName("ContextMenu");
|
||||||
|
Assert.IsNotNull(menu, "Context menu not found");
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Click_CreateNewLayout()
|
||||||
|
{
|
||||||
|
var button = Session?.FindElementByAccessibilityId("NewLayoutButton");
|
||||||
|
Assert.IsNotNull(button, "Create new layout button not found");
|
||||||
|
button?.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Click_EditLayout(string layoutName)
|
||||||
|
{
|
||||||
|
var layout = GetLayout(layoutName);
|
||||||
|
var editButton = layout?.FindElementByAccessibilityId("EditLayoutButton");
|
||||||
|
Assert.IsNotNull(editButton, "Edit button not found");
|
||||||
|
editButton.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RightClick_Layout(string layoutName)
|
||||||
|
{
|
||||||
|
var layout = GetLayout(layoutName);
|
||||||
|
Actions actions = new Actions(Session);
|
||||||
|
actions.MoveToElement(layout);
|
||||||
|
actions.MoveByOffset(30, 30);
|
||||||
|
actions.ContextClick();
|
||||||
|
actions.Build().Perform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
// 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.IO;
|
||||||
|
using System.IO.Abstractions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.FancyZonesEditor.UITests.Utils
|
||||||
|
{
|
||||||
|
public class IOTestHelper
|
||||||
|
{
|
||||||
|
private readonly IFileSystem _fileSystem = new FileSystem();
|
||||||
|
|
||||||
|
private string _file;
|
||||||
|
|
||||||
|
private string _data = string.Empty;
|
||||||
|
|
||||||
|
public IOTestHelper(string file)
|
||||||
|
{
|
||||||
|
_file = file;
|
||||||
|
|
||||||
|
if (_fileSystem.File.Exists(_file))
|
||||||
|
{
|
||||||
|
_data = ReadFile(_file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_fileSystem.Directory.CreateDirectory(Path.GetDirectoryName(file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~IOTestHelper()
|
||||||
|
{
|
||||||
|
RestoreData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RestoreData()
|
||||||
|
{
|
||||||
|
if (_data != string.Empty)
|
||||||
|
{
|
||||||
|
WriteData(_data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeleteFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteData(string data)
|
||||||
|
{
|
||||||
|
var attempts = 0;
|
||||||
|
while (attempts < 10)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_fileSystem.File.WriteAllText(_file, data);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Task.Delay(10).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
attempts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ReadFile(string fileName)
|
||||||
|
{
|
||||||
|
var attempts = 0;
|
||||||
|
while (attempts < 10)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Stream inputStream = _fileSystem.File.Open(fileName, FileMode.Open))
|
||||||
|
using (StreamReader reader = new StreamReader(inputStream))
|
||||||
|
{
|
||||||
|
string data = reader.ReadToEnd();
|
||||||
|
inputStream.Close();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Task.Delay(10).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
attempts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteFile()
|
||||||
|
{
|
||||||
|
var attempts = 0;
|
||||||
|
while (attempts < 10)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_fileSystem.File.Delete(_file);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Task.Delay(10).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
attempts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -69,6 +69,7 @@
|
|||||||
<ProjectReference Include="..\..\..\..\common\interop\PowerToys.Interop.vcxproj" />
|
<ProjectReference Include="..\..\..\..\common\interop\PowerToys.Interop.vcxproj" />
|
||||||
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||||
<ProjectReference Include="..\..\..\..\common\Common.UI\Common.UI.csproj" />
|
<ProjectReference Include="..\..\..\..\common\Common.UI\Common.UI.csproj" />
|
||||||
|
<ProjectReference Include="..\..\FancyZonesEditorCommon\FancyZonesEditorCommon.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Update="Properties\Resources.Designer.cs">
|
<Compile Update="Properties\Resources.Designer.cs">
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using FancyZonesEditorCommon.Data;
|
||||||
|
|
||||||
namespace FancyZonesEditor.Models
|
namespace FancyZonesEditor.Models
|
||||||
{
|
{
|
||||||
@ -99,7 +100,7 @@ namespace FancyZonesEditor.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _showSpacing = LayoutSettings.DefaultShowSpacing;
|
private bool _showSpacing = LayoutDefaultSettings.DefaultShowSpacing;
|
||||||
|
|
||||||
// Spacing - free space between cells
|
// Spacing - free space between cells
|
||||||
public int Spacing
|
public int Spacing
|
||||||
@ -129,7 +130,7 @@ namespace FancyZonesEditor.Models
|
|||||||
get { return 1000; }
|
get { return 1000; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _spacing = LayoutSettings.DefaultSpacing;
|
private int _spacing = LayoutDefaultSettings.DefaultSpacing;
|
||||||
|
|
||||||
public GridLayoutModel()
|
public GridLayoutModel()
|
||||||
: base()
|
: base()
|
||||||
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using FancyZonesEditorCommon.Data;
|
||||||
|
|
||||||
namespace FancyZonesEditor.Models
|
namespace FancyZonesEditor.Models
|
||||||
{
|
{
|
||||||
@ -195,7 +196,7 @@ namespace FancyZonesEditor.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _sensitivityRadius = LayoutSettings.DefaultSensitivityRadius;
|
private int _sensitivityRadius = LayoutDefaultSettings.DefaultSensitivityRadius;
|
||||||
|
|
||||||
public int SensitivityRadiusMinimum
|
public int SensitivityRadiusMinimum
|
||||||
{
|
{
|
||||||
@ -304,13 +305,13 @@ namespace FancyZonesEditor.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _zoneCount = LayoutSettings.DefaultZoneCount;
|
private int _zoneCount = LayoutDefaultSettings.DefaultZoneCount;
|
||||||
|
|
||||||
public bool IsZoneAddingAllowed
|
public bool IsZoneAddingAllowed
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return TemplateZoneCount < LayoutSettings.MaxZones;
|
return TemplateZoneCount < LayoutDefaultSettings.MaxZones;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,32 +3,22 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using FancyZonesEditor.Models;
|
using FancyZonesEditor.Models;
|
||||||
|
using FancyZonesEditorCommon.Data;
|
||||||
|
|
||||||
namespace FancyZonesEditor
|
namespace FancyZonesEditor
|
||||||
{
|
{
|
||||||
public class LayoutSettings
|
public class LayoutSettings
|
||||||
{
|
{
|
||||||
// TODO: share the constants b/w C# Editor and FancyZoneLib
|
|
||||||
public const bool DefaultShowSpacing = true;
|
|
||||||
|
|
||||||
public const int DefaultSpacing = 16;
|
|
||||||
|
|
||||||
public const int DefaultZoneCount = 3;
|
|
||||||
|
|
||||||
public const int DefaultSensitivityRadius = 20;
|
|
||||||
|
|
||||||
public const int MaxZones = 128;
|
|
||||||
|
|
||||||
public string ZonesetUuid { get; set; } = string.Empty;
|
public string ZonesetUuid { get; set; } = string.Empty;
|
||||||
|
|
||||||
public LayoutType Type { get; set; } = LayoutType.PriorityGrid;
|
public LayoutType Type { get; set; } = LayoutType.PriorityGrid;
|
||||||
|
|
||||||
public bool ShowSpacing { get; set; } = DefaultShowSpacing;
|
public bool ShowSpacing { get; set; } = LayoutDefaultSettings.DefaultShowSpacing;
|
||||||
|
|
||||||
public int Spacing { get; set; } = DefaultSpacing;
|
public int Spacing { get; set; } = LayoutDefaultSettings.DefaultSpacing;
|
||||||
|
|
||||||
public int ZoneCount { get; set; } = DefaultZoneCount;
|
public int ZoneCount { get; set; } = LayoutDefaultSettings.DefaultZoneCount;
|
||||||
|
|
||||||
public int SensitivityRadius { get; set; } = DefaultSensitivityRadius;
|
public int SensitivityRadius { get; set; } = LayoutDefaultSettings.DefaultSensitivityRadius;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -487,6 +487,15 @@ namespace FancyZonesEditor.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to An error occurred while parsing editor parameters..
|
||||||
|
/// </summary>
|
||||||
|
public static string Error_Parsing_Editor_Parameters_Message {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Error_Parsing_Editor_Parameters_Message", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to An error occurred while parsing layout hotkeys..
|
/// Looks up a localized string similar to An error occurred while parsing layout hotkeys..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -435,4 +435,7 @@
|
|||||||
<data name="Set_Layout_As_Vertical_Default" xml:space="preserve">
|
<data name="Set_Layout_As_Vertical_Default" xml:space="preserve">
|
||||||
<value>Set layout as a default for vertical monitor orientation</value>
|
<value>Set layout as a default for vertical monitor orientation</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Error_Parsing_Editor_Parameters_Message" xml:space="preserve">
|
||||||
|
<value>An error occurred while parsing editor parameters.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,22 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace FancyZonesEditor.Utils
|
||||||
|
{
|
||||||
|
public struct ParsingResult
|
||||||
|
{
|
||||||
|
public bool Result { get; }
|
||||||
|
|
||||||
|
public string Message { get; }
|
||||||
|
|
||||||
|
public string MalformedData { get; }
|
||||||
|
|
||||||
|
public ParsingResult(bool result, string message = "", string data = "")
|
||||||
|
{
|
||||||
|
Result = result;
|
||||||
|
Message = message;
|
||||||
|
MalformedData = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,301 +0,0 @@
|
|||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
using OpenQA.Selenium.Appium.Windows;
|
|
||||||
using OpenQA.Selenium.Interactions;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class FancyZonesEditorCanvasZoneResizeTests : FancyZonesEditor
|
|
||||||
{
|
|
||||||
private void MoveCorner(WindowsElement corner, bool shiftLeft, bool shiftUp, int xOffset, int yOffset)
|
|
||||||
{
|
|
||||||
int shiftX = shiftLeft ? -(corner.Rect.Width / 2) + 1 : (corner.Rect.Width / 2) - 1;
|
|
||||||
int shiftY = shiftUp ? -(corner.Rect.Height / 2) + 1 : (corner.Rect.Height / 2) - 1;
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(corner)
|
|
||||||
.MoveByOffset(shiftX, shiftY)
|
|
||||||
.ClickAndHold().MoveByOffset(xOffset, yOffset).Release().Perform();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveTopBorder()
|
|
||||||
{
|
|
||||||
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
|
|
||||||
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
|
|
||||||
Assert.IsNotNull(topBorder);
|
|
||||||
Assert.IsNotNull(bottomBorder);
|
|
||||||
|
|
||||||
int height = bottomBorder.Rect.Y - topBorder.Rect.Y;
|
|
||||||
|
|
||||||
//up
|
|
||||||
new Actions(session).MoveToElement(topBorder).ClickAndHold().MoveByOffset(0, -5000).Release().Perform();
|
|
||||||
Assert.IsTrue(topBorder.Rect.Y >= 0);
|
|
||||||
Assert.IsTrue(height < bottomBorder.Rect.Y - topBorder.Rect.Y);
|
|
||||||
height = bottomBorder.Rect.Y - topBorder.Rect.Y;
|
|
||||||
|
|
||||||
//down
|
|
||||||
new Actions(session).MoveToElement(topBorder).ClickAndHold().MoveByOffset(0, 5000).Release().Perform();
|
|
||||||
Assert.IsTrue(topBorder.Rect.Y <= bottomBorder.Rect.Y);
|
|
||||||
Assert.IsTrue(height > bottomBorder.Rect.Y - topBorder.Rect.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveBottomBorder()
|
|
||||||
{
|
|
||||||
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
|
|
||||||
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
|
|
||||||
Assert.IsNotNull(topBorder);
|
|
||||||
Assert.IsNotNull(bottomBorder);
|
|
||||||
|
|
||||||
int height = bottomBorder.Rect.Y - topBorder.Rect.Y;
|
|
||||||
|
|
||||||
//up
|
|
||||||
new Actions(session).MoveToElement(bottomBorder).ClickAndHold().MoveByOffset(0, -5000).Release().Perform();
|
|
||||||
Assert.IsTrue(topBorder.Rect.Y <= bottomBorder.Rect.Y);
|
|
||||||
Assert.IsTrue(height > bottomBorder.Rect.Y - topBorder.Rect.Y);
|
|
||||||
height = bottomBorder.Rect.Y - topBorder.Rect.Y;
|
|
||||||
|
|
||||||
//down
|
|
||||||
new Actions(session).MoveToElement(bottomBorder).ClickAndHold().MoveByOffset(0, 5000).Release().Perform();
|
|
||||||
Assert.IsTrue(bottomBorder.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
|
||||||
Assert.IsTrue(height < bottomBorder.Rect.Y - topBorder.Rect.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveLeftBorder()
|
|
||||||
{
|
|
||||||
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
|
|
||||||
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
|
|
||||||
Assert.IsNotNull(leftBorder);
|
|
||||||
Assert.IsNotNull(rightBorder);
|
|
||||||
|
|
||||||
int width = rightBorder.Rect.X - leftBorder.Rect.X;
|
|
||||||
|
|
||||||
//to the left
|
|
||||||
new Actions(session).MoveToElement(leftBorder).ClickAndHold().MoveByOffset(-5000, 0).Release().Perform();
|
|
||||||
Assert.IsTrue(leftBorder.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
|
||||||
Assert.IsTrue(width < rightBorder.Rect.X - leftBorder.Rect.X);
|
|
||||||
width = rightBorder.Rect.X - leftBorder.Rect.X;
|
|
||||||
|
|
||||||
//to the right
|
|
||||||
new Actions(session).MoveToElement(leftBorder).ClickAndHold().MoveByOffset(5000, 0).Release().Perform();
|
|
||||||
Assert.IsTrue(leftBorder.Rect.X <= rightBorder.Rect.X);
|
|
||||||
Assert.IsTrue(width > rightBorder.Rect.X - leftBorder.Rect.X);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveRightBorder()
|
|
||||||
{
|
|
||||||
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
|
|
||||||
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
|
|
||||||
Assert.IsNotNull(leftBorder);
|
|
||||||
Assert.IsNotNull(rightBorder);
|
|
||||||
|
|
||||||
int width = rightBorder.Rect.X - leftBorder.Rect.X;
|
|
||||||
|
|
||||||
//to the left
|
|
||||||
new Actions(session).MoveToElement(rightBorder).ClickAndHold().MoveByOffset(-5000, 0).Release().Perform();
|
|
||||||
Assert.IsTrue(leftBorder.Rect.X <= rightBorder.Rect.X);
|
|
||||||
Assert.IsTrue(width > rightBorder.Rect.X - leftBorder.Rect.X);
|
|
||||||
width = rightBorder.Rect.X - leftBorder.Rect.X;
|
|
||||||
|
|
||||||
//to the right
|
|
||||||
new Actions(session).MoveToElement(rightBorder).ClickAndHold().MoveByOffset(5000, 0).Release().Perform();
|
|
||||||
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
|
||||||
Assert.IsTrue(width < rightBorder.Rect.X - leftBorder.Rect.X);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveTopLeftCorner()
|
|
||||||
{
|
|
||||||
WindowsElement topLeftCorner = session.FindElementByAccessibilityId("NWResize");
|
|
||||||
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
|
|
||||||
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
|
|
||||||
Assert.IsNotNull(topLeftCorner);
|
|
||||||
Assert.IsNotNull(bottomBorder);
|
|
||||||
Assert.IsNotNull(rightBorder);
|
|
||||||
|
|
||||||
int expectedWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
|
|
||||||
int expectedHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
|
|
||||||
int actualWidth, actualHeight;
|
|
||||||
|
|
||||||
//up-left
|
|
||||||
MoveCorner(topLeftCorner, true, true, -5000, -5000);
|
|
||||||
actualHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
|
|
||||||
actualWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
|
|
||||||
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.Y >= 0);
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.X >= 0);
|
|
||||||
Assert.IsTrue(actualHeight > expectedHeight);
|
|
||||||
Assert.IsTrue(actualWidth > expectedWidth);
|
|
||||||
|
|
||||||
expectedHeight = actualHeight;
|
|
||||||
expectedWidth = actualWidth;
|
|
||||||
|
|
||||||
//down-right
|
|
||||||
MoveCorner(topLeftCorner, true, true, 5000, 5000);
|
|
||||||
actualHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
|
|
||||||
actualWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
|
|
||||||
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.Y <= bottomBorder.Rect.Y);
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.X <= rightBorder.Rect.X);
|
|
||||||
Assert.IsTrue(actualHeight < expectedHeight);
|
|
||||||
Assert.IsTrue(actualWidth < expectedWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveTopRightCorner()
|
|
||||||
{
|
|
||||||
WindowsElement topRightCorner = session.FindElementByAccessibilityId("NEResize");
|
|
||||||
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
|
|
||||||
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
|
|
||||||
Assert.IsNotNull(topRightCorner);
|
|
||||||
Assert.IsNotNull(bottomBorder);
|
|
||||||
Assert.IsNotNull(leftBorder);
|
|
||||||
|
|
||||||
int expectedWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
|
|
||||||
int expectedHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
|
|
||||||
int actualWidth, actualHeight;
|
|
||||||
|
|
||||||
//up-right
|
|
||||||
MoveCorner(topRightCorner, false, true, 5000, -5000);
|
|
||||||
actualHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
|
|
||||||
actualWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
|
|
||||||
|
|
||||||
Assert.IsTrue(topRightCorner.Rect.Y >= 0);
|
|
||||||
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
|
||||||
Assert.IsTrue(actualHeight > expectedHeight);
|
|
||||||
Assert.IsTrue(actualWidth > expectedWidth);
|
|
||||||
|
|
||||||
expectedHeight = actualHeight;
|
|
||||||
expectedWidth = actualWidth;
|
|
||||||
|
|
||||||
//down-left
|
|
||||||
MoveCorner(topRightCorner, false, true, -5000, 5000);
|
|
||||||
actualHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
|
|
||||||
actualWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
|
|
||||||
|
|
||||||
Assert.IsTrue(topRightCorner.Rect.Y <= bottomBorder.Rect.Y);
|
|
||||||
Assert.IsTrue(topRightCorner.Rect.X >= leftBorder.Rect.X);
|
|
||||||
Assert.IsTrue(actualHeight < expectedHeight);
|
|
||||||
Assert.IsTrue(actualWidth < expectedWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveBottomLeftCorner()
|
|
||||||
{
|
|
||||||
WindowsElement bottomLeftCorner = session.FindElementByAccessibilityId("SWResize");
|
|
||||||
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
|
|
||||||
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
|
|
||||||
Assert.IsNotNull(bottomLeftCorner);
|
|
||||||
Assert.IsNotNull(topBorder);
|
|
||||||
Assert.IsNotNull(rightBorder);
|
|
||||||
|
|
||||||
int expectedWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
|
|
||||||
int expectedHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
|
|
||||||
int actualWidth, actualHeight;
|
|
||||||
|
|
||||||
//up-left
|
|
||||||
MoveCorner(bottomLeftCorner, true, false, 5000, -5000);
|
|
||||||
actualHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
|
|
||||||
actualWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
|
|
||||||
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.Y >= topBorder.Rect.Y);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.X <= rightBorder.Rect.X);
|
|
||||||
Assert.IsTrue(actualHeight < expectedHeight);
|
|
||||||
Assert.IsTrue(actualWidth < expectedWidth);
|
|
||||||
|
|
||||||
expectedHeight = actualHeight;
|
|
||||||
expectedWidth = actualWidth;
|
|
||||||
|
|
||||||
//down-right
|
|
||||||
MoveCorner(bottomLeftCorner, true, false, -5000, 5000);
|
|
||||||
actualHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
|
|
||||||
actualWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
|
|
||||||
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.X >= 0);
|
|
||||||
Assert.IsTrue(actualHeight > expectedHeight);
|
|
||||||
Assert.IsTrue(actualWidth > expectedWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveBottomRightCorner()
|
|
||||||
{
|
|
||||||
WindowsElement zone = session.FindElementByAccessibilityId("Caption");
|
|
||||||
Assert.IsNotNull(zone, "Unable to move zone");
|
|
||||||
new Actions(session).MoveToElement(zone).ClickAndHold().MoveByOffset(creatorWindow.Rect.Width / 2, 0).Release().Perform();
|
|
||||||
WindowsElement bottomRightCorner = session.FindElementByAccessibilityId("SEResize");
|
|
||||||
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
|
|
||||||
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
|
|
||||||
Assert.IsNotNull(bottomRightCorner);
|
|
||||||
Assert.IsNotNull(topBorder);
|
|
||||||
Assert.IsNotNull(leftBorder);
|
|
||||||
|
|
||||||
int expectedWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
|
|
||||||
int expectedHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
|
|
||||||
int actualWidth, actualHeight;
|
|
||||||
|
|
||||||
//up-left
|
|
||||||
MoveCorner(bottomRightCorner, false, false, -5000, -5000);
|
|
||||||
actualHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
|
|
||||||
actualWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
|
|
||||||
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.Y >= topBorder.Rect.Y);
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.X >= leftBorder.Rect.X);
|
|
||||||
Assert.IsTrue(actualHeight < expectedHeight);
|
|
||||||
Assert.IsTrue(actualWidth < expectedWidth);
|
|
||||||
|
|
||||||
expectedHeight = actualHeight;
|
|
||||||
expectedWidth = actualWidth;
|
|
||||||
|
|
||||||
//down-right
|
|
||||||
MoveCorner(bottomRightCorner, false, false, 5000, 5000);
|
|
||||||
actualHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
|
|
||||||
actualWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
|
|
||||||
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
|
||||||
Assert.IsTrue(actualHeight > expectedHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassInitialize]
|
|
||||||
public static void ClassInitialize(TestContext context)
|
|
||||||
{
|
|
||||||
Setup(context);
|
|
||||||
Assert.IsNotNull(session);
|
|
||||||
|
|
||||||
EnableModules(false, true, false, false, false, false, false, false);
|
|
||||||
ResetSettings();
|
|
||||||
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
OpenCustomLayouts();
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassCleanup]
|
|
||||||
public static void ClassCleanup()
|
|
||||||
{
|
|
||||||
CloseEditor();
|
|
||||||
ExitPowerToys();
|
|
||||||
TearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void TestInitialize()
|
|
||||||
{
|
|
||||||
//create canvas zone
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
creatorWindow.FindElementByAccessibilityId("newZoneButton").Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCleanup]
|
|
||||||
public void TestCleanup()
|
|
||||||
{
|
|
||||||
AppiumWebElement cancelButton = creatorWindow.FindElementByName("Cancel");
|
|
||||||
Assert.IsNotNull(cancelButton);
|
|
||||||
new Actions(session).MoveToElement(cancelButton).Click().Perform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,258 +0,0 @@
|
|||||||
using System.IO.Abstractions;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using OpenQA.Selenium;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
using OpenQA.Selenium.Appium.Windows;
|
|
||||||
using OpenQA.Selenium.Interactions;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class FancyZonesEditorCustomLayoutsTests : FancyZonesEditor
|
|
||||||
{
|
|
||||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
|
||||||
private static readonly IFile File = FileSystem.File;
|
|
||||||
|
|
||||||
private void SetLayoutName(string name)
|
|
||||||
{
|
|
||||||
AppiumWebElement textBox = creatorWindow.FindElementByClassName("TextBox");
|
|
||||||
textBox.Click();
|
|
||||||
textBox.SendKeys(Keys.Control + "a");
|
|
||||||
textBox.SendKeys(Keys.Backspace);
|
|
||||||
textBox.SendKeys(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CancelTest()
|
|
||||||
{
|
|
||||||
AppiumWebElement cancelButton = creatorWindow.FindElementByXPath("//Button[@Name=\"Cancel\"]");
|
|
||||||
new Actions(session).MoveToElement(cancelButton).Click().Perform();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
Assert.AreEqual(_initialZoneSettings, File.ReadAllText(_zoneSettingsPath), "Settings were changed");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SaveTest(string type, string name, int zoneCount)
|
|
||||||
{
|
|
||||||
new Actions(session).MoveToElement(editorWindow.FindElementByName("Save and apply")).Click().Perform();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
|
||||||
Assert.AreEqual(name, settings["custom-zone-sets"][0]["name"]);
|
|
||||||
Assert.AreEqual(settings["custom-zone-sets"][0]["uuid"], settings["devices"][0]["active-zoneset"]["uuid"]);
|
|
||||||
Assert.AreEqual(type, settings["custom-zone-sets"][0]["type"]);
|
|
||||||
Assert.AreEqual(zoneCount, settings["custom-zone-sets"][0]["info"]["zones"].ToObject<JArray>().Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateCancel()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
ZoneCountTest(0, 0);
|
|
||||||
|
|
||||||
editorWindow.FindElementByAccessibilityId("newZoneButton").Click();
|
|
||||||
ZoneCountTest(1, 0);
|
|
||||||
|
|
||||||
CancelTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateEmpty()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
ZoneCountTest(0, 0);
|
|
||||||
|
|
||||||
SaveTest("canvas", "Custom Layout 1", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateSingleZone()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
ZoneCountTest(0, 0);
|
|
||||||
|
|
||||||
editorWindow.FindElementByAccessibilityId("newZoneButton").Click();
|
|
||||||
ZoneCountTest(1, 0);
|
|
||||||
|
|
||||||
SaveTest("canvas", "Custom Layout 1", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateManyZones()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
ZoneCountTest(0, 0);
|
|
||||||
|
|
||||||
const int expectedZoneCount = 20;
|
|
||||||
AppiumWebElement addButton = editorWindow.FindElementByAccessibilityId("newZoneButton");
|
|
||||||
for (int i = 0; i < expectedZoneCount; i++)
|
|
||||||
{
|
|
||||||
addButton.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
ZoneCountTest(expectedZoneCount, 0);
|
|
||||||
SaveTest("canvas", "Custom Layout 1", expectedZoneCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateDeleteZone()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
ZoneCountTest(0, 0);
|
|
||||||
|
|
||||||
AppiumWebElement addButton = editorWindow.FindElementByAccessibilityId("newZoneButton");
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
//add zone
|
|
||||||
addButton.Click();
|
|
||||||
WindowsElement zone = session.FindElementByClassName("CanvasZone");
|
|
||||||
Assert.IsNotNull(zone, "Zone was not created");
|
|
||||||
Assert.IsTrue(zone.Displayed, "Zone was not displayed");
|
|
||||||
|
|
||||||
//remove zone
|
|
||||||
zone.FindElementByClassName("Button").Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
ZoneCountTest(0, 0);
|
|
||||||
CancelTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateWithName()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
string name = "My custom zone layout name";
|
|
||||||
SetLayoutName(name);
|
|
||||||
SaveTest("canvas", name, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateWithEmptyName()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
string name = "";
|
|
||||||
SetLayoutName(name);
|
|
||||||
SaveTest("canvas", name, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateWithUnicodeCharactersName()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
string name = "ёÖ±¬āݾᵩὡ√ﮘﻹտ";
|
|
||||||
SetLayoutName(name);
|
|
||||||
SaveTest("canvas", name, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void RenameLayout()
|
|
||||||
{
|
|
||||||
//create layout
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
string name = "My custom zone layout name";
|
|
||||||
SetLayoutName(name);
|
|
||||||
SaveTest("canvas", name, 0);
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
//rename layout
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
OpenCustomLayouts();
|
|
||||||
OpenCreatorWindow(name);
|
|
||||||
name = "New name";
|
|
||||||
SetLayoutName(name);
|
|
||||||
SaveTest("canvas", name, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void AddRemoveSameLayoutNames()
|
|
||||||
{
|
|
||||||
string name = "Name";
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
//create layout
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
SetLayoutName(name);
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(editorWindow.FindElementByName("Save and apply")).Click().Perform();
|
|
||||||
|
|
||||||
//remove layout
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
OpenCustomLayouts();
|
|
||||||
AppiumWebElement nameLabel = editorWindow.FindElementByXPath("//Text[@Name=\"" + name + "\"]");
|
|
||||||
new Actions(session).MoveToElement(nameLabel).MoveByOffset(nameLabel.Rect.Width / 2 + 10, 0).Click().Perform();
|
|
||||||
}
|
|
||||||
|
|
||||||
//settings are saved on window closing
|
|
||||||
new Actions(session).MoveToElement(editorWindow.FindElementByAccessibilityId("PART_Close")).Click().Perform();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
//check settings
|
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
|
||||||
Assert.AreEqual(0, settings["custom-zone-sets"].ToObject<JArray>().Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void RemoveApply()
|
|
||||||
{
|
|
||||||
string name = "Name";
|
|
||||||
|
|
||||||
//create layout
|
|
||||||
OpenCreatorWindow("Create new custom");
|
|
||||||
SetLayoutName(name);
|
|
||||||
new Actions(session).MoveToElement(editorWindow.FindElementByName("Save and apply")).Click().Perform();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
//save layout id
|
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
|
||||||
Assert.AreEqual(1, settings["custom-zone-sets"].ToObject<JArray>().Count);
|
|
||||||
|
|
||||||
//remove layout
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
OpenCustomLayouts();
|
|
||||||
AppiumWebElement nameLabel = editorWindow.FindElementByXPath("//Text[@Name=\"" + name + "\"]");
|
|
||||||
new Actions(session).MoveToElement(nameLabel).MoveByOffset(nameLabel.Rect.Width / 2 + 10, 0).Click().Perform();
|
|
||||||
|
|
||||||
//apply
|
|
||||||
new Actions(session).MoveToElement(editorWindow.FindElementByName("Apply")).Click().Perform();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
//check settings
|
|
||||||
settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
|
||||||
Assert.AreEqual(0, settings["custom-zone-sets"].ToObject<JArray>().Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassInitialize]
|
|
||||||
public static void ClassInitialize(TestContext context)
|
|
||||||
{
|
|
||||||
Setup(context);
|
|
||||||
Assert.IsNotNull(session);
|
|
||||||
EnableModules(false, true, false, false, false, false, false, false);
|
|
||||||
|
|
||||||
ResetDefaultFancyZonesSettings(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassCleanup]
|
|
||||||
public static void ClassCleanup()
|
|
||||||
{
|
|
||||||
ExitPowerToys();
|
|
||||||
TearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void TestInitialize()
|
|
||||||
{
|
|
||||||
ResetDefaultZoneSettings(true);
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
OpenCustomLayouts();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCleanup]
|
|
||||||
public void TestCleanup()
|
|
||||||
{
|
|
||||||
CloseEditor();
|
|
||||||
ExitPowerToys();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,438 +0,0 @@
|
|||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
using OpenQA.Selenium.Appium.Windows;
|
|
||||||
using OpenQA.Selenium.Interactions;
|
|
||||||
using System;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class FancyZonesEditorGridZoneResizeTests : FancyZonesEditor
|
|
||||||
{
|
|
||||||
private const int moveStep = 5;
|
|
||||||
|
|
||||||
private void Move(AppiumWebElement thumb, int border, bool moveAscending, bool moveHorizontally, int clickShift = 0)
|
|
||||||
{
|
|
||||||
Actions action = new Actions(session);
|
|
||||||
action.MoveToElement(thumb).MoveByOffset(0, clickShift).ClickAndHold();
|
|
||||||
|
|
||||||
int thumbCenter = 0;
|
|
||||||
if (moveHorizontally)
|
|
||||||
{
|
|
||||||
thumbCenter = thumb.Rect.X + thumb.Rect.Width / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
thumbCenter = thumb.Rect.Y + thumb.Rect.Height / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moves = Math.Abs(thumbCenter - border) / moveStep;
|
|
||||||
for (int j = 0; j < moves; j++)
|
|
||||||
{
|
|
||||||
int step = moveAscending ? moveStep : -moveStep;
|
|
||||||
if (moveHorizontally)
|
|
||||||
{
|
|
||||||
action.MoveByOffset(step, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
action.MoveByOffset(0, step);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action.Release().Perform();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveVerticalSplitter()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Columns", "EditTemplateButton");
|
|
||||||
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
|
|
||||||
Assert.IsNotNull(gridEditor);
|
|
||||||
|
|
||||||
Assert.AreEqual(3, gridEditor.FindElementsByClassName("GridZone").Count);
|
|
||||||
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
Assert.AreEqual(2, thumbs.Count);
|
|
||||||
|
|
||||||
//move left
|
|
||||||
for (int i = 0; i < thumbs.Count; i++)
|
|
||||||
{
|
|
||||||
AppiumWebElement thumb = thumbs[i];
|
|
||||||
int border = i == 0 ? 0 : thumbs[i - 1].Rect.Right;
|
|
||||||
Move(thumb, border, false, true);
|
|
||||||
|
|
||||||
Assert.IsTrue(thumb.Rect.Left - border <= moveStep);
|
|
||||||
Assert.IsTrue(thumb.Rect.Right > border);
|
|
||||||
}
|
|
||||||
|
|
||||||
//move right
|
|
||||||
for (int i = thumbs.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
AppiumWebElement thumb = thumbs[i];
|
|
||||||
int border = i == thumbs.Count - 1 ? Screen.PrimaryScreen.WorkingArea.Right : thumbs[i + 1].Rect.Left;
|
|
||||||
Move(thumb, border, true, true);
|
|
||||||
|
|
||||||
Assert.IsTrue(border - thumb.Rect.Right <= moveStep);
|
|
||||||
Assert.IsTrue(thumb.Rect.Left < border);
|
|
||||||
}
|
|
||||||
|
|
||||||
//move up
|
|
||||||
foreach (AppiumWebElement thumb in thumbs)
|
|
||||||
{
|
|
||||||
int expected = thumb.Rect.X;
|
|
||||||
|
|
||||||
Move(thumb, 0, false, false);
|
|
||||||
int actual = thumb.Rect.X;
|
|
||||||
|
|
||||||
Assert.AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
//move down
|
|
||||||
foreach (AppiumWebElement thumb in thumbs)
|
|
||||||
{
|
|
||||||
int expected = thumb.Rect.X;
|
|
||||||
|
|
||||||
Move(thumb, Screen.PrimaryScreen.WorkingArea.Right, true, false);
|
|
||||||
int actual = thumb.Rect.X;
|
|
||||||
|
|
||||||
Assert.AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveHorizontalSplitter()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Rows", "EditTemplateButton");
|
|
||||||
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
|
|
||||||
Assert.IsNotNull(gridEditor);
|
|
||||||
|
|
||||||
Assert.AreEqual(3, gridEditor.FindElementsByClassName("GridZone").Count);
|
|
||||||
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
Assert.AreEqual(2, thumbs.Count);
|
|
||||||
|
|
||||||
//move up
|
|
||||||
for (int i = 0; i < thumbs.Count; i++)
|
|
||||||
{
|
|
||||||
AppiumWebElement thumb = thumbs[i];
|
|
||||||
int border = i == 0 ? 0 : thumbs[i - 1].Rect.Bottom;
|
|
||||||
Move(thumb, border, false, false);
|
|
||||||
|
|
||||||
Assert.IsTrue(thumb.Rect.Top - border <= moveStep);
|
|
||||||
Assert.IsTrue(thumb.Rect.Right > border);
|
|
||||||
}
|
|
||||||
|
|
||||||
//move down
|
|
||||||
for (int i = thumbs.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
AppiumWebElement thumb = thumbs[i];
|
|
||||||
int border = i == thumbs.Count - 1 ? Screen.PrimaryScreen.WorkingArea.Bottom : thumbs[i + 1].Rect.Top;
|
|
||||||
Move(thumb, border, true, false);
|
|
||||||
|
|
||||||
Assert.IsTrue(border - thumb.Rect.Bottom <= moveStep);
|
|
||||||
Assert.IsTrue(thumb.Rect.Top < border);
|
|
||||||
}
|
|
||||||
|
|
||||||
//move left
|
|
||||||
foreach (AppiumWebElement thumb in thumbs)
|
|
||||||
{
|
|
||||||
int expected = thumb.Rect.Y;
|
|
||||||
|
|
||||||
Move(thumb, 0, false, true);
|
|
||||||
int actual = thumb.Rect.Y;
|
|
||||||
|
|
||||||
Assert.AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
//move right
|
|
||||||
foreach (AppiumWebElement thumb in thumbs)
|
|
||||||
{
|
|
||||||
int expected = thumb.Rect.Y;
|
|
||||||
|
|
||||||
Move(thumb, Screen.PrimaryScreen.WorkingArea.Right, true, true);
|
|
||||||
int actual = thumb.Rect.Y;
|
|
||||||
|
|
||||||
Assert.AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateSplitter()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Columns", "EditTemplateButton");
|
|
||||||
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
|
|
||||||
Assert.IsNotNull(gridEditor);
|
|
||||||
|
|
||||||
ReadOnlyCollection<AppiumWebElement> zones = gridEditor.FindElementsByClassName("GridZone");
|
|
||||||
Assert.AreEqual(3, zones.Count, "Zones count invalid");
|
|
||||||
|
|
||||||
const int defaultSpacing = 16;
|
|
||||||
int splitPos = zones[0].Rect.Y + zones[0].Rect.Height / 2;
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(zones[0]).Click().Perform();
|
|
||||||
|
|
||||||
zones = gridEditor.FindElementsByClassName("GridZone");
|
|
||||||
Assert.AreEqual(4, zones.Count);
|
|
||||||
|
|
||||||
//check splitted zone
|
|
||||||
Assert.AreEqual(defaultSpacing, zones[0].Rect.Top);
|
|
||||||
Assert.IsTrue(Math.Abs(zones[0].Rect.Bottom - splitPos + defaultSpacing / 2) <= 2);
|
|
||||||
Assert.IsTrue(Math.Abs(zones[1].Rect.Top - splitPos - defaultSpacing / 2) <= 2);
|
|
||||||
Assert.AreEqual(Screen.PrimaryScreen.Bounds.Bottom - defaultSpacing, zones[1].Rect.Bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void TestSplitterShiftAfterCreation()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Columns", "EditTemplateButton");
|
|
||||||
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
|
|
||||||
Assert.IsNotNull(gridEditor);
|
|
||||||
|
|
||||||
ReadOnlyCollection<AppiumWebElement> zones = gridEditor.FindElementsByClassName("GridZone");
|
|
||||||
Assert.AreEqual(3, zones.Count, "Zones count invalid");
|
|
||||||
|
|
||||||
const int defaultSpacing = 16;
|
|
||||||
|
|
||||||
//create first split
|
|
||||||
int firstSplitPos = zones[0].Rect.Y + zones[0].Rect.Height / 4;
|
|
||||||
new Actions(session).MoveToElement(zones[0]).MoveByOffset(0, -(zones[0].Rect.Height / 4)).Click().Perform();
|
|
||||||
|
|
||||||
zones = gridEditor.FindElementsByClassName("GridZone");
|
|
||||||
Assert.AreEqual(4, zones.Count);
|
|
||||||
|
|
||||||
Assert.AreEqual(defaultSpacing, zones[0].Rect.Top);
|
|
||||||
Assert.IsTrue(Math.Abs(zones[0].Rect.Bottom - firstSplitPos + defaultSpacing / 2) <= 2);
|
|
||||||
Assert.IsTrue(Math.Abs(zones[1].Rect.Top - firstSplitPos - defaultSpacing / 2) <= 2);
|
|
||||||
Assert.AreEqual(Screen.PrimaryScreen.Bounds.Bottom - defaultSpacing, zones[3].Rect.Bottom);
|
|
||||||
|
|
||||||
//create second split
|
|
||||||
int secondSplitPos = zones[3].Rect.Y + zones[3].Rect.Height / 2;
|
|
||||||
int expectedTop = zones[3].Rect.Top;
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(zones[3]).Click().Perform();
|
|
||||||
|
|
||||||
zones = gridEditor.FindElementsByClassName("GridZone");
|
|
||||||
Assert.AreEqual(5, zones.Count);
|
|
||||||
|
|
||||||
//check first split on same position
|
|
||||||
Assert.AreEqual(defaultSpacing, zones[0].Rect.Top);
|
|
||||||
Assert.IsTrue(Math.Abs(zones[0].Rect.Bottom - firstSplitPos + defaultSpacing / 2) <= 2);
|
|
||||||
|
|
||||||
//check second split
|
|
||||||
Assert.AreEqual(expectedTop, zones[3].Rect.Top);
|
|
||||||
Assert.IsTrue(Math.Abs(zones[3].Rect.Bottom - secondSplitPos + defaultSpacing / 2) <= 2);
|
|
||||||
Assert.IsTrue(Math.Abs(zones[4].Rect.Top - secondSplitPos - defaultSpacing / 2) <= 2);
|
|
||||||
Assert.AreEqual(Screen.PrimaryScreen.Bounds.Bottom - defaultSpacing, zones[4].Rect.Bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateSplitterWithShiftPressed()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Columns", "EditTemplateButton");
|
|
||||||
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
|
|
||||||
Assert.IsNotNull(gridEditor);
|
|
||||||
|
|
||||||
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
Assert.AreEqual(3, gridEditor.FindElementsByClassName("GridZone").Count);
|
|
||||||
Assert.AreEqual(2, thumbs.Count);
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(-100, 0)
|
|
||||||
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
|
|
||||||
.Perform();
|
|
||||||
Assert.AreEqual(3, gridEditor.FindElementsByClassName("Thumb").Count);
|
|
||||||
|
|
||||||
ReadOnlyCollection<AppiumWebElement> zones = gridEditor.FindElementsByClassName("GridZone");
|
|
||||||
Assert.AreEqual(4, zones.Count);
|
|
||||||
|
|
||||||
//check that zone was splitted vertically
|
|
||||||
Assert.AreEqual(zones[0].Rect.Height, zones[1].Rect.Height);
|
|
||||||
Assert.AreEqual(zones[1].Rect.Height, zones[2].Rect.Height);
|
|
||||||
Assert.AreEqual(zones[2].Rect.Height, zones[3].Rect.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void CreateSplitterWithShiftPressedFocusOnGridEditor()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Columns", "EditTemplateButton");
|
|
||||||
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
|
|
||||||
Assert.IsNotNull(gridEditor);
|
|
||||||
|
|
||||||
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
Assert.AreEqual(3, gridEditor.FindElementsByClassName("GridZone").Count);
|
|
||||||
Assert.AreEqual(2, thumbs.Count);
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(-100, 0)
|
|
||||||
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
|
|
||||||
.Perform();
|
|
||||||
Assert.AreEqual(3, gridEditor.FindElementsByClassName("Thumb").Count);
|
|
||||||
|
|
||||||
ReadOnlyCollection<AppiumWebElement> zones = gridEditor.FindElementsByClassName("GridZone");
|
|
||||||
Assert.AreEqual(4, zones.Count);
|
|
||||||
|
|
||||||
//check that zone was splitted vertically
|
|
||||||
Assert.AreEqual(zones[0].Rect.Height, zones[1].Rect.Height);
|
|
||||||
Assert.AreEqual(zones[1].Rect.Height, zones[2].Rect.Height);
|
|
||||||
Assert.AreEqual(zones[2].Rect.Height, zones[3].Rect.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveHorizontallyWithLimiter()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Columns", "EditTemplateButton");
|
|
||||||
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
|
|
||||||
Assert.IsNotNull(gridEditor);
|
|
||||||
|
|
||||||
Assert.AreEqual(3, gridEditor.FindElementsByClassName("GridZone").Count);
|
|
||||||
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
Assert.AreEqual(2, thumbs.Count);
|
|
||||||
|
|
||||||
//create new zones
|
|
||||||
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(-30, 0)
|
|
||||||
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
|
|
||||||
.Perform();
|
|
||||||
thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
Assert.AreEqual(4, gridEditor.FindElementsByClassName("GridZone").Count);
|
|
||||||
Assert.AreEqual(3, thumbs.Count);
|
|
||||||
|
|
||||||
//move thumbs
|
|
||||||
AppiumWebElement limiter = gridEditor.FindElementsByClassName("Thumb")[0];
|
|
||||||
AppiumWebElement movable = gridEditor.FindElementsByClassName("Thumb")[1];
|
|
||||||
|
|
||||||
Move(movable, 0, false, true);
|
|
||||||
Assert.IsTrue(movable.Rect.X > limiter.Rect.X);
|
|
||||||
Assert.IsTrue(movable.Rect.X - limiter.Rect.X < movable.Rect.Width);
|
|
||||||
|
|
||||||
Move(limiter, limiter.Rect.X - (limiter.Rect.X / 2), false, true);
|
|
||||||
|
|
||||||
Move(movable, 0, false, true);
|
|
||||||
Assert.IsTrue(movable.Rect.X > limiter.Rect.X);
|
|
||||||
Assert.IsTrue(movable.Rect.X - limiter.Rect.X < movable.Rect.Width);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveVerticallyWithLimiter()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Rows", "EditTemplateButton");
|
|
||||||
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
|
|
||||||
Assert.IsNotNull(gridEditor);
|
|
||||||
|
|
||||||
Assert.AreEqual(3, gridEditor.FindElementsByClassName("GridZone").Count);
|
|
||||||
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
Assert.AreEqual(2, thumbs.Count);
|
|
||||||
|
|
||||||
//create new zones
|
|
||||||
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(0, -(thumbs[0].Rect.Y / 2))
|
|
||||||
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
|
|
||||||
.Perform();
|
|
||||||
thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
Assert.AreEqual(4, gridEditor.FindElementsByClassName("GridZone").Count);
|
|
||||||
Assert.AreEqual(3, thumbs.Count);
|
|
||||||
|
|
||||||
//move thumbs
|
|
||||||
AppiumWebElement limiter = gridEditor.FindElementsByClassName("Thumb")[0];
|
|
||||||
AppiumWebElement movable = gridEditor.FindElementsByClassName("Thumb")[1];
|
|
||||||
|
|
||||||
Move(movable, 0, false, false);
|
|
||||||
Assert.IsTrue(movable.Rect.Y > limiter.Rect.Y);
|
|
||||||
Assert.IsTrue(movable.Rect.Y - limiter.Rect.Y < movable.Rect.Height);
|
|
||||||
|
|
||||||
Move(limiter, limiter.Rect.Y - (limiter.Rect.Y / 2), false, false, -5);
|
|
||||||
|
|
||||||
Move(movable, 0, false, false);
|
|
||||||
Assert.IsTrue(movable.Rect.Y > limiter.Rect.Y);
|
|
||||||
Assert.IsTrue(movable.Rect.Y - limiter.Rect.Y < movable.Rect.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MergeZones()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Columns", "EditTemplateButton");
|
|
||||||
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
|
|
||||||
Assert.IsNotNull(gridEditor);
|
|
||||||
|
|
||||||
ReadOnlyCollection<AppiumWebElement> zones = gridEditor.FindElementsByClassName("GridZone");
|
|
||||||
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
Assert.AreEqual(3, zones.Count);
|
|
||||||
Assert.AreEqual(2, thumbs.Count);
|
|
||||||
|
|
||||||
Move(zones[0], thumbs[0].Rect.X + thumbs[0].Rect.Width + 10, true, true, -(zones[0].Rect.Height / 2) + 10);
|
|
||||||
|
|
||||||
AppiumWebElement mergeButton = gridEditor.FindElementByName("Merge zones");
|
|
||||||
Assert.IsNotNull(mergeButton, "Cannot merge: no merge button");
|
|
||||||
new Actions(session).Click(mergeButton).Perform();
|
|
||||||
|
|
||||||
Assert.AreEqual(2, gridEditor.FindElementsByClassName("GridZone").Count);
|
|
||||||
Assert.AreEqual(1, gridEditor.FindElementsByClassName("Thumb").Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MoveAfterMerge()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Columns", "EditTemplateButton");
|
|
||||||
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
|
|
||||||
Assert.IsNotNull(gridEditor);
|
|
||||||
|
|
||||||
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
|
|
||||||
//create new zones
|
|
||||||
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(-(thumbs[0].Rect.X / 2), 0)
|
|
||||||
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
|
|
||||||
.Perform();
|
|
||||||
thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
|
|
||||||
//merge zones
|
|
||||||
ReadOnlyCollection<AppiumWebElement> zones = gridEditor.FindElementsByClassName("GridZone");
|
|
||||||
Move(zones[0], thumbs[0].Rect.X + thumbs[0].Rect.Width + 10, true, true, -(zones[0].Rect.Height / 2) + 10);
|
|
||||||
AppiumWebElement mergeButton = gridEditor.FindElementByName("Merge zones");
|
|
||||||
Assert.IsNotNull(mergeButton, "Cannot merge: no merge button");
|
|
||||||
new Actions(session).Click(mergeButton).Perform();
|
|
||||||
|
|
||||||
//move thumb
|
|
||||||
thumbs = gridEditor.FindElementsByClassName("Thumb");
|
|
||||||
AppiumWebElement thumb = thumbs[0];
|
|
||||||
Move(thumb, 0, false, true);
|
|
||||||
Assert.IsTrue(thumb.Rect.Left <= moveStep);
|
|
||||||
Assert.IsTrue(thumb.Rect.Right > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassInitialize]
|
|
||||||
public static void ClassInitialize(TestContext context)
|
|
||||||
{
|
|
||||||
Setup(context);
|
|
||||||
Assert.IsNotNull(session);
|
|
||||||
EnableModules(false, true, false, false, false, false, false, false);
|
|
||||||
|
|
||||||
ResetSettings();
|
|
||||||
|
|
||||||
if (!isPowerToysLaunched)
|
|
||||||
{
|
|
||||||
LaunchPowerToys();
|
|
||||||
}
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
OpenTemplates();
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassCleanup]
|
|
||||||
public static void ClassCleanup()
|
|
||||||
{
|
|
||||||
CloseEditor();
|
|
||||||
ExitPowerToys();
|
|
||||||
TearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void TestInitialize()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCleanup]
|
|
||||||
public void TestCleanup()
|
|
||||||
{
|
|
||||||
AppiumWebElement cancelButton = creatorWindow.FindElementByName("Cancel");
|
|
||||||
Assert.IsNotNull(cancelButton);
|
|
||||||
new Actions(session).MoveToElement(cancelButton).Click().Perform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,300 +0,0 @@
|
|||||||
using System.IO.Abstractions;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
using OpenQA.Selenium.Appium.Windows;
|
|
||||||
using OpenQA.Selenium.Interactions;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class FancyZonesEditorOpeningTests : FancyZonesEditor
|
|
||||||
{
|
|
||||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
|
||||||
private static readonly IFile File = FileSystem.File;
|
|
||||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
|
||||||
void RemoveSettingsFile()
|
|
||||||
{
|
|
||||||
File.Delete(_zoneSettingsPath);
|
|
||||||
File.Delete(_appHistoryPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveSettingsFolder()
|
|
||||||
{
|
|
||||||
Directory.Delete(_settingsFolderPath, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateEmptySettingsFile()
|
|
||||||
{
|
|
||||||
string zoneSettings = "";
|
|
||||||
File.WriteAllText(_zoneSettingsPath, zoneSettings);
|
|
||||||
|
|
||||||
string appHistory = "";
|
|
||||||
File.WriteAllText(_appHistoryPath, appHistory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateDefaultSettingsFile()
|
|
||||||
{
|
|
||||||
string zoneSettings = "{\"devices\":[],\"custom-zone-sets\":[]}";
|
|
||||||
File.WriteAllText(_zoneSettingsPath, zoneSettings);
|
|
||||||
|
|
||||||
string appHistory = "{\"app-zone-history\":[]}";
|
|
||||||
File.WriteAllText(_appHistoryPath, appHistory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateValidSettingsFile()
|
|
||||||
{
|
|
||||||
string zoneSettings = "{\"devices\":[{\"device-id\":\"DELA026#5&10a58c63&0&UID16777488_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}\",\"active-zoneset\":{\"uuid\":\"{D13ABB6D-7721-4176-9647-C8C0836D99CC}\",\"type\":\"columns\"},\"editor-show-spacing\":true,\"editor-spacing\":16,\"editor-zone-count\":3}],\"custom-zone-sets\":[]}";
|
|
||||||
File.WriteAllText(_zoneSettingsPath, zoneSettings);
|
|
||||||
|
|
||||||
string appHistory = "{\"app-zone-history\":[{\"app-path\":\"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Common7\\IDE\\Extensions\\TestPlatform\\testhost.exe\",\"zone-index\":3,\"device-id\":\"DELA026#5&10a58c63&0&UID16777488_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}\",\"zoneset-uuid\":\"{D13ABB6D-7721-4176-9647-C8C0836D99CC}\"}]}";
|
|
||||||
File.WriteAllText(_appHistoryPath, appHistory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateValidSettingsFileWithUtf8()
|
|
||||||
{
|
|
||||||
string zoneSettings = "{\"devices\":[{\"device-id\":\"DELA026#5&10a58c63&0&UID16777488_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}\",\"active-zoneset\":{\"uuid\":\"{D13ABB6D-7721-4176-9647-C8C0836D99CC}\",\"type\":\"columns\"},\"editor-show-spacing\":true,\"editor-spacing\":16,\"editor-zone-count\":3}],\"custom-zone-sets\":[]}";
|
|
||||||
File.WriteAllText(_zoneSettingsPath, zoneSettings);
|
|
||||||
|
|
||||||
string appHistory = "{\"app-zone-history\":[{\"app-path\":\"C:\\Program Files (x86)\\йцукен\\testhost.exe\",\"zone-index\":3,\"device-id\":\"DELA026#5&10a58c63&0&UID16777488_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}\",\"zoneset-uuid\":\"{D13ABB6D-7721-4176-9647-C8C0836D99CC}\"}]}";
|
|
||||||
File.WriteAllText(_appHistoryPath, appHistory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateInvalidSettingsFile()
|
|
||||||
{
|
|
||||||
string zoneSettings = "{\"app-zone-history\":[{\"app-path\":\"C:\\Program Files (x86)\\Microsoft Visual Studio\\testhost.exe\",\"zone-index\":3,\"device-id\":\"wrong-device-id\",\"zoneset-uuid\":\"{D13ABB6D-invalid-uuid-C8C0836D99CC}\"}],\"devices\":[{\"device-id\":\"DELA026#5&10a58c63&0&UID16777488_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}\",\"active-zoneset\":{\"uuid\":\"{D13ABB6D-7721-4176-9647-C8C0836D99CC}\",\"type\":\"columns\"},\"editor-show-spacing\":true,\"editor-spacing\":16,\"editor-zone-count\":3}],\"custom-zone-sets\":[]}";
|
|
||||||
File.WriteAllText(_zoneSettingsPath, zoneSettings);
|
|
||||||
|
|
||||||
string appHistory = "";
|
|
||||||
File.WriteAllText(_appHistoryPath, appHistory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateCroppedSettingsFile()
|
|
||||||
{
|
|
||||||
string zoneSettings = "{\"devices\":[],\"custom-zone-sets\":[{\"uuid\":\"{8BEC7183-C90E-4D41-AD1C-1AC2BC4760BA}\",\"name\":\"";
|
|
||||||
File.WriteAllText(_zoneSettingsPath, zoneSettings);
|
|
||||||
|
|
||||||
string appHistory = "{\"app-zone-history\":[]}";
|
|
||||||
File.WriteAllText(_appHistoryPath, appHistory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestEditorOpened(bool errorExpected = false)
|
|
||||||
{
|
|
||||||
WindowsElement errorMessage = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
errorMessage = session.FindElementByName("FancyZones Editor Exception Handler");
|
|
||||||
if (errorMessage != null)
|
|
||||||
{
|
|
||||||
errorMessage.FindElementByName("OK").Click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (OpenQA.Selenium.WebDriverException)
|
|
||||||
{
|
|
||||||
//no error message, it's ok
|
|
||||||
}
|
|
||||||
|
|
||||||
editorWindow = session.FindElementByName("FancyZones Editor");
|
|
||||||
Assert.IsNotNull(editorWindow);
|
|
||||||
|
|
||||||
if (!errorExpected)
|
|
||||||
{
|
|
||||||
Assert.IsNull(errorMessage);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert.IsNotNull(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenEditorBySettingsButton()
|
|
||||||
{
|
|
||||||
OpenSettings();
|
|
||||||
OpenFancyZonesSettings();
|
|
||||||
settingsWindow.FindElementByName("Launch zones editor").Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenEditorByHotkey()
|
|
||||||
{
|
|
||||||
new Actions(session).KeyDown(OpenQA.Selenium.Keys.Command).SendKeys("`").KeyUp(OpenQA.Selenium.Keys.Command).Perform();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorBySettingsButtonNoSettings()
|
|
||||||
{
|
|
||||||
RemoveSettingsFile();
|
|
||||||
OpenEditorBySettingsButton();
|
|
||||||
TestEditorOpened(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorBySettingsButtonNoSettingsFolder()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (isPowerToysLaunched)
|
|
||||||
{
|
|
||||||
ExitPowerToys();
|
|
||||||
}
|
|
||||||
RemoveSettingsFolder();
|
|
||||||
LaunchPowerToys();
|
|
||||||
*/
|
|
||||||
|
|
||||||
RemoveSettingsFolder();
|
|
||||||
OpenEditorBySettingsButton();
|
|
||||||
TestEditorOpened(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorBySettingsButtonEmptySettings()
|
|
||||||
{
|
|
||||||
CreateEmptySettingsFile();
|
|
||||||
OpenEditorBySettingsButton();
|
|
||||||
TestEditorOpened(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorBySettingsButtonDefaultSettings()
|
|
||||||
{
|
|
||||||
CreateDefaultSettingsFile();
|
|
||||||
OpenEditorBySettingsButton();
|
|
||||||
TestEditorOpened();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorBySettingsButtonValidSettings()
|
|
||||||
{
|
|
||||||
CreateValidSettingsFile();
|
|
||||||
OpenEditorBySettingsButton();
|
|
||||||
TestEditorOpened();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorBySettingsButtonValidUtf8Settings()
|
|
||||||
{
|
|
||||||
CreateValidSettingsFileWithUtf8();
|
|
||||||
OpenEditorBySettingsButton();
|
|
||||||
TestEditorOpened();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorBySettingsButtonInvalidSettings()
|
|
||||||
{
|
|
||||||
CreateInvalidSettingsFile();
|
|
||||||
OpenEditorBySettingsButton();
|
|
||||||
TestEditorOpened(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorBySettingsButtonCroppedSettings()
|
|
||||||
{
|
|
||||||
CreateCroppedSettingsFile();
|
|
||||||
OpenEditorBySettingsButton();
|
|
||||||
TestEditorOpened(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorByHotkeyNoSettings()
|
|
||||||
{
|
|
||||||
RemoveSettingsFile();
|
|
||||||
OpenEditorByHotkey();
|
|
||||||
TestEditorOpened(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorByHotkeyNoSettingsFolder()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (isPowerToysLaunched)
|
|
||||||
{
|
|
||||||
ExitPowerToys();
|
|
||||||
}
|
|
||||||
RemoveSettingsFolder();
|
|
||||||
LaunchPowerToys();
|
|
||||||
*/
|
|
||||||
RemoveSettingsFolder();
|
|
||||||
OpenEditorByHotkey();
|
|
||||||
TestEditorOpened(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorByHotkeyEmptySettings()
|
|
||||||
{
|
|
||||||
CreateEmptySettingsFile();
|
|
||||||
OpenEditorByHotkey();
|
|
||||||
TestEditorOpened(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorByHotkeyDefaultSettings()
|
|
||||||
{
|
|
||||||
CreateDefaultSettingsFile();
|
|
||||||
OpenEditorByHotkey();
|
|
||||||
TestEditorOpened();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorByHotkeyValidSettings()
|
|
||||||
{
|
|
||||||
CreateValidSettingsFile();
|
|
||||||
OpenEditorByHotkey();
|
|
||||||
TestEditorOpened();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorByHotkeyValidUtf8Settings()
|
|
||||||
{
|
|
||||||
CreateValidSettingsFileWithUtf8();
|
|
||||||
OpenEditorByHotkey();
|
|
||||||
TestEditorOpened();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorByHotkeyInvalidSettings()
|
|
||||||
{
|
|
||||||
CreateInvalidSettingsFile();
|
|
||||||
OpenEditorByHotkey();
|
|
||||||
TestEditorOpened(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void OpenEditorByHotkeyCroppedSettings()
|
|
||||||
{
|
|
||||||
CreateCroppedSettingsFile();
|
|
||||||
OpenEditorByHotkey();
|
|
||||||
TestEditorOpened(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassInitialize]
|
|
||||||
public static void ClassInitialize(TestContext context)
|
|
||||||
{
|
|
||||||
Setup(context);
|
|
||||||
Assert.IsNotNull(session);
|
|
||||||
EnableModules(false, true, false, false, false, false, false, false);
|
|
||||||
|
|
||||||
ResetDefaultFancyZonesSettings(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassCleanup]
|
|
||||||
public static void ClassCleanup()
|
|
||||||
{
|
|
||||||
ExitPowerToys();
|
|
||||||
TearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void TestInitialize()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCleanup]
|
|
||||||
public void TestCleanup()
|
|
||||||
{
|
|
||||||
CloseEditor();
|
|
||||||
|
|
||||||
if (!Directory.Exists(_settingsFolderPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(_settingsFolderPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,206 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO.Abstractions;
|
|
||||||
//using System.IO;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using OpenQA.Selenium;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class FancyZonesEditorSettingsTests : FancyZonesEditor
|
|
||||||
{
|
|
||||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
|
||||||
private static readonly IFile File = FileSystem.File;
|
|
||||||
|
|
||||||
private const string editorZoneCount = "editor-zone-count";
|
|
||||||
private const string editorShowSpacing = "editor-show-spacing";
|
|
||||||
private const string editorSpacing = "editor-spacing";
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ZoneCount()
|
|
||||||
{
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
|
|
||||||
AppiumWebElement minusButton = editorWindow.FindElementByAccessibilityId("decrementZones");
|
|
||||||
AppiumWebElement zoneCount = editorWindow.FindElementByAccessibilityId("zoneCount");
|
|
||||||
|
|
||||||
int editorZoneCountValue;
|
|
||||||
Assert.IsTrue(Int32.TryParse(zoneCount.Text, out editorZoneCountValue));
|
|
||||||
|
|
||||||
for (int i = editorZoneCountValue - 1, j = 0; i > -5; --i, ++j)
|
|
||||||
{
|
|
||||||
minusButton.Click();
|
|
||||||
|
|
||||||
Assert.IsTrue(Int32.TryParse(zoneCount.Text, out editorZoneCountValue));
|
|
||||||
Assert.AreEqual(Math.Max(i, 1), editorZoneCountValue);
|
|
||||||
|
|
||||||
if (j == 0 || i == -4)
|
|
||||||
{
|
|
||||||
editorWindow.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
|
||||||
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual(editorZoneCountValue, GetEditZonesSetting<int>(editorZoneCount));
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
|
|
||||||
minusButton = editorWindow.FindElementByAccessibilityId("decrementZones");
|
|
||||||
zoneCount = editorWindow.FindElementByAccessibilityId("zoneCount");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AppiumWebElement plusButton = editorWindow.FindElementByAccessibilityId("incrementZones");
|
|
||||||
|
|
||||||
for (int i = 2; i < 45; ++i)
|
|
||||||
{
|
|
||||||
plusButton.Click();
|
|
||||||
|
|
||||||
Assert.IsTrue(Int32.TryParse(zoneCount.Text, out editorZoneCountValue));
|
|
||||||
Assert.AreEqual(Math.Min(i, 40), editorZoneCountValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
editorWindow.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual(editorZoneCountValue, GetEditZonesSetting<int>(editorZoneCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ShowSpacingTest()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 2; ++i)
|
|
||||||
{
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
|
|
||||||
AppiumWebElement spaceAroundSetting = editorWindow.FindElementByAccessibilityId("spaceAroundSetting");
|
|
||||||
bool spaceAroundSettingValue = spaceAroundSetting.Selected;
|
|
||||||
spaceAroundSetting.Click();
|
|
||||||
|
|
||||||
editorWindow.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
|
||||||
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
Assert.AreNotEqual(spaceAroundSettingValue, GetEditZonesSetting<bool>(editorShowSpacing));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void SpacingTestsValid()
|
|
||||||
{
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
|
|
||||||
AppiumWebElement spaceAroundSetting = editorWindow.FindElementByAccessibilityId("spaceAroundSetting");
|
|
||||||
bool editorShowSpacingValue = spaceAroundSetting.Selected;
|
|
||||||
|
|
||||||
editorWindow.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
|
||||||
|
|
||||||
string[] validValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
|
||||||
|
|
||||||
foreach (string editorSpacingValue in validValues)
|
|
||||||
{
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
|
|
||||||
AppiumWebElement paddingValue = editorWindow.FindElementByAccessibilityId("paddingValue");
|
|
||||||
ClearText(paddingValue);
|
|
||||||
paddingValue.SendKeys(editorSpacingValue);
|
|
||||||
|
|
||||||
editorWindow.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
Assert.AreEqual(editorShowSpacingValue, GetEditZonesSetting<bool>(editorShowSpacing));
|
|
||||||
Assert.AreEqual(editorSpacingValue, GetEditZonesSetting<string>(editorSpacing));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void SpacingTestsInvalid()
|
|
||||||
{
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
|
|
||||||
AppiumWebElement spaceAroundSetting = editorWindow.FindElementByAccessibilityId("spaceAroundSetting");
|
|
||||||
bool editorShowSpacingValue = spaceAroundSetting.Selected;
|
|
||||||
|
|
||||||
editorWindow.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
|
||||||
|
|
||||||
string[] invalidValues = { "!", "/", "<", "?", "D", "Z", "]", "m", "}", "1.5", "2,5" };
|
|
||||||
|
|
||||||
string editorSpacingValue = GetEditZonesSetting<string>(editorSpacing);
|
|
||||||
|
|
||||||
foreach (string value in invalidValues)
|
|
||||||
{
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
|
|
||||||
AppiumWebElement paddingValue = editorWindow.FindElementByAccessibilityId("paddingValue");
|
|
||||||
ClearText(paddingValue);
|
|
||||||
paddingValue.SendKeys(value);
|
|
||||||
|
|
||||||
editorWindow.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
|
||||||
|
|
||||||
Assert.AreEqual(editorShowSpacingValue, GetEditZonesSetting<bool>(editorShowSpacing));
|
|
||||||
Assert.AreEqual(editorSpacingValue, GetEditZonesSetting<string>(editorSpacing));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void SpacingTestLargeValue()
|
|
||||||
{
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
editorWindow.FindElementByName("Grid").Click();
|
|
||||||
|
|
||||||
AppiumWebElement paddingValue = editorWindow.FindElementByAccessibilityId("paddingValue");
|
|
||||||
ClearText(paddingValue);
|
|
||||||
paddingValue.SendKeys("1000");
|
|
||||||
|
|
||||||
editorWindow.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
|
||||||
editorWindow = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
Assert.AreNotEqual(editorWindow, null, "Editor Zones Window is not starting after setting large padding value");
|
|
||||||
}
|
|
||||||
|
|
||||||
private T GetEditZonesSetting<T>(string value)
|
|
||||||
{
|
|
||||||
JObject zoneSettings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
|
||||||
T result = zoneSettings["devices"][0][value].ToObject<T>();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClearText(AppiumWebElement windowsElement)
|
|
||||||
{
|
|
||||||
windowsElement.SendKeys(Keys.Home);
|
|
||||||
windowsElement.SendKeys(Keys.Control + Keys.Delete);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassInitialize]
|
|
||||||
public static void ClassInitialize(TestContext context)
|
|
||||||
{
|
|
||||||
Setup(context);
|
|
||||||
Assert.IsNotNull(session);
|
|
||||||
EnableModules(false, true, false, false, false, false, false, false);
|
|
||||||
ResetSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassCleanup]
|
|
||||||
public static void ClassCleanup()
|
|
||||||
{
|
|
||||||
CloseSettings();
|
|
||||||
ResetDefaultFancyZonesSettings(false);
|
|
||||||
ResetDefaultZoneSettings(false);
|
|
||||||
TearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void TestInitialize()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCleanup]
|
|
||||||
public void TestCleanup()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
using System.IO.Abstractions;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class FancyZonesEditorTemplatesApplyTests : FancyZonesEditor
|
|
||||||
{
|
|
||||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
|
||||||
private static readonly IFile File = FileSystem.File;
|
|
||||||
|
|
||||||
private void ApplyLayout(string tabName)
|
|
||||||
{
|
|
||||||
editorWindow.FindElementByName(tabName).Click();
|
|
||||||
editorWindow.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Assert.IsNull(session.FindElementByName("FancyZones Editor"));
|
|
||||||
}
|
|
||||||
catch (OpenQA.Selenium.WebDriverException)
|
|
||||||
{
|
|
||||||
//editor was closed as expected
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckSettingsLayout(string expectedLayout)
|
|
||||||
{
|
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
|
||||||
Assert.AreEqual(expectedLayout, settings["devices"][0]["active-zoneset"]["type"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ApplyFocus()
|
|
||||||
{
|
|
||||||
ApplyLayout("Focus");
|
|
||||||
CheckSettingsLayout("focus");
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ApplyColumns()
|
|
||||||
{
|
|
||||||
ApplyLayout("Columns");
|
|
||||||
CheckSettingsLayout("columns");
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ApplyRows()
|
|
||||||
{
|
|
||||||
ApplyLayout("Rows");
|
|
||||||
CheckSettingsLayout("rows");
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ApplyGrid()
|
|
||||||
{
|
|
||||||
ApplyLayout("Grid");
|
|
||||||
CheckSettingsLayout("grid");
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ApplyPriorityGrid()
|
|
||||||
{
|
|
||||||
ApplyLayout("Priority Grid");
|
|
||||||
CheckSettingsLayout("priority-grid");
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassInitialize]
|
|
||||||
public static void ClassInitialize(TestContext context)
|
|
||||||
{
|
|
||||||
Setup(context);
|
|
||||||
Assert.IsNotNull(session);
|
|
||||||
EnableModules(false, true, false, false, false, false, false, false);
|
|
||||||
|
|
||||||
ResetDefaultFancyZonesSettings(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassCleanup]
|
|
||||||
public static void ClassCleanup()
|
|
||||||
{
|
|
||||||
CloseSettings();
|
|
||||||
ExitPowerToys();
|
|
||||||
TearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void TestInitialize()
|
|
||||||
{
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
OpenTemplates();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCleanup]
|
|
||||||
public void TestCleanup()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,207 +0,0 @@
|
|||||||
using System.IO.Abstractions;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
using OpenQA.Selenium.Interactions;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class FancyZonesEditorTemplatesEditTests : FancyZonesEditor
|
|
||||||
{
|
|
||||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
|
||||||
private static readonly IFile File = FileSystem.File;
|
|
||||||
private void ChangeLayout()
|
|
||||||
{
|
|
||||||
new Actions(session).MoveToElement(creatorWindow.FindElementByAccessibilityId("PART_TitleBar")).MoveByOffset(0, -50).Click().Perform();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Cancel(AppiumWebElement creatorWindow)
|
|
||||||
{
|
|
||||||
AppiumWebElement cancelButton = creatorWindow.FindElementByName("Cancel");
|
|
||||||
Assert.IsNotNull(cancelButton);
|
|
||||||
new Actions(session).MoveToElement(cancelButton).Click().Perform();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CancelTest(AppiumWebElement creatorWindow)
|
|
||||||
{
|
|
||||||
Cancel(creatorWindow);
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
Assert.AreEqual(_defaultZoneSettings, File.ReadAllText(_zoneSettingsPath), "Settings were changed");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SaveTest()
|
|
||||||
{
|
|
||||||
new Actions(session).MoveToElement(creatorWindow.FindElementByName("Save and apply")).Click().Perform();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
|
||||||
Assert.AreEqual("Custom Layout 1", settings["custom-zone-sets"][0]["name"]);
|
|
||||||
Assert.AreEqual(settings["custom-zone-sets"][0]["uuid"], settings["devices"][0]["active-zoneset"]["uuid"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void EditFocusCancel()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Focus", "EditTemplateButton");
|
|
||||||
ZoneCountTest(3, 0);
|
|
||||||
|
|
||||||
creatorWindow.FindElementByAccessibilityId("newZoneButton").Click();
|
|
||||||
ZoneCountTest(4, 0);
|
|
||||||
|
|
||||||
CancelTest(creatorWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void EditColumnsCancel()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Columns", "EditTemplateButton");
|
|
||||||
ZoneCountTest(0, 3);
|
|
||||||
|
|
||||||
ChangeLayout();
|
|
||||||
ZoneCountTest(0, 4);
|
|
||||||
|
|
||||||
CancelTest(creatorWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void EditRowsCancel()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Rows", "EditTemplateButton");
|
|
||||||
ZoneCountTest(0, 3);
|
|
||||||
|
|
||||||
ChangeLayout();
|
|
||||||
ZoneCountTest(0, 4);
|
|
||||||
|
|
||||||
CancelTest(creatorWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void EditGridCancel()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Grid", "EditTemplateButton");
|
|
||||||
ZoneCountTest(0, 3);
|
|
||||||
|
|
||||||
ChangeLayout();
|
|
||||||
ZoneCountTest(0, 4);
|
|
||||||
|
|
||||||
CancelTest(creatorWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void EditPriorityGridCancel()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Priority Grid", "EditTemplateButton");
|
|
||||||
ZoneCountTest(0, 3);
|
|
||||||
|
|
||||||
ChangeLayout();
|
|
||||||
ZoneCountTest(0, 4);
|
|
||||||
|
|
||||||
CancelTest(creatorWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void EditFocusSave()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Focus", "EditTemplateButton");
|
|
||||||
ZoneCountTest(3, 0);
|
|
||||||
|
|
||||||
creatorWindow.FindElementByAccessibilityId("newZoneButton").Click();
|
|
||||||
ZoneCountTest(4, 0);
|
|
||||||
|
|
||||||
SaveTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void EditColumnsSave()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Columns", "EditTemplateButton");
|
|
||||||
ZoneCountTest(0, 3);
|
|
||||||
|
|
||||||
ChangeLayout();
|
|
||||||
ZoneCountTest(0, 4);
|
|
||||||
|
|
||||||
SaveTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void EditRowsSave()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Rows", "EditTemplateButton");
|
|
||||||
ZoneCountTest(0, 3);
|
|
||||||
|
|
||||||
ChangeLayout();
|
|
||||||
ZoneCountTest(0, 4);
|
|
||||||
|
|
||||||
SaveTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void EditGridSave()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Grid", "EditTemplateButton");
|
|
||||||
ZoneCountTest(0, 3);
|
|
||||||
|
|
||||||
ChangeLayout();
|
|
||||||
ZoneCountTest(0, 4);
|
|
||||||
|
|
||||||
SaveTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void EditPriorityGridSave()
|
|
||||||
{
|
|
||||||
OpenCreatorWindow("Priority Grid", "EditTemplateButton");
|
|
||||||
ZoneCountTest(0, 3);
|
|
||||||
|
|
||||||
ChangeLayout();
|
|
||||||
ZoneCountTest(0, 4);
|
|
||||||
|
|
||||||
SaveTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassInitialize]
|
|
||||||
public static void ClassInitialize(TestContext context)
|
|
||||||
{
|
|
||||||
Setup(context);
|
|
||||||
Assert.IsNotNull(session);
|
|
||||||
EnableModules(false, true, false, false, false, false, false, false);
|
|
||||||
|
|
||||||
ResetDefaultFancyZonesSettings(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassCleanup]
|
|
||||||
public static void ClassCleanup()
|
|
||||||
{
|
|
||||||
CloseSettings();
|
|
||||||
ExitPowerToys();
|
|
||||||
TearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void TestInitialize()
|
|
||||||
{
|
|
||||||
ResetDefaultZoneSettings(true);
|
|
||||||
Assert.IsTrue(OpenEditor());
|
|
||||||
OpenTemplates();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCleanup]
|
|
||||||
public void TestCleanup()
|
|
||||||
{
|
|
||||||
//Close editor
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (editorWindow != null)
|
|
||||||
{
|
|
||||||
editorWindow.SendKeys(OpenQA.Selenium.Keys.Alt + OpenQA.Selenium.Keys.F4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (OpenQA.Selenium.WebDriverException)
|
|
||||||
{
|
|
||||||
//editor was already closed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
using OpenQA.Selenium.Appium.Windows;
|
|
||||||
using OpenQA.Selenium.Interactions;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
public class FancyZonesEditor : PowerToysSession
|
|
||||||
{
|
|
||||||
protected static WindowsElement editorWindow;
|
|
||||||
protected static AppiumWebElement creatorWindow;
|
|
||||||
|
|
||||||
protected static void ResetSettings()
|
|
||||||
{
|
|
||||||
ResetDefaultFancyZonesSettings(false);
|
|
||||||
ResetDefaultZoneSettings(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static bool OpenEditor()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
new Actions(session).KeyDown(OpenQA.Selenium.Keys.Command).SendKeys("`").KeyUp(OpenQA.Selenium.Keys.Command).Perform();
|
|
||||||
|
|
||||||
//editorWindow = WaitElementByXPath("//Window[@Name=\"FancyZones Editor\"]");
|
|
||||||
editorWindow = session.FindElementByName("FancyZones Editor");
|
|
||||||
Assert.IsNotNull(editorWindow, "Couldn't find editor window");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void CloseEditor()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (editorWindow != null)
|
|
||||||
{
|
|
||||||
editorWindow.SendKeys(OpenQA.Selenium.Keys.Alt + OpenQA.Selenium.Keys.F4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (OpenQA.Selenium.WebDriverException)
|
|
||||||
{
|
|
||||||
//editor has been already closed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void OpenCustomLayouts()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
WindowsElement customsTab = session.FindElementByName("Custom");
|
|
||||||
customsTab.Click();
|
|
||||||
string isSelected = customsTab.GetAttribute("SelectionItem.IsSelected");
|
|
||||||
Assert.AreEqual("True", isSelected, "Custom tab cannot be opened");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void OpenTemplates()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
WindowsElement templatesTab = session.FindElementByName("Templates");
|
|
||||||
templatesTab.Click();
|
|
||||||
string isSelected = templatesTab.GetAttribute("SelectionItem.IsSelected");
|
|
||||||
Assert.AreEqual("True", isSelected, "Templates tab cannot be opened");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void OpenCreatorWindow(string tabName, string buttonId = "EditCustomButton")
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
editorWindow.FindElementByName(tabName).Click();
|
|
||||||
editorWindow.FindElementByAccessibilityId(buttonId).Click();
|
|
||||||
creatorWindow = editorWindow.FindElementByXPath("//Window");
|
|
||||||
Assert.IsNotNull(creatorWindow, "Creator window didn't open");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void ZoneCountTest(int canvasZoneCount, int gridZoneCount)
|
|
||||||
{
|
|
||||||
Assert.AreEqual(canvasZoneCount, session.FindElementsByClassName("CanvasZone").Count);
|
|
||||||
Assert.AreEqual(gridZoneCount, session.FindElementsByClassName("GridZone").Count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,776 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.IO.Abstractions;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
using OpenQA.Selenium.Appium.Windows;
|
|
||||||
using OpenQA.Selenium.Interactions;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
[Ignore]
|
|
||||||
[TestClass]
|
|
||||||
public class FancyZonesSettingsTests : PowerToysSession
|
|
||||||
{
|
|
||||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
|
||||||
private static readonly IFile File = FileSystem.File;
|
|
||||||
|
|
||||||
|
|
||||||
private JObject _initialSettingsJson;
|
|
||||||
|
|
||||||
private static WindowsElement _saveButton;
|
|
||||||
private static Actions _scrollUp;
|
|
||||||
|
|
||||||
private const int _expectedTogglesCount = 9;
|
|
||||||
|
|
||||||
private static void Init()
|
|
||||||
{
|
|
||||||
OpenSettings();
|
|
||||||
OpenFancyZonesSettings();
|
|
||||||
|
|
||||||
_saveButton = session.FindElementByName("Save");
|
|
||||||
Assert.IsNotNull(_saveButton);
|
|
||||||
|
|
||||||
_scrollUp = new Actions(session).MoveToElement(_saveButton).MoveByOffset(0, _saveButton.Rect.Height).ContextClick()
|
|
||||||
.SendKeys(OpenQA.Selenium.Keys.Home);
|
|
||||||
Assert.IsNotNull(_scrollUp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JObject GetProperties()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_fancyZonesSettingsPath));
|
|
||||||
return settings["properties"].ToObject<JObject>();
|
|
||||||
}
|
|
||||||
catch (Newtonsoft.Json.JsonReaderException)
|
|
||||||
{
|
|
||||||
return new JObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private T GetPropertyValue<T>(string propertyName)
|
|
||||||
{
|
|
||||||
JObject properties = GetProperties();
|
|
||||||
return properties[propertyName].ToObject<JObject>()["value"].Value<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private T GetPropertyValue<T>(JObject properties, string propertyName)
|
|
||||||
{
|
|
||||||
return properties[propertyName].ToObject<JObject>()["value"].Value<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ScrollDown(int count)
|
|
||||||
{
|
|
||||||
Actions scroll = new Actions(session);
|
|
||||||
scroll.MoveToElement(_saveButton).MoveByOffset(0, _saveButton.Rect.Height).ContextClick();
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
scroll.SendKeys(OpenQA.Selenium.Keys.PageDown);
|
|
||||||
}
|
|
||||||
|
|
||||||
scroll.Perform();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ScrollUp()
|
|
||||||
{
|
|
||||||
_scrollUp.Perform();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SaveChanges()
|
|
||||||
{
|
|
||||||
string isEnabled = _saveButton.GetAttribute("IsEnabled");
|
|
||||||
Assert.AreEqual("True", isEnabled);
|
|
||||||
|
|
||||||
_saveButton.Click();
|
|
||||||
|
|
||||||
isEnabled = _saveButton.GetAttribute("IsEnabled");
|
|
||||||
Assert.AreEqual("False", isEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SaveAndCheckOpacitySettings(WindowsElement editor, int expected)
|
|
||||||
{
|
|
||||||
Assert.AreEqual(expected.ToString() + "\r\n", editor.Text);
|
|
||||||
|
|
||||||
SaveChanges();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
int value = GetPropertyValue<int>("fancyzones_highlight_opacity");
|
|
||||||
Assert.AreEqual(expected, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetOpacity(WindowsElement editor, string key)
|
|
||||||
{
|
|
||||||
editor.Click(); //activate
|
|
||||||
editor.SendKeys(OpenQA.Selenium.Keys.Control + OpenQA.Selenium.Keys.Backspace); //clear previous value
|
|
||||||
editor.SendKeys(key);
|
|
||||||
editor.SendKeys(OpenQA.Selenium.Keys.Enter); //confirm changes
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TestRgbInput(string name)
|
|
||||||
{
|
|
||||||
WindowsElement colorInput = session.FindElementByXPath("//Edit[@Name=\"" + name + "\"]");
|
|
||||||
Assert.IsNotNull(colorInput);
|
|
||||||
|
|
||||||
colorInput.SendKeys(OpenQA.Selenium.Keys.Control + OpenQA.Selenium.Keys.Backspace);
|
|
||||||
colorInput.SendKeys("0");
|
|
||||||
colorInput.SendKeys(OpenQA.Selenium.Keys.Enter);
|
|
||||||
Assert.AreEqual("0\r\n", colorInput.Text);
|
|
||||||
|
|
||||||
string invalidSymbols = "qwertyuiopasdfghjklzxcvbnm,./';][{}:`~!@#$%^&*()_-+=\"\'\\";
|
|
||||||
foreach (char symbol in invalidSymbols)
|
|
||||||
{
|
|
||||||
colorInput.SendKeys(symbol.ToString() + OpenQA.Selenium.Keys.Enter);
|
|
||||||
Assert.AreEqual("0\r\n", colorInput.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
string validSymbols = "0123456789";
|
|
||||||
foreach (char symbol in validSymbols)
|
|
||||||
{
|
|
||||||
colorInput.SendKeys(symbol.ToString() + OpenQA.Selenium.Keys.Enter);
|
|
||||||
Assert.AreEqual(symbol.ToString() + "\r\n", colorInput.Text);
|
|
||||||
colorInput.SendKeys(OpenQA.Selenium.Keys.Backspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
//print zero first
|
|
||||||
colorInput.SendKeys(OpenQA.Selenium.Keys.Control + OpenQA.Selenium.Keys.Backspace);
|
|
||||||
colorInput.SendKeys("0");
|
|
||||||
colorInput.SendKeys("1");
|
|
||||||
Assert.AreEqual("1\r\n", colorInput.Text);
|
|
||||||
|
|
||||||
//too many symbols
|
|
||||||
colorInput.SendKeys(OpenQA.Selenium.Keys.Control + OpenQA.Selenium.Keys.Backspace);
|
|
||||||
colorInput.SendKeys("1");
|
|
||||||
colorInput.SendKeys("2");
|
|
||||||
colorInput.SendKeys("3");
|
|
||||||
colorInput.SendKeys("4");
|
|
||||||
Assert.AreEqual("123\r\n", colorInput.Text);
|
|
||||||
|
|
||||||
//too big value
|
|
||||||
colorInput.SendKeys(OpenQA.Selenium.Keys.Control + OpenQA.Selenium.Keys.Backspace);
|
|
||||||
colorInput.SendKeys("555");
|
|
||||||
|
|
||||||
Actions action = new Actions(session); //reset focus from input
|
|
||||||
action.MoveToElement(colorInput).MoveByOffset(0, colorInput.Rect.Height).Click().Perform();
|
|
||||||
|
|
||||||
Assert.AreEqual("255\r\n", colorInput.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClearInput(WindowsElement input)
|
|
||||||
{
|
|
||||||
input.Click();
|
|
||||||
input.SendKeys(OpenQA.Selenium.Keys.Control + "a");
|
|
||||||
input.SendKeys(OpenQA.Selenium.Keys.Backspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TestHotkey(WindowsElement input, int modifierKeysState, string key, string keyString)
|
|
||||||
{
|
|
||||||
BitArray b = new BitArray(new int[] { modifierKeysState });
|
|
||||||
int[] flags = b.Cast<bool>().Select(bit => bit ? 1 : 0).ToArray();
|
|
||||||
|
|
||||||
Actions action = new Actions(session).MoveToElement(input).Click();
|
|
||||||
string expectedText = "";
|
|
||||||
if (flags[0] == 1)
|
|
||||||
{
|
|
||||||
action.KeyDown(OpenQA.Selenium.Keys.Command);
|
|
||||||
expectedText += "Win + ";
|
|
||||||
}
|
|
||||||
if (flags[1] == 1)
|
|
||||||
{
|
|
||||||
action.KeyDown(OpenQA.Selenium.Keys.Control);
|
|
||||||
expectedText += "Ctrl + ";
|
|
||||||
}
|
|
||||||
if (flags[2] == 1)
|
|
||||||
{
|
|
||||||
action.KeyDown(OpenQA.Selenium.Keys.Alt);
|
|
||||||
expectedText += "Alt + ";
|
|
||||||
}
|
|
||||||
if (flags[3] == 1)
|
|
||||||
{
|
|
||||||
action.KeyDown(OpenQA.Selenium.Keys.Shift);
|
|
||||||
expectedText += "Shift + ";
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedText += keyString + "\r\n";
|
|
||||||
|
|
||||||
action.SendKeys(key + key);
|
|
||||||
action.MoveByOffset(0, (input.Rect.Height / 2) + 10).ContextClick();
|
|
||||||
if (flags[0] == 1)
|
|
||||||
{
|
|
||||||
action.KeyUp(OpenQA.Selenium.Keys.Command);
|
|
||||||
}
|
|
||||||
if (flags[1] == 1)
|
|
||||||
{
|
|
||||||
action.KeyUp(OpenQA.Selenium.Keys.Control);
|
|
||||||
}
|
|
||||||
if (flags[2] == 1)
|
|
||||||
{
|
|
||||||
action.KeyUp(OpenQA.Selenium.Keys.Alt);
|
|
||||||
}
|
|
||||||
if (flags[3] == 1)
|
|
||||||
{
|
|
||||||
action.KeyUp(OpenQA.Selenium.Keys.Shift);
|
|
||||||
}
|
|
||||||
action.Perform();
|
|
||||||
|
|
||||||
SaveChanges();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
//Assert.AreEqual(expectedText, input.Text);
|
|
||||||
|
|
||||||
JObject props = GetProperties();
|
|
||||||
JObject hotkey = props["fancyzones_editor_hotkey"].ToObject<JObject>()["value"].ToObject<JObject>();
|
|
||||||
Assert.AreEqual(flags[0] == 1, hotkey.Value<bool>("win"));
|
|
||||||
Assert.AreEqual(flags[1] == 1, hotkey.Value<bool>("ctrl"));
|
|
||||||
Assert.AreEqual(flags[2] == 1, hotkey.Value<bool>("alt"));
|
|
||||||
Assert.AreEqual(flags[3] == 1, hotkey.Value<bool>("shift"));
|
|
||||||
//Assert.AreEqual(keyString, hotkey.Value<string>("key"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TestColorSliders(WindowsElement saturationAndBrightness, WindowsElement hue, WindowsElement hex, WindowsElement red, WindowsElement green, WindowsElement blue, string propertyName)
|
|
||||||
{
|
|
||||||
System.Drawing.Rectangle satRect = saturationAndBrightness.Rect;
|
|
||||||
System.Drawing.Rectangle hueRect = hue.Rect;
|
|
||||||
|
|
||||||
//black on the bottom
|
|
||||||
new Actions(session).MoveToElement(saturationAndBrightness).ClickAndHold().MoveByOffset(0, satRect.Height).Release().Perform();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
Assert.AreEqual("0\r\n", red.Text);
|
|
||||||
Assert.AreEqual("0\r\n", green.Text);
|
|
||||||
Assert.AreEqual("0\r\n", blue.Text);
|
|
||||||
Assert.AreEqual("000000\r\n", hex.Text);
|
|
||||||
|
|
||||||
SaveChanges();
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual("#000000", GetPropertyValue<string>(propertyName));
|
|
||||||
|
|
||||||
//white in left corner
|
|
||||||
new Actions(session).MoveToElement(saturationAndBrightness).ClickAndHold().MoveByOffset(-(satRect.Width / 2), -(satRect.Height / 2)).Release().Perform();
|
|
||||||
Assert.AreEqual("255\r\n", red.Text);
|
|
||||||
Assert.AreEqual("255\r\n", green.Text);
|
|
||||||
Assert.AreEqual("255\r\n", blue.Text);
|
|
||||||
Assert.AreEqual("ffffff\r\n", hex.Text);
|
|
||||||
|
|
||||||
SaveChanges();
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual("#ffffff", GetPropertyValue<string>(propertyName));
|
|
||||||
|
|
||||||
//color in right corner
|
|
||||||
new Actions(session).MoveToElement(saturationAndBrightness).ClickAndHold().MoveByOffset((satRect.Width / 2), -(satRect.Height / 2)).Release()
|
|
||||||
.MoveToElement(hue).ClickAndHold().MoveByOffset(-(hueRect.Width / 2), 0).Release().Perform();
|
|
||||||
Assert.AreEqual("255\r\n", red.Text);
|
|
||||||
Assert.AreEqual("0\r\n", green.Text);
|
|
||||||
Assert.AreEqual("0\r\n", blue.Text);
|
|
||||||
Assert.AreEqual("ff0000\r\n", hex.Text);
|
|
||||||
|
|
||||||
SaveChanges();
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual("#ff0000", GetPropertyValue<string>(propertyName));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void FancyZonesSettingsOpen()
|
|
||||||
{
|
|
||||||
WindowsElement fzTitle = session.FindElementByName("FancyZones Settings");
|
|
||||||
Assert.IsNotNull(fzTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* click each toggle,
|
|
||||||
* save changes,
|
|
||||||
* check if settings are changed after clicking save button
|
|
||||||
*/
|
|
||||||
[TestMethod]
|
|
||||||
public void TogglesSingleClickSaveButtonTest()
|
|
||||||
{
|
|
||||||
List<WindowsElement> toggles = session.FindElementsByXPath("//Pane[@Name=\"PowerToys Settings\"]/*[@LocalizedControlType=\"toggleswitch\"]").ToList();
|
|
||||||
Assert.AreEqual(_expectedTogglesCount, toggles.Count);
|
|
||||||
|
|
||||||
List<bool> toggleValues = new List<bool>();
|
|
||||||
foreach (WindowsElement toggle in toggles)
|
|
||||||
{
|
|
||||||
Assert.IsNotNull(toggle);
|
|
||||||
|
|
||||||
bool isOn = toggle.GetAttribute("Toggle.ToggleState") == "1";
|
|
||||||
toggleValues.Add(isOn);
|
|
||||||
|
|
||||||
toggle.Click();
|
|
||||||
|
|
||||||
SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
//check saved settings
|
|
||||||
JObject savedProps = GetProperties();
|
|
||||||
Assert.AreNotEqual(toggleValues[0], GetPropertyValue<bool>(savedProps, "fancyzones_shiftDrag"));
|
|
||||||
Assert.AreNotEqual(toggleValues[1], GetPropertyValue<bool>(savedProps, "fancyzones_mouseSwitch"));
|
|
||||||
Assert.AreNotEqual(toggleValues[2], GetPropertyValue<bool>(savedProps, "fancyzones_overrideSnapHotkeys"));
|
|
||||||
Assert.AreNotEqual(toggleValues[3], GetPropertyValue<bool>(savedProps, "fancyzones_moveWindowAcrossMonitors"));
|
|
||||||
Assert.AreNotEqual(toggleValues[4], GetPropertyValue<bool>(savedProps, "fancyzones_moveWindowsBasedOnPosition"));
|
|
||||||
Assert.AreNotEqual(toggleValues[5], GetPropertyValue<bool>(savedProps, "fancyzones_displayChange_moveWindows"));
|
|
||||||
Assert.AreNotEqual(toggleValues[6], GetPropertyValue<bool>(savedProps, "fancyzones_zoneSetChange_moveWindows"));
|
|
||||||
Assert.AreNotEqual(toggleValues[7], GetPropertyValue<bool>(savedProps, "fancyzones_appLastZone_moveWindows"));
|
|
||||||
Assert.AreNotEqual(toggleValues[8], GetPropertyValue<bool>(savedProps, "fancyzones_restoreSize"));
|
|
||||||
Assert.AreNotEqual(toggleValues[9], GetPropertyValue<bool>(savedProps, "use_cursorpos_editor_startupscreen"));
|
|
||||||
Assert.AreNotEqual(toggleValues[10], GetPropertyValue<bool>(savedProps, "fancyzones_show_on_all_monitors"));
|
|
||||||
Assert.AreNotEqual(toggleValues[11], GetPropertyValue<bool>(savedProps, "fancyzones_multi_monitor_mode"));
|
|
||||||
Assert.AreNotEqual(toggleValues[12], GetPropertyValue<bool>(savedProps, "fancyzones_makeDraggedWindowTransparent"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* click each toggle twice,
|
|
||||||
* save changes,
|
|
||||||
* check if settings are unchanged after clicking save button
|
|
||||||
*/
|
|
||||||
[TestMethod]
|
|
||||||
public void TogglesDoubleClickSave()
|
|
||||||
{
|
|
||||||
List<WindowsElement> toggles = session.FindElementsByXPath("//Pane[@Name=\"PowerToys Settings\"]/*[@LocalizedControlType=\"toggleswitch\"]").ToList();
|
|
||||||
Assert.AreEqual(_expectedTogglesCount, toggles.Count);
|
|
||||||
|
|
||||||
List<bool> toggleValues = new List<bool>();
|
|
||||||
foreach (WindowsElement toggle in toggles)
|
|
||||||
{
|
|
||||||
Assert.IsNotNull(toggle);
|
|
||||||
|
|
||||||
bool isOn = toggle.GetAttribute("Toggle.ToggleState") == "1";
|
|
||||||
toggleValues.Add(isOn);
|
|
||||||
|
|
||||||
toggle.Click();
|
|
||||||
toggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveChanges();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
JObject savedProps = GetProperties();
|
|
||||||
Assert.AreEqual(toggleValues[0], GetPropertyValue<bool>(savedProps, "fancyzones_shiftDrag"));
|
|
||||||
Assert.AreEqual(toggleValues[1], GetPropertyValue<bool>(savedProps, "fancyzones_mouseSwitch"));
|
|
||||||
Assert.AreEqual(toggleValues[2], GetPropertyValue<bool>(savedProps, "fancyzones_overrideSnapHotkeys"));
|
|
||||||
Assert.AreEqual(toggleValues[3], GetPropertyValue<bool>(savedProps, "fancyzones_moveWindowAcrossMonitors"));
|
|
||||||
Assert.AreEqual(toggleValues[4], GetPropertyValue<bool>(savedProps, "fancyzones_moveWindowsBasedOnPosition"));
|
|
||||||
Assert.AreEqual(toggleValues[5], GetPropertyValue<bool>(savedProps, "fancyzones_displayChange_moveWindows"));
|
|
||||||
Assert.AreEqual(toggleValues[6], GetPropertyValue<bool>(savedProps, "fancyzones_zoneSetChange_moveWindows"));
|
|
||||||
Assert.AreEqual(toggleValues[7], GetPropertyValue<bool>(savedProps, "fancyzones_appLastZone_moveWindows"));
|
|
||||||
Assert.AreEqual(toggleValues[8], GetPropertyValue<bool>(savedProps, "fancyzones_restoreSize"));
|
|
||||||
Assert.AreEqual(toggleValues[9], GetPropertyValue<bool>(savedProps, "use_cursorpos_editor_startupscreen"));
|
|
||||||
Assert.AreEqual(toggleValues[10], GetPropertyValue<bool>(savedProps, "fancyzones_show_on_all_monitors"));
|
|
||||||
Assert.AreEqual(toggleValues[11], GetPropertyValue<bool>(savedProps, "fancyzones_span_zones_across_monitors"));
|
|
||||||
Assert.AreEqual(toggleValues[12], GetPropertyValue<bool>(savedProps, "fancyzones_makeDraggedWindowTransparent"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void HighlightOpacitySetValue()
|
|
||||||
{
|
|
||||||
WindowsElement editor = session.FindElementByName("Zone opacity (%)");
|
|
||||||
Assert.IsNotNull(editor);
|
|
||||||
|
|
||||||
SetOpacity(editor, "50");
|
|
||||||
SaveAndCheckOpacitySettings(editor, 50);
|
|
||||||
|
|
||||||
SetOpacity(editor, "-50");
|
|
||||||
SaveAndCheckOpacitySettings(editor, 0);
|
|
||||||
|
|
||||||
SetOpacity(editor, "200");
|
|
||||||
SaveAndCheckOpacitySettings(editor, 100);
|
|
||||||
|
|
||||||
//for invalid input values previously saved value expected
|
|
||||||
SetOpacity(editor, "asdf");
|
|
||||||
SaveAndCheckOpacitySettings(editor, 100);
|
|
||||||
|
|
||||||
SetOpacity(editor, "*");
|
|
||||||
SaveAndCheckOpacitySettings(editor, 100);
|
|
||||||
|
|
||||||
SetOpacity(editor, OpenQA.Selenium.Keys.Return);
|
|
||||||
SaveAndCheckOpacitySettings(editor, 100);
|
|
||||||
|
|
||||||
Clipboard.SetText("Hello, clipboard");
|
|
||||||
SetOpacity(editor, OpenQA.Selenium.Keys.Control + "v");
|
|
||||||
SaveAndCheckOpacitySettings(editor, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void HighlightOpacityIncreaseValue()
|
|
||||||
{
|
|
||||||
WindowsElement editor = session.FindElementByName("Zone opacity (%)");
|
|
||||||
Assert.IsNotNull(editor);
|
|
||||||
|
|
||||||
SetOpacity(editor, "99");
|
|
||||||
SaveAndCheckOpacitySettings(editor, 99);
|
|
||||||
|
|
||||||
System.Drawing.Rectangle editorRect = editor.Rect;
|
|
||||||
|
|
||||||
Actions action = new Actions(session);
|
|
||||||
action.MoveToElement(editor).MoveByOffset(editorRect.Width / 2 + 10, -editorRect.Height / 4).Perform();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
action.Click().Perform();
|
|
||||||
Assert.AreEqual("100\r\n", editor.Text);
|
|
||||||
SaveAndCheckOpacitySettings(editor, 100);
|
|
||||||
|
|
||||||
action.Click().Perform();
|
|
||||||
Assert.AreEqual("100\r\n", editor.Text);
|
|
||||||
SaveAndCheckOpacitySettings(editor, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void HighlightOpacityDecreaseValue()
|
|
||||||
{
|
|
||||||
|
|
||||||
WindowsElement editor = session.FindElementByName("Zone opacity (%)");
|
|
||||||
Assert.IsNotNull(editor);
|
|
||||||
|
|
||||||
SetOpacity(editor, "1");
|
|
||||||
SaveAndCheckOpacitySettings(editor, 1);
|
|
||||||
|
|
||||||
System.Drawing.Rectangle editorRect = editor.Rect;
|
|
||||||
|
|
||||||
Actions action = new Actions(session);
|
|
||||||
action.MoveToElement(editor).MoveByOffset(editorRect.Width / 2 + 10, editorRect.Height / 4).Perform();
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
action.Click().Perform();
|
|
||||||
Assert.AreEqual("0\r\n", editor.Text);
|
|
||||||
SaveAndCheckOpacitySettings(editor, 0);
|
|
||||||
|
|
||||||
action.Click().Perform();
|
|
||||||
Assert.AreEqual("0\r\n", editor.Text);
|
|
||||||
SaveAndCheckOpacitySettings(editor, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void HighlightOpacityClearValueButton()
|
|
||||||
{
|
|
||||||
ScrollDown(3);
|
|
||||||
WindowsElement editor = session.FindElementByName("Zone opacity (%)");
|
|
||||||
Assert.IsNotNull(editor);
|
|
||||||
|
|
||||||
editor.Click(); //activate
|
|
||||||
AppiumWebElement clearButton = editor.FindElementByName("Clear value");
|
|
||||||
Assert.IsNotNull(clearButton);
|
|
||||||
|
|
||||||
/*element is not pointer- or keyboard interactable.*/
|
|
||||||
Actions action = new Actions(session);
|
|
||||||
action.MoveToElement(clearButton).Click().Perform();
|
|
||||||
|
|
||||||
Assert.AreEqual("\r\n", editor.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void HighlightColorSlidersTest()
|
|
||||||
{
|
|
||||||
ScrollDown(4);
|
|
||||||
|
|
||||||
ReadOnlyCollection<WindowsElement> saturationAndBrightness = session.FindElementsByName("Saturation and brightness");
|
|
||||||
ReadOnlyCollection<WindowsElement> hue = session.FindElementsByName("Hue");
|
|
||||||
ReadOnlyCollection<WindowsElement> hex = session.FindElementsByXPath("//Edit[@Name=\"Hex\"]");
|
|
||||||
ReadOnlyCollection<WindowsElement> red = session.FindElementsByXPath("//Edit[@Name=\"Red\"]");
|
|
||||||
ReadOnlyCollection<WindowsElement> green = session.FindElementsByXPath("//Edit[@Name=\"Green\"]");
|
|
||||||
ReadOnlyCollection<WindowsElement> blue = session.FindElementsByXPath("//Edit[@Name=\"Blue\"]");
|
|
||||||
|
|
||||||
TestColorSliders(saturationAndBrightness[2], hue[2], hex[2], red[2], green[2], blue[2], "fancyzones_zoneBorderColor");
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(saturationAndBrightness[2]).MoveByOffset(saturationAndBrightness[2].Rect.Width / 2 + 10, 0)
|
|
||||||
.Click().SendKeys(OpenQA.Selenium.Keys.PageUp).Perform();
|
|
||||||
TestColorSliders(saturationAndBrightness[1], hue[1], hex[1], red[1], green[1], blue[1], "fancyzones_zoneColor");
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(saturationAndBrightness[1]).MoveByOffset(saturationAndBrightness[1].Rect.Width / 2 + 10, 0)
|
|
||||||
.Click().SendKeys(OpenQA.Selenium.Keys.PageDown + OpenQA.Selenium.Keys.PageDown).SendKeys(OpenQA.Selenium.Keys.PageUp + OpenQA.Selenium.Keys.PageUp).Perform();
|
|
||||||
TestColorSliders(saturationAndBrightness[0], hue[0], hex[0], red[0], green[0], blue[0], "fancyzones_zoneHighlightColor");
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void HighlightColorTest()
|
|
||||||
{
|
|
||||||
ScrollDown(2);
|
|
||||||
|
|
||||||
WindowsElement saturationAndBrightness = session.FindElementByName("Saturation and brightness");
|
|
||||||
WindowsElement hue = session.FindElementByName("Hue");
|
|
||||||
WindowsElement hex = session.FindElementByXPath("//Edit[@Name=\"Hex\"]");
|
|
||||||
|
|
||||||
Assert.IsNotNull(saturationAndBrightness);
|
|
||||||
Assert.IsNotNull(hue);
|
|
||||||
Assert.IsNotNull(hex);
|
|
||||||
|
|
||||||
hex.SendKeys(OpenQA.Selenium.Keys.Control + OpenQA.Selenium.Keys.Backspace);
|
|
||||||
hex.SendKeys("63c99a");
|
|
||||||
new Actions(session).MoveToElement(hex).MoveByOffset(0, hex.Rect.Height).Click().Perform();
|
|
||||||
|
|
||||||
Assert.AreEqual("Saturation 51 brightness 79", saturationAndBrightness.Text);
|
|
||||||
Assert.AreEqual("152", hue.Text);
|
|
||||||
|
|
||||||
SaveChanges();
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual("#63c99a", GetPropertyValue<string>("fancyzones_zoneHighlightColor"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void HighlightRGBInputsTest()
|
|
||||||
{
|
|
||||||
ScrollDown(2);
|
|
||||||
|
|
||||||
TestRgbInput("Red");
|
|
||||||
TestRgbInput("Green");
|
|
||||||
TestRgbInput("Blue");
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void HighlightHexInputTest()
|
|
||||||
{
|
|
||||||
ScrollDown(2);
|
|
||||||
|
|
||||||
WindowsElement hexInput = session.FindElementByXPath("//Edit[@Name=\"Hex\"]");
|
|
||||||
Assert.IsNotNull(hexInput);
|
|
||||||
|
|
||||||
hexInput.SendKeys(OpenQA.Selenium.Keys.Control + OpenQA.Selenium.Keys.Backspace);
|
|
||||||
|
|
||||||
string invalidSymbols = "qwrtyuiopsghjklzxvnm,./';][{}:`~!#@$%^&*()_-+=\"\'\\";
|
|
||||||
foreach (char symbol in invalidSymbols)
|
|
||||||
{
|
|
||||||
hexInput.SendKeys(symbol.ToString());
|
|
||||||
Assert.AreEqual("", hexInput.Text.Trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
string validSymbols = "0123456789abcdef";
|
|
||||||
foreach (char symbol in validSymbols)
|
|
||||||
{
|
|
||||||
hexInput.SendKeys(symbol.ToString());
|
|
||||||
Assert.AreEqual(symbol.ToString(), hexInput.Text.Trim());
|
|
||||||
hexInput.SendKeys(OpenQA.Selenium.Keys.Backspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
//too many symbols
|
|
||||||
hexInput.SendKeys(OpenQA.Selenium.Keys.Control + OpenQA.Selenium.Keys.Backspace);
|
|
||||||
hexInput.SendKeys("000000");
|
|
||||||
hexInput.SendKeys("1");
|
|
||||||
Assert.AreEqual("000000\r\n", hexInput.Text);
|
|
||||||
|
|
||||||
//short string
|
|
||||||
hexInput.SendKeys(OpenQA.Selenium.Keys.Control + OpenQA.Selenium.Keys.Backspace);
|
|
||||||
hexInput.SendKeys("000");
|
|
||||||
new Actions(session).MoveToElement(hexInput).MoveByOffset(0, hexInput.Rect.Height).Click().Perform();
|
|
||||||
Assert.AreEqual("000000\r\n", hexInput.Text);
|
|
||||||
|
|
||||||
hexInput.SendKeys(OpenQA.Selenium.Keys.Control + OpenQA.Selenium.Keys.Backspace);
|
|
||||||
hexInput.SendKeys("1234");
|
|
||||||
new Actions(session).MoveToElement(hexInput).MoveByOffset(0, hexInput.Rect.Height).Click().Perform();
|
|
||||||
Assert.AreEqual("112233\r\n", hexInput.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ExcludeApps()
|
|
||||||
{
|
|
||||||
WindowsElement input = session.FindElementByXPath("//Edit[contains(@Name, \"exclude\")]");
|
|
||||||
Assert.IsNotNull(input);
|
|
||||||
ClearInput(input);
|
|
||||||
|
|
||||||
string inputValue;
|
|
||||||
|
|
||||||
//valid
|
|
||||||
inputValue = "Notepad\nChrome";
|
|
||||||
input.SendKeys(inputValue);
|
|
||||||
SaveChanges();
|
|
||||||
ClearInput(input);
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
|
||||||
|
|
||||||
//invalid
|
|
||||||
inputValue = "Notepad Chrome";
|
|
||||||
input.SendKeys(inputValue);
|
|
||||||
SaveChanges();
|
|
||||||
ClearInput(input);
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
|
||||||
|
|
||||||
inputValue = "Notepad,Chrome";
|
|
||||||
input.SendKeys(inputValue);
|
|
||||||
SaveChanges();
|
|
||||||
ClearInput(input);
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
|
||||||
|
|
||||||
inputValue = "Note*";
|
|
||||||
input.SendKeys(inputValue);
|
|
||||||
SaveChanges();
|
|
||||||
ClearInput(input);
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
|
||||||
|
|
||||||
inputValue = "Кириллица";
|
|
||||||
input.SendKeys(inputValue);
|
|
||||||
SaveChanges();
|
|
||||||
ClearInput(input);
|
|
||||||
WaitSeconds(1);
|
|
||||||
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ExitDialogSave()
|
|
||||||
{
|
|
||||||
WindowsElement toggle = session.FindElementByXPath("//Pane[@Name=\"PowerToys Settings\"]/*[@LocalizedControlType=\"toggleswitch\"]");
|
|
||||||
Assert.IsNotNull(toggle);
|
|
||||||
|
|
||||||
bool initialToggleValue = toggle.GetAttribute("Toggle.ToggleState") == "1";
|
|
||||||
|
|
||||||
toggle.Click();
|
|
||||||
CloseSettings();
|
|
||||||
WindowsElement exitDialog = session.FindElementByName("Changes not saved");
|
|
||||||
Assert.IsNotNull(exitDialog);
|
|
||||||
|
|
||||||
exitDialog.FindElementByName("Save").Click();
|
|
||||||
|
|
||||||
//check if window still opened
|
|
||||||
WindowsElement powerToysWindow = session.FindElementByXPath("//Window[@Name=\"PowerToys Settings\"]");
|
|
||||||
Assert.IsNotNull(powerToysWindow);
|
|
||||||
|
|
||||||
//check settings change
|
|
||||||
JObject savedProps = GetProperties();
|
|
||||||
|
|
||||||
Assert.AreNotEqual(initialToggleValue, GetPropertyValue<bool>(savedProps, "fancyzones_shiftDrag"));
|
|
||||||
|
|
||||||
//return initial app state
|
|
||||||
toggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ExitDialogExit()
|
|
||||||
{
|
|
||||||
WindowsElement toggle = session.FindElementByXPath("//Pane[@Name=\"PowerToys Settings\"]/*[@LocalizedControlType=\"toggleswitch\"]");
|
|
||||||
Assert.IsNotNull(toggle);
|
|
||||||
|
|
||||||
bool initialToggleValue = toggle.GetAttribute("Toggle.ToggleState") == "1";
|
|
||||||
|
|
||||||
toggle.Click();
|
|
||||||
CloseSettings();
|
|
||||||
|
|
||||||
WindowsElement exitDialog = session.FindElementByName("Changes not saved");
|
|
||||||
Assert.IsNotNull(exitDialog);
|
|
||||||
|
|
||||||
exitDialog.FindElementByName("Exit").Click();
|
|
||||||
|
|
||||||
//check if window still opened
|
|
||||||
try
|
|
||||||
{
|
|
||||||
WindowsElement powerToysWindow = session.FindElementByXPath("//Window[@Name=\"PowerToys Settings\"]");
|
|
||||||
Assert.IsNull(powerToysWindow);
|
|
||||||
}
|
|
||||||
catch (OpenQA.Selenium.WebDriverException)
|
|
||||||
{
|
|
||||||
//window is no longer available, which is expected
|
|
||||||
}
|
|
||||||
|
|
||||||
//return initial app state
|
|
||||||
Init();
|
|
||||||
|
|
||||||
//check settings change
|
|
||||||
JObject savedProps = GetProperties();
|
|
||||||
Assert.AreEqual(initialToggleValue, GetPropertyValue<bool>(savedProps, "fancyzones_shiftDrag"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ExitDialogCancel()
|
|
||||||
{
|
|
||||||
WindowsElement toggle = session.FindElementByXPath("//Pane[@Name=\"PowerToys Settings\"]/*[@LocalizedControlType=\"toggleswitch\"]");
|
|
||||||
Assert.IsNotNull(toggle);
|
|
||||||
|
|
||||||
toggle.Click();
|
|
||||||
CloseSettings();
|
|
||||||
WindowsElement exitDialog = session.FindElementByName("Changes not saved");
|
|
||||||
Assert.IsNotNull(exitDialog);
|
|
||||||
|
|
||||||
exitDialog.FindElementByName("Cancel").Click();
|
|
||||||
|
|
||||||
//check if window still opened
|
|
||||||
WindowsElement powerToysWindow = session.FindElementByXPath("//Window[@Name=\"PowerToys Settings\"]");
|
|
||||||
Assert.IsNotNull(powerToysWindow);
|
|
||||||
|
|
||||||
//check settings change
|
|
||||||
JObject savedProps = GetProperties();
|
|
||||||
JObject initialProps = _initialSettingsJson["properties"].ToObject<JObject>();
|
|
||||||
Assert.AreEqual(GetPropertyValue<bool>(initialProps, "fancyzones_shiftDrag"), GetPropertyValue<bool>(savedProps, "fancyzones_shiftDrag"));
|
|
||||||
|
|
||||||
//return initial app state
|
|
||||||
toggle.Click();
|
|
||||||
SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ConfigureHotkey()
|
|
||||||
{
|
|
||||||
WindowsElement input = session.FindElementByXPath("//Edit[contains(@Name, \"hotkey\")]");
|
|
||||||
Assert.IsNotNull(input);
|
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
TestHotkey(input, i, OpenQA.Selenium.Keys.End, "End");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void ConfigureLocalSymbolHotkey()
|
|
||||||
{
|
|
||||||
WindowsElement input = session.FindElementByXPath("//Edit[contains(@Name, \"hotkey\")]");
|
|
||||||
Assert.IsNotNull(input);
|
|
||||||
TestHotkey(input, 0, "ё", "Ё");
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassInitialize]
|
|
||||||
public static void ClassInitialize(TestContext context)
|
|
||||||
{
|
|
||||||
Setup(context);
|
|
||||||
Assert.IsNotNull(session);
|
|
||||||
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassCleanup]
|
|
||||||
public static void ClassCleanup()
|
|
||||||
{
|
|
||||||
CloseSettings();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
WindowsElement exitDialogButton = session.FindElementByName("Exit");
|
|
||||||
if (exitDialogButton != null)
|
|
||||||
{
|
|
||||||
exitDialogButton.Click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (OpenQA.Selenium.WebDriverException)
|
|
||||||
{
|
|
||||||
//element couldn't be located
|
|
||||||
}
|
|
||||||
|
|
||||||
ExitPowerToys();
|
|
||||||
TearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void TestInitialize()
|
|
||||||
{
|
|
||||||
if (session == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_initialSettingsJson = JObject.Parse(_initialFancyZonesSettings);
|
|
||||||
}
|
|
||||||
catch (Newtonsoft.Json.JsonReaderException)
|
|
||||||
{
|
|
||||||
//empty settings
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCleanup]
|
|
||||||
public void TestCleanup()
|
|
||||||
{
|
|
||||||
ScrollUp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
# FancyZones Test Plan
|
|
||||||
|
|
||||||
## Settings
|
|
||||||
- [x] Test if settings are saved in file properly
|
|
||||||
|
|
||||||
## Editor
|
|
||||||
- [x] Open editor by clicking button from settings
|
|
||||||
- [x] without settings file
|
|
||||||
- [x] without settings folder
|
|
||||||
- [x] with valid settings file
|
|
||||||
- [x] with valid settings file contained cyrillic characters
|
|
||||||
- [x] with invalid settings file
|
|
||||||
- [x] with cropped file
|
|
||||||
- [x] Open editor by hotkey
|
|
||||||
- [x] without settings file
|
|
||||||
- [x] without settings folder
|
|
||||||
- [x] with valid settings file
|
|
||||||
- [x] with valid settings file contained cyrillic characters
|
|
||||||
- [x] with invalid settings file
|
|
||||||
- [x] with cropped file
|
|
||||||
- [ ] Increase/decrease zone count, check min and max possible values
|
|
||||||
- [ ] Test if settings are saved in file properly
|
|
||||||
- [ ] `Show spacing` checked/unchecked
|
|
||||||
- [ ] `Space around zone` saved correctly
|
|
||||||
- [ ] `Space around zone` possible input values
|
|
||||||
- [ ] Edit templates, check settings files
|
|
||||||
- [ ] Create new custom layout
|
|
||||||
- [ ] empty
|
|
||||||
- [ ] one zone
|
|
||||||
- [ ] fullscreen
|
|
||||||
- [ ] not fullscreen
|
|
||||||
- [ ] many zones
|
|
||||||
- [ ] overlapping
|
|
||||||
- [ ] non-overlapping
|
|
||||||
- [ ] utf-16 layout name
|
|
||||||
- [ ] empty layout name
|
|
||||||
- [ ] special characters in layout name
|
|
||||||
- [ ] Remove custom layout
|
|
||||||
- [ ] Edit selected layout
|
|
||||||
|
|
||||||
### Usage
|
|
@ -1,335 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO.Abstractions;
|
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using OpenQA.Selenium;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
using OpenQA.Selenium.Appium.Windows;
|
|
||||||
using OpenQA.Selenium.Interactions;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
public class PowerToysSession
|
|
||||||
{
|
|
||||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
|
||||||
private static readonly IPath Path = FileSystem.Path;
|
|
||||||
private static readonly IFile File = FileSystem.File;
|
|
||||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
|
||||||
|
|
||||||
protected const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
|
|
||||||
protected const string AppPath = "C:\\Program Files\\PowerToys\\PowerToys.exe";
|
|
||||||
|
|
||||||
protected static WindowsDriver<WindowsElement> session;
|
|
||||||
protected static bool isPowerToysLaunched = false;
|
|
||||||
|
|
||||||
protected static WindowsElement trayButton;
|
|
||||||
protected static WindowsElement settingsWindow;
|
|
||||||
|
|
||||||
protected static string _commonSettingsFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft\\PowerToys");
|
|
||||||
protected static string _settingsFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft\\PowerToys\\FancyZones");
|
|
||||||
protected static string _fancyZonesSettingsPath = _settingsFolderPath + "\\settings.json";
|
|
||||||
protected static string _zoneSettingsPath = _settingsFolderPath + "\\zones-settings.json";
|
|
||||||
protected static string _appHistoryPath = _settingsFolderPath + "\\app-zone-history.json";
|
|
||||||
protected static string _commonSettingsPath = _commonSettingsFolderPath + "\\settings.json";
|
|
||||||
|
|
||||||
protected static string _initialFancyZonesSettings = "";
|
|
||||||
protected static string _initialZoneSettings = "";
|
|
||||||
protected static string _initialAppHistorySettings = "";
|
|
||||||
protected static string _initialCommonSettings = "";
|
|
||||||
|
|
||||||
protected const string _defaultFancyZonesSettings = "{\"version\":\"1.0\",\"name\":\"FancyZones\",\"properties\":{\"fancyzones_shiftDrag\":{\"value\":true},\"fancyzones_mouseSwitch\":{\"value\":false},\"fancyzones_overrideSnapHotkeys\":{\"value\":false},\"fancyzones_moveWindowAcrossMonitors\":{\"value\":false},\"fancyzones_zoneSetChange_flashZones\":{\"value\":false},\"fancyzones_displayChange_moveWindows\":{\"value\":false},\"fancyzones_zoneSetChange_moveWindows\":{\"value\":false},\"fancyzones_appLastZone_moveWindows\":{\"value\":false},\"use_cursorpos_editor_startupscreen\":{\"value\":true},\"fancyzones_zoneHighlightColor\":{\"value\":\"#0078D7\"},\"fancyzones_highlight_opacity\":{\"value\":90},\"fancyzones_editor_hotkey\":{\"value\":{\"win\":true,\"ctrl\":false,\"alt\":false,\"shift\":false,\"code\":192,\"key\":\"`\"}},\"fancyzones_excluded_apps\":{\"value\":\"\"}}}";
|
|
||||||
protected const string _defaultZoneSettings = "{\"devices\":[],\"custom-zone-sets\":[]}";
|
|
||||||
|
|
||||||
|
|
||||||
public static void Setup(TestContext context)
|
|
||||||
{
|
|
||||||
if (session == null)
|
|
||||||
{
|
|
||||||
ReadUserSettings(); //read settings before running tests to restore them after
|
|
||||||
|
|
||||||
// Create a new Desktop session to use PowerToys.
|
|
||||||
AppiumOptions appiumOptions = new AppiumOptions();
|
|
||||||
appiumOptions.PlatformName = "Windows";
|
|
||||||
appiumOptions.AddAdditionalCapability("app", "Root");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appiumOptions);
|
|
||||||
session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1);
|
|
||||||
|
|
||||||
trayButton = session.FindElementByAccessibilityId("1502");
|
|
||||||
|
|
||||||
isPowerToysLaunched = CheckPowerToysLaunched();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TearDown()
|
|
||||||
{
|
|
||||||
RestoreUserSettings(); //restore initial settings files
|
|
||||||
|
|
||||||
if (session != null)
|
|
||||||
{
|
|
||||||
trayButton = null;
|
|
||||||
settingsWindow = null;
|
|
||||||
|
|
||||||
session.Quit();
|
|
||||||
session = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void WaitSeconds(double seconds)
|
|
||||||
{
|
|
||||||
Thread.Sleep(TimeSpan.FromSeconds(seconds));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void OpenSettings()
|
|
||||||
{
|
|
||||||
trayButton.Click();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
PowerToysTrayButton().Click();
|
|
||||||
settingsWindow = session.FindElementByName("PowerToys Settings");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
trayButton.Click(); //close
|
|
||||||
Assert.IsNotNull(settingsWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void OpenFancyZonesSettings()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AppiumWebElement fzNavigationButton = settingsWindow.FindElementByName("FancyZones");
|
|
||||||
Assert.IsNotNull(fzNavigationButton);
|
|
||||||
|
|
||||||
fzNavigationButton.Click();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CloseSettings()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
WindowsElement settings = session.FindElementByName("PowerToys Settings");
|
|
||||||
if (settings != null)
|
|
||||||
{
|
|
||||||
settings.Click();
|
|
||||||
settings.FindElementByName("Close").Click();
|
|
||||||
//settings.SendKeys(Keys.Alt + Keys.F4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static AppiumWebElement PowerToysTrayButton()
|
|
||||||
{
|
|
||||||
WindowsElement notificationOverflow = session.FindElementByName("Notification Overflow");
|
|
||||||
AppiumWebElement overflowArea = notificationOverflow.FindElementByName("Overflow Notification Area");
|
|
||||||
AppiumWebElement powerToys = overflowArea.FindElementByXPath("//Button[contains(@Name, \"PowerToys\")]");
|
|
||||||
return powerToys;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool CheckPowerToysLaunched()
|
|
||||||
{
|
|
||||||
bool isLaunched = false;
|
|
||||||
trayButton.Click();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AppiumWebElement pt = PowerToysTrayButton();
|
|
||||||
isLaunched = (pt != null);
|
|
||||||
}
|
|
||||||
catch (OpenQA.Selenium.WebDriverException)
|
|
||||||
{
|
|
||||||
//PowerToys not found
|
|
||||||
}
|
|
||||||
|
|
||||||
trayButton.Click(); //close
|
|
||||||
return isLaunched;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LaunchPowerToys()
|
|
||||||
{
|
|
||||||
AppiumOptions opts = new AppiumOptions();
|
|
||||||
opts.AddAdditionalCapability("app", AppPath);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
WindowsDriver<WindowsElement> driver = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), opts);
|
|
||||||
Assert.IsNotNull(driver);
|
|
||||||
driver.LaunchApp();
|
|
||||||
}
|
|
||||||
catch (WebDriverException)
|
|
||||||
{
|
|
||||||
//exception is expected since WinApDriver tries to find main app window
|
|
||||||
}
|
|
||||||
|
|
||||||
isPowerToysLaunched = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ExitPowerToys()
|
|
||||||
{
|
|
||||||
trayButton.Click();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
AppiumWebElement pt = PowerToysTrayButton();
|
|
||||||
Assert.IsNotNull(pt, "Could not exit PowerToys");
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(pt).ContextClick().Perform();
|
|
||||||
session.FindElementByAccessibilityId("40001").Click();
|
|
||||||
//WaitElementByXPath("//MenuItem[@Name=\"Exit\"]").Click();
|
|
||||||
|
|
||||||
isPowerToysLaunched = false;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
trayButton.Click(); //close tray
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void EnableModules(bool colorPicker, bool fancyZones, bool fileExplorer, bool imageResizer, bool keyboardManager, bool powerRename, bool powerRun, bool shortcutGuide, bool relaunch = false)
|
|
||||||
{
|
|
||||||
JObject json = JObject.Parse(_initialCommonSettings);
|
|
||||||
JObject enabled = new JObject();
|
|
||||||
enabled["ColorPicker"] = colorPicker;
|
|
||||||
enabled["FancyZones"] = fancyZones;
|
|
||||||
enabled["File Explorer"] = fileExplorer;
|
|
||||||
enabled["Image Resizer"] = imageResizer;
|
|
||||||
enabled["Keyboard Manager"] = keyboardManager;
|
|
||||||
enabled["PowerRename"] = powerRename;
|
|
||||||
enabled["PowerToys Run"] = powerRun;
|
|
||||||
enabled["Shortcut Guide"] = shortcutGuide;
|
|
||||||
|
|
||||||
json["enabled"] = enabled;
|
|
||||||
|
|
||||||
ResetSettings(_commonSettingsFolderPath, _commonSettingsPath, json.ToString(), relaunch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ResetDefaultFancyZonesSettings(bool relaunch)
|
|
||||||
{
|
|
||||||
ResetSettings(_settingsFolderPath, _fancyZonesSettingsPath, _defaultFancyZonesSettings, relaunch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ResetDefaultZoneSettings(bool relaunch)
|
|
||||||
{
|
|
||||||
ResetSettings(_settingsFolderPath, _zoneSettingsPath, _defaultZoneSettings, relaunch);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ResetSettings(string folder, string filePath, string data, bool relaunch)
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(folder))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(folder);
|
|
||||||
}
|
|
||||||
File.WriteAllText(filePath, data);
|
|
||||||
|
|
||||||
ExitPowerToys();
|
|
||||||
if (relaunch)
|
|
||||||
{
|
|
||||||
LaunchPowerToys();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ReadUserSettings()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_initialCommonSettings.Length == 0)
|
|
||||||
{
|
|
||||||
_initialCommonSettings = File.ReadAllText(_commonSettingsPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_initialFancyZonesSettings.Length == 0)
|
|
||||||
{
|
|
||||||
_initialFancyZonesSettings = File.ReadAllText(_fancyZonesSettingsPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_initialZoneSettings.Length == 0)
|
|
||||||
{
|
|
||||||
_initialZoneSettings = File.ReadAllText(_zoneSettingsPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_initialAppHistorySettings.Length == 0)
|
|
||||||
{
|
|
||||||
_initialAppHistorySettings = File.ReadAllText(_appHistoryPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RestoreUserSettings()
|
|
||||||
{
|
|
||||||
if (_initialCommonSettings.Length > 0)
|
|
||||||
{
|
|
||||||
File.WriteAllText(_commonSettingsPath, _initialCommonSettings);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
File.Delete(_commonSettingsPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_initialFancyZonesSettings.Length > 0)
|
|
||||||
{
|
|
||||||
File.WriteAllText(_fancyZonesSettingsPath, _initialFancyZonesSettings);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
File.Delete(_fancyZonesSettingsPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_initialZoneSettings.Length > 0)
|
|
||||||
{
|
|
||||||
File.WriteAllText(_zoneSettingsPath, _initialZoneSettings);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
File.Delete(_zoneSettingsPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_initialAppHistorySettings.Length > 0)
|
|
||||||
{
|
|
||||||
File.WriteAllText(_appHistoryPath, _initialAppHistorySettings);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
File.Delete(_appHistoryPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,121 +0,0 @@
|
|||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
using OpenQA.Selenium.Appium.Windows;
|
|
||||||
using OpenQA.Selenium.Interactions;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class PowerToysTrayTests : PowerToysSession
|
|
||||||
{
|
|
||||||
private bool isSettingsOpened;
|
|
||||||
private bool isTrayOpened;
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void SettingsOpen()
|
|
||||||
{
|
|
||||||
OpenSettings();
|
|
||||||
|
|
||||||
//check settings window opened
|
|
||||||
WindowsElement settingsWindow = session.FindElementByName("PowerToys Settings");
|
|
||||||
Assert.IsNotNull(settingsWindow);
|
|
||||||
|
|
||||||
isSettingsOpened = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void SettingsOpenWithContextMenu()
|
|
||||||
{
|
|
||||||
//open tray
|
|
||||||
trayButton.Click();
|
|
||||||
WaitSeconds(1);
|
|
||||||
isTrayOpened = true;
|
|
||||||
|
|
||||||
//open PowerToys context menu
|
|
||||||
AppiumWebElement pt = PowerToysTrayButton();
|
|
||||||
Assert.IsNotNull(pt);
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(pt).ContextClick().Perform();
|
|
||||||
|
|
||||||
//open settings
|
|
||||||
session.FindElementByXPath("//MenuItem[@Name=\"Settings\"]").Click();
|
|
||||||
|
|
||||||
//check settings window opened
|
|
||||||
WindowsElement settingsWindow = session.FindElementByName("PowerToys Settings");
|
|
||||||
Assert.IsNotNull(settingsWindow);
|
|
||||||
|
|
||||||
isSettingsOpened = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void PowerToysExit()
|
|
||||||
{
|
|
||||||
//open PowerToys context menu
|
|
||||||
trayButton.Click();
|
|
||||||
isTrayOpened = true;
|
|
||||||
WaitSeconds(1);
|
|
||||||
|
|
||||||
AppiumWebElement powerToys = PowerToysTrayButton();
|
|
||||||
Assert.IsNotNull(powerToys);
|
|
||||||
|
|
||||||
new Actions(session).MoveToElement(powerToys).ContextClick().Perform();
|
|
||||||
|
|
||||||
//exit
|
|
||||||
session.FindElementByAccessibilityId("40001").Click();
|
|
||||||
|
|
||||||
//check PowerToys exited
|
|
||||||
powerToys = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
powerToys = PowerToysTrayButton();
|
|
||||||
}
|
|
||||||
catch (OpenQA.Selenium.WebDriverException)
|
|
||||||
{
|
|
||||||
//expected, PowerToys shouldn't be here
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchPowerToys();
|
|
||||||
Assert.IsNull(powerToys);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassInitialize]
|
|
||||||
public static void ClassInitialize(TestContext context)
|
|
||||||
{
|
|
||||||
Setup(context);
|
|
||||||
Assert.IsNotNull(session);
|
|
||||||
|
|
||||||
if (!isPowerToysLaunched)
|
|
||||||
{
|
|
||||||
LaunchPowerToys();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassCleanup]
|
|
||||||
public static void ClassCleanup()
|
|
||||||
{
|
|
||||||
ExitPowerToys();
|
|
||||||
TearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void TestInitialize()
|
|
||||||
{
|
|
||||||
isSettingsOpened = false;
|
|
||||||
isTrayOpened = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCleanup]
|
|
||||||
public void TestCleanup()
|
|
||||||
{
|
|
||||||
if (isSettingsOpened)
|
|
||||||
{
|
|
||||||
CloseSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isTrayOpened)
|
|
||||||
{
|
|
||||||
trayButton.Click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
# PowerToys Tests
|
|
||||||
|
|
||||||
The PowerToys tests are implemented using Appium and use the [Windows Application Driver](https://github.com/microsoft/WinAppDriver) as an Appium compatible server for Windows applications.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
- Install the latest stable version of Windows Application Driver in the test machine: [v1.1 Release](https://github.com/microsoft/WinAppDriver/releases/tag/v1.1)
|
|
||||||
- Install the ".Net desktop development" components in Visual Studio 2019. It should have support for `C#` and `.Net Framework 4.7.2`.
|
|
||||||
- Install [PowerToys](https://github.com/microsoft/PowerToys/releases/)
|
|
||||||
- In Windows 10 Settings, turn on `Developer Mode` (open the Windows 10 Settings and search "Developer settings").
|
|
||||||
|
|
||||||
If you have `PowerToys` installed, it can be launched automatically. Otherwise, if you are testing a local build, you should start `PowerToys` before running the tests.
|
|
||||||
|
|
||||||
### Preparing the test machine
|
|
||||||
- Start `PowerToys` if necessary (see the Prerequisites).
|
|
||||||
- Run `WinAppDriver.exe` in Administrator mode, on the test machine. By default it's installed in `C:\Program Files (x86)\Windows Application Driver\`
|
|
||||||
- **Note:** notifications or other application windows, that are shown above the PowerToys settings window or tray icon, can disrupt the testing process.
|
|
||||||
|
|
||||||
When testing on a remote machine, a Firewall exceptions must be added and the IP and port must be passed when starting "Windows Application Driver". Here's how to do it from the [Windows Application Driver FAQ](https://github.com/microsoft/WinAppDriver/wiki/Frequently-Asked-Questions#running-on-a-remote-machine):
|
|
||||||
|
|
||||||
#### Running on a Remote Machine
|
|
||||||
|
|
||||||
Windows Application Driver can run remotely on any Windows 10 machine with `WinAppDriver.exe` installed and running. This *test machine* can then serve any JSON wire protocol commands coming from the *test runner* remotely through the network. Below are the steps to the one-time setup for the *test machine* to receive inbound requests:
|
|
||||||
|
|
||||||
1. On the *test machine* you want to run the test application on, open up **Windows Firewall with Advanced Security**
|
|
||||||
- Select **Inbound Rules** -> **New Rule...**
|
|
||||||
- **Rule Type** -> **Port**
|
|
||||||
- Select **TCP**
|
|
||||||
- Choose specific local port (4723 is WinAppDriver standard)
|
|
||||||
- **Action** -> **Allow the connection**
|
|
||||||
- **Profile** -> select all
|
|
||||||
- **Name** -> optional, choose name for rule (e.g. WinAppDriver remote).
|
|
||||||
|
|
||||||
Below command when run in admin command prompt gives same result
|
|
||||||
```shell
|
|
||||||
netsh advfirewall firewall add rule name="WinAppDriver remote" dir=in action=allow protocol=TCP localport=4723
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Run `ipconfig.exe` to determine your machine's local IP address
|
|
||||||
> **Note**: Setting `*` as the IP address command line option will cause it to bind to all bound IP addresses on the machine
|
|
||||||
3. Run `WinAppDriver.exe 10.X.X.10 4723/wd/hub` as **administrator** with command line arguments as seen above specifying local IP and port
|
|
||||||
4. On the *test runner* machine where the runner and scripts are, update the test script to point to the IP of the remote *test machine*
|
|
||||||
|
|
||||||
### Starting the tests on the Development Machine
|
|
||||||
- Open `PowerToys.sln` in Visual Studio.
|
|
||||||
- Build the `PowerToysTests` project.
|
|
||||||
- Select `Test > Windows > Test Explorer`.
|
|
||||||
- Select `Test > Run > All` tests in the menu bar.
|
|
||||||
|
|
||||||
> Once the project is successfully built, you can use the **TestExplorer** to pick and choose the test scenario(s) to run
|
|
||||||
|
|
||||||
> If Visual Studio fail to discover and run the test scenarios:
|
|
||||||
> 1. Select **Tools** > **Options...** > **Test**
|
|
||||||
> 2. Under *Active Solution*, uncheck *For improved performance, only use test adapters in test assembly folder or as specified in runsettings file*
|
|
||||||
|
|
||||||
If a remote test machine is being used, the IP of the test machine must be used to replace the `WindowsApplicationDriverUrl` value in [PowerToysSession.cs](PowerToysSession.cs).
|
|
||||||
|
|
||||||
### Extra tools and information
|
|
||||||
|
|
||||||
For tests creation you will need a tool that enables you select any UI element and view the element's accessibility data. For this purpose you could use [AccessibilityInsights](https://accessibilityinsights.io/docs/windows/overview) or [Inspect](https://learn.microsoft.com/windows/win32/winauto/inspect-objects?redirectedfrom=MSDN).
|
|
||||||
|
|
||||||
* `inspect.exe` you can find installed at `C:\Program Files (x86)\Windows Kits\10\bin\<version>\<platform>\inspect.exe`
|
|
||||||
* `AccessibilityInsights` you can download [here](https://aka.ms/accessibilityinsights-windows/download)
|
|
||||||
|
|
||||||
##### How to use Inspect
|
|
||||||
Open Inspect, find element you need to investigate (by clicking on element or finding it in a tree) and in the right part of inspector window you will see info about this element.
|
|
||||||
|
|
||||||
Examples for searching elements with values of `Name`, `AutomationId` and `ControlType`:
|
|
||||||
```
|
|
||||||
//use FindElementByAccessibilityId with AutomationId value
|
|
||||||
session.FindElementByAccessibilityId("40001");
|
|
||||||
session.FindElementByAccessibilityId("decrementZones");
|
|
||||||
|
|
||||||
session.FindElementByName("PowerToys Settings");
|
|
||||||
|
|
||||||
//with XPath you can search elements with more specific information
|
|
||||||
session.FindElementByXPath("//Pane[@Name=\"PowerToys Settings\"]");
|
|
||||||
session.FindElementByXPath("//Edit[contains(@Name, \"hotkey\")]");
|
|
||||||
session.FindElementByXPath("//Pane[@Name=\"PowerToys Settings\"]/*[@LocalizedControlType=\"toggleswitch\"]");
|
|
||||||
```
|
|
||||||
|
|
||||||
>One more thing to notice: close helper tools while running tests. Overlapping windows can affect test results.
|
|
@ -1,166 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using OpenQA.Selenium.Appium;
|
|
||||||
using OpenQA.Selenium.Appium.Windows;
|
|
||||||
using OpenQA.Selenium.Interactions;
|
|
||||||
|
|
||||||
namespace PowerToysTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class TestShortcutGuideHelper : PowerToysSession
|
|
||||||
{
|
|
||||||
// Try to manage Press/Release of Windows Key here,
|
|
||||||
// since Keyboard.PressKey seems to release the key if pressed
|
|
||||||
// and Keyboard.ReleaseKey seems to press the key if not pressed.
|
|
||||||
private bool isWinKeyPressed;
|
|
||||||
|
|
||||||
private void PressWinKey()
|
|
||||||
{
|
|
||||||
if (!isWinKeyPressed)
|
|
||||||
{
|
|
||||||
new Actions(session).KeyDown(OpenQA.Selenium.Keys.Command).Perform();
|
|
||||||
isWinKeyPressed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ReleaseWinKey()
|
|
||||||
{
|
|
||||||
if (isWinKeyPressed)
|
|
||||||
{
|
|
||||||
new Actions(session).KeyUp(OpenQA.Selenium.Keys.Command).Perform();
|
|
||||||
isWinKeyPressed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void AppearsOnWinKeyPress()
|
|
||||||
{
|
|
||||||
PressWinKey();
|
|
||||||
WaitSeconds(3);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
WindowsElement shortcutHelperWindow = session.FindElementByXPath("/Pane[@ClassName=\"#32769\"]/Pane[@ClassName=\"PToyD2DPopup\"]");
|
|
||||||
Assert.IsNotNull(shortcutHelperWindow);
|
|
||||||
}
|
|
||||||
catch(OpenQA.Selenium.WebDriverException)
|
|
||||||
{
|
|
||||||
Assert.Fail("Shortcut Guide not found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
[ExpectedException(typeof(InvalidOperationException),
|
|
||||||
"The Shortcut Guide UI was still found after releasing the key.")]
|
|
||||||
public void DisappearsOnWinKeyRelease()
|
|
||||||
{
|
|
||||||
PressWinKey();
|
|
||||||
WaitSeconds(2);
|
|
||||||
WindowsElement shortcutHelperWindow;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
shortcutHelperWindow = session.FindElementByXPath("/Pane[@ClassName=\"#32769\"]/Pane[@ClassName=\"PToyD2DPopup\"]");
|
|
||||||
Assert.IsNotNull(shortcutHelperWindow);
|
|
||||||
}
|
|
||||||
catch (InvalidOperationException)
|
|
||||||
{
|
|
||||||
// Not the exception we wanted to catch here.
|
|
||||||
Assert.Fail("Shortcut Guide not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseWinKey();
|
|
||||||
shortcutHelperWindow = session.FindElementByXPath("/Pane[@ClassName=\"#32769\"]/Pane[@ClassName=\"PToyD2DPopup\"]");
|
|
||||||
Assert.IsNull(shortcutHelperWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void DoesNotBlockStartMenuOnShortPress()
|
|
||||||
{
|
|
||||||
PressWinKey();
|
|
||||||
WaitSeconds(0.4);
|
|
||||||
// FindElementByClassName will be faster than using with XPath.
|
|
||||||
WindowsElement shortcutHelperWindow = session.FindElementByClassName("PToyD2DPopup");
|
|
||||||
Assert.IsNotNull(shortcutHelperWindow);
|
|
||||||
ReleaseWinKey();
|
|
||||||
WindowsElement startMenuWindow = session.FindElementByXPath("/Pane[@ClassName=\"#32769\"]/Window[@Name=\"Start\"]");
|
|
||||||
}
|
|
||||||
[TestMethod]
|
|
||||||
[ExpectedException(typeof(InvalidOperationException),
|
|
||||||
"The Start Menu was found after releasing the key on a long press.")]
|
|
||||||
public void DoesNotSpawnStartMenuOnLongPress()
|
|
||||||
{
|
|
||||||
PressWinKey();
|
|
||||||
WaitSeconds(2);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// FindElementByClassName will be faster than using with XPath.
|
|
||||||
WindowsElement shortcutHelperWindow = session.FindElementByClassName("PToyD2DPopup");
|
|
||||||
Assert.IsNotNull(shortcutHelperWindow);
|
|
||||||
}
|
|
||||||
catch (InvalidOperationException)
|
|
||||||
{
|
|
||||||
// Not the exception we wanted to catch here.
|
|
||||||
Assert.Fail("Shortcut Guide not found");
|
|
||||||
}
|
|
||||||
ReleaseWinKey();
|
|
||||||
WindowsElement startMenuWindow = session.FindElementByXPath("/Pane[@ClassName=\"#32769\"]/Window[@Name=\"Start\"]");
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassInitialize]
|
|
||||||
public static void ClassInitialize(TestContext context)
|
|
||||||
{
|
|
||||||
Setup(context);
|
|
||||||
Assert.IsNotNull(session);
|
|
||||||
EnableModules(false, false, false, false, false, false, false, true);
|
|
||||||
|
|
||||||
if (!isPowerToysLaunched)
|
|
||||||
{
|
|
||||||
LaunchPowerToys();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ClassCleanup]
|
|
||||||
public static void ClassCleanup()
|
|
||||||
{
|
|
||||||
ExitPowerToys();
|
|
||||||
TearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void TestInitialize()
|
|
||||||
{
|
|
||||||
isWinKeyPressed = false;
|
|
||||||
|
|
||||||
// If the start menu is open, close it.
|
|
||||||
WindowsElement startMenuWindow = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
startMenuWindow = session.FindElementByXPath("/Pane[@ClassName=\"#32769\"]/Window[@Name=\"Start\"]");
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
//Start menu not found, as expected.
|
|
||||||
}
|
|
||||||
if (startMenuWindow != null)
|
|
||||||
{
|
|
||||||
string startMenuWindowHandle = (int.Parse(startMenuWindow.GetAttribute("NativeWindowHandle"))).ToString("x");
|
|
||||||
// Create session for controlling the Start Menu.
|
|
||||||
AppiumOptions appiumOptions = new AppiumOptions();
|
|
||||||
appiumOptions.PlatformName = "Windows";
|
|
||||||
appiumOptions.AddAdditionalCapability("appTopLevelWindow", startMenuWindowHandle);
|
|
||||||
WindowsDriver<WindowsElement> startMenuSession = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appiumOptions);
|
|
||||||
if (startMenuSession != null)
|
|
||||||
{
|
|
||||||
new Actions(session).SendKeys(OpenQA.Selenium.Keys.Escape + OpenQA.Selenium.Keys.Escape).Perform();
|
|
||||||
startMenuSession.Quit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[TestCleanup]
|
|
||||||
public void TestCleanup()
|
|
||||||
{
|
|
||||||
// Release Windows Key in case it's being pressed by some of the tests
|
|
||||||
ReleaseWinKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
|
||||||
<RootNamespace>PowerToysTests</RootNamespace>
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Appium.WebDriver" Version="4.2.1" />
|
|
||||||
<PackageReference Include="DotNetSeleniumExtras.WaitHelpers" Version="3.11.0" />
|
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
|
||||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
|
|
||||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
|
|
||||||
<PackageReference Include="coverlet.collector" Version="1.3.0" />
|
|
||||||
<PackageReference Include="System.IO.Abstractions" Version="13.2.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
Loading…
Reference in New Issue
Block a user