mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-10-07 22:16:43 +00:00
311 lines
17 KiB
PowerShell
311 lines
17 KiB
PowerShell
# Headless component tests: no main/settings XAML, Show/ShowDialog, or message loop.
|
|
BeforeAll {
|
|
Add-Type -AssemblyName PresentationFramework
|
|
$script:RepoRoot = Split-Path $PSScriptRoot -Parent
|
|
foreach ($file in @('FileIO/Import-JsonFile', 'FileIO/Import-LanguageFile',
|
|
'GUI/Ui-Preferences', 'GUI/Show-SettingsDialog', 'GUI/Set-WindowThemeResources',
|
|
'GUI/MainWindow-Localization', 'GUI/MainWindow-TweaksBuilder', 'GUI/MainWindow-AppSelection',
|
|
'GUI/MainWindow-Deployment', 'GUI/Show-Bubble', 'Helpers/Get-UserName')) {
|
|
. "$script:RepoRoot/Scripts/$file.ps1"
|
|
}
|
|
$script:LanguagesPath = Join-Path $script:RepoRoot 'Config/Languages'
|
|
$script:FeaturesFilePath = Join-Path $script:RepoRoot 'Config/Features.json'
|
|
$script:Features = @{}
|
|
foreach ($feature in (Import-JsonFile -filePath $script:FeaturesFilePath).Features) { $script:Features[$feature.FeatureId] = $feature }
|
|
$tokens = $null; $parseErrors = $null
|
|
$mainAst = [System.Management.Automation.Language.Parser]::ParseFile("$script:RepoRoot/Scripts/GUI/Show-MainWindow.ps1", [ref]$tokens, [ref]$parseErrors)
|
|
$script:SearchHandlers = @{}
|
|
foreach ($handler in $mainAst.FindAll({
|
|
param($node)
|
|
$node -is [System.Management.Automation.Language.InvokeMemberExpressionAst] -and
|
|
$node.Member.Value -eq 'Add_TextChanged' -and $node.Expression.VariablePath.UserPath -in @('appSearchBox', 'tweakSearchBox')
|
|
}, $true)) {
|
|
$script:SearchHandlers[$handler.Expression.VariablePath.UserPath] = $handler.Arguments[0].ScriptBlock.GetScriptBlock()
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Creates a minimal window for dynamic tweak localization tests.
|
|
|
|
.OUTPUTS
|
|
System.Windows.Window. The test window with its registered column panels.
|
|
#>
|
|
function New-LanguageTestWindow {
|
|
$window = [System.Windows.Window]::new()
|
|
[System.Windows.NameScope]::SetNameScope($window, [System.Windows.NameScope]::new())
|
|
$window.Content = [System.Windows.Controls.StackPanel]::new()
|
|
foreach ($name in @('Column0Panel', 'Column1Panel', 'Column2Panel')) {
|
|
$panel = [System.Windows.Controls.StackPanel]::new()
|
|
$window.RegisterName($name, $panel)
|
|
[void]$window.Content.Children.Add($panel)
|
|
}
|
|
return $window
|
|
}
|
|
}
|
|
|
|
Describe 'Language changes on existing controls' {
|
|
BeforeEach {
|
|
$script:Lang = Import-LanguageFile -LanguageCode 'en-US'
|
|
$script:ModernStandbySupported = $false
|
|
}
|
|
|
|
It 'matches fresh and refreshed tweak text on Windows build <Build>' -ForEach @(
|
|
@{ Build = 19045 }
|
|
@{ Build = 26100 }
|
|
) {
|
|
<#
|
|
.SYNOPSIS
|
|
Serializes current tweak presentation text for comparison.
|
|
|
|
.DESCRIPTION
|
|
Captures labels, tooltips, and options to compare freshly created controls
|
|
with controls refreshed after a language change.
|
|
|
|
.PARAMETER Window
|
|
The test window containing registered tweak controls and label borders.
|
|
|
|
.OUTPUTS
|
|
System.String. The serialized presentation snapshot.
|
|
#>
|
|
function Get-TweakPresentationSnapshot($window) {
|
|
$rows = foreach ($name in ($script:UiControlMappings.Keys | Sort-Object)) {
|
|
$control = $window.FindName($name)
|
|
$label = if ($control -is [System.Windows.Controls.CheckBox]) { $control.Content }
|
|
else { $window.FindName("${name}_LabelBorder").Child.Text }
|
|
[PSCustomObject]@{
|
|
Name = $name
|
|
Label = $label
|
|
ToolTip = if ($control.ToolTip) { $control.ToolTip.Text } else { $null }
|
|
Options = @($control.Items | ForEach-Object { $_.Content })
|
|
}
|
|
}
|
|
return ConvertTo-Json -InputObject @($rows) -Depth 4 -Compress
|
|
}
|
|
|
|
foreach ($language in @('nl-NL', 'pt-BR')) {
|
|
$script:Lang = Import-LanguageFile -LanguageCode $language
|
|
$fresh = New-LanguageTestWindow
|
|
New-DynamicTweakControls -Window $fresh -WinVersion $Build
|
|
$expected = Get-TweakPresentationSnapshot $fresh
|
|
|
|
$script:Lang = Import-LanguageFile -LanguageCode 'en-US'
|
|
$refreshed = New-LanguageTestWindow
|
|
New-DynamicTweakControls -Window $refreshed -WinVersion $Build
|
|
$script:Lang = Import-LanguageFile -LanguageCode $language
|
|
Update-MainWindowTweakLanguage -Window $refreshed
|
|
Get-TweakPresentationSnapshot $refreshed | Should -Be $expected
|
|
}
|
|
}
|
|
|
|
It 'updates text, accessibility names and detached menu resources with English fallback' {
|
|
$window = New-LanguageTestWindow
|
|
$button = [System.Windows.Controls.Button]::new()
|
|
$button.SetResourceReference([System.Windows.Controls.ContentControl]::ContentProperty, 'Language_SettingsTitle')
|
|
$button.SetResourceReference([System.Windows.Automation.AutomationProperties]::NameProperty, 'Language_SettingsTitle')
|
|
[void]$window.Content.Children.Add($button)
|
|
$menu = [System.Windows.Controls.ContextMenu]::new()
|
|
$window.RegisterName('MainMenu', $menu)
|
|
$item = [System.Windows.Controls.MenuItem]::new()
|
|
$item.SetResourceReference([System.Windows.Controls.HeaderedItemsControl]::HeaderProperty, 'Language_MenuAbout')
|
|
[void]$menu.Items.Add($item)
|
|
|
|
foreach ($language in @('en-US', 'nl-NL', 'pt-BR', 'en-US')) {
|
|
$script:Lang = Import-LanguageFile -LanguageCode $language
|
|
Update-WindowLanguageResources -Window $window
|
|
$button.Content | Should -Be (Get-Translation -Key 'SettingsTitle')
|
|
[System.Windows.Automation.AutomationProperties]::GetName($button) | Should -Be $button.Content
|
|
$item.Header | Should -Be (Get-Translation -Key 'MenuAbout')
|
|
}
|
|
$script:Lang = [PSCustomObject]@{ Chrome = [PSCustomObject]@{ SettingsTitle = 'Custom & <text>' }; Fallback = $script:Lang }
|
|
Update-WindowLanguageResources -Window $window
|
|
$button.Content | Should -Be 'Custom & <text>'
|
|
$item.Header | Should -Be 'About'
|
|
}
|
|
|
|
It 'translates generated tweaks without replacing controls, selections or applied-state metadata' {
|
|
$window = New-LanguageTestWindow
|
|
New-DynamicTweakControls -Window $window -WinVersion 26100
|
|
$checkbox = $window.FindName('Feature_DisableTelemetry_Combo')
|
|
$checkbox.IsChecked = $false
|
|
$checkbox | Add-Member -NotePropertyMembers @{ InitialState = $true; SystemState = $true }
|
|
$disabled = $window.FindName('Feature_DisableWidgets_Combo')
|
|
$disabled.IsChecked = $true
|
|
$disabled.IsEnabled = $false
|
|
$disabled | Add-Member -NotePropertyMembers @{ InitialState = $true; SystemState = $true; DisableWhenApplied = $true }
|
|
$group = $window.FindName('Group_SearchIconCombo')
|
|
$group.SelectedIndex = 2
|
|
$group | Add-Member -NotePropertyMembers @{ InitialIndex = 1; SystemIndex = 1 }
|
|
$selectedItem = $group.SelectedItem
|
|
$script:SelectionChanges = 0
|
|
$group.Add_SelectionChanged({ $script:SelectionChanges++ })
|
|
$before = @(Get-PendingTweakActions -Window $window -ShowAppliedTweaksMode $true | ForEach-Object { "$($_.Action):$($_.FeatureId)" } | Sort-Object)
|
|
|
|
foreach ($language in @('nl-NL', 'pt-BR', 'en-US')) {
|
|
$script:Lang = Import-LanguageFile -LanguageCode $language
|
|
Update-MainWindowTweakLanguage -Window $window
|
|
[object]::ReferenceEquals($window.FindName('Feature_DisableTelemetry_Combo'), $checkbox) | Should -BeTrue
|
|
$checkbox.Content | Should -Be (Get-Translation -Key 'DisableTelemetry' -Field 'Label' -Section 'Features')
|
|
$checkbox.ToolTip.Text | Should -Be (Get-Translation -Key 'DisableTelemetry' -Field 'ToolTip' -Section 'Features')
|
|
$disabled.IsEnabled | Should -BeFalse
|
|
$disabled.DisableWhenApplied | Should -BeTrue
|
|
$disabled.ToolTip.Text | Should -Be (Get-Translation -Key 'TweaksAlreadyAppliedTooltip')
|
|
[object]::ReferenceEquals($group.SelectedItem, $selectedItem) | Should -BeTrue
|
|
$group.SelectedIndex | Should -Be 2
|
|
$selectedItem.Content | Should -Be (Get-GroupValueTranslation -GroupId 'SearchIcon' -FeatureId $script:UiControlMappings['Group_SearchIconCombo'].Values[1].FeatureIds[0] -FallbackLabel 'fallback')
|
|
@(Get-PendingTweakActions -Window $window -ShowAppliedTweaksMode $true | ForEach-Object { "$($_.Action):$($_.FeatureId)" } | Sort-Object) | Should -Be $before
|
|
$script:FeatureLabelLookup['DisableTelemetry'] | Should -Be $checkbox.Content
|
|
foreach ($category in $script:CategoryLanguageControls) {
|
|
$category.Header.Text | Should -Be (Get-Translation -Key $category.CategoryId -Field 'Label' -Section 'Categories')
|
|
}
|
|
}
|
|
$script:SelectionChanges | Should -Be 0
|
|
}
|
|
|
|
It 'updates app display and search metadata while preserving removal IDs and selection' {
|
|
$panel = [System.Windows.Controls.StackPanel]::new()
|
|
$app = [System.Windows.Controls.CheckBox]::new()
|
|
$app.IsChecked = $true
|
|
$app.Tag = 'Microsoft.WindowsCalculator, Other.Id'
|
|
$app | Add-Member -NotePropertyMembers @{
|
|
AppIds = @('Microsoft.WindowsCalculator', 'Other.Id'); AppName = ''; AppDescription = ''
|
|
AppNameText = [System.Windows.Controls.TextBlock]::new()
|
|
AppDescriptionText = [System.Windows.Controls.TextBlock]::new()
|
|
}
|
|
[void]$panel.Children.Add($app)
|
|
$script:JsonPresetCheckboxes = @()
|
|
$script:PreloadedAppData = @('old catalog')
|
|
|
|
foreach ($language in @('nl-NL', 'pt-BR', 'en-US')) {
|
|
$script:Lang = Import-LanguageFile -LanguageCode $language
|
|
Update-MainWindowAppLanguage -AppsPanel $panel
|
|
$app.AppNameText.Text | Should -Be (Get-Translation -Key 'Microsoft.WindowsCalculator' -Field 'FriendlyName' -Section 'Apps')
|
|
$app.AppName | Should -Be $app.AppNameText.Text
|
|
$app.AppDescriptionText.ToolTip | Should -Be $app.AppDescription
|
|
$app.AppIds | Should -Be @('Microsoft.WindowsCalculator', 'Other.Id')
|
|
$app.Tag | Should -Be 'Microsoft.WindowsCalculator, Other.Id'
|
|
$app.IsChecked | Should -BeTrue
|
|
}
|
|
$script:PreloadedAppData | Should -BeNullOrEmpty
|
|
}
|
|
|
|
It 'refreshes search and deployment text without changing user input or selections' {
|
|
Mock Get-UserName { 'TestUser' }
|
|
Mock Update-AppsPanelSort {}
|
|
Mock Hide-Bubble {}
|
|
$window = New-LanguageTestWindow
|
|
New-DynamicTweakControls -Window $window -WinVersion 26100
|
|
$appsPanel = [System.Windows.Controls.StackPanel]::new()
|
|
$window.RegisterName('AppSelectionPanel', $appsPanel)
|
|
[void]$window.Content.Children.Add($appsPanel)
|
|
$app = [System.Windows.Controls.CheckBox]::new()
|
|
$app.IsChecked = $true
|
|
$app.Tag = 'Microsoft.WindowsCalculator'
|
|
$app | Add-Member -NotePropertyMembers @{
|
|
AppIds = @('Microsoft.WindowsCalculator'); AppName = 'Calculator'; AppDescription = ''
|
|
AppNameText = [System.Windows.Controls.TextBlock]::new()
|
|
AppDescriptionText = [System.Windows.Controls.TextBlock]::new()
|
|
}
|
|
[void]$appsPanel.Children.Add($app)
|
|
foreach ($name in @('UserSelectionDescription', 'UsernameValidationMessage', 'AppSelectionStatus', 'AppRemovalScopeDescription', 'AppSearchPlaceholder', 'TweakSearchPlaceholder')) {
|
|
$window.RegisterName($name, [System.Windows.Controls.TextBlock]::new())
|
|
}
|
|
foreach ($name in @('OtherUsernameTextBox', 'AppSearchBox', 'TweakSearchBox')) {
|
|
$window.RegisterName($name, [System.Windows.Controls.TextBox]::new())
|
|
}
|
|
$userCombo = [System.Windows.Controls.ComboBox]::new()
|
|
foreach ($label in @('Current', 'Other', 'Default')) {
|
|
[void]$userCombo.Items.Add([System.Windows.Controls.ComboBoxItem]::new())
|
|
}
|
|
$userCombo.SelectedIndex = 1
|
|
$window.RegisterName('UserSelectionCombo', $userCombo)
|
|
$window.FindName('OtherUsernameTextBox').Text = 'Alice'
|
|
$scope = [System.Windows.Controls.ComboBox]::new()
|
|
$target = [System.Windows.Controls.ComboBoxItem]::new()
|
|
$target.Name = 'AppRemovalScopeTargetUser'
|
|
[void]$scope.Items.Add($target)
|
|
$scope.SelectedIndex = 0
|
|
$window.RegisterName('AppRemovalScopeCombo', $scope)
|
|
$window.RegisterName('AppRemovalScopeSection', [System.Windows.Controls.Border]::new())
|
|
$tabs = [System.Windows.Controls.TabControl]::new()
|
|
foreach ($label in @('Home', 'Apps', 'Tweaks', 'Deploy')) { [void]$tabs.Items.Add($label) }
|
|
$tabs.SelectedIndex = 2
|
|
$window.RegisterName('MainTabControl', $tabs)
|
|
$appSearchBox = $window.FindName('AppSearchBox')
|
|
$appSearchPlaceholder = $window.FindName('AppSearchPlaceholder')
|
|
$tweakSearchBox = $window.FindName('TweakSearchBox')
|
|
$tweakSearchPlaceholder = $window.FindName('TweakSearchPlaceholder')
|
|
$tweaksScrollViewer = $null
|
|
$appSearchBox.Text = 'rekenmachine'
|
|
$tweakSearchBox.Text = 'telemetrie'
|
|
$appSearchBox.Add_TextChanged($script:SearchHandlers['appSearchBox'])
|
|
$tweakSearchBox.Add_TextChanged($script:SearchHandlers['tweakSearchBox'])
|
|
$script:AppSearchMatches = @(); $script:AppSearchMatchIndex = -1
|
|
$script:JsonPresetCheckboxes = @()
|
|
$script:SortColumn = 'Name'; $script:SortAscending = $true
|
|
$window.Resources['SearchHighlightColor'] = [System.Windows.Media.Brushes]::Yellow
|
|
$window.Resources['SearchHighlightActiveColor'] = [System.Windows.Media.Brushes]::Orange
|
|
$checkbox = $window.FindName('Feature_DisableTelemetry_Combo')
|
|
$checkbox.IsChecked = $true
|
|
|
|
$script:Lang = Import-LanguageFile -LanguageCode 'nl-NL'
|
|
Update-MainWindowLanguage -Window $window
|
|
|
|
$userCombo.SelectedIndex | Should -Be 1
|
|
$scope.SelectedItem | Should -Be $target
|
|
$window.FindName('OtherUsernameTextBox').Text | Should -Be 'Alice'
|
|
$tabs.SelectedIndex | Should -Be 2
|
|
$appSearchBox.Text | Should -Be 'rekenmachine'
|
|
$tweakSearchBox.Text | Should -Be 'telemetrie'
|
|
$script:AppSearchMatches.Count | Should -Be 1
|
|
[object]::ReferenceEquals($script:AppSearchMatches[0], $app) | Should -BeTrue
|
|
$checkbox.Background | Should -Be ([System.Windows.Media.Brushes]::Yellow)
|
|
$checkbox.IsChecked | Should -BeTrue
|
|
$app.IsChecked | Should -BeTrue
|
|
$window.FindName('AppSelectionStatus').Text | Should -Be (Get-Translation -Key 'AppSelectionStatusSelected' -Count 1 -FormatArgs @(1))
|
|
$window.FindName('UserSelectionDescription').Text | Should -Be (Get-Translation -Key 'DeployUserDescriptionOtherUserNamed' -FormatArgs @('Alice'))
|
|
$window.FindName('AppRemovalScopeDescription').Text | Should -Be (Get-Translation -Key 'AppRemovalScopeDescriptionTargetUser')
|
|
$script:UpdatingLanguage | Should -BeFalse
|
|
}
|
|
}
|
|
|
|
Describe 'Settings update the same window after Save' {
|
|
BeforeEach {
|
|
$script:IsLoadingApps = $false
|
|
$script:UiPreferences = @{ Theme = 'Auto'; Language = 'en-US' }
|
|
$script:Lang = [PSCustomObject]@{ LanguageCode = 'en-US' }
|
|
Mock Set-WindowThemeResources {}
|
|
Mock Update-MainWindowLanguage {}
|
|
$script:WindowClosed = $false
|
|
$script:WindowUnderTest = New-LanguageTestWindow
|
|
$script:WindowUnderTest.Add_Closed({ $script:WindowClosed = $true })
|
|
}
|
|
|
|
It 'updates a saved theme without changing language or closing the window' {
|
|
Mock Show-SettingsDialog { $script:UiPreferences.Theme = 'Dark'; return $true }
|
|
Open-MainWindowSettings -Window $script:WindowUnderTest
|
|
Should -Invoke Set-WindowThemeResources -Times 1 -Exactly -ParameterFilter { $usesDarkMode -eq $true }
|
|
Should -Invoke Update-MainWindowLanguage -Times 0 -Exactly
|
|
$script:WindowClosed | Should -BeFalse
|
|
}
|
|
|
|
It 'updates a saved language without closing the window' {
|
|
Mock Show-SettingsDialog {
|
|
$script:Lang = [PSCustomObject]@{ LanguageCode = 'nl-NL' }
|
|
$script:UiPreferences.Theme = 'Dark'
|
|
return $true
|
|
}
|
|
Open-MainWindowSettings -Window $script:WindowUnderTest
|
|
Should -Invoke Update-MainWindowLanguage -Times 1 -Exactly -ParameterFilter { [object]::ReferenceEquals($Window, $script:WindowUnderTest) }
|
|
Should -Invoke Set-WindowThemeResources -Times 1 -Exactly -ParameterFilter { $usesDarkMode -eq $true }
|
|
$script:WindowClosed | Should -BeFalse
|
|
}
|
|
|
|
It 'does not update presentation when the settings dialog is cancelled' {
|
|
Mock Show-SettingsDialog { $false }
|
|
Open-MainWindowSettings -Window $script:WindowUnderTest
|
|
Should -Invoke Set-WindowThemeResources -Times 0 -Exactly
|
|
Should -Invoke Update-MainWindowLanguage -Times 0 -Exactly
|
|
$script:WindowClosed | Should -BeFalse
|
|
}
|
|
}
|