mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-01-27 14:37:17 +01:00
Compare commits
4 Commits
user/yeela
...
dev/vanzue
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2f0008473 | ||
|
|
8586dc88bb | ||
|
|
3322b8ca2f | ||
|
|
50038cbf3e |
2
.github/actions/spell-check/expect.txt
vendored
2
.github/actions/spell-check/expect.txt
vendored
@@ -1440,6 +1440,7 @@ secpol
|
||||
securestring
|
||||
SEEMASKINVOKEIDLIST
|
||||
SELCHANGE
|
||||
selfhost
|
||||
SENDCHANGE
|
||||
sendvirtualinput
|
||||
serverside
|
||||
@@ -1879,6 +1880,7 @@ winexe
|
||||
winforms
|
||||
winget
|
||||
wingetcreate
|
||||
wingetpkgs
|
||||
Winhook
|
||||
WINL
|
||||
winlogon
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
# Guidelines: Moving UI Tests into Unit Tests (WinUI 3 / MVVM Focused)
|
||||
|
||||
## ✅ General Principles
|
||||
|
||||
* **UI tests are expensive** — reserve them for UI-specific behaviors only (e.g., layout, visual hierarchy, interaction with OS).
|
||||
* **Push logic into ViewModels or services**, keeping Views as dumb as possible.
|
||||
* **Validate data bindings and wiring once**; don’t repeatedly test binding correctness in every case.
|
||||
* **Design with testability in mind** — favor DI, separation of concerns, and immutability.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Best Practices \& Coding Guidelines
|
||||
|
||||
### a. ✔️ Verify Data Binding via Default vs Non-default Cases (Once)
|
||||
|
||||
* Ensure each UI Page has a **ViewModel that encapsulates state**.
|
||||
* For each ViewModel:
|
||||
|
||||
* Write unit tests that setting can be loaded and saved (e.g., default → custom).
|
||||
* Use 1–2 **UI integration tests** (can be screenshot or state probe) to validate:
|
||||
|
||||
* Binding is correct
|
||||
* UI reflects the ViewModel state
|
||||
|
||||
```csharp
|
||||
// Unit test example
|
||||
\[Fact]
|
||||
public void SettingEnabledFlag\_ShouldTriggerChange()
|
||||
{
|
||||
var vm = new MySettingsViewModel();
|
||||
vm.IsFeatureEnabled = true;
|
||||
Assert.True(VerifyMySettings(SettingEnabledFlag.json));
|
||||
}
|
||||
```
|
||||
|
||||
> ✅ Don’t write multiple UI tests for each setting — use binding verification for confidence.
|
||||
|
||||
---
|
||||
|
||||
### b. 🧪 Business Logic Should Be Tested in ViewModel or Service
|
||||
|
||||
* Any logic that changes behavior based on inputs (e.g., "Action A should do X under Y setting") belongs in a **unit test**.
|
||||
* Avoid verifying the same logic again via UI automation — instead:
|
||||
|
||||
* Simulate inputs directly in the ViewModel
|
||||
* Assert the business result
|
||||
|
||||
```csharp
|
||||
\[Fact]
|
||||
public void Resize\_WithPercentSetting\_ShouldCalculateCorrectSize()
|
||||
{
|
||||
var vm = new ResizeViewModel();
|
||||
vm.InputSize = new Size(100, 100);
|
||||
vm.DimensionUnit = ResizeUnit.Percent;
|
||||
vm.ResizeValue = 200;
|
||||
|
||||
var result = vm.CalculateSize();
|
||||
Assert.Equal(new Size(200, 200), result);
|
||||
}
|
||||
```
|
||||
|
||||
> ✅ UI tests should NOT repeat all permutations — test logic in ViewModel.
|
||||
|
||||
---
|
||||
|
||||
### c. 🗱️ UI-Heavy Actions (e.g., Mouse, Focus) Should Be Stable and SOLID
|
||||
|
||||
* Abstract UI logic (e.g., pointer handling, UI effects) into **dedicated classes or handlers**.
|
||||
* Follow **SOLID principles**:
|
||||
|
||||
* Single Responsibility: one class = one behavior
|
||||
* Open/Closed: once stable, avoid modifying
|
||||
|
||||
* Write **manual test case or visual validation once**
|
||||
* Avoid repeating UI automation if the logic or visual interaction never changes
|
||||
|
||||
> ✅ Document test cases if necessary, but don’t keep re-running UI tests once frozen and stable.
|
||||
|
||||
---
|
||||
|
||||
## 🔀 Patterns to Apply
|
||||
|
||||
* **Command-based actions** (`ICommand`) → Test logic behind the command, not the UI element
|
||||
* **Observable ViewModels** (`INotifyPropertyChanged`) → Unit test property update logic and side effects
|
||||
* **Service Abstractions** (`IFileService`, `IImageProcessor`) → Pure logic tests without UI
|
||||
|
||||
---
|
||||
|
||||
## ✅ Summary: How to Migrate UI Tests Effectively
|
||||
|
||||
| Strategy | Practice |
|
||||
| --------------------------------- | --------------------------------------- |
|
||||
| 🔄 Move logic to ViewModel | Encapsulate all state \& decision-making |
|
||||
| 🔬 Write unit tests for all logic | Validate behavior without UI |
|
||||
| 🧪 UI test only once for binding | Default vs non-default case |
|
||||
| 🚫 Avoid repeating UI tests | Don't verify same flow again via UI |
|
||||
| 🗱️ Design for stability | Apply SOLID, document UI-only behaviors |
|
||||
|
||||
@@ -87,6 +87,13 @@
|
||||
|
||||
### Building PowerToys Locally
|
||||
|
||||
#### One stop script for building installer
|
||||
1. Open developer powershell for vs 2022
|
||||
2. Run tools\build\build-installer.ps1
|
||||
> For the first-time setup, please run the installer as an administrator. This ensures that the Wix tool can move wix.target to the desired location and trust the certificate used to sign the MSIX packages.
|
||||
|
||||
The following manual steps will not install the MSIX apps (such as Command Palette) on your local installer.
|
||||
|
||||
#### Prerequisites for building the MSI installer
|
||||
|
||||
1. Install the [WiX Toolset Visual Studio 2022 Extension](https://marketplace.visualstudio.com/items?itemName=WixToolset.WixToolsetVisualStudio2022Extension).
|
||||
|
||||
33
doc/devdocs/development/test-winget-install-locally.md
Normal file
33
doc/devdocs/development/test-winget-install-locally.md
Normal file
@@ -0,0 +1,33 @@
|
||||
## If for any reason, you'd like to test winget install scenario, you can follow this doc:
|
||||
|
||||
### Powertoys winget manifest definition:
|
||||
[winget repository](https://github.com/microsoft/winget-pkgs/tree/master/manifests/m/Microsoft/PowerToys)
|
||||
|
||||
### How to test a winget installation locally:
|
||||
1. Get artifacts from release CI pipeline Pipelines - Runs for PowerToys Signed YAML Release Build, or you can build one yourself by execute the
|
||||
'tools\build\build-installer.ps1' script
|
||||
|
||||
2. Get the artifact hash, this is required to define winget manifest
|
||||
```powershell
|
||||
cd /path/to/your/directory/contains/installer
|
||||
Get-FileHash -Path ".\<Installer-name>.exe" -Algorithm SHA256
|
||||
```
|
||||
3. Host your installer.exe - Attention: staged github release artifacts or artifacts in release pipeline is not OK in this step
|
||||
You can self-host it or you can upload to a publicly available endpoint
|
||||
**How to selfhost it** (A extremely simple way):
|
||||
```powershell
|
||||
python -m http.server 8000
|
||||
```
|
||||
|
||||
4. Download a version folder from wingetpkgs like: [version 0.92.1](https://github.com/microsoft/winget-pkgs/tree/master/manifests/m/Microsoft/PowerToys/0.92.1)
|
||||
and you get **a folder contains 3 yml files**
|
||||
>note: Do not put any files other than these three in this folder
|
||||
|
||||
5. Modify the yml files based on your version and the self hosted artifact link, and modify the sha256 hash for the installer you'd like to use
|
||||
|
||||
6. Start winget install:
|
||||
```powershell
|
||||
#execute as admin
|
||||
winget settings --enable LocalManifestFiles
|
||||
winget install --manifest "<folder_path_of_manifest_files>" --architecture x64 --scope user
|
||||
```
|
||||
Reference in New Issue
Block a user