Files
PowerToys/src/modules/fancyzones/UITests-FancyZonesEditor/ApplyLayoutTests.cs
XiaofengWang 350b9b78fe UI Test Automation (#39777)
### Summary

This pull request includes the following updates:

1. Improvements and stabilization of the UI automation framework  
2. Setup of the UI automation pipeline  
3. Add UI test cases for FancyZones  
4. Add UI test cases for MouseUtils  
5. Improvements of Hosts Editor UI tests

---

### Related Links

- **Current Release checklist coverage**:  
 
https://github.com/microsoft/PowerToys/blob/feature/UITestAutomation/src/common/UITestAutomation/Doc/ui-automation-cover-list.md

- **UI Automation pipeline**:  
 
https://microsoft.visualstudio.com/Dart/_build?definitionId=161438&_a=summary

---------

Signed-off-by: Shawn Yuan <shuai.yuan.zju@gmail.com>
Signed-off-by: Shawn Yuan <shuaiyuan@microsoft.com>
Co-authored-by: Jerry Xu <n.xu@outlook.com>
Co-authored-by: Zhaopeng Wang <zhaopengwang@microsoft.com>
Co-authored-by: Xiaofeng Wang (from Dev Box) <xiaofengwang@microsoft.com>
Co-authored-by: Mengyuan <162882040+chenmy77@users.noreply.github.com>
Co-authored-by: yaqingmi <miyaqing01@gmail.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: Yaqing Mi (from Dev Box) <yaqingmi@microsoft.com>
Co-authored-by: Kai Tao <69313318+vanzue@users.noreply.github.com>
Co-authored-by: zhaopeng wang <33367956+wang563681252@users.noreply.github.com>
Co-authored-by: Laszlo Nemeth <57342539+donlaci@users.noreply.github.com>
Co-authored-by: RokyZevon <12629919+RokyZevon@users.noreply.github.com>
Co-authored-by: Yu Leng <42196638+moooyo@users.noreply.github.com>
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Davide Giacometti <25966642+davidegiacometti@users.noreply.github.com>
Co-authored-by: Gordon Lam <73506701+yeelam-gordon@users.noreply.github.com>
Co-authored-by: ruslanlap <106077551+ruslanlap@users.noreply.github.com>
Co-authored-by: Muhammad Danish <mdanishkhdev@gmail.com>
Co-authored-by: Bennett Blodinger <benwa@users.noreply.github.com>
Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
Co-authored-by: Ionuț Manța <ionut@janeasystems.com>
Co-authored-by: Hao Liu <liuhaobupt@163.com>
Co-authored-by: OlegHarchevkin <40352094+OlegKharchevkin@users.noreply.github.com>
Co-authored-by: dcog989 <89043002+dcog989@users.noreply.github.com>
Co-authored-by: PesBandi <127593627+PesBandi@users.noreply.github.com>
Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com>
Co-authored-by: vanzue <vanzue@outlook.com>
Co-authored-by: Typpi <20943337+Nick2bad4u@users.noreply.github.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
Co-authored-by: Abhyudit <64366765+bitmap4@users.noreply.github.com>
Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>
Co-authored-by: Ved Nig <vednig12@outlook.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: Aung Khaing Khant <aungkhaingkhant.dev@gmail.com>
Co-authored-by: Aung Khaing Khant <aungkhaingkhant@advent-soft.com>
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
Co-authored-by: leileizhang <leilzh@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
Co-authored-by: Shawn Yuan <128874481+shuaiyuanxx@users.noreply.github.com>
Co-authored-by: Shawn Yuan <shuai.yuan.zju@gmail.com>
Co-authored-by: cryolithic <cryolithic@gmail.com>
Co-authored-by: Lemonyte <49930425+lemonyte@users.noreply.github.com>
Co-authored-by: Gordon Lam (SH) <yeelam@microsoft.com>
Co-authored-by: Corey Hayward <72159232+CoreyHayward@users.noreply.github.com>
Co-authored-by: Jerry Xu <nxu@microsoft.com>
Co-authored-by: Shawn Yuan <shuaiyuan@microsoft.com>
Co-authored-by: Kayla Cinnamon <cinnamon@microsoft.com>
Co-authored-by: Jeremy Sinclair <4016293+snickler@users.noreply.github.com>
2025-06-17 17:56:48 +08:00

306 lines
15 KiB
C#

// 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 FancyZonesEditor.Models;
using FancyZonesEditorCommon.Data;
using Microsoft.FancyZonesEditor.UnitTests.Utils;
using Microsoft.PowerToys.UITest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ModernWpf.Controls;
using OpenQA.Selenium;
using static Microsoft.FancyZonesEditor.UnitTests.Utils.FancyZonesEditorHelper;
namespace Microsoft.FancyZonesEditor.UITests
{
[TestClass]
public class ApplyLayoutTests : UITestBase
{
public ApplyLayoutTests()
: base(PowerToysModule.FancyZone, WindowSize.UnSpecified)
{
}
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 = CustomLayout.Canvas.TypeToString(),
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 = LayoutType.Blank.TypeToString(),
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = LayoutType.Focus.TypeToString(),
ZoneCount = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = LayoutType.Rows.TypeToString(),
ZoneCount = 2,
ShowSpacing = true,
Spacing = 10,
SensitivityRadius = 10,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = LayoutType.Columns.TypeToString(),
ZoneCount = 2,
ShowSpacing = true,
Spacing = 20,
SensitivityRadius = 20,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = LayoutType.Grid.TypeToString(),
ZoneCount = 4,
ShowSpacing = false,
Spacing = 10,
SensitivityRadius = 30,
},
new LayoutTemplates.TemplateLayoutWrapper
{
Type = LayoutType.PriorityGrid.TypeToString(),
ZoneCount = 3,
ShowSpacing = true,
Spacing = 1,
SensitivityRadius = 40,
},
},
};
[TestInitialize]
public void TestInitialize()
{
FancyZonesEditorHelper.Files.Restore();
EditorParameters editorParameters = new EditorParameters();
FancyZonesEditorHelper.Files.ParamsIOHelper.WriteData(editorParameters.Serialize(Parameters));
LayoutTemplates layoutTemplates = new LayoutTemplates();
FancyZonesEditorHelper.Files.LayoutTemplatesIOHelper.WriteData(layoutTemplates.Serialize(TemplateLayoutsList));
CustomLayouts customLayouts = new CustomLayouts();
FancyZonesEditorHelper.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 = MonitorConfigurationType.Horizontal.TypeToString(),
Layout = new DefaultLayouts.DefaultLayoutWrapper.LayoutWrapper
{
Type = LayoutType.Focus.TypeToString(),
ZoneCount = 4,
ShowSpacing = true,
Spacing = 5,
SensitivityRadius = 20,
},
},
new DefaultLayouts.DefaultLayoutWrapper
{
MonitorConfiguration = MonitorConfigurationType.Vertical.TypeToString(),
Layout = new DefaultLayouts.DefaultLayoutWrapper.LayoutWrapper
{
Type = LayoutType.Custom.TypeToString(),
Uuid = "{0D6D2F58-9184-4804-81E4-4E4CC3476DC1}",
ZoneCount = 0,
ShowSpacing = false,
Spacing = 0,
SensitivityRadius = 0,
},
},
},
};
FancyZonesEditorHelper.Files.DefaultLayoutsIOHelper.WriteData(defaultLayouts.Serialize(defaultLayoutsListWrapper));
LayoutHotkeys layoutHotkeys = new LayoutHotkeys();
LayoutHotkeys.LayoutHotkeysWrapper layoutHotkeysWrapper = new LayoutHotkeys.LayoutHotkeysWrapper
{
LayoutHotkeys = new List<LayoutHotkeys.LayoutHotkeyWrapper> { },
};
FancyZonesEditorHelper.Files.LayoutHotkeysIOHelper.WriteData(layoutHotkeys.Serialize(layoutHotkeysWrapper));
AppliedLayouts appliedLayouts = new AppliedLayouts();
AppliedLayouts.AppliedLayoutsListWrapper appliedLayoutsWrapper = new AppliedLayouts.AppliedLayoutsListWrapper
{
AppliedLayouts = new List<AppliedLayouts.AppliedLayoutWrapper> { },
};
FancyZonesEditorHelper.Files.AppliedLayoutsIOHelper.WriteData(appliedLayouts.Serialize(appliedLayoutsWrapper));
this.RestartScopeExe();
}
[TestMethod]
public void ApplyCustomLayout()
{
var layout = CustomLayoutsList.CustomLayouts[0];
Assert.IsFalse(Session.Find<Element>(layout.Name).Selected);
Session.Find<Element>(layout.Name).Click();
Assert.IsTrue(Session.Find<Element>(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 = LayoutType.Columns;
var layout = TestConstants.TemplateLayoutNames[layoutType];
Assert.IsFalse(Session.Find<Element>(layout).Selected);
Session.Find<Element>(layout).Click();
Assert.IsTrue(Session.Find<Element>(layout).Selected);
AppliedLayouts appliedLayouts = new AppliedLayouts();
var data = appliedLayouts.Read(appliedLayouts.File);
Assert.AreEqual(Parameters.Monitors.Count, data.AppliedLayouts.Count);
Assert.AreEqual(layoutType.TypeToString(), data.AppliedLayouts[0].AppliedLayout.Type);
Assert.AreEqual(Parameters.Monitors[0].MonitorNumber, data.AppliedLayouts[0].Device.MonitorNumber);
}
[TestMethod("FancyZonesEditor.Basic.ApplyLayoutsOnEachMonitor")]
[TestCategory("FancyZones Editor #10")]
public void ApplyLayoutsOnEachMonitor()
{
// apply the layout on the first monitor
var firstLayoutType = LayoutType.Columns;
var firstLayoutName = TestConstants.TemplateLayoutNames[firstLayoutType];
Session.Find<Element>(firstLayoutName).Click();
Assert.IsTrue(Session.Find<Element>(firstLayoutName)!.Selected);
// apply the layout on the second monitor
Session.Find<Element>(PowerToys.UITest.By.AccessibilityId("Monitors")).Find<Element>("Monitor 2").Click();
var secondLayout = CustomLayoutsList.CustomLayouts[0];
Session.Find<Element>(secondLayout.Name).Click();
Assert.IsTrue(Session.Find<Element>(secondLayout.Name)!.Selected);
// verify the layout on the first monitor wasn't changed
Session.Find<Element>(PowerToys.UITest.By.AccessibilityId("Monitors")).Find<Element>("Monitor 1").Click();
Assert.IsTrue(Session.Find<Element>(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(firstLayoutType.TypeToString(), 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("FancyZonesEditor.Basic.ApplyTemplateWithDifferentParametersOnEachMonitor")]
[TestCategory("FancyZones Editor #10")]
public void ApplyTemplateWithDifferentParametersOnEachMonitor()
{
var layoutType = LayoutType.Columns;
var layoutName = TestConstants.TemplateLayoutNames[layoutType];
// apply the layout on the first monitor, set parameters
Session.Find<Element>(layoutName).Click();
Session.Find<Element>(layoutName).Find<Button>(PowerToys.UITest.By.AccessibilityId(AccessibilityId.EditLayoutButton)).Click();
var slider = Session.Find<Custom>(PowerToys.UITest.By.AccessibilityId(AccessibilityId.TemplateZoneSlider));
Assert.IsNotNull(slider);
slider.SendKeys(Key.Right);
slider.SendKeys(Key.Right);
var expectedFirstLayoutZoneCount = int.Parse(slider.Text!, CultureInfo.InvariantCulture);
Session.Find<Button>(ElementName.Save).Click();
// apply the layout on the second monitor, set different parameters
Session.Find<Element>(PowerToys.UITest.By.AccessibilityId("Monitors")).Find<Element>("Monitor 2").Click();
Session.Find<Element>(layoutName).Click();
Session.Find<Element>(layoutName).Find<Button>(PowerToys.UITest.By.AccessibilityId(AccessibilityId.EditLayoutButton)).Click();
slider = Session.Find<Custom>(PowerToys.UITest.By.AccessibilityId(AccessibilityId.TemplateZoneSlider));
Assert.IsNotNull(slider);
slider.SendKeys(Key.Left);
var expectedSecondLayoutZoneCount = int.Parse(slider.Text!, CultureInfo.InvariantCulture);
Session.Find<Button>(ElementName.Save).Click();
// verify the layout on the first monitor wasn't changed
Session.Find<Element>(PowerToys.UITest.By.AccessibilityId("Monitors")).Find<Element>("Monitor 1").Click();
Session.Find<Element>(layoutName).Find<Button>(PowerToys.UITest.By.AccessibilityId(AccessibilityId.EditLayoutButton)).Click();
slider = Session.Find<Custom>(PowerToys.UITest.By.AccessibilityId(AccessibilityId.TemplateZoneSlider));
Assert.IsNotNull(slider);
Assert.AreEqual(expectedFirstLayoutZoneCount, int.Parse(slider.Text!, CultureInfo.InvariantCulture));
Session.Find<Button>(ElementName.Cancel).Click();
// check the file
var appliedLayouts = new AppliedLayouts();
var data = appliedLayouts.Read(appliedLayouts.File);
Assert.AreEqual(Parameters.Monitors.Count, data.AppliedLayouts.Count);
Assert.AreEqual(layoutType.TypeToString(), 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(layoutType.TypeToString(), data.AppliedLayouts.Find(x => x.Device.MonitorNumber == 2).AppliedLayout.Type);
Assert.AreEqual(expectedSecondLayoutZoneCount, data.AppliedLayouts.Find(x => x.Device.MonitorNumber == 2).AppliedLayout.ZoneCount);
}
}
}