Compare commits

...

173 Commits

Author SHA1 Message Date
seraphima
fb80c851bb replace cilcks 2024-03-18 21:49:03 +01:00
seraphima
efb235536f wait popup 2024-03-18 21:17:54 +01:00
seraphima
98ada58f29 replaced one-line getters 2024-03-18 21:04:49 +01:00
seraphima
46e2648050 name constants 2024-03-18 20:38:30 +01:00
seraphima
d818700ceb refactoring 2024-03-18 19:40:28 +01:00
seraphima
26d8f89be6 edit layout tests 2024-03-18 15:02:58 +01:00
seraphima
89460d3f3a fix: not restoring the layout when called from context menu 2024-03-15 17:29:51 +01:00
seraphima
0660de54db creation tests 2024-03-12 20:50:17 +01:00
seraphima
80a5d43810 rename 2024-03-12 20:46:13 +01:00
seraphima
d813b63432 rename clicks 2024-03-08 16:28:49 +01:00
seraphima
58a513a8a6 reduce waiting time 2024-03-08 15:53:39 +01:00
seraphima
c42c116dbf fix: serialize data after deletion 2024-03-08 15:38:35 +01:00
seraphima
aa41af5eb9 fix: refresh hotkeys 2024-03-08 15:37:36 +01:00
seraphima
1daae799bf delete layout tests 2024-03-08 15:37:36 +01:00
seraphima
585d3b4754 keep other applied layouts tests 2024-03-07 12:54:01 +01:00
seraphima
edad88cdbe added applied layouts tests 2024-03-07 12:18:57 +01:00
seraphima
394ac183e9 applied layouts initialization tests 2024-03-05 19:54:46 +01:00
seraphima
e1241b3de5 copy layout tests 2024-03-04 21:56:13 +01:00
seraphima
c2d3eb0aef interact with context menu items 2024-03-04 20:30:42 +01:00
seraphima
7ae037edbd update tests 2024-03-04 17:05:08 +01:00
seraphima
be2f5a5463 fix after conflicts 2024-03-04 15:07:59 +01:00
seraphima
cdf600dd54 build fix 2024-03-04 14:53:17 +01:00
seraphima
041cddf095 spelling 2024-03-04 14:53:17 +01:00
seraphima
c3d04d956a default layouts tests 2024-03-04 14:52:30 +01:00
seraphima
1c5dc3f96f added hotkey test 2024-03-04 14:52:30 +01:00
seraphima
99c4a34896 replaced assert with log 2024-03-04 14:52:30 +01:00
seraphima
8085198dad added retry attempts to wait 2024-03-04 14:52:30 +01:00
seraphima
8692aade81 correct names 2024-03-04 14:52:30 +01:00
seraphima
2e482b56ec changed the order of template layouts 2024-03-04 14:52:30 +01:00
seraphima
69b3da2256 hotkey tests 2024-03-04 14:52:30 +01:00
seraphima
5eed7f8739 spelling 2024-03-04 14:52:30 +01:00
seraphima
3ecaafa28e remove io helper dtor 2024-03-04 14:52:30 +01:00
seraphima
da3ed72e06 click 2024-03-04 14:52:30 +01:00
seraphima
f97865e49d changed assert message 2024-03-04 14:52:30 +01:00
seraphima
285127020a wait less 2024-03-04 14:52:30 +01:00
seraphima
0ab6f001c4 consider error dialog on closing 2024-03-04 14:52:30 +01:00
seraphima
72ef8966aa rename context click 2024-03-04 14:51:35 +01:00
seraphima
cda1511ba3 always add "None" value 2024-03-04 14:51:35 +01:00
seraphima
efdb4025dc log if element not displayed 2024-03-04 14:51:35 +01:00
seraphima
a4aedae4a8 restore applied layouts with editor params 2024-03-04 14:51:35 +01:00
seraphima
0b6aec03d1 custom layouts initialization 2024-03-04 14:50:56 +01:00
seraphima
5e030f0357 restore applied layouts 2024-03-04 14:50:56 +01:00
seraphima
d9394fd0ea template layouts: save-cancel tests 2024-03-04 14:50:56 +01:00
seraphima
42539d1e25 fix: restore name 2024-03-04 14:50:56 +01:00
seraphima
16311560d6 fix name checks 2024-03-04 14:50:56 +01:00
seraphima
e22faa6453 changed test initialization 2024-03-04 14:50:56 +01:00
seraphima
2bfaf0f7eb custom layouts tests 2024-03-04 14:50:56 +01:00
seraphima
cb47f11bbc spelling 2024-03-04 14:50:56 +01:00
seraphima
88ca89b90d replace assert when searching a layout 2024-03-04 14:50:56 +01:00
seraphima
d837ef9a10 wait 2024-03-04 14:50:17 +01:00
seraphima
b71c2b76d5 rename template layouts constants 2024-03-04 14:50:17 +01:00
seraphima
5c555ba5fd rename test class 2024-03-04 14:50:17 +01:00
seraphima
e5668fb239 template layouts tests 2024-03-04 14:50:17 +01:00
seraphima
96d426b52f wait 2024-03-04 14:50:17 +01:00
seraphima
502e73a7ca accessibility ids 2024-03-04 14:50:17 +01:00
seraphima
8658ed2530 template zone number test 2024-03-04 14:49:10 +01:00
seraphima
b227488e43 separate io helpers 2024-03-04 14:49:10 +01:00
seraphima
d97329acef fix layout name 2024-03-04 14:49:10 +01:00
seraphima
c2fa3bae98 handy assert 2024-03-04 14:49:10 +01:00
seraphima
11aa0eb753 save and cancel clicks 2024-03-04 14:49:10 +01:00
seraphima
7f27b69079 get zone slider 2024-03-04 14:49:10 +01:00
seraphima
2b336c4bfa moved enum 2024-03-04 14:49:10 +01:00
seraphima
f8ac674c45 added ui initialization tests 2024-03-04 14:48:09 +01:00
seraphima
4663095edb click monitor test 2024-03-04 14:48:09 +01:00
seraphima
9cf0ab28af click item 2024-03-04 14:46:54 +01:00
seraphima
8ab5c1b929 add name to monitors list 2024-03-04 14:46:54 +01:00
seraphima
dbe4982166 fixed cleaning up 2024-03-01 15:28:30 +01:00
seraphima
8942090911 create directory 2024-02-29 20:48:24 +01:00
seraphima
c4f595b19e spellcheck 2024-02-29 17:36:10 +01:00
seraphima
fe3d49cb19 remove unused file 2024-02-29 17:33:36 +01:00
seraphima
8a2fdca92d prepare editor files before launch 2024-02-29 17:27:22 +01:00
seraphima
5f7269ced1 file utils 2024-02-29 17:27:01 +01:00
seraphima
ed4940ca68 Moved constants 2024-02-29 17:11:43 +01:00
seraphima
bf4290866f write retry 2024-02-28 17:00:51 +01:00
seraphima
e0f67fc2c0 io test helper 2024-02-28 16:58:44 +01:00
seraphima
89e7b49de4 move data to the common project 2024-02-28 16:56:38 +01:00
seraphima
70eb880363 remove unnecessary 2024-02-28 15:35:41 +01:00
seraphima
c7cf00e5db split io class: editor params 2024-02-28 15:34:53 +01:00
seraphima
21ee6db3f5 exclude WinAppDriver files from spell-check 2024-02-28 14:26:04 +01:00
seraphima
dd8420156f log session info 2024-02-28 13:51:18 +01:00
seraphima
e12266541d rerun 2024-02-28 11:19:36 +01:00
seraphima
343a8a9858 try waiting 2024-02-28 11:19:31 +01:00
seraphima
2966dc4828 set longer timeout 2024-02-27 19:19:23 +01:00
seraphima
47e05ee477 added init to the second project 2024-02-27 16:15:00 +01:00
seraphima
41edad57cb src dir variable 2024-02-27 12:40:46 +01:00
seraphima
69de2646c6 path 2024-02-26 12:38:01 +01:00
seraphima
ebdf0b8114 checkout 2024-02-26 11:13:21 +01:00
seraphima
40e79e7bb2 remove task 2024-02-26 11:05:43 +01:00
seraphima
4bdc395730 spellcheck 2024-02-23 21:23:58 +01:00
seraphima
d159ab070a Merge branch 'main' into dev/seraphima/tests/29246-fancyzones-tests-initial-step 2024-02-23 20:38:37 +01:00
seraphima
8a8100416e added WinAppDriver.exe 2024-02-23 20:21:40 +01:00
Clint Rutkas
91299802ed Update run-ui-tests-ci.yml 2024-02-09 21:17:24 -08:00
Clint Rutkas
fdab112728 Update run-ui-tests-ci.yml 2024-02-09 20:53:39 -08:00
Clint Rutkas
57f5fb1d8f Update run-ui-tests-ci.yml
testing against what WinUI gallery has for agent
2024-02-09 08:13:48 -08:00
Jaime Bernardo
061d337195 AgentResolution should be a string 2024-02-09 09:32:04 +00:00
Clint Rutkas
82def1c5a0 Update run-ui-tests-ci.yml 2024-02-08 21:59:07 -08:00
Clint Rutkas
a0e2c27746 Update run-ui-tests-ci.yml 2024-02-08 21:56:05 -08:00
Clint Rutkas
1fc0d047f9 Update run-ui-tests-ci.yml 2024-02-08 20:50:30 -08:00
Clint Rutkas
de827e6068 Update run-ui-tests-ci.yml 2024-02-08 20:49:52 -08:00
seraphima
f07b6848cf Merge branch 'main' into dev/seraphima/tests/29246-fancyzones-tests-initial-step 2024-02-07 15:24:18 +01:00
seraphima
950f6ae5e4 Merge branch 'main' into dev/seraphima/tests/29246-fancyzones-tests-initial-step 2024-02-07 13:36:22 +01:00
seraphima
668b133496 remove resolution 2024-02-07 13:02:29 +01:00
seraphima
759e5ad1b1 task name 2024-02-06 19:09:22 +01:00
seraphima
995610a967 added start operation type 2024-02-06 16:35:37 +01:00
seraphima
47a228d295 default address 2024-02-06 14:18:08 +01:00
seraphima
3ba5edb697 changed args and condition 2024-02-06 10:58:01 +01:00
seraphima
1adad0de2f winappdriver task 2024-02-05 18:50:48 +01:00
seraphima
c17a886ad7 test with full vsconsole path 2024-02-01 23:28:31 +01:00
seraphima
7b89e31900 change path, remove unnecessary 2024-02-01 19:54:36 +01:00
seraphima
6df4fc6735 try full path in vstest task 2024-02-01 14:09:17 +01:00
seraphima
653838d604 try vstest task 2024-02-01 09:54:38 +01:00
seraphima
ce895e74b3 try full path 2024-01-31 18:43:43 +01:00
seraphima
ea16192bc8 check files 2024-01-31 17:00:31 +01:00
seraphima
78701d8243 tools dir 2024-01-30 22:22:09 +01:00
seraphima
864248f18f vs path 2024-01-30 19:44:59 +01:00
seraphima
6fbd2de127 search vstest.console 2024-01-30 12:31:31 +01:00
seraphima
101cff736f script path 2024-01-29 13:36:41 +01:00
seraphima
c5326584ca upd command 2024-01-29 12:31:01 +01:00
seraphima
de5a60217b vstest.console 2024-01-29 12:24:49 +01:00
seraphima
928ea7021d location 2024-01-26 14:22:42 +01:00
seraphima
6a2fae87a1 are other tests running? 2024-01-26 12:23:13 +01:00
seraphima
cefe6ac235 hardcoded vstest location 2024-01-25 14:15:08 +01:00
seraphima
1fa1c7d310 package feed selector 2024-01-25 14:02:22 +01:00
seraphima
ed5fb23237 set test platform version 2024-01-25 13:52:46 +01:00
seraphima
f5f0fcb3ac spellcheck 2024-01-25 12:40:11 +01:00
seraphima
202cf72121 set vs test version 2024-01-25 12:35:18 +01:00
seraphima
7bc6d897cf test build agents 2024-01-22 13:30:55 +01:00
seraphima
dd030d7ffe Merge branch 'main' into dev/seraphima/tests/29246-fancyzones-tests-initial-step 2024-01-19 18:09:31 +01:00
seraphima
4a43d427e3 target dotnet8 2024-01-19 16:13:42 +01:00
seraphima
c29e4ddfd2 copy all 2024-01-19 14:59:27 +01:00
seraphima
7a061ab337 prepare dotnet and vstest platform 2024-01-18 13:38:38 +01:00
seraphima
d93b436c7d set folders 2024-01-18 12:28:02 +01:00
seraphima
f929ca6847 artifact name, default download path 2024-01-17 18:40:08 +01:00
seraphima
efacbc2e3f artifact publish conditions 2024-01-17 18:33:48 +01:00
seraphima
ab56bd1ec1 publish artifact 2024-01-17 17:16:34 +01:00
seraphima
b21f81b2dc Merge branch 'main' into dev/seraphima/tests/29246-fancyzones-tests-initial-step 2024-01-16 18:36:30 +01:00
seraphima
451c7e6393 download artifact 2024-01-16 15:03:42 +01:00
seraphima
981b616ef4 dependance 2024-01-15 18:24:35 +01:00
seraphima
70f31ae14e vs test 2024-01-15 18:18:59 +01:00
seraphima
51f4969362 pool 2024-01-15 17:16:27 +01:00
seraphima
4f103199a2 pool 2024-01-15 17:02:18 +01:00
seraphima
f4b3e59e0b added parameters 2024-01-15 16:57:55 +01:00
seraphima
af59339b5a test 2024-01-12 15:54:10 +01:00
seraphima
8f39e739a1 test 2024-01-12 15:47:21 +01:00
seraphima
2559501827 removed parameters 2024-01-12 15:38:32 +01:00
seraphima
b6cf2f32ac removed log 2024-01-12 14:51:36 +01:00
seraphima
1c338ee02a removed dependance 2024-01-12 14:47:14 +01:00
seraphima
7fbdffd307 removed arg 2024-01-12 14:40:50 +01:00
seraphima
59282afa74 tabulation fix 2024-01-12 14:39:30 +01:00
seraphima
5e6c704eb4 removed condition 2024-01-12 14:25:08 +01:00
seraphima
7d15b4137a run test template 2024-01-12 14:20:55 +01:00
seraphima
799bfe44b4 change dependance 2024-01-12 14:20:20 +01:00
seraphima
b62c41413a rename job 2024-01-12 14:20:08 +01:00
seraphima
e435e7465b fix test configuration 2024-01-12 14:16:11 +01:00
seraphima
937229da8a removed run 2024-01-12 14:11:42 +01:00
seraphima
441cd1f25b removed unrecognized 2024-01-12 13:59:29 +01:00
seraphima
0e6784888b added file for tests run 2024-01-12 13:54:13 +01:00
seraphima
61138a8f67 Merge branch 'microsoft/main' into dev/seraphima/tests/29246-fancyzones-tests-initial-step 2024-01-09 14:52:40 +01:00
seraphima
588f65663b Merge branch 'main' into dev/seraphima/tests/29246-fancyzones-tests-initial-step 2023-11-21 12:28:42 +01:00
seraphima
3991e202cf added sample tests 2023-11-14 13:07:23 +01:00
seraphima
13571d168d update packages list in notice.md 2023-10-30 16:55:06 +01:00
seraphima
31a4711ac3 exclude ui tests deps 2023-10-30 16:07:54 +01:00
seraphima
ac5437c0a6 update to latest stable 2023-10-30 15:14:21 +01:00
seraphima
f4e346adf2 spelling 2023-10-27 17:54:36 +02:00
seraphima
057eba8b92 dev docs 2023-10-27 17:42:10 +02:00
seraphima
40dc94fd5c spelling 2023-10-27 15:55:20 +02:00
seraphima
66ed4dd07b added assert messages 2023-10-27 15:43:52 +02:00
seraphima
48c448f1c1 rename 2023-10-27 15:43:37 +02:00
seraphima
662a2e1715 check if FZ is running 2023-10-27 15:38:40 +02:00
seraphima
d0ebc2d09f editor test project 2023-10-26 14:36:10 +02:00
seraphima
238aa70ccb rename proj 2023-10-26 12:49:23 +02:00
seraphima
d2b598e843 run fz test 2023-10-26 12:39:20 +02:00
seraphima
c8d5d3c6d1 added test project 2023-10-24 14:18:45 +02:00
77 changed files with 7965 additions and 737 deletions

View File

@@ -98,6 +98,8 @@
^\Q.github/workflows/spelling2.yml\E$
^\Q.pipelines/ESRPSigning_core.json\E$
^\Q.pipelines/sdl.gdnbaselines\E$
^\Qdeps/WinAppDriver/EULA.rtf\E$
^\Qdeps/WinAppDriver/Readme.txt\E$
^\Qinstaller/PowerToysSetup/Settings.wxs\E$
^\Qsrc/common/FilePreviewCommon/Assets/Monaco/monaco_languages.json\E$
^\Qsrc/common/ManagedCommon/ColorFormatHelper.cs\E$

View File

@@ -1639,6 +1639,7 @@ USEDEFAULT
USEFILEATTRIBUTES
USERDATA
Userenv
uservoice
USESHOWWINDOW
USESTDHANDLES
USRDLL
@@ -1696,6 +1697,7 @@ VSM
vso
vsonline
vstemplate
vstest
VSTHRD
VSTT
vswhere
@@ -1790,6 +1792,7 @@ WNDPROC
workarounds
wox
wparam
wpdev
wpf
wpftmp
wpfui

View File

@@ -33,4 +33,7 @@ jobs:
platform: x64
- template: ./templates/build-powertoys-ci.yml
parameters:
platform: arm64
platform: arm64
- template: ./templates/run-ui-tests-ci.yml
parameters:
platform: x64

View File

@@ -299,3 +299,18 @@ steps:
displayName: Publish Logs
artifact: '$(System.JobDisplayName) logs'
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)

View File

@@ -0,0 +1,66 @@
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: 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\**

View File

@@ -15,7 +15,8 @@ Param(
$referencedFileVersionsPerDll = @{}
$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
$depsJsonFileName = $_.Name
$depsJson = Get-Content $depsJsonFullFileName | ConvertFrom-Json

View File

@@ -3,7 +3,7 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<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.WinUI.Animations" Version="8.0.240109" />
<PackageVersion Include="CommunityToolkit.WinUI.Collections" Version="8.0.240109" />

View File

@@ -1296,6 +1296,7 @@ EXHIBIT A -Mozilla Public License.
## NuGet Packages used by PowerToys
- Appium.WebDriver 4.4.5
- CommunityToolkit.Mvvm 8.2.2
- CommunityToolkit.WinUI.Animations 8.0.240109
- CommunityToolkit.WinUI.Collections 8.0.240109

View File

@@ -568,6 +568,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithContextMenu",
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithLib", "src\modules\FileLocksmith\FileLocksmithLib\FileLocksmithLib.vcxproj", "{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}"
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
GlobalSection(SolutionConfigurationPlatforms) = preSolution
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|x86.ActiveCfg = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2703,6 +2745,9 @@ Global
{0014D652-901F-4456-8D65-06FC5F997FB0} = {4C0D0746-BE5B-49EE-BD5D-A7811628AE8B}
{799A50D8-DE89-4ED1-8FF8-AD5A9ED8C0CA} = {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
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}

1102
deps/WinAppDriver/EULA.rtf vendored Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

BIN
deps/WinAppDriver/MitaBroker.dll vendored Normal file

Binary file not shown.

BIN
deps/WinAppDriver/MitaLite.AppModel.dll vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
deps/WinAppDriver/Newtonsoft.Json.dll vendored Normal file

Binary file not shown.

7
deps/WinAppDriver/Readme.txt vendored Normal file
View File

@@ -0,0 +1,7 @@
Windows Application Driver
For documentation, sample code, and logging issues:
https://github.com/Microsoft/WinAppDriver
To request new features and upvote requests filed by others:
https://wpdev.uservoice.com

Binary file not shown.

Binary file not shown.

BIN
deps/WinAppDriver/WinAppDriver.exe vendored Normal file

Binary file not shown.

BIN
deps/WinAppDriver/WinAppDriverCore.dll vendored Normal file

Binary file not shown.

BIN
deps/WinAppDriver/cpprest140_2_9.dll vendored Normal file

Binary file not shown.

View File

@@ -1,85 +1,25 @@
## FancyZones Lib
# FancyZones UI tests
#### [`FancyZones.cpp`](/src/modules/fancyzones/lib/FancyZones.cpp)
TODO
UI tests are implemented using [Windows Application Driver](https://github.com/microsoft/WinAppDriver).
#### [`Settings.cpp`](/src/modules/fancyzones/lib/Settings.cpp)
TODO
## Before running tests
#### [`trace.cpp`](/src/modules/fancyzones/lib/trace.cpp)
TODO
- Download and run Windows Application Driver installer from https://github.com/Microsoft/WinAppDriver/releases
- Enable Developer Mode in Windows settings
#### [`Zone.cpp`](/src/modules/fancyzones/lib/Zone.cpp)
TODO
## Running tests
- Run WinAppDriver.exe from the installation directory (E.g. `C:\Program Files (x86)\Windows Application Driver`)
- 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)
TODO
>Note: notifications or other application windows, that are shown above the window under test, can disrupt the testing process.
#### [`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)
TODO
**Test samples**: https://github.com/microsoft/WinAppDriver/tree/master/Samples
#### [`Properties\AssemblyInfo.cs`](/src/modules/fancyzones/editor/Properties\AssemblyInfo.cs)
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
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).
>Note: close helper tools while running tests. Overlapping windows can affect test results.

View File

@@ -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; }
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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; }
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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()
{
}
}
}

View File

@@ -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;
}
}

View File

@@ -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; }
}
}
}

View File

@@ -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; }
}
}
}

View File

@@ -0,0 +1,44 @@
// 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 enum MonitorConfigurationType
{
Horizontal = 0,
Vertical,
}
public static class MonitorConfigurationTypeEnumExtensions
{
private const string HorizontalJsonTag = "horizontal";
private const string VerticalJsonTag = "vertical";
public static string MonitorConfigurationTypeToString(this MonitorConfigurationType value)
{
switch (value)
{
case MonitorConfigurationType.Horizontal:
return HorizontalJsonTag;
case MonitorConfigurationType.Vertical:
return VerticalJsonTag;
}
return HorizontalJsonTag;
}
public static MonitorConfigurationType GetTypeFromString(string value)
{
switch (value)
{
case HorizontalJsonTag:
return MonitorConfigurationType.Horizontal;
case VerticalJsonTag:
return MonitorConfigurationType.Vertical;
}
return MonitorConfigurationType.Horizontal;
}
}
}

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net7.0-windows</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>

View File

@@ -4,9 +4,7 @@
using System.Text.Json;
using FancyZonesEditor.Utils;
namespace FancyZonesEditor
namespace FancyZonesEditorCommon.Utils
{
public class DashCaseNamingPolicy : JsonNamingPolicy
{

View File

@@ -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;
}
}
}

View File

@@ -4,7 +4,7 @@
using System.Linq;
namespace FancyZonesEditor.Utils
namespace FancyZonesEditorCommon.Utils
{
public static class StringUtils
{

View File

@@ -0,0 +1,45 @@
// 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 Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class Init
{
private static Process? appDriver;
[AssemblyInitialize]
public static void SetupAll(TestContext context)
{
string? sourceDirPath = Environment.GetEnvironmentVariable("SrcPath"); // get source dir in CI
if (sourceDirPath == null)
{
sourceDirPath = Path.GetFullPath($"{Environment.CurrentDirectory}" + @".\..\..\..\..\..\"); // local
}
context.WriteLine($"Source dir: {sourceDirPath}");
string winAppDriver = Path.Combine(sourceDirPath, @".\deps\WinAppDriver", "WinAppDriver.exe");
context.WriteLine($"Attempting to launch WinAppDriver at: {winAppDriver}");
appDriver = Process.Start(winAppDriver);
}
[AssemblyCleanup]
public static void CleanupAll()
{
try
{
appDriver?.Kill();
}
catch
{
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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();
}
}
}
}

View File

@@ -0,0 +1,319 @@
// 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 FancyZonesEditorCommon.Data;
using Microsoft.FancyZonesEditor.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class ApplyLayoutTests
{
private static readonly 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,
},
new EditorParameters.NativeMonitorDataWrapper
{
Monitor = "monitor-2",
MonitorInstanceId = "instance-id-2",
MonitorSerialNumber = "serial-number-2",
MonitorNumber = 2,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 96,
LeftCoordinate = 1920,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = false,
},
},
};
private static readonly CustomLayouts.CustomLayoutListWrapper CustomLayoutsList = new CustomLayouts.CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayouts.CustomLayoutWrapper>
{
new CustomLayouts.CustomLayoutWrapper
{
Uuid = "{E7807D0D-6223-4883-B15B-1F3883944C09}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Custom layout",
Info = new CustomLayouts().ToJsonElement(new CustomLayouts.CanvasInfoWrapper
{
RefHeight = 952,
RefWidth = 1500,
SensitivityRadius = 10,
Zones = new List<CustomLayouts.CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
},
};
private static readonly LayoutTemplates.TemplateLayoutsListWrapper TemplateLayoutsList = new LayoutTemplates.TemplateLayoutsListWrapper
{
LayoutTemplates = new List<LayoutTemplates.TemplateLayoutWrapper>
{
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid],
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
};
private static FancyZonesEditorSession? _session;
private static TestContext? _context;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
}
[ClassCleanup]
public static void ClassCleanup()
{
_context = null;
}
[TestInitialize]
public void TestInitialize()
{
EditorParameters editorParameters = new EditorParameters();
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(Parameters));
LayoutTemplates layoutTemplates = new LayoutTemplates();
FancyZonesEditorSession.Files.LayoutTemplatesIOHelper.WriteData(layoutTemplates.Serialize(TemplateLayoutsList));
CustomLayouts customLayouts = new CustomLayouts();
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(CustomLayoutsList));
DefaultLayouts defaultLayouts = new DefaultLayouts();
DefaultLayouts.DefaultLayoutsListWrapper defaultLayoutsListWrapper = new DefaultLayouts.DefaultLayoutsListWrapper
{
DefaultLayouts = new List<DefaultLayouts.DefaultLayoutWrapper>
{
new DefaultLayouts.DefaultLayoutWrapper
{
MonitorConfiguration = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Horizontal),
Layout = new DefaultLayouts.DefaultLayoutWrapper.LayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 4,
ShowSpacing = true,
Spacing = 5,
SensitivityRadius = 20,
},
},
new DefaultLayouts.DefaultLayoutWrapper
{
MonitorConfiguration = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Vertical),
Layout = new DefaultLayouts.DefaultLayoutWrapper.LayoutWrapper
{
Type = "custom",
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
ZoneCount = 0,
ShowSpacing = false,
Spacing = 0,
SensitivityRadius = 0,
},
},
},
};
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));
_session = new FancyZonesEditorSession(_context!);
}
[TestCleanup]
public void TestCleanup()
{
_session?.Close();
FancyZonesEditorSession.Files.Restore();
}
[TestMethod]
public void ApplyCustomLayout()
{
var layout = CustomLayoutsList.CustomLayouts[0];
Assert.IsFalse(_session?.GetLayout(layout.Name)!.Selected);
_session?.Click(_session?.GetLayout(layout.Name)!);
Assert.IsTrue(_session?.GetLayout(layout.Name)!.Selected);
AppliedLayouts appliedLayouts = new AppliedLayouts();
var data = appliedLayouts.Read(appliedLayouts.File);
Assert.AreEqual(Parameters.Monitors.Count, data.AppliedLayouts.Count);
Assert.AreEqual(layout.Uuid, data.AppliedLayouts[0].AppliedLayout.Uuid);
Assert.AreEqual(Parameters.Monitors[0].MonitorNumber, data.AppliedLayouts[0].Device.MonitorNumber);
}
[TestMethod]
public void ApplyTemplateLayout()
{
var layoutType = Constants.TemplateLayouts.Columns;
var layout = Constants.TemplateLayoutNames[layoutType];
Assert.IsFalse(_session?.GetLayout(layout)!.Selected);
_session?.Click(_session?.GetLayout(layout)!);
Assert.IsTrue(_session?.GetLayout(layout)!.Selected);
AppliedLayouts appliedLayouts = new AppliedLayouts();
var data = appliedLayouts.Read(appliedLayouts.File);
Assert.AreEqual(Parameters.Monitors.Count, data.AppliedLayouts.Count);
Assert.AreEqual(Constants.TemplateLayoutTypes[layoutType], data.AppliedLayouts[0].AppliedLayout.Type);
Assert.AreEqual(Parameters.Monitors[0].MonitorNumber, data.AppliedLayouts[0].Device.MonitorNumber);
}
[TestMethod]
public void ApplyLayoutsOnEachMonitor()
{
// apply the layout on the first monitor
var firstLayoutType = Constants.TemplateLayouts.Columns;
var firstLayoutName = Constants.TemplateLayoutNames[firstLayoutType];
_session?.Click(_session?.GetLayout(firstLayoutName)!);
Assert.IsTrue(_session?.GetLayout(firstLayoutName)!.Selected);
// apply the layout on the second monitor
_session?.ClickMonitor(2);
var secondLayout = CustomLayoutsList.CustomLayouts[0];
_session?.Click(_session?.GetLayout(secondLayout.Name)!);
Assert.IsTrue(_session?.GetLayout(secondLayout.Name)!.Selected);
// verify the layout on the first monitor wasn't changed
_session?.ClickMonitor(1);
Assert.IsTrue(_session?.GetLayout(firstLayoutName)!.Selected);
// verify the file
var appliedLayouts = new AppliedLayouts();
var data = appliedLayouts.Read(appliedLayouts.File);
Assert.AreEqual(Parameters.Monitors.Count, data.AppliedLayouts.Count);
Assert.AreEqual(Constants.TemplateLayoutTypes[firstLayoutType], data.AppliedLayouts.Find(x => x.Device.MonitorNumber == 1).AppliedLayout.Type);
Assert.AreEqual(secondLayout.Uuid, data.AppliedLayouts.Find(x => x.Device.MonitorNumber == 2).AppliedLayout.Uuid);
}
[TestMethod]
public void ApplyTemplateWithDifferentParametersOnEachMonitor()
{
var layoutType = Constants.TemplateLayouts.Columns;
var layoutName = Constants.TemplateLayoutNames[layoutType];
// apply the layout on the first monitor, set parameters
_session?.Click(_session?.GetLayout(layoutName)!);
_session?.ClickEditLayout(layoutName);
var slider = _session?.FindByAccessibilityId(AccessibilityId.TemplateZoneSlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Right);
slider.SendKeys(Keys.Right);
var expectedFirstLayoutZoneCount = int.Parse(slider.Text!, CultureInfo.InvariantCulture);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(slider); // let the dialog window close
// apply the layout on the second monitor, set different parameters
_session?.ClickMonitor(2);
_session?.Click(_session?.GetLayout(layoutName)!);
_session?.ClickEditLayout(layoutName);
slider = _session?.FindByAccessibilityId(AccessibilityId.TemplateZoneSlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Left);
var expectedSecondLayoutZoneCount = int.Parse(slider.Text!, CultureInfo.InvariantCulture);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the layout on the first monitor wasn't changed
_session?.ClickMonitor(1);
_session?.ClickEditLayout(layoutName);
slider = _session?.FindByAccessibilityId(AccessibilityId.TemplateZoneSlider);
Assert.IsNotNull(slider);
Assert.AreEqual(expectedFirstLayoutZoneCount, int.Parse(slider.Text!, CultureInfo.InvariantCulture));
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider); // let the dialog window close
// check the file
var appliedLayouts = new AppliedLayouts();
var data = appliedLayouts.Read(appliedLayouts.File);
Assert.AreEqual(Parameters.Monitors.Count, data.AppliedLayouts.Count);
Assert.AreEqual(Constants.TemplateLayoutTypes[layoutType], data.AppliedLayouts.Find(x => x.Device.MonitorNumber == 1).AppliedLayout.Type);
Assert.AreEqual(expectedFirstLayoutZoneCount, data.AppliedLayouts.Find(x => x.Device.MonitorNumber == 1).AppliedLayout.ZoneCount);
Assert.AreEqual(Constants.TemplateLayoutTypes[layoutType], data.AppliedLayouts.Find(x => x.Device.MonitorNumber == 2).AppliedLayout.Type);
Assert.AreEqual(expectedSecondLayoutZoneCount, data.AppliedLayouts.Find(x => x.Device.MonitorNumber == 2).AppliedLayout.ZoneCount);
}
}
}

View File

@@ -0,0 +1,55 @@
// 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 Microsoft.FancyZonesEditor.UITests
{
public static class Constants
{
public enum TemplateLayouts
{
Empty,
Focus,
Columns,
Rows,
Grid,
PriorityGrid,
}
public static readonly Dictionary<TemplateLayouts, string> TemplateLayoutNames = new Dictionary<TemplateLayouts, string>()
{
{ TemplateLayouts.Empty, "No layout" },
{ TemplateLayouts.Focus, "Focus" },
{ TemplateLayouts.Columns, "Columns" },
{ TemplateLayouts.Rows, "Rows" },
{ TemplateLayouts.Grid, "Grid" },
{ TemplateLayouts.PriorityGrid, "Priority Grid" },
};
public static readonly Dictionary<TemplateLayouts, string> TemplateLayoutTypes = new Dictionary<TemplateLayouts, string>()
{
{ TemplateLayouts.Empty, "blank" },
{ TemplateLayouts.Focus, "focus" },
{ TemplateLayouts.Columns, "columns" },
{ TemplateLayouts.Rows, "rows" },
{ TemplateLayouts.Grid, "grid" },
{ TemplateLayouts.PriorityGrid, "priority-grid" },
};
public static readonly string CustomLayoutTypeString = "custom";
public enum CustomLayoutType
{
Canvas,
Grid,
}
public static readonly Dictionary<CustomLayoutType, string> CustomLayoutTypeNames = new Dictionary<CustomLayoutType, string>()
{
{ CustomLayoutType.Canvas, "canvas" },
{ CustomLayoutType.Grid, "grid" },
};
}
}

View File

@@ -0,0 +1,359 @@
// 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.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static FancyZonesEditorCommon.Data.EditorParameters;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class CopyLayoutTests
{
private static readonly CustomLayouts.CustomLayoutListWrapper CustomLayouts = new CustomLayouts.CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayouts.CustomLayoutWrapper>
{
new CustomLayouts.CustomLayoutWrapper
{
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid],
Name = "Grid custom layout",
Info = new CustomLayouts().ToJsonElement(new CustomLayouts.GridInfoWrapper
{
Rows = 2,
Columns = 3,
RowsPercentage = new List<int> { 2967, 7033 },
ColumnsPercentage = new List<int> { 2410, 6040, 1550 },
CellChildMap = new int[][] { [0, 1, 1], [0, 2, 3] },
SensitivityRadius = 30,
Spacing = 26,
ShowSpacing = false,
}),
},
},
};
private static readonly LayoutHotkeys.LayoutHotkeysWrapper Hotkeys = new LayoutHotkeys.LayoutHotkeysWrapper
{
LayoutHotkeys = new List<LayoutHotkeys.LayoutHotkeyWrapper>
{
new LayoutHotkeys.LayoutHotkeyWrapper
{
LayoutId = CustomLayouts.CustomLayouts[0].Uuid,
Key = 0,
},
},
};
private static readonly DefaultLayouts.DefaultLayoutsListWrapper DefaultLayouts = new DefaultLayouts.DefaultLayoutsListWrapper
{
DefaultLayouts = new List<DefaultLayouts.DefaultLayoutWrapper>
{
new DefaultLayouts.DefaultLayoutWrapper
{
MonitorConfiguration = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Vertical),
Layout = new DefaultLayouts.DefaultLayoutWrapper.LayoutWrapper
{
Type = "custom",
Uuid = CustomLayouts.CustomLayouts[0].Uuid,
},
},
},
};
private static TestContext? _context;
private static FancyZonesEditorSession? _session;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
}
[ClassCleanup]
public static void ClassCleanup()
{
_context = null;
}
[TestInitialize]
public void TestInitialize()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new NativeMonitorDataWrapper
{
Monitor = "monitor-1",
MonitorInstanceId = "instance-id-1",
MonitorSerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 192,
LeftCoordinate = 0,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
},
};
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
CustomLayouts customLayouts = new CustomLayouts();
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(CustomLayouts));
LayoutTemplates layoutTemplates = new LayoutTemplates();
LayoutTemplates.TemplateLayoutsListWrapper templateLayoutsListWrapper = new LayoutTemplates.TemplateLayoutsListWrapper
{
LayoutTemplates = new List<LayoutTemplates.TemplateLayoutWrapper>
{
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid],
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
};
FancyZonesEditorSession.Files.LayoutTemplatesIOHelper.WriteData(layoutTemplates.Serialize(templateLayoutsListWrapper));
DefaultLayouts defaultLayouts = new DefaultLayouts();
FancyZonesEditorSession.Files.DefaultLayoutsIOHelper.WriteData(defaultLayouts.Serialize(DefaultLayouts));
LayoutHotkeys layoutHotkeys = new LayoutHotkeys();
FancyZonesEditorSession.Files.LayoutHotkeysIOHelper.WriteData(layoutHotkeys.Serialize(Hotkeys));
AppliedLayouts appliedLayouts = new AppliedLayouts();
AppliedLayouts.AppliedLayoutsListWrapper appliedLayoutsWrapper = new AppliedLayouts.AppliedLayoutsListWrapper
{
AppliedLayouts = new List<AppliedLayouts.AppliedLayoutWrapper> { },
};
FancyZonesEditorSession.Files.AppliedLayoutsIOHelper.WriteData(appliedLayouts.Serialize(appliedLayoutsWrapper));
_session = new FancyZonesEditorSession(_context!);
}
[TestCleanup]
public void TestCleanup()
{
_session?.Close();
FancyZonesEditorSession.Files.Restore();
}
[TestMethod]
public void CopyTemplate_FromEditLayoutWindow()
{
string copiedLayoutName = Constants.TemplateLayoutNames[Constants.TemplateLayouts.Focus] + " (1)";
_session?.ClickEditLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Focus]);
_session?.ClickCopyLayout();
// verify the layout is copied
Assert.IsNotNull(_session?.GetLayout(copiedLayoutName)); // new name is presented
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count + 1, data.CustomLayouts.Count);
Assert.IsTrue(data.CustomLayouts.Exists(x => x.Name == copiedLayoutName));
}
[TestMethod]
public void CopyTemplate_FromContextMenu()
{
string copiedLayoutName = Constants.TemplateLayoutNames[Constants.TemplateLayouts.Rows] + " (1)";
_session?.ClickContextMenuItem(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Rows], ElementName.CreateCustomLayout);
// verify the layout is copied
_session?.WaitElementDisplayedByName(copiedLayoutName);
Assert.IsNotNull(_session?.GetLayout(copiedLayoutName)); // new name is presented
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count + 1, data.CustomLayouts.Count);
Assert.IsTrue(data.CustomLayouts.Exists(x => x.Name == copiedLayoutName));
}
[TestMethod]
public void CopyTemplate_DefaultLayout()
{
string copiedLayoutName = Constants.TemplateLayoutNames[Constants.TemplateLayouts.PriorityGrid] + " (1)";
_session?.ClickEditLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.PriorityGrid]);
_session?.ClickCopyLayout();
// verify the layout is copied
_session?.Click(ElementName.Save);
Assert.IsNotNull(_session?.GetLayout(copiedLayoutName)); // new name is presented
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count + 1, data.CustomLayouts.Count);
// verify the default layout wasn't changed
_session?.ClickEditLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.PriorityGrid]);
var horizontalDefaultButton = _session?.GetHorizontalDefaultButton(true);
Assert.IsNotNull(horizontalDefaultButton);
_session?.Click(ElementName.Cancel);
_session?.ClickEditLayout(copiedLayoutName);
horizontalDefaultButton = _session?.GetHorizontalDefaultButton(false);
Assert.IsNotNull(horizontalDefaultButton);
_session?.Click(ElementName.Cancel);
// verify the default layouts file wasn't changed
var defaultLayouts = new DefaultLayouts();
var defaultLayoutData = defaultLayouts.Read(defaultLayouts.File);
Assert.AreEqual(defaultLayouts.Serialize(DefaultLayouts), defaultLayouts.Serialize(defaultLayoutData));
}
[TestMethod]
public void CopyCustomLayout_FromEditLayoutWindow()
{
string copiedLayoutName = CustomLayouts.CustomLayouts[0].Name + " (1)";
_session?.ClickEditLayout(CustomLayouts.CustomLayouts[0].Name);
_session?.ClickCopyLayout();
// verify the layout is copied
Assert.IsNotNull(_session?.GetLayout(copiedLayoutName)); // new name is presented
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count + 1, data.CustomLayouts.Count);
Assert.IsTrue(data.CustomLayouts.Exists(x => x.Name == copiedLayoutName));
}
[TestMethod]
public void CopyCustomLayout_FromContextMenu()
{
string copiedLayoutName = CustomLayouts.CustomLayouts[0].Name + " (1)";
_session?.ClickContextMenuItem(CustomLayouts.CustomLayouts[0].Name, ElementName.Duplicate);
// verify the layout is copied
_session?.WaitElementDisplayedByName(copiedLayoutName);
Assert.IsNotNull(_session?.GetLayout(copiedLayoutName)); // new name is presented
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count + 1, data.CustomLayouts.Count);
Assert.IsTrue(data.CustomLayouts.Exists(x => x.Name == copiedLayoutName));
}
[TestMethod]
public void CopyCustomLayout_DefaultLayout()
{
string copiedLayoutName = CustomLayouts.CustomLayouts[0].Name + " (1)";
_session?.ClickEditLayout(CustomLayouts.CustomLayouts[0].Name);
_session?.ClickCopyLayout();
// verify the layout is copied
_session?.Click(ElementName.Save);
Assert.IsNotNull(_session?.GetLayout(copiedLayoutName)); // new name is presented
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count + 1, data.CustomLayouts.Count);
// verify the default layout wasn't changed
_session?.ClickEditLayout(CustomLayouts.CustomLayouts[0].Name);
var horizontalDefaultButton = _session?.GetVerticalDefaultButton(true);
Assert.IsNotNull(horizontalDefaultButton);
_session?.Click(ElementName.Cancel);
_session?.ClickEditLayout(copiedLayoutName);
horizontalDefaultButton = _session?.GetVerticalDefaultButton(false);
Assert.IsNotNull(horizontalDefaultButton);
_session?.Click(ElementName.Cancel);
// verify the default layouts file wasn't changed
var defaultLayouts = new DefaultLayouts();
var defaultLayoutData = defaultLayouts.Read(defaultLayouts.File);
Assert.AreEqual(defaultLayouts.Serialize(DefaultLayouts), defaultLayouts.Serialize(defaultLayoutData));
}
[TestMethod]
public void CopyCustomLayout_Hotkey()
{
string copiedLayoutName = CustomLayouts.CustomLayouts[0].Name + " (1)";
_session?.ClickEditLayout(CustomLayouts.CustomLayouts[0].Name);
_session?.ClickCopyLayout();
// verify the layout is copied
_session?.Click(ElementName.Save);
Assert.IsNotNull(_session?.GetLayout(copiedLayoutName)); // new name is presented
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count + 1, data.CustomLayouts.Count);
// verify the hotkey wasn't changed
_session?.ClickEditLayout(CustomLayouts.CustomLayouts[0].Name);
var hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
Assert.AreEqual("0", hotkeyComboBox.Text);
_session?.Click(ElementName.Cancel);
_session?.ClickEditLayout(copiedLayoutName);
hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
Assert.AreEqual("None", hotkeyComboBox.Text);
_session?.Click(ElementName.Cancel);
// verify the hotkey file wasn't changed
var hotkeys = new LayoutHotkeys();
var hotkeyData = hotkeys.Read(hotkeys.File);
Assert.AreEqual(hotkeys.Serialize(Hotkeys), hotkeys.Serialize(hotkeyData));
}
}
}

View File

@@ -0,0 +1,252 @@
// 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.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class CreateLayoutTests
{
private static FancyZonesEditorSession? _session;
private static TestContext? _context;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
}
[ClassCleanup]
public static void ClassCleanup()
{
_context = null;
}
[TestInitialize]
public void TestInitialize()
{
// prepare test editor parameters with 2 monitors before launching the editor
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.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.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));
_session = new FancyZonesEditorSession(_context!);
}
[TestCleanup]
public void TestCleanup()
{
_session?.Close();
FancyZonesEditorSession.Files.Restore();
}
[TestMethod]
public void CreateWithDefaultName()
{
string name = "Custom layout 1";
_session?.Click(_session?.FindByAccessibilityId(AccessibilityId.NewLayoutButton));
_session?.ClickConfirm();
_session?.Click(ElementName.Save);
// verify new layout presented
Assert.IsNotNull(_session?.GetLayout(name));
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(1, data.CustomLayouts.Count);
Assert.IsTrue(data.CustomLayouts.Exists(x => x.Name == name));
}
[TestMethod]
public void CreateWithCustomName()
{
string name = "Layout Name";
_session?.Click(_session?.FindByAccessibilityId(AccessibilityId.NewLayoutButton));
var input = _session?.FindByClassName(ClassName.TextBox);
Assert.IsNotNull(input);
input.Clear();
input.SendKeys(name);
_session?.ClickConfirm();
_session?.Click(ElementName.Save);
// verify new layout presented
Assert.IsNotNull(_session?.GetLayout(name));
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(1, data.CustomLayouts.Count);
Assert.IsTrue(data.CustomLayouts.Exists(x => x.Name == name));
}
[TestMethod]
public void CreateGrid()
{
Constants.CustomLayoutType type = Constants.CustomLayoutType.Grid;
_session?.Click(_session?.FindByAccessibilityId(AccessibilityId.NewLayoutButton));
_session?.SelectNewLayoutType(type);
_session?.ClickConfirm();
_session?.Click(ElementName.Save);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(1, data.CustomLayouts.Count);
Assert.IsTrue(data.CustomLayouts.Exists(x => x.Type == Constants.CustomLayoutTypeNames[type]));
}
[TestMethod]
public void CreateCanvas()
{
Constants.CustomLayoutType type = Constants.CustomLayoutType.Canvas;
_session?.Click(_session?.FindByAccessibilityId(AccessibilityId.NewLayoutButton));
_session?.SelectNewLayoutType(type);
_session?.ClickConfirm();
_session?.Click(ElementName.Save);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(1, data.CustomLayouts.Count);
Assert.IsTrue(data.CustomLayouts.Exists(x => x.Type == Constants.CustomLayoutTypeNames[type]));
}
[TestMethod]
public void CancelGridCreation()
{
Constants.CustomLayoutType type = Constants.CustomLayoutType.Grid;
_session?.Click(_session?.FindByAccessibilityId(AccessibilityId.NewLayoutButton));
_session?.SelectNewLayoutType(type);
_session?.ClickConfirm();
_session?.Click(ElementName.Cancel);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(0, data.CustomLayouts.Count);
}
[TestMethod]
public void CancelCanvasCreation()
{
Constants.CustomLayoutType type = Constants.CustomLayoutType.Canvas;
_session?.Click(_session?.FindByAccessibilityId(AccessibilityId.NewLayoutButton));
_session?.SelectNewLayoutType(type);
_session?.ClickConfirm();
_session?.Click(ElementName.Cancel);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(0, data.CustomLayouts.Count);
}
}
}

View File

@@ -0,0 +1,468 @@
// 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.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using static FancyZonesEditorCommon.Data.CustomLayouts;
using static FancyZonesEditorCommon.Data.EditorParameters;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class CustomLayoutsTests
{
private static readonly CustomLayoutListWrapper Layouts = new CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayoutWrapper>
{
new CustomLayoutWrapper
{
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid],
Name = "Grid custom layout",
Info = new CustomLayouts().ToJsonElement(new GridInfoWrapper
{
Rows = 2,
Columns = 3,
RowsPercentage = new List<int> { 2967, 7033 },
ColumnsPercentage = new List<int> { 2410, 6040, 1550 },
CellChildMap = new int[][] { [0, 1, 1], [0, 2, 3] },
SensitivityRadius = 30,
Spacing = 26,
ShowSpacing = false,
}),
},
new CustomLayoutWrapper
{
Uuid = "{E7807D0D-6223-4883-B15B-1F3883944C09}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Canvas custom layout",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 952,
RefWidth = 1500,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper>
{
new CanvasInfoWrapper.CanvasZoneWrapper
{
X = 0,
Y = 0,
Width = 900,
Height = 522,
},
new CanvasInfoWrapper.CanvasZoneWrapper
{
X = 900,
Y = 0,
Width = 600,
Height = 750,
},
new CanvasInfoWrapper.CanvasZoneWrapper
{
X = 0,
Y = 522,
Width = 1500,
Height = 430,
},
},
}),
},
new CustomLayoutWrapper
{
Uuid = "{F1A94F38-82B6-4876-A653-70D0E882DE2A}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid],
Name = "Grid custom layout spacing enabled",
Info = new CustomLayouts().ToJsonElement(new GridInfoWrapper
{
Rows = 2,
Columns = 3,
RowsPercentage = new List<int> { 2967, 7033 },
ColumnsPercentage = new List<int> { 2410, 6040, 1550 },
CellChildMap = new int[][] { [0, 1, 1], [0, 2, 3] },
SensitivityRadius = 30,
Spacing = 10,
ShowSpacing = true,
}),
},
},
};
private static TestContext? _context;
private static FancyZonesEditorSession? _session;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
}
[ClassCleanup]
public static void ClassCleanup()
{
_context = null;
}
[TestInitialize]
public void TestInitialize()
{
CustomLayouts customLayouts = new CustomLayouts();
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(Layouts));
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new NativeMonitorDataWrapper
{
Monitor = "monitor-1",
MonitorInstanceId = "instance-id-1",
MonitorSerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 192,
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.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid],
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
};
FancyZonesEditorSession.Files.LayoutTemplatesIOHelper.WriteData(layoutTemplates.Serialize(templateLayoutsListWrapper));
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));
_session = new FancyZonesEditorSession(_context!);
}
[TestCleanup]
public void TestCleanup()
{
_session?.Close();
FancyZonesEditorSession.Files.Restore();
}
[TestMethod]
public void Name_Initialize()
{
// verify all custom layouts are presented
foreach (var layout in Layouts.CustomLayouts)
{
Assert.IsNotNull(_session?.GetLayout(layout.Name));
}
}
[TestMethod]
public void Rename_Save()
{
string newName = "New layout name";
var oldName = Layouts.CustomLayouts[0].Name;
// rename the layout
_session?.ClickEditLayout(oldName);
var input = _session?.FindByClassName(ClassName.TextBox);
Assert.IsNotNull(input);
input.Clear();
input.SendKeys(newName);
// verify new name
_session?.Click(ElementName.Save);
Assert.IsNull(_session?.GetLayout(oldName)); // previous name isn't presented
Assert.IsNotNull(_session?.GetLayout(newName)); // new name is presented
}
[TestMethod]
public void Rename_Cancel()
{
string newName = "New layout name";
var oldName = Layouts.CustomLayouts[0].Name;
// rename the layout
_session?.ClickEditLayout(oldName);
var input = _session?.FindByClassName(ClassName.TextBox);
Assert.IsNotNull(input);
input.Clear();
input.SendKeys(newName);
// verify new name
_session?.Click(ElementName.Cancel);
Assert.IsNotNull(_session?.GetLayout(oldName));
Assert.IsNull(_session?.GetLayout(newName));
}
[TestMethod]
public void HighlightDistance_Initialize()
{
foreach (var layout in Layouts.CustomLayouts)
{
_session?.ClickEditLayout(layout.Name);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SensitivitySlider);
Assert.IsNotNull(slider);
var expected = layout.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas] ?
new CustomLayouts().CanvasFromJsonElement(layout.Info.GetRawText()).SensitivityRadius :
new CustomLayouts().GridFromJsonElement(layout.Info.GetRawText()).SensitivityRadius;
Assert.AreEqual($"{expected}", slider.Text);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider);
}
}
[TestMethod]
public void HighlightDistance_Save()
{
var layout = Layouts.CustomLayouts[0];
var type = layout.Type;
_session?.ClickEditLayout(layout.Name);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SensitivitySlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Right);
var value = type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas] ?
new CustomLayouts().CanvasFromJsonElement(layout.Info.GetRawText()).SensitivityRadius :
new CustomLayouts().GridFromJsonElement(layout.Info.GetRawText()).SensitivityRadius;
var expected = value + 1; // one step right
Assert.AreEqual($"{expected}", slider.Text);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var actual = type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas] ?
new CustomLayouts().CanvasFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == layout.Uuid).Info.GetRawText()).SensitivityRadius :
new CustomLayouts().GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == layout.Uuid).Info.GetRawText()).SensitivityRadius;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void HighlightDistance_Cancel()
{
var layout = Layouts.CustomLayouts[0];
var type = layout.Type;
_session?.ClickEditLayout(layout.Name);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SensitivitySlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Right);
var expected = type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas] ?
new CustomLayouts().CanvasFromJsonElement(layout.Info.GetRawText()).SensitivityRadius :
new CustomLayouts().GridFromJsonElement(layout.Info.GetRawText()).SensitivityRadius;
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var actual = type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas] ?
new CustomLayouts().CanvasFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == layout.Uuid).Info.GetRawText()).SensitivityRadius :
new CustomLayouts().GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == layout.Uuid).Info.GetRawText()).SensitivityRadius;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void SpaceAroundZones_Initialize()
{
foreach (var layout in Layouts.CustomLayouts)
{
if (layout.Type != Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid])
{
// only for grid layouts
continue;
}
_session?.ClickEditLayout(layout.Name);
var toggle = _session?.FindByAccessibilityId(AccessibilityId.SpacingToggle);
Assert.IsNotNull(toggle);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider);
Assert.IsNotNull(slider);
var spacingEnabled = new CustomLayouts().GridFromJsonElement(layout.Info.GetRawText()).ShowSpacing;
Assert.AreEqual(spacingEnabled, slider.Enabled);
Assert.AreEqual(spacingEnabled, toggle.Selected);
var expected = new CustomLayouts().GridFromJsonElement(layout.Info.GetRawText()).Spacing;
Assert.AreEqual($"{expected}", slider.Text);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider); // let the dialog window close
}
}
[TestMethod]
public void SpaceAroundZones_Slider_Save()
{
var layout = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid] && new CustomLayouts().GridFromJsonElement(x.Info.GetRawText()).ShowSpacing);
var expected = new CustomLayouts().GridFromJsonElement(layout.Info.GetRawText()).Spacing + 1; // one step right
_session?.ClickEditLayout(layout.Name);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Right);
Assert.AreEqual($"{expected}", slider.Text);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var actual = new CustomLayouts().GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == layout.Uuid).Info.GetRawText()).Spacing;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void SpaceAroundZones_Slider_Cancel()
{
var layout = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid] && new CustomLayouts().GridFromJsonElement(x.Info.GetRawText()).ShowSpacing);
_session?.ClickEditLayout(layout.Name);
var expected = new CustomLayouts().GridFromJsonElement(layout.Info.GetRawText()).Spacing;
var slider = _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Right);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var actual = new CustomLayouts().GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == layout.Uuid).Info.GetRawText()).Spacing;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void SpaceAroundZones_Toggle_Save()
{
var layout = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid]);
var value = new CustomLayouts().GridFromJsonElement(layout.Info.GetRawText()).ShowSpacing;
var expected = !value;
_session?.ClickEditLayout(layout.Name);
var toggle = _session?.FindByAccessibilityId(AccessibilityId.SpacingToggle);
Assert.IsNotNull(toggle);
toggle.Click();
Assert.AreEqual(expected, toggle.Selected, "Toggle value not changed");
Assert.AreEqual(expected, _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider)?.Enabled);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(toggle); // let the dialog window close
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var actual = new CustomLayouts().GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == layout.Uuid).Info.GetRawText()).ShowSpacing;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void SpaceAroundZones_Toggle_Cancel()
{
var layout = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid]);
var expected = new CustomLayouts().GridFromJsonElement(layout.Info.GetRawText()).ShowSpacing;
_session?.ClickEditLayout(layout.Name);
var toggle = _session?.FindByAccessibilityId(AccessibilityId.SpacingToggle);
Assert.IsNotNull(toggle);
toggle.Click();
Assert.AreNotEqual(expected, toggle.Selected, "Toggle value not changed");
Assert.AreNotEqual(expected, _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider)?.Enabled);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(toggle); // let the dialog window close
// verify the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var actual = new CustomLayouts().GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == layout.Uuid).Info.GetRawText()).ShowSpacing;
Assert.AreEqual(expected, actual);
}
}
}

View File

@@ -0,0 +1,342 @@
// 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.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static FancyZonesEditorCommon.Data.CustomLayouts;
using static FancyZonesEditorCommon.Data.DefaultLayouts;
using static FancyZonesEditorCommon.Data.EditorParameters;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class DefaultLayoutsTests
{
private static readonly string Vertical = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Vertical);
private static readonly string Horizontal = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Horizontal);
private static readonly CustomLayoutListWrapper CustomLayouts = new CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayoutWrapper>
{
new CustomLayoutWrapper
{
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 0",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{E7807D0D-6223-4883-B15B-1F3883944C09}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 1",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{F1A94F38-82B6-4876-A653-70D0E882DE2A}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 2",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{F5FDBC04-0760-4776-9F05-96AAC4AE613F}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 3",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
},
};
private static readonly DefaultLayoutsListWrapper Layouts = new DefaultLayoutsListWrapper
{
DefaultLayouts = new List<DefaultLayoutWrapper>
{
new DefaultLayoutWrapper
{
MonitorConfiguration = Horizontal,
Layout = new DefaultLayoutWrapper.LayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = true,
Spacing = 5,
SensitivityRadius = 20,
},
},
new DefaultLayoutWrapper
{
MonitorConfiguration = Vertical,
Layout = new DefaultLayoutWrapper.LayoutWrapper
{
Type = "custom",
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
ZoneCount = 0,
ShowSpacing = false,
Spacing = 0,
SensitivityRadius = 0,
},
},
},
};
private static TestContext? _context;
private static FancyZonesEditorSession? _session;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
}
[ClassCleanup]
public static void ClassCleanup()
{
_context = null;
}
[TestInitialize]
public void TestInitialize()
{
var defaultLayouts = new DefaultLayouts();
FancyZonesEditorSession.Files.DefaultLayoutsIOHelper.WriteData(defaultLayouts.Serialize(Layouts));
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new NativeMonitorDataWrapper
{
Monitor = "monitor-1",
MonitorInstanceId = "instance-id-1",
MonitorSerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 192,
LeftCoordinate = 0,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
new NativeMonitorDataWrapper
{
Monitor = "monitor-2",
MonitorInstanceId = "instance-id-2",
MonitorSerialNumber = "serial-number-2",
MonitorNumber = 2,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 96,
LeftCoordinate = 1920,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
},
};
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
CustomLayouts customLayouts = new CustomLayouts();
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(CustomLayouts));
LayoutTemplates layoutTemplates = new LayoutTemplates();
LayoutTemplates.TemplateLayoutsListWrapper templateLayoutsListWrapper = new LayoutTemplates.TemplateLayoutsListWrapper
{
LayoutTemplates = new List<LayoutTemplates.TemplateLayoutWrapper>
{
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid],
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
};
FancyZonesEditorSession.Files.LayoutTemplatesIOHelper.WriteData(layoutTemplates.Serialize(templateLayoutsListWrapper));
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));
_session = new FancyZonesEditorSession(_context!);
}
[TestCleanup]
public void TestCleanup()
{
_session?.Close();
FancyZonesEditorSession.Files.Restore();
}
[TestMethod]
public void Initialize()
{
CheckTemplateLayouts(Constants.TemplateLayouts.Grid, null);
CheckCustomLayouts(string.Empty, CustomLayouts.CustomLayouts[0].Uuid);
}
[TestMethod]
public void Assign_Cancel()
{
// assign Focus as a default horizontal and vertical layout
_session?.ClickEditLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Focus]);
var horizontalDefaultButton = _session?.GetHorizontalDefaultButton(false);
horizontalDefaultButton?.Click();
var verticalDefaultButton = _session?.GetVerticalDefaultButton(false);
verticalDefaultButton?.Click();
// cancel
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(horizontalDefaultButton!);
// check that default layouts weren't changed
CheckTemplateLayouts(Constants.TemplateLayouts.Grid, null);
CheckCustomLayouts(string.Empty, CustomLayouts.CustomLayouts[0].Uuid);
}
[TestMethod]
public void Assign_Save()
{
// assign Focus as a default horizontal and vertical layout
_session?.ClickEditLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Focus]);
var horizontalDefaultButton = _session?.GetHorizontalDefaultButton(false);
horizontalDefaultButton?.Click();
var verticalDefaultButton = _session?.GetVerticalDefaultButton(false);
verticalDefaultButton?.Click();
// cancel
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(horizontalDefaultButton!);
// check that default layout was changed
CheckTemplateLayouts(Constants.TemplateLayouts.Focus, Constants.TemplateLayouts.Focus);
CheckCustomLayouts(string.Empty, string.Empty);
}
private void CheckTemplateLayouts(Constants.TemplateLayouts? horizontalDefault, Constants.TemplateLayouts? verticalDefault)
{
foreach (var (key, name) in Constants.TemplateLayoutNames)
{
if (key == Constants.TemplateLayouts.Empty)
{
continue;
}
_session?.ClickEditLayout(name);
bool isCheckedHorizontal = key == horizontalDefault;
bool isCheckedVertical = key == verticalDefault;
var horizontalDefaultButton = _session?.GetHorizontalDefaultButton(isCheckedHorizontal);
Assert.IsNotNull(horizontalDefaultButton, "Incorrect horizontal default layout set at " + name);
var verticalDefaultButton = _session?.GetVerticalDefaultButton(isCheckedVertical);
Assert.IsNotNull(verticalDefaultButton, "Incorrect vertical default layout set at " + name);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(horizontalDefaultButton!);
}
}
private void CheckCustomLayouts(string horizontalDefaultLayoutUuid, string verticalDefaultLayoutUuid)
{
foreach (var layout in CustomLayouts.CustomLayouts)
{
_session?.ClickEditLayout(layout.Name);
bool isCheckedHorizontal = layout.Uuid == horizontalDefaultLayoutUuid;
var horizontalDefaultButton = _session?.GetHorizontalDefaultButton(isCheckedHorizontal);
Assert.IsNotNull(horizontalDefaultButton, "Incorrect horizontal custom layout set at " + layout.Name);
bool isCheckedVertical = layout.Uuid == verticalDefaultLayoutUuid;
var verticalDefaultButton = _session?.GetVerticalDefaultButton(isCheckedVertical);
Assert.IsNotNull(verticalDefaultButton, "Incorrect vertical custom layout set at " + layout.Name);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(horizontalDefaultButton!);
}
}
}
}

View File

@@ -0,0 +1,371 @@
// 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.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static FancyZonesEditorCommon.Data.CustomLayouts;
using static FancyZonesEditorCommon.Data.DefaultLayouts;
using static FancyZonesEditorCommon.Data.EditorParameters;
using static FancyZonesEditorCommon.Data.LayoutHotkeys;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class DeleteLayoutTests
{
private static readonly CustomLayoutListWrapper CustomLayouts = new CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayoutWrapper>
{
new CustomLayoutWrapper
{
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid],
Name = "Custom layout 1",
Info = new CustomLayouts().ToJsonElement(new CustomLayouts.GridInfoWrapper
{
Rows = 2,
Columns = 3,
RowsPercentage = new List<int> { 2967, 7033 },
ColumnsPercentage = new List<int> { 2410, 6040, 1550 },
CellChildMap = new int[][] { [0, 1, 1], [0, 2, 3] },
SensitivityRadius = 30,
Spacing = 26,
ShowSpacing = false,
}),
},
new CustomLayoutWrapper
{
Uuid = "{E7807D0D-6223-4883-B15B-1F3883944C09}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Custom layout 2",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 952,
RefWidth = 1500,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper>
{
new CanvasInfoWrapper.CanvasZoneWrapper
{
X = 0,
Y = 0,
Width = 900,
Height = 522,
},
new CanvasInfoWrapper.CanvasZoneWrapper
{
X = 900,
Y = 0,
Width = 600,
Height = 750,
},
new CanvasInfoWrapper.CanvasZoneWrapper
{
X = 0,
Y = 522,
Width = 1500,
Height = 430,
},
},
}),
},
},
};
private static readonly DefaultLayouts.DefaultLayoutsListWrapper DefaultLayoutsList = new DefaultLayouts.DefaultLayoutsListWrapper
{
DefaultLayouts = new List<DefaultLayouts.DefaultLayoutWrapper>
{
new DefaultLayoutWrapper
{
MonitorConfiguration = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Horizontal),
Layout = new DefaultLayoutWrapper.LayoutWrapper
{
Type = Constants.CustomLayoutTypeString,
Uuid = CustomLayouts.CustomLayouts[1].Uuid,
},
},
},
};
private static readonly LayoutHotkeys.LayoutHotkeysWrapper Hotkeys = new LayoutHotkeys.LayoutHotkeysWrapper
{
LayoutHotkeys = new List<LayoutHotkeys.LayoutHotkeyWrapper>
{
new LayoutHotkeyWrapper
{
LayoutId = CustomLayouts.CustomLayouts[1].Uuid,
Key = 0,
},
},
};
private static readonly ParamsWrapper Parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new NativeMonitorDataWrapper
{
Monitor = "monitor-1",
MonitorInstanceId = "instance-id-1",
MonitorSerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 192,
LeftCoordinate = 0,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
},
};
private static TestContext? _context;
private static FancyZonesEditorSession? _session;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
}
[ClassCleanup]
public static void ClassCleanup()
{
_context = null;
}
[TestInitialize]
public void TestInitialize()
{
EditorParameters editorParameters = new EditorParameters();
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(Parameters));
CustomLayouts customLayouts = new CustomLayouts();
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(CustomLayouts));
LayoutTemplates layoutTemplates = new LayoutTemplates();
LayoutTemplates.TemplateLayoutsListWrapper templateLayoutsListWrapper = new LayoutTemplates.TemplateLayoutsListWrapper
{
LayoutTemplates = new List<LayoutTemplates.TemplateLayoutWrapper>
{
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid],
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
};
FancyZonesEditorSession.Files.LayoutTemplatesIOHelper.WriteData(layoutTemplates.Serialize(templateLayoutsListWrapper));
DefaultLayouts defaultLayouts = new DefaultLayouts();
FancyZonesEditorSession.Files.DefaultLayoutsIOHelper.WriteData(defaultLayouts.Serialize(DefaultLayoutsList));
LayoutHotkeys layoutHotkeys = new LayoutHotkeys();
FancyZonesEditorSession.Files.LayoutHotkeysIOHelper.WriteData(layoutHotkeys.Serialize(Hotkeys));
AppliedLayouts appliedLayouts = new AppliedLayouts();
AppliedLayouts.AppliedLayoutsListWrapper appliedLayoutsWrapper = new AppliedLayouts.AppliedLayoutsListWrapper
{
AppliedLayouts = new List<AppliedLayouts.AppliedLayoutWrapper> { },
};
FancyZonesEditorSession.Files.AppliedLayoutsIOHelper.WriteData(appliedLayouts.Serialize(appliedLayoutsWrapper));
_session = new FancyZonesEditorSession(_context!);
_session.Click(_session.GetLayout(CustomLayouts.CustomLayouts[0].Name)!);
}
[TestCleanup]
public void TestCleanup()
{
_session?.Close();
FancyZonesEditorSession.Files.Restore();
}
[TestMethod]
public void DeleteNotAppliedLayout()
{
var deletedLayout = CustomLayouts.CustomLayouts[1].Name;
_session?.ClickEditLayout(deletedLayout);
_session?.Click(_session.FindByAccessibilityId(AccessibilityId.DeleteLayoutButton));
_session?.ClickConfirmDialog();
_session?.WaitFor(1);
// verify the layout is removed
Assert.IsNull(_session?.GetLayout(deletedLayout));
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count - 1, data.CustomLayouts.Count);
Assert.IsFalse(data.CustomLayouts.Exists(x => x.Name == deletedLayout));
}
[TestMethod]
public void DeleteAppliedLayout()
{
var deletedLayout = CustomLayouts.CustomLayouts[0].Name;
_session?.ClickEditLayout(deletedLayout);
_session?.Click(_session.FindByAccessibilityId(AccessibilityId.DeleteLayoutButton));
_session?.ClickConfirmDialog();
_session?.WaitFor(1);
// verify the layout is removed
Assert.IsNull(_session?.GetLayout(deletedLayout));
// verify the empty layout is selected
Assert.IsTrue(_session?.GetLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Empty])!.Selected);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count - 1, data.CustomLayouts.Count);
Assert.IsFalse(data.CustomLayouts.Exists(x => x.Name == deletedLayout));
var appliedLayouts = new AppliedLayouts();
var appliedLayoutsData = appliedLayouts.Read(appliedLayouts.File);
Assert.AreEqual(Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Empty], appliedLayoutsData.AppliedLayouts.Find(x => x.Device.Monitor == Parameters.Monitors[0].Monitor).AppliedLayout.Type);
}
[TestMethod]
public void CancelDeletion()
{
var deletedLayout = CustomLayouts.CustomLayouts[1].Name;
_session?.ClickEditLayout(deletedLayout);
_session?.Click(_session.FindByAccessibilityId(AccessibilityId.DeleteLayoutButton));
_session?.ClickCancelDialog();
_session?.WaitFor(1);
// verify the layout is not removed
Assert.IsNotNull(_session?.GetLayout(deletedLayout));
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count, data.CustomLayouts.Count);
Assert.IsTrue(data.CustomLayouts.Exists(x => x.Name == deletedLayout));
}
[TestMethod]
public void DeleteFromContextMenu()
{
var deletedLayout = CustomLayouts.CustomLayouts[1].Name;
_session?.ClickContextMenuItem(deletedLayout, ElementName.Delete);
_session?.ClickConfirmDialog();
_session?.WaitFor(1);
// verify the layout is removed
Assert.IsNull(_session?.GetLayout(deletedLayout));
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
Assert.AreEqual(CustomLayouts.CustomLayouts.Count - 1, data.CustomLayouts.Count);
Assert.IsFalse(data.CustomLayouts.Exists(x => x.Name == deletedLayout));
}
[TestMethod]
public void DeleteDefaultLayout()
{
var deletedLayout = CustomLayouts.CustomLayouts[1].Name;
_session?.ClickContextMenuItem(deletedLayout, ElementName.Delete);
_session?.ClickConfirmDialog();
_session?.WaitFor(1);
// verify the default layout is reset to the "default" default
_session?.ClickEditLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.PriorityGrid]);
Assert.IsNotNull(_session?.GetHorizontalDefaultButton(true));
_session?.Click(ElementName.Cancel);
// check the file
var defaultLayouts = new DefaultLayouts();
var data = defaultLayouts.Read(defaultLayouts.File);
string configuration = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Horizontal);
Assert.AreEqual(Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid], data.DefaultLayouts.Find(x => x.MonitorConfiguration == configuration).Layout.Type);
}
[TestMethod]
public void DeleteLayoutWithHotkey()
{
var deletedLayout = CustomLayouts.CustomLayouts[1].Name;
_session?.ClickContextMenuItem(deletedLayout, ElementName.Delete);
_session?.ClickConfirmDialog();
_session?.WaitFor(1);
// verify the hotkey is available
_session?.ClickEditLayout(CustomLayouts.CustomLayouts[0].Name);
var hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
var popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
try
{
for (int i = 0; i < 10; i++)
{
popup.FindElementByName($"{i}");
}
}
catch
{
_session?.Click(ElementName.Cancel);
Assert.Fail("Hotkey not found");
}
_session?.Click(ElementName.Cancel);
// check the file
var hotkeys = new LayoutHotkeys();
var data = hotkeys.Read(hotkeys.File);
Assert.AreEqual(0, data.LayoutHotkeys.Count);
}
}
}

View File

@@ -0,0 +1,608 @@
// 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.Linq;
using FancyZonesEditorCommon.Data;
using Microsoft.FancyZonesEditor.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium.Windows;
using static FancyZonesEditorCommon.Data.CustomLayouts;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class EditLayoutTests
{
private static readonly CustomLayouts.CustomLayoutListWrapper Layouts = new CustomLayouts.CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayouts.CustomLayoutWrapper>
{
new CustomLayoutWrapper
{
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid],
Name = "Grid custom layout",
Info = new CustomLayouts().ToJsonElement(new GridInfoWrapper
{
Rows = 2,
Columns = 2,
RowsPercentage = new List<int> { 5000, 5000 },
ColumnsPercentage = new List<int> { 5000, 5000 },
CellChildMap = new int[][] { [0, 1], [2, 3] },
SensitivityRadius = 30,
Spacing = 26,
ShowSpacing = false,
}),
},
new CustomLayoutWrapper
{
Uuid = "{0EB9BF3E-010E-46D7-8681-1879D1E111E1}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid],
Name = "Grid-9",
Info = new CustomLayouts().ToJsonElement(new GridInfoWrapper
{
Rows = 3,
Columns = 3,
RowsPercentage = new List<int> { 3333, 3333, 3334 },
ColumnsPercentage = new List<int> { 3333, 3333, 3334 },
CellChildMap = new int[][] { [0, 1, 2], [3, 4, 5], [6, 7, 8] },
SensitivityRadius = 20,
Spacing = 3,
ShowSpacing = false,
}),
},
new CustomLayoutWrapper
{
Uuid = "{E7807D0D-6223-4883-B15B-1F3883944C09}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Canvas custom layout",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 952,
RefWidth = 1500,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper>
{
new CanvasInfoWrapper.CanvasZoneWrapper
{
X = 0,
Y = 0,
Width = 900,
Height = 522,
},
new CanvasInfoWrapper.CanvasZoneWrapper
{
X = 900,
Y = 0,
Width = 600,
Height = 750,
},
new CanvasInfoWrapper.CanvasZoneWrapper
{
X = 0,
Y = 522,
Width = 1500,
Height = 430,
},
},
}),
},
},
};
private static TestContext? _context;
private static FancyZonesEditorSession? _session;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
}
[ClassCleanup]
public static void ClassCleanup()
{
_context = null;
}
[TestInitialize]
public void TestInitialize()
{
LayoutTemplates layoutTemplates = new LayoutTemplates();
LayoutTemplates.TemplateLayoutsListWrapper templateLayoutsListWrapper = new LayoutTemplates.TemplateLayoutsListWrapper
{
LayoutTemplates = new List<LayoutTemplates.TemplateLayoutWrapper>
{
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid],
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
};
FancyZonesEditorSession.Files.LayoutTemplatesIOHelper.WriteData(layoutTemplates.Serialize(templateLayoutsListWrapper));
CustomLayouts customLayouts = new CustomLayouts();
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(Layouts));
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));
_session = new FancyZonesEditorSession(_context!);
}
[TestCleanup]
public void TestCleanup()
{
_session?.Close();
FancyZonesEditorSession.Files.Restore();
}
[TestMethod]
public void OpenEditMode()
{
_session?.ClickEditLayout(Layouts.CustomLayouts[0].Name);
_session?.Click(_session?.FindByAccessibilityId(AccessibilityId.EditZonesButton));
Assert.IsNotNull(_session?.FindByName(ElementName.GridLayoutEditor));
_session?.Click(ElementName.Cancel);
}
[TestMethod]
public void OpenEditModeFromContextMenu()
{
_session?.ClickContextMenuItem(Layouts.CustomLayouts[0].Name, FancyZonesEditorSession.ElementName.EditZones);
Assert.IsNotNull(_session?.FindByName(ElementName.GridLayoutEditor));
_session?.Click(ElementName.Cancel);
}
[TestMethod]
public void Canvas_AddZone_Save()
{
var canvas = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas]);
_session?.ClickContextMenuItem(canvas.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.Click(_session?.FindByAccessibilityId(AccessibilityId.NewZoneButton));
_session?.Click(ElementName.Save);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.CanvasFromJsonElement(canvas.Info.ToString());
var actual = customLayouts.CanvasFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == canvas.Uuid).Info.GetRawText());
Assert.AreEqual(expected.Zones.Count + 1, actual.Zones.Count);
}
[TestMethod]
public void Canvas_AddZone_Cancel()
{
var canvas = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas]);
_session?.ClickContextMenuItem(canvas.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.Click(_session?.FindByAccessibilityId(AccessibilityId.NewZoneButton));
_session?.Click(ElementName.Cancel);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.CanvasFromJsonElement(canvas.Info.ToString());
var actual = customLayouts.CanvasFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == canvas.Uuid).Info.GetRawText());
Assert.AreEqual(expected.Zones.Count, actual.Zones.Count);
}
[TestMethod]
public void Canvas_DeleteZone_Save()
{
var canvas = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas]);
_session?.ClickContextMenuItem(canvas.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.WaitElementDisplayedByName(FancyZonesEditorSession.ElementName.CanvasEditorWindow);
_session?.ClickDeleteZone(1);
_session?.Click(ElementName.Save);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.CanvasFromJsonElement(canvas.Info.ToString());
var actual = customLayouts.CanvasFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == canvas.Uuid).Info.GetRawText());
Assert.AreEqual(expected.Zones.Count - 1, actual.Zones.Count);
}
[TestMethod]
public void Canvas_DeleteZone_Cancel()
{
var canvas = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas]);
_session?.ClickContextMenuItem(canvas.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.ClickDeleteZone(1);
_session?.Click(ElementName.Cancel);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.CanvasFromJsonElement(canvas.Info.ToString());
var actual = customLayouts.CanvasFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == canvas.Uuid).Info.GetRawText());
Assert.AreEqual(expected.Zones.Count, actual.Zones.Count);
}
[TestMethod]
public void Canvas_MoveZone_Save()
{
int zoneNumber = 1;
int xOffset = 100;
int yOffset = 100;
var canvas = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas]);
_session?.ClickContextMenuItem(canvas.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.Drag(_session.GetZone(zoneNumber, FancyZonesEditorSession.ClassName.CanvasZone)!, xOffset, yOffset);
_session?.Click(ElementName.Save);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.CanvasFromJsonElement(canvas.Info.ToString());
var actual = customLayouts.CanvasFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == canvas.Uuid).Info.GetRawText());
// changed zone, exact offset may vary depending on screen resolution
Assert.IsTrue(expected.Zones[zoneNumber - 1].X < actual.Zones[zoneNumber - 1].X, $"X: {expected.Zones[zoneNumber - 1].X} > {actual.Zones[zoneNumber - 1].X}");
Assert.IsTrue(expected.Zones[zoneNumber - 1].Y < actual.Zones[zoneNumber - 1].Y, $"Y: {expected.Zones[zoneNumber - 1].Y} > {actual.Zones[zoneNumber - 1].Y}");
Assert.AreEqual(expected.Zones[zoneNumber - 1].Width, actual.Zones[zoneNumber - 1].Width);
Assert.AreEqual(expected.Zones[zoneNumber - 1].Height, actual.Zones[zoneNumber - 1].Height);
// other zones
for (int i = 0; i < expected.Zones.Count; i++)
{
if (i != zoneNumber - 1)
{
Assert.AreEqual(expected.Zones[i].X, actual.Zones[i].X);
Assert.AreEqual(expected.Zones[i].Y, actual.Zones[i].Y);
Assert.AreEqual(expected.Zones[i].Width, actual.Zones[i].Width);
Assert.AreEqual(expected.Zones[i].Height, actual.Zones[i].Height);
}
}
}
[TestMethod]
public void Canvas_MoveZone_Cancel()
{
int zoneNumber = 1;
var canvas = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas]);
_session?.ClickContextMenuItem(canvas.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.Drag(_session.GetZone(zoneNumber, FancyZonesEditorSession.ClassName.CanvasZone)!, 100, 100);
_session?.Click(ElementName.Cancel);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.CanvasFromJsonElement(canvas.Info.ToString());
var actual = customLayouts.CanvasFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == canvas.Uuid).Info.GetRawText());
for (int i = 0; i < expected.Zones.Count; i++)
{
Assert.AreEqual(expected.Zones[i].X, actual.Zones[i].X);
Assert.AreEqual(expected.Zones[i].Y, actual.Zones[i].Y);
Assert.AreEqual(expected.Zones[i].Width, actual.Zones[i].Width);
Assert.AreEqual(expected.Zones[i].Height, actual.Zones[i].Height);
}
}
[TestMethod]
public void Canvas_ResizeZone_Save()
{
int zoneNumber = 1;
int xOffset = 100;
int yOffset = 100;
var canvas = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas]);
_session?.ClickContextMenuItem(canvas.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.Drag((WindowsElement)_session.GetZone(zoneNumber, FancyZonesEditorSession.ClassName.CanvasZone)?.FindElementByAccessibilityId(FancyZonesEditorSession.AccessibilityId.TopRightCorner)!, xOffset, yOffset);
_session?.Click(ElementName.Save);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.CanvasFromJsonElement(canvas.Info.ToString());
var actual = customLayouts.CanvasFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == canvas.Uuid).Info.GetRawText());
// changed zone, exact offset may vary depending on screen resolution
Assert.AreEqual(expected.Zones[zoneNumber - 1].X, actual.Zones[zoneNumber - 1].X);
Assert.IsTrue(expected.Zones[zoneNumber - 1].Y < actual.Zones[zoneNumber - 1].Y, $"Y: {expected.Zones[zoneNumber - 1].Y} > {actual.Zones[zoneNumber - 1].Y}");
Assert.IsTrue(expected.Zones[zoneNumber - 1].Width < actual.Zones[zoneNumber - 1].Width, $"Width: {expected.Zones[zoneNumber - 1].Width} < {actual.Zones[zoneNumber - 1].Width}");
Assert.IsTrue(expected.Zones[zoneNumber - 1].Height > actual.Zones[zoneNumber - 1].Height, $"Height: {expected.Zones[zoneNumber - 1].Height} < {actual.Zones[zoneNumber - 1].Height}");
// other zones
for (int i = 0; i < expected.Zones.Count; i++)
{
if (i != zoneNumber - 1)
{
Assert.AreEqual(expected.Zones[i].X, actual.Zones[i].X);
Assert.AreEqual(expected.Zones[i].Y, actual.Zones[i].Y);
Assert.AreEqual(expected.Zones[i].Width, actual.Zones[i].Width);
Assert.AreEqual(expected.Zones[i].Height, actual.Zones[i].Height);
}
}
}
[TestMethod]
public void Canvas_ResizeZone_Cancel()
{
int zoneNumber = 1;
int xOffset = 100;
int yOffset = 100;
var canvas = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas]);
_session?.ClickContextMenuItem(canvas.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.Drag((WindowsElement)_session.GetZone(zoneNumber, FancyZonesEditorSession.ClassName.CanvasZone)?.FindElementByAccessibilityId(FancyZonesEditorSession.AccessibilityId.TopRightCorner)!, xOffset, yOffset);
_session?.Click(ElementName.Cancel);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.CanvasFromJsonElement(canvas.Info.ToString());
var actual = customLayouts.CanvasFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == canvas.Uuid).Info.GetRawText());
for (int i = 0; i < expected.Zones.Count; i++)
{
Assert.AreEqual(expected.Zones[i].X, actual.Zones[i].X);
Assert.AreEqual(expected.Zones[i].Y, actual.Zones[i].Y);
Assert.AreEqual(expected.Zones[i].Width, actual.Zones[i].Width);
Assert.AreEqual(expected.Zones[i].Height, actual.Zones[i].Height);
}
}
[TestMethod]
public void Grid_SplitZone_Save()
{
int zoneNumber = 1;
var grid = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid]);
_session?.ClickContextMenuItem(grid.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.GetZone(zoneNumber, FancyZonesEditorSession.ClassName.GridZone)!.Click(); // horizontal split in the middle of the zone
_session?.Click(ElementName.Save);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.GridFromJsonElement(grid.Info.ToString());
var actual = customLayouts.GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == grid.Uuid).Info.GetRawText());
// new column added
Assert.AreEqual(expected.Columns + 1, actual.Columns);
Assert.AreEqual(expected.ColumnsPercentage[0], actual.ColumnsPercentage[0] + actual.ColumnsPercentage[1]);
Assert.AreEqual(expected.ColumnsPercentage[1], actual.ColumnsPercentage[2]);
// rows are not changed
Assert.AreEqual(expected.Rows, actual.Rows);
for (int i = 0; i < expected.Rows; i++)
{
Assert.AreEqual(expected.RowsPercentage[i], actual.RowsPercentage[i]);
}
}
[TestMethod]
public void Grid_SplitZone_Cancel()
{
int zoneNumber = 1;
var grid = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid]);
_session?.ClickContextMenuItem(grid.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.GetZone(zoneNumber, FancyZonesEditorSession.ClassName.GridZone)!.Click(); // horizontal split in the middle of the zone
_session?.Click(ElementName.Cancel);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.GridFromJsonElement(grid.Info.ToString());
var actual = customLayouts.GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == grid.Uuid).Info.GetRawText());
// columns are not changed
Assert.AreEqual(expected.Columns, actual.Columns);
for (int i = 0; i < expected.Columns; i++)
{
Assert.AreEqual(expected.ColumnsPercentage[i], actual.ColumnsPercentage[i]);
}
// rows are not changed
Assert.AreEqual(expected.Rows, actual.Rows);
for (int i = 0; i < expected.Rows; i++)
{
Assert.AreEqual(expected.RowsPercentage[i], actual.RowsPercentage[i]);
}
}
[TestMethod]
public void Grid_MergeZones_Save()
{
var grid = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid]);
_session?.ClickContextMenuItem(grid.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.MergeGridZones(1, 2);
_session?.Click(ElementName.Save);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.GridFromJsonElement(grid.Info.ToString());
var actual = customLayouts.GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == grid.Uuid).Info.GetRawText());
// columns are not changed
Assert.AreEqual(expected.Columns, actual.Columns);
for (int i = 0; i < expected.Columns; i++)
{
Assert.AreEqual(expected.ColumnsPercentage[i], actual.ColumnsPercentage[i]);
}
// rows are not changed
Assert.AreEqual(expected.Rows, actual.Rows);
for (int i = 0; i < expected.Rows; i++)
{
Assert.AreEqual(expected.RowsPercentage[i], actual.RowsPercentage[i]);
}
// cells are updated to [0,0][1,2]
Assert.IsTrue(actual.CellChildMap[0].SequenceEqual([0, 0]));
Assert.IsTrue(actual.CellChildMap[1].SequenceEqual([1, 2]));
}
[TestMethod]
public void Grid_MergeZones_Cancel()
{
var grid = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid]);
_session?.ClickContextMenuItem(grid.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.MergeGridZones(1, 2);
_session?.Click(ElementName.Cancel);
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.GridFromJsonElement(grid.Info.ToString());
var actual = customLayouts.GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == grid.Uuid).Info.GetRawText());
// columns are not changed
Assert.AreEqual(expected.Columns, actual.Columns);
for (int i = 0; i < expected.Columns; i++)
{
Assert.AreEqual(expected.ColumnsPercentage[i], actual.ColumnsPercentage[i]);
}
// rows are not changed
Assert.AreEqual(expected.Rows, actual.Rows);
for (int i = 0; i < expected.Rows; i++)
{
Assert.AreEqual(expected.RowsPercentage[i], actual.RowsPercentage[i]);
}
// cells are not changed
for (int i = 0; i < expected.CellChildMap.Length; i++)
{
Assert.IsTrue(actual.CellChildMap[i].SequenceEqual(expected.CellChildMap[i]));
}
}
[TestMethod]
public void Grid_MoveSplitter_Save()
{
var grid = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid] && x.Name == "Grid-9");
_session?.ClickContextMenuItem(grid.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.MoveSplitter(0, -100);
_session?.Click(ElementName.Save);
_session?.Click(ElementName.Save); // single click doesn't work after moving a splitter
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.GridFromJsonElement(grid.Info.ToString());
var actual = customLayouts.GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == grid.Uuid).Info.GetRawText());
// columns are not changed
Assert.AreEqual(expected.Columns, actual.Columns);
for (int i = 0; i < expected.Columns; i++)
{
Assert.AreEqual(expected.ColumnsPercentage[i], actual.ColumnsPercentage[i]);
}
// rows are changed
Assert.AreEqual(expected.Rows, actual.Rows);
Assert.IsTrue(expected.RowsPercentage[0] > actual.RowsPercentage[0]);
Assert.IsTrue(expected.RowsPercentage[1] < actual.RowsPercentage[1]);
Assert.AreEqual(expected.RowsPercentage[2], actual.RowsPercentage[2]);
// cells are not changed
for (int i = 0; i < expected.CellChildMap.Length; i++)
{
Assert.IsTrue(actual.CellChildMap[i].SequenceEqual(expected.CellChildMap[i]));
}
}
[TestMethod]
public void Grid_MoveSplitter_Cancel()
{
var grid = Layouts.CustomLayouts.Find(x => x.Type == Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Grid] && x.Name == "Grid-9");
_session?.ClickContextMenuItem(grid.Name, FancyZonesEditorSession.ElementName.EditZones);
_session?.MoveSplitter(0, -100);
_session?.Click(ElementName.Cancel);
_session?.Click(ElementName.Cancel); // single click doesn't work after moving a splitter
// check the file
var customLayouts = new CustomLayouts();
var data = customLayouts.Read(customLayouts.File);
var expected = customLayouts.GridFromJsonElement(grid.Info.ToString());
var actual = customLayouts.GridFromJsonElement(data.CustomLayouts.Find(x => x.Uuid == grid.Uuid).Info.GetRawText());
// columns are not changed
Assert.AreEqual(expected.Columns, actual.Columns);
for (int i = 0; i < expected.Columns; i++)
{
Assert.AreEqual(expected.ColumnsPercentage[i], actual.ColumnsPercentage[i]);
}
// rows are not changed
Assert.AreEqual(expected.Rows, actual.Rows);
for (int i = 0; i < expected.Rows; i++)
{
Assert.AreEqual(expected.RowsPercentage[i], actual.RowsPercentage[i]);
}
// cells are not changed
for (int i = 0; i < expected.CellChildMap.Length; i++)
{
Assert.IsTrue(actual.CellChildMap[i].SequenceEqual(expected.CellChildMap[i]));
}
}
}
}

View File

@@ -0,0 +1,45 @@
// 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 Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class Init
{
private static Process? appDriver;
[AssemblyInitialize]
public static void SetupAll(TestContext context)
{
string? sourceDirPath = Environment.GetEnvironmentVariable("SrcPath"); // get source dir in CI
if (sourceDirPath == null)
{
sourceDirPath = Path.GetFullPath($"{Environment.CurrentDirectory}" + @".\..\..\..\..\..\"); // local
}
context.WriteLine($"Source dir: {sourceDirPath}");
string winAppDriver = Path.Combine(sourceDirPath, @".\deps\WinAppDriver", "WinAppDriver.exe");
context.WriteLine($"Attempting to launch WinAppDriver at: {winAppDriver}");
appDriver = Process.Start(winAppDriver);
}
[AssemblyCleanup]
public static void CleanupAll()
{
try
{
appDriver?.Kill();
}
catch
{
}
}
}
}

View File

@@ -0,0 +1,600 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using FancyZonesEditorCommon.Data;
using Microsoft.FancyZonesEditor.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static FancyZonesEditorCommon.Data.CustomLayouts;
using static FancyZonesEditorCommon.Data.EditorParameters;
using static FancyZonesEditorCommon.Data.LayoutHotkeys;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class LayoutHotkeysTests
{
private static readonly CustomLayoutListWrapper CustomLayouts = new CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayoutWrapper>
{
new CustomLayoutWrapper
{
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 0",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{E7807D0D-6223-4883-B15B-1F3883944C09}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 1",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{F1A94F38-82B6-4876-A653-70D0E882DE2A}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 2",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{F5FDBC04-0760-4776-9F05-96AAC4AE613F}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 3",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{1CDB1CC5-51B1-4E49-9C8C-B7A371CCB489}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 4",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{B1F600A5-9C2B-44C1-BF96-42D39E9DC004}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 5",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{DFBE08C3-7C34-482B-811F-C7DBFE368A96}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 6",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{4DB29206-24CE-421C-BFF4-35987D1A744B}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 7",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{51E1BBBA-1C6F-4E3C-85A2-4BFBAE154963}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 8",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{61F9E568-DB74-44FF-8AA8-4093E80D9BCF}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 9",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
new CustomLayoutWrapper
{
Uuid = "{8D328880-9E16-4CA8-B4A3-F6AE1C762CD5}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 10",
Info = new CustomLayouts().ToJsonElement(new CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
},
};
private static readonly LayoutHotkeysWrapper Hotkeys = new LayoutHotkeysWrapper
{
LayoutHotkeys = new List<LayoutHotkeyWrapper>
{
new LayoutHotkeyWrapper
{
LayoutId = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
Key = 0,
},
new LayoutHotkeyWrapper
{
LayoutId = "{E7807D0D-6223-4883-B15B-1F3883944C09}",
Key = 1,
},
},
};
private static TestContext? _context;
private static FancyZonesEditorSession? _session;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
}
[ClassCleanup]
public static void ClassCleanup()
{
_context = null;
}
[TestInitialize]
public void TestInitialize()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new NativeMonitorDataWrapper
{
Monitor = "monitor-1",
MonitorInstanceId = "instance-id-1",
MonitorSerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 192,
LeftCoordinate = 0,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
},
};
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
CustomLayouts customLayouts = new CustomLayouts();
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(CustomLayouts));
var layoutHotkeys = new LayoutHotkeys();
FancyZonesEditorSession.Files.LayoutHotkeysIOHelper.WriteData(layoutHotkeys.Serialize(Hotkeys));
LayoutTemplates layoutTemplates = new LayoutTemplates();
LayoutTemplates.TemplateLayoutsListWrapper templateLayoutsListWrapper = new LayoutTemplates.TemplateLayoutsListWrapper
{
LayoutTemplates = new List<LayoutTemplates.TemplateLayoutWrapper>
{
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid],
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
};
FancyZonesEditorSession.Files.LayoutTemplatesIOHelper.WriteData(layoutTemplates.Serialize(templateLayoutsListWrapper));
DefaultLayouts defaultLayouts = new DefaultLayouts();
DefaultLayouts.DefaultLayoutsListWrapper defaultLayoutsListWrapper = new DefaultLayouts.DefaultLayoutsListWrapper
{
DefaultLayouts = new List<DefaultLayouts.DefaultLayoutWrapper> { },
};
FancyZonesEditorSession.Files.DefaultLayoutsIOHelper.WriteData(defaultLayouts.Serialize(defaultLayoutsListWrapper));
AppliedLayouts appliedLayouts = new AppliedLayouts();
AppliedLayouts.AppliedLayoutsListWrapper appliedLayoutsWrapper = new AppliedLayouts.AppliedLayoutsListWrapper
{
AppliedLayouts = new List<AppliedLayouts.AppliedLayoutWrapper> { },
};
FancyZonesEditorSession.Files.AppliedLayoutsIOHelper.WriteData(appliedLayouts.Serialize(appliedLayoutsWrapper));
try
{
_session = new FancyZonesEditorSession(_context!);
}
catch (Exception ex)
{
_context?.WriteLine("Unable to start session. " + ex.Message);
}
}
[TestCleanup]
public void TestCleanup()
{
try
{
_session?.Click(ElementName.Cancel); // in case if test has failed
}
catch
{
}
_session?.Close();
FancyZonesEditorSession.Files.Restore();
}
[TestMethod]
public void Initialize()
{
foreach (var layout in CustomLayouts.CustomLayouts)
{
_session?.ClickEditLayout(layout.Name);
var hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
// verify the selected key
string expected = "None";
if (Hotkeys.LayoutHotkeys.Any(x => x.LayoutId == layout.Uuid))
{
expected = $"{Hotkeys.LayoutHotkeys.Find(x => x.LayoutId == layout.Uuid).Key}";
}
Assert.AreEqual($"{expected}", hotkeyComboBox.Text);
// verify the available values
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
var popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup, "Hotkey combo box wasn't opened");
try
{
popup.FindElementByName(expected); // the current value should be available
// 0 and 1 are assigned, all others should be available
for (int i = 2; i < 10; i++)
{
popup.FindElementByName($"{i}");
}
}
catch
{
Assert.Fail("Hotkey is missed");
}
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(hotkeyComboBox); // let the dialog window close
}
}
[TestMethod]
public void Assign_Save()
{
var layout = CustomLayouts.CustomLayouts[4]; // a layout without assigned hotkey
_session?.ClickEditLayout(layout.Name);
// assign hotkey
const string key = "3";
var hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
var popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
_session?.Click(popup.FindElementByName($"{key}")!); // assign a free hotkey
Assert.AreEqual(key, hotkeyComboBox.Text);
// verify the file
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(hotkeyComboBox); // let the dialog window close
var hotkeys = new LayoutHotkeys();
var actualData = hotkeys.Read(hotkeys.File);
Assert.IsTrue(actualData.LayoutHotkeys.Contains(new LayoutHotkeyWrapper { Key = int.Parse(key, CultureInfo.InvariantCulture), LayoutId = layout.Uuid }));
// verify the availability
_session?.ClickEditLayout(CustomLayouts.CustomLayouts[5].Name);
hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
try
{
popup.FindElementByName($"{key}"); // verify the key is not available
Assert.Fail(key, "The assigned key is still available for other layouts.");
}
catch
{
// key not found as expected
}
}
[TestMethod]
public void Assign_Cancel()
{
var layout = CustomLayouts.CustomLayouts[4]; // a layout without assigned hotkey
_session?.ClickEditLayout(layout.Name);
// assign a hotkey
const string key = "3";
var hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
var popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
_session?.Click(popup.FindElementByName($"{key}")!);
Assert.AreEqual(key, hotkeyComboBox.Text);
// verify the file
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(hotkeyComboBox); // let the dialog window close
var hotkeys = new LayoutHotkeys();
var actualData = hotkeys.Read(hotkeys.File);
Assert.AreEqual(Hotkeys.ToString(), actualData.ToString());
// verify the availability
_session?.ClickEditLayout(CustomLayouts.CustomLayouts[5].Name);
hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
try
{
popup.FindElementByName($"{key}"); // verify the key is available
}
catch
{
Assert.Fail("The key is not available for other layouts.");
}
}
[TestMethod]
public void Assign_AllPossibleValues()
{
for (int i = 0; i < 10; i++)
{
string layoutName = $"Layout {i}";
_session?.ClickEditLayout(layoutName);
var hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
var popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
_session?.Click(popup.FindElementByName($"{i}")!);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(hotkeyComboBox); // let the dialog window close
}
// check there nothing except None
{
int layout = 10;
string layoutName = $"Layout {layout}";
_session?.ClickEditLayout(layoutName);
var hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
var popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
for (int i = 0; i < 10; i++)
{
try
{
popup.FindElementByName($"{i}");
Assert.Fail("The assigned key is still available for other layouts.");
}
catch
{
}
}
_session?.Click(popup.FindElementByName($"None")!);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(hotkeyComboBox); // let the dialog window close
}
}
[TestMethod]
public void Reset_Save()
{
var layout = CustomLayouts.CustomLayouts[0]; // a layout with assigned hotkey
int assignedKey = Hotkeys.LayoutHotkeys.Find(x => x.LayoutId == layout.Uuid).Key;
_session?.ClickEditLayout(layout.Name);
const string None = "None";
// reset the hotkey
var hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
var popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
_session?.Click(popup.FindElementByName(None)!);
Assert.AreEqual(None, hotkeyComboBox.Text);
// verify the file
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(hotkeyComboBox); // let the dialog window close
var hotkeys = new LayoutHotkeys();
var actualData = hotkeys.Read(hotkeys.File);
Assert.IsFalse(actualData.LayoutHotkeys.Contains(new LayoutHotkeyWrapper { Key = assignedKey, LayoutId = layout.Uuid }));
// verify the previously assigned key is available
_session?.ClickEditLayout(CustomLayouts.CustomLayouts[6].Name);
hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
try
{
popup.FindElementByName($"{assignedKey}"); // verify the key is available
}
catch
{
Assert.Fail("The key is not available for other layouts.");
}
}
[TestMethod]
public void Reset_Cancel()
{
var layout = CustomLayouts.CustomLayouts[0]; // a layout with assigned hotkey
int assignedKey = Hotkeys.LayoutHotkeys.Find(x => x.LayoutId == layout.Uuid).Key;
_session?.ClickEditLayout(layout.Name);
const string None = "None";
// assign hotkey
var hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
var popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
_session?.Click(popup.FindElementByName(None)!); // reset the hotkey
Assert.AreEqual(None, hotkeyComboBox.Text);
// verify the file
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(hotkeyComboBox); // let the dialog window close
var hotkeys = new LayoutHotkeys();
var actualData = hotkeys.Read(hotkeys.File);
Assert.IsTrue(actualData.LayoutHotkeys.Contains(new LayoutHotkeyWrapper { Key = assignedKey, LayoutId = layout.Uuid }));
// verify the previously assigned key is not available
_session?.ClickEditLayout(CustomLayouts.CustomLayouts[6].Name);
hotkeyComboBox = _session?.FindByAccessibilityId(AccessibilityId.HotkeyComboBox);
Assert.IsNotNull(hotkeyComboBox);
hotkeyComboBox.Click();
_session?.WaitElementDisplayedByClassName(ClassName.Popup);
popup = _session?.FindByClassName(ClassName.Popup);
Assert.IsNotNull(popup);
try
{
popup.FindElementByName($"{assignedKey}"); // verify the key is not available
Assert.Fail("The key is still available for other layouts.");
}
catch
{
// the key is not available as expected
}
}
}
}

View File

@@ -0,0 +1,238 @@
// 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.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class RunFancyZonesEditorTest
{
private static FancyZonesEditorSession? _session;
private static TestContext? _context;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
// prepare test editor parameters with 2 monitors before launching the editor
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,
},
new EditorParameters.NativeMonitorDataWrapper
{
Monitor = "monitor-2",
MonitorInstanceId = "instance-id-2",
MonitorSerialNumber = "serial-number-2",
MonitorNumber = 2,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 96,
LeftCoordinate = 1920,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = false,
},
},
};
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.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.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>
{
new CustomLayouts.CustomLayoutWrapper
{
Uuid = "{E7807D0D-6223-4883-B15B-1F3883944C09}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Custom layout",
Info = new CustomLayouts().ToJsonElement(new CustomLayouts.CanvasInfoWrapper
{
RefHeight = 952,
RefWidth = 1500,
SensitivityRadius = 10,
Zones = new List<CustomLayouts.CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
},
};
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();
}
[TestMethod]
public void OpenNewLayoutDialog() // verify the new layout dialog is opened
{
_session?.Click(_session?.FindByAccessibilityId(AccessibilityId.NewLayoutButton));
Assert.IsNotNull(_session?.FindByName("Choose layout type")); // check the pane header
}
[TestMethod]
public void OpenEditLayoutDialog() // verify the edit layout dialog is opened
{
_session?.ClickEditLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Grid]);
Assert.IsNotNull(_session?.FindByAccessibilityId(FancyZonesEditorSession.AccessibilityId.DialogTitle)); // check the pane header
Assert.IsNotNull(_session?.FindByName($"Edit '{Constants.TemplateLayoutNames[Constants.TemplateLayouts.Grid]}'")); // verify it's opened for the correct layout
}
[TestMethod]
public void OpenEditLayoutDialog_ByContextMenu_TemplateLayout() // verify the edit layout dialog is opened
{
_session?.ClickContextMenuItem(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Grid], FancyZonesEditorSession.ElementName.Edit);
_session?.WaitElementDisplayedById(FancyZonesEditorSession.AccessibilityId.DialogTitle);
Assert.IsNotNull(_session?.FindByAccessibilityId(FancyZonesEditorSession.AccessibilityId.DialogTitle)); // check the pane header
Assert.IsNotNull(_session?.FindByName($"Edit '{Constants.TemplateLayoutNames[Constants.TemplateLayouts.Grid]}'")); // verify it's opened for the correct layout
}
[TestMethod]
public void OpenEditLayoutDialog_ByContextMenu_CustomLayout() // verify the edit layout dialog is opened
{
string layoutName = "Custom layout";
_session?.ClickContextMenuItem(layoutName, FancyZonesEditorSession.ElementName.Edit);
_session?.WaitElementDisplayedById(FancyZonesEditorSession.AccessibilityId.DialogTitle);
Assert.IsNotNull(_session?.FindByAccessibilityId(FancyZonesEditorSession.AccessibilityId.DialogTitle)); // check the pane header
Assert.IsNotNull(_session?.FindByName($"Edit '{layoutName}'")); // verify it's opened for the correct layout
}
[TestMethod]
public void OpenContextMenu() // verify the context menu is opened
{
Assert.IsNotNull(_session?.OpenContextMenu(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Columns]));
}
[TestMethod]
public void ClickMonitor()
{
Assert.IsNotNull(_session?.GetMonitorItem(1));
Assert.IsNotNull(_session?.GetMonitorItem(2));
// verify that the monitor 1 is selected initially
Assert.IsTrue(_session?.GetMonitorItem(1).Selected);
Assert.IsFalse(_session?.GetMonitorItem(2).Selected);
_session?.ClickMonitor(2);
// verify that the monitor 2 is selected after click
Assert.IsFalse(_session?.GetMonitorItem(1).Selected);
Assert.IsTrue(_session?.GetMonitorItem(2).Selected);
}
}
}

View File

@@ -0,0 +1,463 @@
// 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.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using static FancyZonesEditorCommon.Data.AppliedLayouts;
using static FancyZonesEditorCommon.Data.DefaultLayouts;
using static FancyZonesEditorCommon.Data.EditorParameters;
using static FancyZonesEditorCommon.Data.LayoutTemplates;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class TemplateLayoutsTests
{
private static readonly TemplateLayoutsListWrapper Layouts = new TemplateLayoutsListWrapper
{
LayoutTemplates = new List<TemplateLayoutWrapper>
{
new TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid],
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
};
private static TestContext? _context;
private static FancyZonesEditorSession? _session;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
}
[ClassCleanup]
public static void ClassCleanup()
{
FancyZonesEditorSession.Files.Restore();
_context = null;
}
[TestInitialize]
public void TestInitialize()
{
LayoutTemplates layoutTemplates = new LayoutTemplates();
FancyZonesEditorSession.Files.LayoutTemplatesIOHelper.WriteData(layoutTemplates.Serialize(Layouts));
// Default layouts should match templates
DefaultLayouts defaultLayouts = new DefaultLayouts();
DefaultLayoutsListWrapper defaultLayoutsList = new DefaultLayoutsListWrapper
{
DefaultLayouts = new List<DefaultLayoutWrapper>
{
new DefaultLayoutWrapper
{
MonitorConfiguration = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Vertical),
Layout = new DefaultLayoutWrapper.LayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
},
new DefaultLayoutWrapper
{
MonitorConfiguration = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Horizontal),
Layout = new DefaultLayoutWrapper.LayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid],
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
},
};
FancyZonesEditorSession.Files.DefaultLayoutsIOHelper.WriteData(defaultLayouts.Serialize(defaultLayoutsList));
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new NativeMonitorDataWrapper
{
Monitor = "monitor-1",
MonitorInstanceId = "instance-id-1",
MonitorSerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 192,
LeftCoordinate = 0,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
},
};
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
// Make sure applied layouts don't replace template settings
AppliedLayouts appliedLayouts = new AppliedLayouts();
AppliedLayoutsListWrapper appliedLayoutsList = new AppliedLayoutsListWrapper
{
AppliedLayouts = new List<AppliedLayoutWrapper>
{
new AppliedLayoutWrapper
{
Device = new AppliedLayoutWrapper.DeviceIdWrapper
{
Monitor = "monitor-1",
MonitorInstance = "instance-id-1",
MonitorNumber = 1,
SerialNumber = "serial-number-1",
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
},
AppliedLayout = new AppliedLayoutWrapper.LayoutWrapper
{
Uuid = "{72409DFC-2B87-469B-AAC4-557273791C26}",
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.PriorityGrid],
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
},
};
FancyZonesEditorSession.Files.AppliedLayoutsIOHelper.WriteData(appliedLayouts.Serialize(appliedLayoutsList));
CustomLayouts customLayouts = new CustomLayouts();
CustomLayouts.CustomLayoutListWrapper customLayoutListWrapper = new CustomLayouts.CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayouts.CustomLayoutWrapper> { },
};
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(customLayoutListWrapper));
LayoutHotkeys layoutHotkeys = new LayoutHotkeys();
LayoutHotkeys.LayoutHotkeysWrapper layoutHotkeysWrapper = new LayoutHotkeys.LayoutHotkeysWrapper
{
LayoutHotkeys = new List<LayoutHotkeys.LayoutHotkeyWrapper> { },
};
FancyZonesEditorSession.Files.LayoutHotkeysIOHelper.WriteData(layoutHotkeys.Serialize(layoutHotkeysWrapper));
_session = new FancyZonesEditorSession(_context!);
}
[TestCleanup]
public void TestCleanup()
{
_session?.Close();
FancyZonesEditorSession.Files.Restore();
}
[TestMethod]
public void ZoneNumber_Initialize()
{
foreach (var (key, name) in Constants.TemplateLayoutNames)
{
if (key == Constants.TemplateLayouts.Empty)
{
continue;
}
_session?.ClickEditLayout(name);
var slider = _session?.FindByAccessibilityId(AccessibilityId.TemplateZoneSlider);
Assert.IsNotNull(slider);
var expected = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[key]).ZoneCount;
Assert.AreEqual($"{expected}", slider.Text);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider); // let the dialog window close
}
}
[TestMethod]
public void ZoneNumber_Save()
{
var type = Constants.TemplateLayouts.Columns;
var layout = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]);
var value = layout.ZoneCount;
var expected = value - 1;
_session?.ClickEditLayout(Constants.TemplateLayoutNames[type]);
var slider = _session?.FindByAccessibilityId(AccessibilityId.TemplateZoneSlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Left);
Assert.AreEqual($"{expected}", slider.Text);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the file
var templateLayouts = new LayoutTemplates();
var data = templateLayouts.Read(templateLayouts.File);
var actual = data.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]).ZoneCount;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void ZoneNumber_Cancel()
{
var type = Constants.TemplateLayouts.Rows;
var layout = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]);
var expected = layout.ZoneCount;
_session?.ClickEditLayout(Constants.TemplateLayoutNames[type]);
var slider = _session?.FindByAccessibilityId(AccessibilityId.TemplateZoneSlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Left);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the file
var templateLayouts = new LayoutTemplates();
var data = templateLayouts.Read(templateLayouts.File);
var actual = data.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]).ZoneCount;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void HighlightDistance_Initialize()
{
foreach (var (key, name) in Constants.TemplateLayoutNames)
{
if (key == Constants.TemplateLayouts.Empty)
{
continue;
}
_session?.ClickEditLayout(name);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SensitivitySlider);
Assert.IsNotNull(slider);
var expected = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[key]).SensitivityRadius;
Assert.AreEqual($"{expected}", slider.Text);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider); // let the dialog window close
}
}
[TestMethod]
public void HighlightDistance_Save()
{
var type = Constants.TemplateLayouts.Focus;
var layout = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]);
var value = layout.SensitivityRadius;
_session?.ClickEditLayout(Constants.TemplateLayoutNames[type]);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SensitivitySlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Right);
var expected = value + 1; // one step right
Assert.AreEqual($"{expected}", slider.Text);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the file
var templateLayouts = new LayoutTemplates();
var data = templateLayouts.Read(templateLayouts.File);
var actual = data.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]).SensitivityRadius;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void HighlightDistance_Cancel()
{
var type = Constants.TemplateLayouts.Focus;
var layout = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]);
var expected = layout.SensitivityRadius;
_session?.ClickEditLayout(Constants.TemplateLayoutNames[type]);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SensitivitySlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Right);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the file
var templateLayouts = new LayoutTemplates();
var data = templateLayouts.Read(templateLayouts.File);
var actual = data.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]).SensitivityRadius;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void SpaceAroundZones_Initialize()
{
foreach (var (key, name) in Constants.TemplateLayoutNames)
{
if (key == Constants.TemplateLayouts.Empty || key == Constants.TemplateLayouts.Focus)
{
// only for grid layouts
continue;
}
_session?.ClickEditLayout(name);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider);
Assert.IsNotNull(slider);
var spacingEnabled = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[key]).ShowSpacing;
Assert.AreEqual(spacingEnabled, slider.Enabled);
var expected = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[key]).Spacing;
Assert.AreEqual($"{expected}", slider.Text);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider); // let the dialog window close
}
}
[TestMethod]
public void SpaceAroundZones_Slider_Save()
{
var type = Constants.TemplateLayouts.PriorityGrid;
var layout = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]);
var expected = layout.Spacing + 1;
_session?.ClickEditLayout(Constants.TemplateLayoutNames[type]);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Right);
Assert.AreEqual($"{expected}", slider.Text);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the file
var templateLayouts = new LayoutTemplates();
var data = templateLayouts.Read(templateLayouts.File);
var actual = data.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]).Spacing;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void SpaceAroundZones_Slider_Cancel()
{
var type = Constants.TemplateLayouts.PriorityGrid;
var layout = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]);
var expected = layout.Spacing;
_session?.ClickEditLayout(Constants.TemplateLayoutNames[type]);
var slider = _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider);
Assert.IsNotNull(slider);
slider.SendKeys(Keys.Right);
Assert.AreEqual($"{expected + 1}", slider.Text);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(slider); // let the dialog window close
// verify the file
var templateLayouts = new LayoutTemplates();
var data = templateLayouts.Read(templateLayouts.File);
var actual = data.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]).Spacing;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void SpaceAroundZones_Toggle_Save()
{
var type = Constants.TemplateLayouts.PriorityGrid;
var layout = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]);
var expected = !layout.ShowSpacing;
_session?.ClickEditLayout(Constants.TemplateLayoutNames[type]);
var toggle = _session?.FindByAccessibilityId(AccessibilityId.SpacingToggle);
Assert.IsNotNull(toggle);
toggle.Click();
Assert.AreEqual(expected, toggle.Selected);
Assert.AreEqual(expected, _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider)?.Enabled);
_session?.Click(ElementName.Save);
_session?.WaitUntilHidden(toggle); // let the dialog window close
// verify the file
var templateLayouts = new LayoutTemplates();
var data = templateLayouts.Read(templateLayouts.File);
var actual = data.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]).ShowSpacing;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void SpaceAroundZones_Toggle_Cancel()
{
var type = Constants.TemplateLayouts.PriorityGrid;
var layout = Layouts.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]);
var expected = layout.ShowSpacing;
_session?.ClickEditLayout(Constants.TemplateLayoutNames[type]);
var toggle = _session?.FindByAccessibilityId(AccessibilityId.SpacingToggle);
Assert.IsNotNull(toggle);
toggle.Click();
Assert.AreNotEqual(expected, toggle.Selected);
Assert.AreNotEqual(expected, _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider)?.Enabled);
_session?.Click(ElementName.Cancel);
_session?.WaitUntilHidden(toggle); // let the dialog window close
// verify the file
var templateLayouts = new LayoutTemplates();
var data = templateLayouts.Read(templateLayouts.File);
var actual = data.LayoutTemplates.Find(x => x.Type == Constants.TemplateLayoutTypes[type]).ShowSpacing;
Assert.AreEqual(expected, actual);
}
}
}

View File

@@ -0,0 +1,808 @@
// 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 FancyZonesEditorCommon.Data;
using Microsoft.FancyZonesEditor.UnitTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static FancyZonesEditorCommon.Data.EditorParameters;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorSession;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class UIInitializationTests
{
private static TestContext? _context;
private static FancyZonesEditorSession? _session;
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_context = testContext;
}
[ClassCleanup]
public static void ClassCleanup()
{
_context = null;
}
[TestInitialize]
public void TestInitialize()
{
LayoutTemplates layoutTemplates = new LayoutTemplates();
LayoutTemplates.TemplateLayoutsListWrapper templateLayoutsListWrapper = new LayoutTemplates.TemplateLayoutsListWrapper
{
LayoutTemplates = new List<LayoutTemplates.TemplateLayoutWrapper>
{
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Empty],
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.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));
}
[TestCleanup]
public void TestCleanup()
{
_session?.Close();
FancyZonesEditorSession.Files.Restore();
}
[TestMethod]
public void EditorParams_VerifySelectedMonitor()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new 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 = false,
},
new NativeMonitorDataWrapper
{
Monitor = "monitor-2",
MonitorInstanceId = "instance-id-2",
MonitorSerialNumber = "serial-number-2",
MonitorNumber = 2,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 96,
LeftCoordinate = 1920,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
},
};
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
_session = new FancyZonesEditorSession(_context!);
Assert.IsFalse(_session.GetMonitorItem(1)?.Selected);
Assert.IsTrue(_session.GetMonitorItem(2)?.Selected);
}
[TestMethod]
public void EditorParams_VerifyMonitorScaling()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new NativeMonitorDataWrapper
{
Monitor = "monitor-1",
MonitorInstanceId = "instance-id-1",
MonitorSerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 192, // 200% scaling
LeftCoordinate = 0,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
},
};
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
_session = new FancyZonesEditorSession(_context!);
var monitor = _session.GetMonitorItem(1);
var scaling = monitor.FindElementByAccessibilityId("ScalingText");
Assert.AreEqual("200%", scaling.Text);
}
[TestMethod]
public void EditorParams_VerifyMonitorResolution()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new NativeMonitorDataWrapper
{
Monitor = "monitor-1",
MonitorInstanceId = "instance-id-1",
MonitorSerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 192,
LeftCoordinate = 0,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
},
};
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
_session = new FancyZonesEditorSession(_context!);
var monitor = _session.GetMonitorItem(1);
var resolution = monitor.FindElementByAccessibilityId("ResolutionText");
Assert.AreEqual("1920 × 1080", resolution.Text);
}
[TestMethod]
public void EditorParams_SpanAcrossMonitors()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = true,
Monitors = new List<NativeMonitorDataWrapper>
{
new NativeMonitorDataWrapper
{
Monitor = "monitor-1",
MonitorInstanceId = "instance-id-1",
MonitorSerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 192,
LeftCoordinate = 0,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
},
};
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
_session = new FancyZonesEditorSession(_context!);
var monitor = _session.GetMonitorItem(1);
Assert.IsNotNull(monitor);
Assert.IsTrue(monitor.Selected);
}
[TestMethod]
public void AppliedLayouts_LayoutsApplied()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new 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,
},
new NativeMonitorDataWrapper
{
Monitor = "monitor-2",
MonitorInstanceId = "instance-id-2",
MonitorSerialNumber = "serial-number-2",
MonitorNumber = 2,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
Dpi = 96,
LeftCoordinate = 1920,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = false,
},
},
};
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
CustomLayouts customLayouts = new CustomLayouts();
CustomLayouts.CustomLayoutListWrapper customLayoutListWrapper = new CustomLayouts.CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayouts.CustomLayoutWrapper>
{
new CustomLayouts.CustomLayoutWrapper
{
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 0",
Info = new CustomLayouts().ToJsonElement(new CustomLayouts.CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CustomLayouts.CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
},
};
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(customLayoutListWrapper));
AppliedLayouts appliedLayouts = new AppliedLayouts();
AppliedLayouts.AppliedLayoutsListWrapper appliedLayoutsWrapper = new AppliedLayouts.AppliedLayoutsListWrapper
{
AppliedLayouts = new List<AppliedLayouts.AppliedLayoutWrapper>
{
new AppliedLayouts.AppliedLayoutWrapper
{
Device = new AppliedLayouts.AppliedLayoutWrapper.DeviceIdWrapper
{
Monitor = "monitor-1",
MonitorInstance = "instance-id-1",
SerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
},
AppliedLayout = new AppliedLayouts.AppliedLayoutWrapper.LayoutWrapper
{
Uuid = "{00000000-0000-0000-0000-000000000000}",
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ShowSpacing = true,
Spacing = 10,
ZoneCount = 1,
SensitivityRadius = 20,
},
},
new AppliedLayouts.AppliedLayoutWrapper
{
Device = new AppliedLayouts.AppliedLayoutWrapper.DeviceIdWrapper
{
Monitor = "monitor-2",
MonitorInstance = "instance-id-2",
SerialNumber = "serial-number-2",
MonitorNumber = 2,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
},
AppliedLayout = new AppliedLayouts.AppliedLayoutWrapper.LayoutWrapper
{
Uuid = customLayoutListWrapper.CustomLayouts[0].Uuid,
Type = Constants.CustomLayoutTypeString,
},
},
},
};
FancyZonesEditorSession.Files.AppliedLayoutsIOHelper.WriteData(appliedLayouts.Serialize(appliedLayoutsWrapper));
_session = new FancyZonesEditorSession(_context!);
// check layout on monitor 1
var layoutOnMonitor1 = _session?.GetLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Columns]);
Assert.IsNotNull(layoutOnMonitor1);
Assert.IsTrue(layoutOnMonitor1.Selected);
// check layout on monitor 2
_session?.ClickMonitor(2);
var layoutOnMonitor2 = _session?.GetLayout(customLayoutListWrapper.CustomLayouts[0].Name);
Assert.IsNotNull(layoutOnMonitor2);
Assert.IsTrue(layoutOnMonitor2.Selected);
}
[TestMethod]
public void AppliedLayouts_CustomLayoutsApplied_LayoutIdNotFound()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new 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));
CustomLayouts customLayouts = new CustomLayouts();
CustomLayouts.CustomLayoutListWrapper customLayoutListWrapper = new CustomLayouts.CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayouts.CustomLayoutWrapper>
{
new CustomLayouts.CustomLayoutWrapper
{
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 0",
Info = new CustomLayouts().ToJsonElement(new CustomLayouts.CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CustomLayouts.CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
},
};
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(customLayoutListWrapper));
AppliedLayouts appliedLayouts = new AppliedLayouts();
AppliedLayouts.AppliedLayoutsListWrapper appliedLayoutsWrapper = new AppliedLayouts.AppliedLayoutsListWrapper
{
AppliedLayouts = new List<AppliedLayouts.AppliedLayoutWrapper>
{
new AppliedLayouts.AppliedLayoutWrapper
{
Device = new AppliedLayouts.AppliedLayoutWrapper.DeviceIdWrapper
{
Monitor = "monitor-1",
MonitorInstance = "instance-id-1",
SerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
},
AppliedLayout = new AppliedLayouts.AppliedLayoutWrapper.LayoutWrapper
{
Uuid = "{00000000-0000-0000-0000-000000000000}",
Type = Constants.CustomLayoutTypeString,
},
},
},
};
FancyZonesEditorSession.Files.AppliedLayoutsIOHelper.WriteData(appliedLayouts.Serialize(appliedLayoutsWrapper));
_session = new FancyZonesEditorSession(_context!);
var emptyLayout = _session?.GetLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Empty]);
Assert.IsNotNull(emptyLayout);
Assert.IsTrue(emptyLayout.Selected);
}
[TestMethod]
public void AppliedLayouts_NoLayoutsApplied_CustomDefaultLayout()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new 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));
CustomLayouts customLayouts = new CustomLayouts();
CustomLayouts.CustomLayoutListWrapper customLayoutListWrapper = new CustomLayouts.CustomLayoutListWrapper
{
CustomLayouts = new List<CustomLayouts.CustomLayoutWrapper>
{
new CustomLayouts.CustomLayoutWrapper
{
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
Type = Constants.CustomLayoutTypeNames[Constants.CustomLayoutType.Canvas],
Name = "Layout 0",
Info = new CustomLayouts().ToJsonElement(new CustomLayouts.CanvasInfoWrapper
{
RefHeight = 1080,
RefWidth = 1920,
SensitivityRadius = 10,
Zones = new List<CustomLayouts.CanvasInfoWrapper.CanvasZoneWrapper> { },
}),
},
},
};
FancyZonesEditorSession.Files.CustomLayoutsIOHelper.WriteData(customLayouts.Serialize(customLayoutListWrapper));
DefaultLayouts defaultLayouts = new DefaultLayouts();
DefaultLayouts.DefaultLayoutsListWrapper defaultLayoutsListWrapper = new DefaultLayouts.DefaultLayoutsListWrapper
{
DefaultLayouts = new List<DefaultLayouts.DefaultLayoutWrapper>
{
new DefaultLayouts.DefaultLayoutWrapper
{
MonitorConfiguration = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Horizontal),
Layout = new DefaultLayouts.DefaultLayoutWrapper.LayoutWrapper
{
Type = Constants.CustomLayoutTypeString,
Uuid = customLayoutListWrapper.CustomLayouts[0].Uuid,
},
},
},
};
FancyZonesEditorSession.Files.DefaultLayoutsIOHelper.WriteData(defaultLayouts.Serialize(defaultLayoutsListWrapper));
_session = new FancyZonesEditorSession(_context!);
var defaultLayout = _session?.GetLayout(customLayoutListWrapper.CustomLayouts[0].Name);
Assert.IsNotNull(defaultLayout);
Assert.IsTrue(defaultLayout.Selected);
}
[TestMethod]
public void AppliedLayouts_NoLayoutsApplied_TemplateDefaultLayout()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new 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));
DefaultLayouts defaultLayouts = new DefaultLayouts();
DefaultLayouts.DefaultLayoutsListWrapper defaultLayoutsListWrapper = new DefaultLayouts.DefaultLayoutsListWrapper
{
DefaultLayouts = new List<DefaultLayouts.DefaultLayoutWrapper>
{
new DefaultLayouts.DefaultLayoutWrapper
{
MonitorConfiguration = MonitorConfigurationTypeEnumExtensions.MonitorConfigurationTypeToString(MonitorConfigurationType.Horizontal),
Layout = new DefaultLayouts.DefaultLayoutWrapper.LayoutWrapper
{
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Grid],
ZoneCount = 6,
ShowSpacing = true,
Spacing = 5,
SensitivityRadius = 20,
},
},
},
};
FancyZonesEditorSession.Files.DefaultLayoutsIOHelper.WriteData(defaultLayouts.Serialize(defaultLayoutsListWrapper));
_session = new FancyZonesEditorSession(_context!);
var defaultLayout = _session?.GetLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Grid]);
Assert.IsNotNull(defaultLayout);
Assert.IsTrue(defaultLayout.Selected);
// check the number of zones and spacing
_session?.ClickEditLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Grid]);
Assert.AreEqual(defaultLayoutsListWrapper.DefaultLayouts[0].Layout.ZoneCount, int.Parse(_session?.FindByAccessibilityId(AccessibilityId.TemplateZoneSlider)?.Text!, CultureInfo.InvariantCulture));
Assert.AreEqual(defaultLayoutsListWrapper.DefaultLayouts[0].Layout.Spacing, int.Parse(_session?.FindByAccessibilityId(AccessibilityId.SpacingSlider)?.Text!, CultureInfo.InvariantCulture));
Assert.AreEqual(defaultLayoutsListWrapper.DefaultLayouts[0].Layout.ShowSpacing, _session?.FindByAccessibilityId(AccessibilityId.SpacingSlider)?.Enabled);
Assert.AreEqual(defaultLayoutsListWrapper.DefaultLayouts[0].Layout.ShowSpacing, _session?.FindByAccessibilityId(AccessibilityId.SpacingToggle)?.Selected);
Assert.AreEqual(defaultLayoutsListWrapper.DefaultLayouts[0].Layout.SensitivityRadius, int.Parse(_session?.FindByAccessibilityId(AccessibilityId.SensitivitySlider)?.Text!, CultureInfo.InvariantCulture));
Assert.IsNotNull(_session?.GetHorizontalDefaultButton(true));
}
[TestMethod]
public void AppliedLayouts_VerifyDisconnectedMonitorsLayoutsAreNotChanged()
{
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new 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));
AppliedLayouts appliedLayouts = new AppliedLayouts();
AppliedLayouts.AppliedLayoutsListWrapper appliedLayoutsWrapper = new AppliedLayouts.AppliedLayoutsListWrapper
{
AppliedLayouts = new List<AppliedLayouts.AppliedLayoutWrapper>
{
new AppliedLayouts.AppliedLayoutWrapper
{
Device = new AppliedLayouts.AppliedLayoutWrapper.DeviceIdWrapper
{
Monitor = "monitor-2",
MonitorInstance = "instance-id-2",
SerialNumber = "serial-number-2",
MonitorNumber = 2,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
},
AppliedLayout = new AppliedLayouts.AppliedLayoutWrapper.LayoutWrapper
{
Uuid = "{00000000-0000-0000-0000-000000000000}",
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ShowSpacing = true,
Spacing = 10,
ZoneCount = 4,
SensitivityRadius = 30,
},
},
new AppliedLayouts.AppliedLayoutWrapper
{
Device = new AppliedLayouts.AppliedLayoutWrapper.DeviceIdWrapper
{
Monitor = "monitor-3",
MonitorInstance = "instance-id-3",
SerialNumber = "serial-number-3",
MonitorNumber = 1,
VirtualDesktop = "{FF34D993-73F3-4B8C-AA03-73730A01D6A8}",
},
AppliedLayout = new AppliedLayouts.AppliedLayoutWrapper.LayoutWrapper
{
Uuid = "{00000000-0000-0000-0000-000000000000}",
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Columns],
ShowSpacing = true,
Spacing = 10,
ZoneCount = 1,
SensitivityRadius = 20,
},
},
},
};
FancyZonesEditorSession.Files.AppliedLayoutsIOHelper.WriteData(appliedLayouts.Serialize(appliedLayoutsWrapper));
_session = new FancyZonesEditorSession(_context!);
_session?.Click(_session?.GetLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Rows])!);
// check the file
var data = appliedLayouts.Read(appliedLayouts.File);
Assert.AreEqual(parameters.Monitors.Count + appliedLayoutsWrapper.AppliedLayouts.Count, data.AppliedLayouts.Count);
foreach (var monitor in parameters.Monitors)
{
Assert.IsNotNull(data.AppliedLayouts.Find(x => x.Device.Monitor == monitor.Monitor));
}
foreach (var layout in appliedLayoutsWrapper.AppliedLayouts)
{
Assert.IsNotNull(data.AppliedLayouts.Find(x => x.Device.Monitor == layout.Device.Monitor));
}
}
[TestMethod]
public void AppliedLayouts_VerifyOtherVirtualDesktopsAreNotChanged()
{
string virtualDesktop1 = "{11111111-1111-1111-1111-111111111111}";
string virtualDesktop2 = "{22222222-2222-2222-2222-222222222222}";
EditorParameters editorParameters = new EditorParameters();
ParamsWrapper parameters = new ParamsWrapper
{
ProcessId = 1,
SpanZonesAcrossMonitors = false,
Monitors = new List<NativeMonitorDataWrapper>
{
new NativeMonitorDataWrapper
{
Monitor = "monitor-1",
MonitorInstanceId = "instance-id-1",
MonitorSerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = virtualDesktop1,
Dpi = 96,
LeftCoordinate = 0,
TopCoordinate = 0,
WorkAreaHeight = 1040,
WorkAreaWidth = 1920,
MonitorHeight = 1080,
MonitorWidth = 1920,
IsSelected = true,
},
},
};
FancyZonesEditorSession.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(parameters));
AppliedLayouts appliedLayouts = new AppliedLayouts();
AppliedLayouts.AppliedLayoutsListWrapper appliedLayoutsWrapper = new AppliedLayouts.AppliedLayoutsListWrapper
{
AppliedLayouts = new List<AppliedLayouts.AppliedLayoutWrapper>
{
new AppliedLayouts.AppliedLayoutWrapper
{
Device = new AppliedLayouts.AppliedLayoutWrapper.DeviceIdWrapper
{
Monitor = "monitor-1",
MonitorInstance = "instance-id-1",
SerialNumber = "serial-number-1",
MonitorNumber = 1,
VirtualDesktop = virtualDesktop2,
},
AppliedLayout = new AppliedLayouts.AppliedLayoutWrapper.LayoutWrapper
{
Uuid = "{00000000-0000-0000-0000-000000000000}",
Type = Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Focus],
ShowSpacing = true,
Spacing = 10,
ZoneCount = 4,
SensitivityRadius = 30,
},
},
},
};
FancyZonesEditorSession.Files.AppliedLayoutsIOHelper.WriteData(appliedLayouts.Serialize(appliedLayoutsWrapper));
_session = new FancyZonesEditorSession(_context!);
_session?.Click(_session?.GetLayout(Constants.TemplateLayoutNames[Constants.TemplateLayouts.Rows])!);
// check the file
var data = appliedLayouts.Read(appliedLayouts.File);
Assert.AreEqual(parameters.Monitors.Count + appliedLayoutsWrapper.AppliedLayouts.Count, data.AppliedLayouts.Count);
Assert.IsNotNull(data.AppliedLayouts.Find(x => x.Device.VirtualDesktop == virtualDesktop1));
Assert.IsNotNull(data.AppliedLayouts.Find(x => x.Device.VirtualDesktop == virtualDesktop2));
Assert.AreEqual(appliedLayoutsWrapper.AppliedLayouts[0].AppliedLayout.Type, data.AppliedLayouts.Find(x => x.Device.VirtualDesktop == virtualDesktop2).AppliedLayout.Type);
Assert.AreEqual(Constants.TemplateLayoutTypes[Constants.TemplateLayouts.Rows], data.AppliedLayouts.Find(x => x.Device.VirtualDesktop == virtualDesktop1).AppliedLayout.Type);
}
}
}

View File

@@ -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>

View File

@@ -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();
}
}
}

View File

@@ -0,0 +1,562 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using Microsoft.FancyZonesEditor.UITests;
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;
using OpenQA.Selenium.Support.UI;
namespace Microsoft.FancyZonesEditor.UnitTests.Utils
{
public class FancyZonesEditorSession
{
private const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
private const string FancyZonesEditorName = "PowerToys.FancyZonesEditor";
private const string FancyZonesEditorPath = @"\..\..\..\" + FancyZonesEditorName + ".exe";
private TestContext context;
private WindowsDriver<WindowsElement> Session { get; }
private static FancyZonesEditorFiles? _files;
public static FancyZonesEditorFiles Files
{
get
{
if (_files == null)
{
_files = new FancyZonesEditorFiles();
}
return _files;
}
}
public static class AccessibilityId
{
// main window
public const string MainWindow = "MainWindow1";
public const string Monitors = "Monitors";
public const string NewLayoutButton = "NewLayoutButton";
// layout card
public const string EditLayoutButton = "EditLayoutButton";
// edit layout window: common for template and custom layouts
public const string DialogTitle = "EditLayoutDialogTitle";
public const string SensitivitySlider = "SensitivityInput";
public const string SpacingSlider = "Spacing";
public const string SpacingToggle = "spaceAroundSetting";
public const string HorizontalDefaultButtonUnchecked = "SetLayoutAsHorizontalDefaultButton";
public const string VerticalDefaultButtonUnchecked = "SetLayoutAsVerticalDefaultButton";
public const string HorizontalDefaultButtonChecked = "HorizontalDefaultLayoutButton";
public const string VerticalDefaultButtonChecked = "VerticalDefaultLayoutButton";
// edit template layout window
public const string CopyTemplate = "createFromTemplateLayoutButton";
public const string TemplateZoneSlider = "TemplateZoneCount";
// edit custom layout window
public const string DuplicateLayoutButton = "duplicateLayoutButton";
public const string DeleteLayoutButton = "deleteLayoutButton";
public const string KeySelectionComboBox = "quickKeySelectionComboBox";
public const string EditZonesButton = "editZoneLayoutButton";
public const string DeleteTextButton = "DeleteButton";
public const string HotkeyComboBox = "quickKeySelectionComboBox";
public const string NewZoneButton = "newZoneButton";
public const string TopRightCorner = "NEResize";
// layout creation dialog
public const string GridRadioButton = "GridLayoutRadioButton";
public const string CanvasRadioButton = "CanvasLayoutRadioButton";
// confirmation dialog
public const string PrimaryButton = "PrimaryButton";
public const string SecondaryButton = "SecondaryButton";
}
public static class ElementName
{
public const string Save = "Save";
public const string Cancel = "Cancel";
// context menu
public const string Edit = "Edit";
public const string EditZones = "Edit zones";
public const string Delete = "Delete";
public const string Duplicate = "Duplicate";
public const string CreateCustomLayout = "Create custom layout";
// canvas layout editor
public const string CanvasEditorWindow = "Canvas layout editor";
// grid layout editor
public const string GridLayoutEditor = "Grid layout editor";
public const string MergeZonesButton = "Merge zones";
}
public static class ClassName
{
public const string ContextMenu = "ContextMenu";
public const string TextBox = "TextBox";
public const string Popup = "Popup";
// layout editor
public const string CanvasZone = "CanvasZone";
public const string GridZone = "GridZone";
public const string Button = "Button";
public const string Thumb = "Thumb";
}
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);
context = testContext;
}
public void Close()
{
// Close the session
try
{
// in case if something went wrong and an error message is shown
var dialog = Session.FindElementByName("Editor data parsing error.");
Session.CloseApp(); // will close the dialog
// session can't access new Editor instance created after closing the dialog
// kill the process
IntPtr appTopLevelWindowHandle = IntPtr.Zero;
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.Equals(FancyZonesEditorName, StringComparison.OrdinalIgnoreCase))
{
clsProcess.Kill();
break;
}
}
}
catch
{
}
try
{
// FZEditor application can be closed by explicitly closing main editor window
var mainEditorWindow = Session.FindElementByAccessibilityId(AccessibilityId.MainWindow);
mainEditorWindow?.SendKeys(Keys.Alt + Keys.F4);
}
catch (Exception ex)
{
context.WriteLine("Unable to close main window. ", ex.Message);
}
Session.Quit();
Session.Dispose();
}
public WindowsElement? GetLayout(string layoutName)
{
try
{
return Session.FindElementByName(layoutName);
}
catch (Exception)
{
context.WriteLine("Layout " + layoutName + " not found");
return null;
}
}
public WindowsElement OpenContextMenu(string layoutName)
{
RightClickLayout(layoutName);
return Session.FindElementByClassName(ClassName.ContextMenu);
}
public WindowsElement? GetMonitorsList()
{
return FindByAccessibilityId(AccessibilityId.Monitors);
}
public WindowsElement GetMonitorItem(int monitorNumber)
{
try
{
var monitorsList = GetMonitorsList();
Assert.IsNotNull(monitorsList, "Monitors list not found");
var listItem = monitorsList?.FindElementByName($"{monitorNumber}");
Assert.IsNotNull(listItem, "Monitor " + monitorNumber + " not found");
return (WindowsElement)listItem;
}
catch (Exception)
{
Assert.Fail("Monitor " + monitorNumber + " not found");
return null;
}
}
public WindowsElement? GetHorizontalDefaultButton(bool isChecked)
{
if (isChecked)
{
return FindByAccessibilityId(AccessibilityId.HorizontalDefaultButtonChecked);
}
else
{
return FindByAccessibilityId(AccessibilityId.HorizontalDefaultButtonUnchecked);
}
}
public WindowsElement? GetVerticalDefaultButton(bool isChecked)
{
if (isChecked)
{
return FindByAccessibilityId(AccessibilityId.VerticalDefaultButtonChecked);
}
else
{
return FindByAccessibilityId(AccessibilityId.VerticalDefaultButtonUnchecked);
}
}
public WindowsElement? GetZone(int zoneNumber, string zoneClassName)
{
ReadOnlyCollection<WindowsElement> zones = Session.FindElementsByClassName(zoneClassName);
foreach (WindowsElement zone in zones)
{
try
{
zone.FindElementByName(zoneNumber.ToString(CultureInfo.InvariantCulture));
return zone;
}
catch
{
// required number not found in the zone
}
}
return null;
}
public void Click(WindowsElement? element)
{
Assert.IsNotNull(element);
element.Click();
}
public void Click(string name)
{
Click(Session.FindElementByName(name));
}
public void ClickEditLayout(string layoutName)
{
var layout = GetLayout(layoutName);
Assert.IsNotNull(layout, $"Layout \"{layoutName}\" not found");
// added retry attempts, because Click can fail for some reason
bool opened = false;
int retryAttempts = 10;
while (!opened && retryAttempts > 0)
{
var editButton = layout?.FindElementByAccessibilityId(AccessibilityId.EditLayoutButton);
Assert.IsNotNull(editButton, "Edit button not found");
editButton.Click();
// wait until the dialog is opened
opened = WaitElementDisplayedByName($"Edit '{layoutName}'");
retryAttempts--;
}
}
public void RightClickLayout(string layoutName)
{
var layout = GetLayout(layoutName);
Assert.IsNotNull(layout);
ContextClick(layout);
}
public void ClickMonitor(int monitorNumber)
{
var monitor = GetMonitorItem(monitorNumber);
Assert.IsNotNull(monitor, $"Monitor {monitorNumber} not found");
Click(monitor);
}
public void ClickCopyLayout()
{
WindowsElement? button = null;
try
{
button = Session.FindElementByAccessibilityId(AccessibilityId.CopyTemplate);
}
catch
{
}
try
{
button = Session.FindElementByAccessibilityId(AccessibilityId.DuplicateLayoutButton);
}
catch
{
}
Assert.IsNotNull(button, "No Copy button");
button.Click();
}
public void ClickConfirm()
{
WaitElementDisplayedById(AccessibilityId.PrimaryButton);
WindowsElement button = Session.FindElementByAccessibilityId(AccessibilityId.PrimaryButton);
button.Click();
WaitUntilHidden(button);
}
public void ClickConfirmDialog()
{
Actions actions = new Actions(Session);
actions.SendKeys(Keys.Tab).SendKeys(Keys.Enter);
actions.Build().Perform();
}
public void ClickCancelDialog()
{
Actions actions = new Actions(Session);
actions.SendKeys(Keys.Tab).SendKeys(Keys.Tab).SendKeys(Keys.Enter);
actions.Build().Perform();
}
public void ClickContextMenuItem(string layoutName, string menuItem)
{
WindowsElement menu = OpenContextMenu(layoutName);
Click(menu.FindElementByName(menuItem));
}
public void ClickDeleteZone(int zoneNumber)
{
var zone = GetZone(zoneNumber, ClassName.CanvasZone);
Assert.IsNotNull(zone);
var button = zone.FindElementByClassName(ClassName.Button);
Assert.IsNotNull(button);
button.Click();
}
public void MergeGridZones(int zoneNumber1, int zoneNumber2)
{
var zone1 = GetZone(zoneNumber1, ClassName.GridZone);
var zone2 = GetZone(zoneNumber2, ClassName.GridZone);
if (zone1 == null || zone2 == null)
{
return;
}
Actions actions = new Actions(Session);
actions.MoveToElement(zone1).ClickAndHold();
int dx = (zone2.Rect.X - zone1.Rect.X) / 10;
int dy = (zone2.Rect.Y - zone1.Rect.Y) / 10;
for (int i = 0; i < 10; i++)
{
actions.MoveByOffset(dx, dy);
}
actions.MoveToElement(zone2).Release();
actions.Build().Perform();
Click(Session.FindElementByName(ElementName.MergeZonesButton)!);
}
public void MoveSplitter(int xOffset, int yOffset)
{
ReadOnlyCollection<WindowsElement> thumbs = Session.FindElementsByClassName(ClassName.Thumb);
if (thumbs.Count == 0)
{
return;
}
Actions actions = new Actions(Session);
actions.MoveToElement(thumbs[0]).ClickAndHold();
int dx = xOffset / 10;
int dy = yOffset / 10;
for (int i = 0; i < 10; i++)
{
actions.MoveByOffset(dx, dy);
}
actions.Build().Perform();
}
public void SelectNewLayoutType(Constants.CustomLayoutType type)
{
WindowsElement? button = null;
switch (type)
{
case Constants.CustomLayoutType.Canvas:
button = FindByAccessibilityId(AccessibilityId.CanvasRadioButton);
break;
case Constants.CustomLayoutType.Grid:
button = FindByAccessibilityId(AccessibilityId.GridRadioButton);
break;
}
Assert.IsNotNull(button);
Click(button);
}
public WindowsElement? FindByAccessibilityId(string name)
{
try
{
return Session.FindElementByAccessibilityId(name);
}
catch (Exception)
{
context.WriteLine($"{name} not found");
return null;
}
}
public WindowsElement? FindByName(string name)
{
try
{
return Session.FindElementByName(name);
}
catch (Exception)
{
context.WriteLine($"{name} not found");
return null;
}
}
public WindowsElement? FindByClassName(string name)
{
try
{
return Session.FindElementByClassName(name);
}
catch (Exception)
{
context.WriteLine($"{name} not found");
return null;
}
}
public bool WaitElementDisplayedByName(string name)
{
try
{
WebDriverWait wait = new WebDriverWait(Session, TimeSpan.FromSeconds(1));
return wait.Until(pred =>
{
var element = Session.FindElementByName(name);
if (element != null)
{
return element.Displayed;
}
return false;
});
}
catch
{
return false;
}
}
public void WaitElementDisplayedById(string id)
{
WebDriverWait wait = new WebDriverWait(Session, TimeSpan.FromSeconds(1));
wait.Until(pred =>
{
var element = Session.FindElementByAccessibilityId(id);
if (element != null)
{
return element.Displayed;
}
return false;
});
}
public void WaitElementDisplayedByClassName(string className)
{
WebDriverWait wait = new WebDriverWait(Session, TimeSpan.FromSeconds(1));
wait.Until(pred =>
{
var element = Session.FindElementByClassName(className);
return element.Displayed;
});
}
public void WaitUntilHidden(WindowsElement element)
{
WebDriverWait wait = new WebDriverWait(Session, TimeSpan.FromSeconds(1));
wait.Until(pred =>
{
return !element.Displayed;
});
}
public void WaitFor(int seconds)
{
System.Threading.Thread.Sleep(seconds * 1000);
}
public void ContextClick(WindowsElement element)
{
Actions actions = new Actions(Session);
actions.MoveToElement(element);
actions.MoveByOffset(10, 10);
actions.ContextClick();
actions.Build().Perform();
}
public void Click(AppiumWebElement element)
{
Actions actions = new Actions(Session);
actions.MoveToElement(element);
actions.MoveByOffset(10, 10);
actions.Click();
actions.Build().Perform();
}
public void Drag(WindowsElement element, int offsetX, int offsetY)
{
Actions actions = new Actions(Session);
actions.MoveToElement(element).MoveByOffset(10, 10).ClickAndHold(element).MoveByOffset(offsetX, offsetY).Release();
actions.Build().Perform();
}
}
}

View File

@@ -0,0 +1,108 @@
// 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));
}
}
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++;
}
}
}
}

View File

@@ -1,7 +1,9 @@
// 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 FancyZonesEditor.Models;
using FancyZonesEditorCommon.Data;
namespace UnitTestsFancyZonesEditor;

View File

@@ -69,6 +69,7 @@
<ProjectReference Include="..\..\..\..\common\interop\PowerToys.Interop.vcxproj" />
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\..\..\common\Common.UI\Common.UI.csproj" />
<ProjectReference Include="..\..\FancyZonesEditorCommon\FancyZonesEditorCommon.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">

View File

@@ -1,10 +1,10 @@
// Copyright (c) Microsoft Corporation
// 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 FancyZonesEditor.Models;
using FancyZonesEditor.Utils;
using FancyZonesEditorCommon.Data;
namespace FancyZonesEditor
{

View File

@@ -337,6 +337,7 @@
</ScrollViewer.DataContext>
<Grid>
<ui:GridView
x:Name="Monitors"
HorizontalAlignment="Center"
IsItemClickEnabled="True"
IsSelectionEnabled="True"

View File

@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Automation;
@@ -16,6 +15,7 @@ using System.Windows.Interop;
using Common.UI;
using FancyZonesEditor.Models;
using FancyZonesEditor.Utils;
using FancyZonesEditorCommon.Data;
using ManagedCommon;
using ModernWpf.Controls;
@@ -347,10 +347,14 @@ namespace FancyZonesEditor
private void EditZones_Click(object sender, RoutedEventArgs e)
{
Logger.LogTrace();
var dataContext = ((FrameworkElement)sender).DataContext;
Select((LayoutModel)dataContext);
App.Overlay.StartEditing(_settings.SelectedModel);
EditLayoutDialog.Hide();
Hide();
App.Overlay.OpenEditor(_settings.SelectedModel);
}
@@ -484,10 +488,12 @@ namespace FancyZonesEditor
}
}
model.Delete();
App.FancyZonesEditorIO.SerializeAppliedLayouts();
App.FancyZonesEditorIO.SerializeCustomLayouts();
App.FancyZonesEditorIO.SerializeDefaultLayouts();
model.Delete();
App.FancyZonesEditorIO.SerializeLayoutHotkeys();
}
}

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation
// 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.
@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using FancyZonesEditorCommon.Data;
namespace FancyZonesEditor.Models
{

View File

@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using FancyZonesEditorCommon.Data;
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
public int Spacing
@@ -129,7 +130,7 @@ namespace FancyZonesEditor.Models
get { return 1000; }
}
private int _spacing = LayoutSettings.DefaultSpacing;
private int _spacing = LayoutDefaultSettings.DefaultSpacing;
public GridLayoutModel()
: base()

View File

@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.CompilerServices;
using FancyZonesEditorCommon.Data;
namespace FancyZonesEditor.Models
{
@@ -195,7 +196,7 @@ namespace FancyZonesEditor.Models
}
}
private int _sensitivityRadius = LayoutSettings.DefaultSensitivityRadius;
private int _sensitivityRadius = LayoutDefaultSettings.DefaultSensitivityRadius;
public int SensitivityRadiusMinimum
{
@@ -220,7 +221,7 @@ namespace FancyZonesEditor.Models
List<string> result = new List<string>();
foreach (var pair in MainWindowSettingsModel.LayoutHotkeys.SelectedKeys)
{
if (string.IsNullOrEmpty(pair.Value) || pair.Value == Uuid)
if (pair.Key == Properties.Resources.Quick_Key_None || string.IsNullOrEmpty(pair.Value) || pair.Value == Uuid)
{
result.Add(pair.Key);
}
@@ -304,13 +305,13 @@ namespace FancyZonesEditor.Models
}
}
private int _zoneCount = LayoutSettings.DefaultZoneCount;
private int _zoneCount = LayoutDefaultSettings.DefaultZoneCount;
public bool IsZoneAddingAllowed
{
get
{
return TemplateZoneCount < LayoutSettings.MaxZones;
return TemplateZoneCount < LayoutDefaultSettings.MaxZones;
}
}
@@ -343,6 +344,7 @@ namespace FancyZonesEditor.Models
{
layout.SensitivityRadius = SensitivityRadius;
layout.TemplateZoneCount = TemplateZoneCount;
layout.Name = Name;
}
// Adds new custom Layout
@@ -390,6 +392,8 @@ namespace FancyZonesEditor.Models
break;
}
}
FirePropertyChanged(nameof(QuickKeysAvailable));
}
public void DefaultLayouts_PropertyChanged(object sender, PropertyChangedEventArgs e)

View File

@@ -3,32 +3,22 @@
// See the LICENSE file in the project root for more information.
using FancyZonesEditor.Models;
using FancyZonesEditorCommon.Data;
namespace FancyZonesEditor
{
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 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;
}
}

View File

@@ -8,6 +8,7 @@ using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using FancyZonesEditor.Models;
using FancyZonesEditorCommon.Data;
namespace FancyZonesEditor
{

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation
// 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.
@@ -7,6 +7,7 @@ using System.Reflection;
using System.Windows;
using System.Windows.Media;
using FancyZonesEditor.Utils;
using FancyZonesEditorCommon.Data;
namespace FancyZonesEditor.Models
{

View File

@@ -1,12 +0,0 @@
// 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.Models
{
public enum MonitorConfigurationType
{
Horizontal = 0,
Vertical,
}
}

View File

@@ -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>
/// Looks up a localized string similar to An error occurred while parsing layout hotkeys..
/// </summary>

View File

@@ -435,4 +435,7 @@
<data name="Set_Layout_As_Vertical_Default" xml:space="preserve">
<value>Set layout as a default for vertical monitor orientation</value>
</data>
<data name="Error_Parsing_Editor_Parameters_Message" xml:space="preserve">
<value>An error occurred while parsing editor parameters.</value>
</data>
</root>

View File

@@ -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 Microsoft.FancyZonesEditor.UITests.Utils
{
public class IOHelper
{
private readonly IFileSystem _fileSystem = new FileSystem();
public IOHelper()
{
}
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;
}
}
}

View File

@@ -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;
}
}
}