mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-09 04:37:30 +02:00
[UI automation test] Add basic tests case for powerrename module. (#40393)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request 1. Add command args support in ui test core 2. Add command line parse logic in powerrename 3. Add some test cases. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] **Closes:** #xxx - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed --------- Co-authored-by: Yu Leng <yuleng@microsoft.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
// 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.Drawing.Text;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.PowerToys.UITest;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace PowerRename.UITests;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BasicRenameTests"/> class.
|
||||
/// Initialize PowerRename UITest with custom test file paths
|
||||
/// </summary>
|
||||
/// <param name="testFilePaths">Array of file/folder paths to test with</param>
|
||||
[TestClass]
|
||||
public class BasicRenameTests : PowerRenameUITestBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BasicRenameTests"/> class.
|
||||
/// Initialize PowerRename UITest with default test files
|
||||
/// </summary>
|
||||
public BasicRenameTests()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BasicInput()
|
||||
{
|
||||
this.SetSearchBoxText("search");
|
||||
this.SetReplaceBoxText("replace");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BasicMatchFileName()
|
||||
{
|
||||
this.SetSearchBoxText("testCase1");
|
||||
this.SetReplaceBoxText("replaced");
|
||||
|
||||
Assert.IsTrue(this.Find<TextBlock>("replaced.txt").Text == "replaced.txt");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BasicRegularMatch()
|
||||
{
|
||||
this.SetSearchBoxText("^test.*\\.txt$");
|
||||
this.SetReplaceBoxText("matched.txt");
|
||||
|
||||
CheckOriginalOrRenamedCount(0);
|
||||
|
||||
this.SetRegularExpressionCheckbox(true);
|
||||
|
||||
CheckOriginalOrRenamedCount(2);
|
||||
|
||||
Assert.IsTrue(this.Find<TextBlock>("matched.txt").Text == "matched.txt");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BasicMatchAllOccurrences()
|
||||
{
|
||||
this.SetSearchBoxText("t");
|
||||
this.SetReplaceBoxText("f");
|
||||
|
||||
this.SetMatchAllOccurrencesCheckbox(true);
|
||||
|
||||
Assert.IsTrue(this.Find<TextBlock>("fesfCase2.fxf").Text == "fesfCase2.fxf");
|
||||
Assert.IsTrue(this.Find<TextBlock>("fesfCase1.fxf").Text == "fesfCase1.fxf");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BasicCaseSensitive()
|
||||
{
|
||||
this.SetSearchBoxText("testcase1");
|
||||
this.SetReplaceBoxText("match1");
|
||||
|
||||
CheckOriginalOrRenamedCount(1);
|
||||
Assert.IsTrue(this.Find<TextBlock>("match1.txt").Text == "match1.txt");
|
||||
|
||||
this.SetCaseSensitiveCheckbox(true);
|
||||
CheckOriginalOrRenamedCount(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>PowerRename.UITests</RootNamespace>
|
||||
<AssemblyName>PowerRename.UITests</AssemblyName>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Library</OutputType>
|
||||
<!-- This is a UI test, so don't run as part of MSBuild -->
|
||||
<RunVSTest>false</RunVSTest>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\tests\PowerRename.UITests\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\codeAnalysis\GlobalSuppressions.cs" Link="GlobalSuppressions.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="BasicRenameTests.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" />
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Copy testItems folder and all contents to output directory -->
|
||||
<Content Include="testItems\**\*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,200 @@
|
||||
// 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.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.PowerToys.UITest;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace PowerRename.UITests;
|
||||
|
||||
[TestClass]
|
||||
public class PowerRenameUITestBase : UITestBase
|
||||
{
|
||||
private static readonly string[] OriginalTestFilePaths = new string[]
|
||||
{
|
||||
Path.Combine("testItems", "folder1"), // Test folder
|
||||
Path.Combine("testItems", "folder2"), // Test folder
|
||||
Path.Combine("testItems", "testCase1.txt"), // Test file
|
||||
};
|
||||
|
||||
private static readonly string BaseTestFileFolderPath = Path.Combine(Assembly.GetExecutingAssembly().Location, "..", "test", typeof(BasicRenameTests).Name);
|
||||
|
||||
private static List<string> TestFilesAndFoldersArray { get; } = InitCleanTestEnvironment();
|
||||
|
||||
private static List<string> InitCleanTestEnvironment()
|
||||
{
|
||||
var testFilesAndFolders = new List<string>
|
||||
{
|
||||
};
|
||||
|
||||
foreach (var files in OriginalTestFilePaths)
|
||||
{
|
||||
var targetFolder = Path.Combine(BaseTestFileFolderPath, files);
|
||||
testFilesAndFolders.Add(targetFolder);
|
||||
}
|
||||
|
||||
return testFilesAndFolders;
|
||||
}
|
||||
|
||||
[TestInitialize]
|
||||
public void InitTestCase()
|
||||
{
|
||||
// Clean up any existing test directories for this test class
|
||||
CleanupTestDirectories();
|
||||
|
||||
// copy files and folders from OriginalTestFilePaths to testFilesAndFoldersArray
|
||||
CopyTestFilesToDestination();
|
||||
|
||||
RestartScopeExe();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PowerRenameUITestBase"/> class.
|
||||
/// Initialize PowerRename UITest with default test files
|
||||
/// </summary>
|
||||
public PowerRenameUITestBase()
|
||||
: base(PowerToysModule.PowerRename, WindowSize.UnSpecified, TestFilesAndFoldersArray.ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any existing test directories for the specified test class
|
||||
/// </summary>
|
||||
private static void CleanupTestDirectories()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(BaseTestFileFolderPath))
|
||||
{
|
||||
Directory.Delete(BaseTestFileFolderPath, true);
|
||||
Console.WriteLine($"Cleaned up old test directory: {BaseTestFileFolderPath}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Warning: Error during cleanup: {ex.Message}");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(BaseTestFileFolderPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Warning: Error during cleanup create folder: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy test files and folders from source paths to destination paths
|
||||
/// </summary>
|
||||
private static void CopyTestFilesToDestination()
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < OriginalTestFilePaths.Length && i < TestFilesAndFoldersArray.Count; i++)
|
||||
{
|
||||
var sourcePath = Path.GetFullPath(OriginalTestFilePaths[i]);
|
||||
var destinationPath = TestFilesAndFoldersArray[i];
|
||||
|
||||
var destinationDir = Path.GetDirectoryName(destinationPath);
|
||||
if (destinationDir != null && !Directory.Exists(destinationDir))
|
||||
{
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
}
|
||||
|
||||
if (Directory.Exists(sourcePath))
|
||||
{
|
||||
CopyDirectory(sourcePath, destinationPath);
|
||||
Console.WriteLine($"Copied directory from {sourcePath} to {destinationPath}");
|
||||
}
|
||||
else if (File.Exists(sourcePath))
|
||||
{
|
||||
File.Copy(sourcePath, destinationPath, true);
|
||||
Console.WriteLine($"Copied file from {sourcePath} to {destinationPath}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Warning: Source path does not exist: {sourcePath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error during file copy operation: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recursively copy a directory and its contents
|
||||
/// </summary>
|
||||
/// <param name="sourceDir">Source directory path</param>
|
||||
/// <param name="destDir">Destination directory path</param>
|
||||
private static void CopyDirectory(string sourceDir, string destDir)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create target directory
|
||||
if (!Directory.Exists(destDir))
|
||||
{
|
||||
Directory.CreateDirectory(destDir);
|
||||
}
|
||||
|
||||
// Copy all files
|
||||
foreach (var file in Directory.GetFiles(sourceDir))
|
||||
{
|
||||
var fileName = Path.GetFileName(file);
|
||||
var destFile = Path.Combine(destDir, fileName);
|
||||
File.Copy(file, destFile, true);
|
||||
}
|
||||
|
||||
// Recursively copy all subdirectories
|
||||
foreach (var dir in Directory.GetDirectories(sourceDir))
|
||||
{
|
||||
var dirName = Path.GetFileName(dir);
|
||||
var destSubDir = Path.Combine(destDir, dirName);
|
||||
CopyDirectory(dir, destSubDir);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error copying directory from {sourceDir} to {destDir}: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
protected void SetSearchBoxText(string text)
|
||||
{
|
||||
Assert.IsTrue(this.Find<TextBox>("Search for").SetText(text, true).Text == text);
|
||||
}
|
||||
|
||||
protected void SetReplaceBoxText(string text)
|
||||
{
|
||||
Assert.IsTrue(this.Find<TextBox>("Replace with").SetText(text, true).Text == text);
|
||||
}
|
||||
|
||||
protected void SetRegularExpressionCheckbox(bool flag)
|
||||
{
|
||||
Assert.IsTrue(this.Find<CheckBox>("Use regular expressions").SetCheck(flag).IsChecked == flag);
|
||||
}
|
||||
|
||||
protected void SetMatchAllOccurrencesCheckbox(bool flag)
|
||||
{
|
||||
Assert.IsTrue(this.Find<CheckBox>("Match all occurrences").SetCheck(flag).IsChecked == flag);
|
||||
}
|
||||
|
||||
protected void SetCaseSensitiveCheckbox(bool flag)
|
||||
{
|
||||
Assert.IsTrue(this.Find<CheckBox>("Case sensitive").SetCheck(flag).IsChecked == flag);
|
||||
}
|
||||
|
||||
protected void CheckOriginalOrRenamedCount(int count)
|
||||
{
|
||||
Assert.IsTrue(this.Find<TextBlock>($"({count})").Text == $"({count})");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user