mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 19:27:56 +01:00
Add more reusable code
This commit is contained in:
@@ -21,6 +21,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
public class SettingsConfigHelper
|
||||
{
|
||||
private static readonly JsonSerializerOptions IndentedJsonOptions = new() { WriteIndented = true };
|
||||
private static readonly SettingsUtils SettingsUtils = new SettingsUtils();
|
||||
|
||||
/// <summary>
|
||||
/// Configures global PowerToys settings to enable only specified modules and disable all others.
|
||||
@@ -36,13 +37,10 @@ namespace Microsoft.PowerToys.UITest
|
||||
|
||||
try
|
||||
{
|
||||
var settingsUtils = new SettingsUtils();
|
||||
|
||||
// Get settings or create default if they don't exist
|
||||
GeneralSettings settings;
|
||||
try
|
||||
{
|
||||
settings = settingsUtils.GetSettingsOrDefault<GeneralSettings>();
|
||||
settings = SettingsUtils.GetSettingsOrDefault<GeneralSettings>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -50,32 +48,24 @@ namespace Microsoft.PowerToys.UITest
|
||||
settings = new GeneralSettings();
|
||||
}
|
||||
|
||||
// Convert settings to JSON string
|
||||
string settingsJson = settings.ToJsonString();
|
||||
|
||||
// Deserialize to JsonDocument to manipulate the Enabled modules
|
||||
using (JsonDocument doc = JsonDocument.Parse(settingsJson))
|
||||
{
|
||||
var options = new JsonSerializerOptions { WriteIndented = true };
|
||||
var root = doc.RootElement.Clone();
|
||||
|
||||
// Get the enabled modules object
|
||||
if (root.TryGetProperty("enabled", out var enabledElement))
|
||||
{
|
||||
// Create a dictionary of module properties with their enable states
|
||||
var enabledModules = new Dictionary<string, bool>();
|
||||
|
||||
// Iterate through all properties in the enabled object
|
||||
foreach (var property in enabledElement.EnumerateObject())
|
||||
{
|
||||
string moduleName = property.Name;
|
||||
|
||||
// Check if this module should be enabled
|
||||
bool shouldEnable = Array.Exists(modulesToEnable, m => string.Equals(m, moduleName, StringComparison.Ordinal));
|
||||
enabledModules[moduleName] = shouldEnable;
|
||||
}
|
||||
|
||||
// Rebuild the settings with updated enabled modules
|
||||
var settingsDict = JsonSerializer.Deserialize<Dictionary<string, object>>(settingsJson);
|
||||
if (settingsDict != null)
|
||||
{
|
||||
@@ -85,8 +75,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
}
|
||||
}
|
||||
|
||||
// Save the modified settings
|
||||
settingsUtils.SaveSettings(settingsJson);
|
||||
SettingsUtils.SaveSettings(settingsJson);
|
||||
|
||||
string enabledList = modulesToEnable.Length > 0 ? string.Join(", ", modulesToEnable) : "none";
|
||||
Debug.WriteLine($"Successfully updated global settings");
|
||||
@@ -98,5 +87,89 @@ namespace Microsoft.PowerToys.UITest
|
||||
throw new InvalidOperationException($"Failed to configure global module settings: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates a module's settings file. If the file doesn't exist, creates it with default content.
|
||||
/// If the file exists, reads it and applies the provided update function to modify the settings.
|
||||
/// </summary>
|
||||
/// <param name="moduleName">The name of the module (e.g., "Peek", "FancyZones").</param>
|
||||
/// <param name="defaultSettingsContent">The default JSON content to use if the settings file doesn't exist.</param>
|
||||
/// <param name="updateSettingsAction">
|
||||
/// A callback function that modifies the settings dictionary. The function receives the deserialized settings
|
||||
/// and should modify it in-place. The function should accept a Dictionary<string, object> and not return a value.
|
||||
/// Example: (settings) => { ((Dictionary<string, object>)settings["properties"])["SomeSetting"] = newValue; }
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when moduleName or updateSettingsAction is null.</exception>
|
||||
/// <exception cref="InvalidOperationException">Thrown when settings file operations fail.</exception>
|
||||
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "This is test code and will not be trimmed")]
|
||||
[UnconditionalSuppressMessage("AOT", "IL3050", Justification = "This is test code and will not be AOT compiled")]
|
||||
public static void UpdateModuleSettings(
|
||||
string moduleName,
|
||||
string defaultSettingsContent,
|
||||
Action<Dictionary<string, object>> updateSettingsAction)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(moduleName);
|
||||
ArgumentNullException.ThrowIfNull(updateSettingsAction);
|
||||
|
||||
try
|
||||
{
|
||||
// Build the path to the module settings file
|
||||
string powerToysSettingsDirectory = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
"Microsoft",
|
||||
"PowerToys");
|
||||
|
||||
string moduleDirectory = Path.Combine(powerToysSettingsDirectory, moduleName);
|
||||
string settingsPath = Path.Combine(moduleDirectory, "settings.json");
|
||||
|
||||
// Ensure directory exists
|
||||
Directory.CreateDirectory(moduleDirectory);
|
||||
|
||||
// Read existing settings or use default
|
||||
string existingJson = string.Empty;
|
||||
if (File.Exists(settingsPath))
|
||||
{
|
||||
existingJson = File.ReadAllText(settingsPath);
|
||||
}
|
||||
|
||||
Dictionary<string, object>? settings;
|
||||
|
||||
// If file doesn't exist or is empty, create from defaults
|
||||
if (string.IsNullOrWhiteSpace(existingJson))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(defaultSettingsContent))
|
||||
{
|
||||
throw new ArgumentException("Default settings content must be provided when file doesn't exist.", nameof(defaultSettingsContent));
|
||||
}
|
||||
|
||||
settings = JsonSerializer.Deserialize<Dictionary<string, object>>(defaultSettingsContent)
|
||||
?? throw new InvalidOperationException($"Failed to deserialize default settings for {moduleName}");
|
||||
|
||||
Debug.WriteLine($"Created default settings for {moduleName} at {settingsPath}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parse existing settings
|
||||
settings = JsonSerializer.Deserialize<Dictionary<string, object>>(existingJson)
|
||||
?? throw new InvalidOperationException($"Failed to deserialize existing settings for {moduleName}");
|
||||
|
||||
Debug.WriteLine($"Loaded existing settings for {moduleName} from {settingsPath}");
|
||||
}
|
||||
|
||||
// Apply the update action to modify settings
|
||||
updateSettingsAction(settings);
|
||||
|
||||
// Serialize and save the updated settings using SettingsUtils
|
||||
string updatedJson = JsonSerializer.Serialize(settings, IndentedJsonOptions);
|
||||
SettingsUtils.SaveSettings(updatedJson, moduleName);
|
||||
|
||||
Debug.WriteLine($"Successfully updated settings for {moduleName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"ERROR in UpdateModuleSettings for {moduleName}: {ex.Message}");
|
||||
throw new InvalidOperationException($"Failed to update settings for {moduleName}: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,30 +47,8 @@ public class PeekFilePreviewTests : UITestBase
|
||||
{
|
||||
try
|
||||
{
|
||||
// Common base path for PowerToys settings
|
||||
string powerToysSettingsDirectory = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
"Microsoft",
|
||||
"PowerToys");
|
||||
|
||||
// Fix Peek module settings
|
||||
string peekDirectory = Path.Combine(powerToysSettingsDirectory, "Peek");
|
||||
string peekSettingsPath = Path.Combine(peekDirectory, "settings.json");
|
||||
|
||||
// Ensure directory exists
|
||||
Directory.CreateDirectory(peekDirectory);
|
||||
|
||||
// Check if file exists and is not empty
|
||||
string existingPeekJson = string.Empty;
|
||||
if (File.Exists(peekSettingsPath))
|
||||
{
|
||||
existingPeekJson = File.ReadAllText(peekSettingsPath);
|
||||
}
|
||||
|
||||
// If file doesn't exist or is empty, create default settings
|
||||
if (string.IsNullOrWhiteSpace(existingPeekJson))
|
||||
{
|
||||
string peekSettingsContent = @"{
|
||||
// Default Peek settings
|
||||
string peekSettingsContent = @"{
|
||||
""name"": ""Peek"",
|
||||
""version"": ""1.0"",
|
||||
""properties"": {
|
||||
@@ -96,50 +74,60 @@ public class PeekFilePreviewTests : UITestBase
|
||||
}
|
||||
}
|
||||
}";
|
||||
File.WriteAllText(peekSettingsPath, peekSettingsContent);
|
||||
Debug.WriteLine($"Created default Peek settings file at {peekSettingsPath}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parse and update existing settings
|
||||
using var peekDoc = JsonDocument.Parse(existingPeekJson);
|
||||
var peekSettings = JsonSerializer.Deserialize<Dictionary<string, object>>(existingPeekJson)
|
||||
?? throw new InvalidOperationException("Failed to deserialize Peek settings");
|
||||
|
||||
// Get properties section
|
||||
var propertiesElement = (JsonElement)peekSettings["properties"];
|
||||
var properties = JsonSerializer.Deserialize<Dictionary<string, object>>(propertiesElement.GetRawText())
|
||||
?? throw new InvalidOperationException("Failed to deserialize properties");
|
||||
|
||||
// Update only the required properties: ActivationShortcut and EnableSpaceToActivate
|
||||
properties["ActivationShortcut"] = new Dictionary<string, object>
|
||||
// Update Peek module settings
|
||||
SettingsConfigHelper.UpdateModuleSettings(
|
||||
"Peek",
|
||||
peekSettingsContent,
|
||||
(settings) =>
|
||||
{
|
||||
{ "win", false },
|
||||
{ "ctrl", true },
|
||||
{ "alt", false },
|
||||
{ "shift", false },
|
||||
{ "code", 32 },
|
||||
{ "key", "Space" },
|
||||
};
|
||||
// Get or ensure properties section exists
|
||||
Dictionary<string, object> properties;
|
||||
|
||||
properties["EnableSpaceToActivate"] = new Dictionary<string, object>
|
||||
{
|
||||
{ "value", false },
|
||||
};
|
||||
if (settings.TryGetValue("properties", out var propertiesObj))
|
||||
{
|
||||
if (propertiesObj is Dictionary<string, object> dict)
|
||||
{
|
||||
properties = dict;
|
||||
}
|
||||
else if (propertiesObj is JsonElement jsonElem)
|
||||
{
|
||||
properties = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonElem.GetRawText())
|
||||
?? throw new InvalidOperationException("Failed to deserialize properties");
|
||||
}
|
||||
else
|
||||
{
|
||||
properties = new Dictionary<string, object>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
properties = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
peekSettings["properties"] = properties;
|
||||
// Update the required properties
|
||||
properties["ActivationShortcut"] = new Dictionary<string, object>
|
||||
{
|
||||
{ "win", false },
|
||||
{ "ctrl", true },
|
||||
{ "alt", false },
|
||||
{ "shift", false },
|
||||
{ "code", 32 },
|
||||
{ "key", "Space" },
|
||||
};
|
||||
|
||||
// Serialize and save Peek settings
|
||||
string peekSettingsJson = JsonSerializer.Serialize(peekSettings, IndentedJsonOptions);
|
||||
File.WriteAllText(peekSettingsPath, peekSettingsJson);
|
||||
properties["EnableSpaceToActivate"] = new Dictionary<string, object>
|
||||
{
|
||||
{ "value", false },
|
||||
};
|
||||
|
||||
Debug.WriteLine($"Successfully updated Ctrl+Space shortcut in settings file at {peekSettingsPath}");
|
||||
}
|
||||
settings["properties"] = properties;
|
||||
});
|
||||
|
||||
// Disable all modules except Peek in global settings
|
||||
SettingsConfigHelper.ConfigureGlobalModuleSettings("Peek");
|
||||
|
||||
Debug.WriteLine("Successfully updated global settings - disabled all modules except Peek");
|
||||
Debug.WriteLine("Successfully updated all settings - Peek shortcut configured and all modules except Peek disabled");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user