diff --git a/.github/scripts/run-ui-tests.ps1 b/.github/scripts/run-ui-tests.ps1 new file mode 100644 index 00000000..e5928038 --- /dev/null +++ b/.github/scripts/run-ui-tests.ps1 @@ -0,0 +1,96 @@ +param ( + [string]$branchName = "" +) + +# Exit script on any error +Set-StrictMode -Version Latest +$ErrorActionPreference = "Stop" + +# Helper function for logging +function Log { + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" + Write-Host "[$timestamp] $args" +} + +# Step 1: Get the branch name and checkout +if ($branchName -eq "") { + Log "No branch name provided. Using the current local branch." +} else { + try { + # Check if the branch exists locally + $localBranchExists = git branch --list $branchName | ForEach-Object { $_.Trim() } + + if ($localBranchExists) { + Log "Branch $branchName exists locally. Checking out..." + git checkout $branchName + } else { + # Check if the branch exists on the remote + $remoteBranchExists = git ls-remote --heads origin $branchName | ForEach-Object { $_.Trim() } + + if ($remoteBranchExists -ne "") { + Log "Branch $branchName does not exist locally. Checking out from remote..." + git checkout -t "origin/$branchName" + } else { + throw "Branch $branchName does not exist locally or on the remote. Please verify the branch name." + } + } + + Log "Pulling latest code..." + git pull + } catch { + Log "Error: $_" + throw "Failed to switch to branch $branchName. Ensure the branch exists locally or remotely." + } +} + +# Navigate to the root directory +try { + Set-Location (git rev-parse --show-toplevel) +} catch { + Log "Error: $_" + throw "Failed to navigate to the Git repository root directory." +} + +# Step 2: Set up paths for Visual Studio executables +$msbuildPath = "C:/Program Files/Microsoft Visual Studio/2022/Community/MSBuild/Current/Bin/MSBuild.exe" +$vsixInstallerPath = "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/VSIXInstaller.exe" +$vsTestPath = "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/TestWindow/vstest.console.exe" + +# Validate paths +if (-not (Test-Path $msbuildPath)) { throw "MSBuild executable not found at $msbuildPath" } +if (-not (Test-Path $vsixInstallerPath)) { throw "VSIX Installer not found at $vsixInstallerPath" } +if (-not (Test-Path $vsTestPath)) { throw "VSTest executable not found at $vsTestPath" } + +# Step 3: Build the solution +try { + Log "Building solution..." + $solutionPath = "$(Get-Location)/ast-visual-studio-extension.sln" + Start-Process -FilePath $msbuildPath -ArgumentList "`"$solutionPath`"", "/p:Configuration=Release" -Wait -NoNewWindow +} catch { + Log "Error: $_" + throw "Failed to build the solution." +} + +# Step 4: Install Checkmarx Extension +try { + Log "Installing Checkmarx Extension..." + $vsixPath = "$(Get-Location)/ast-visual-studio-extension/bin/Release/ast-visual-studio-extension.vsix" + Start-Process -FilePath $vsixInstallerPath -ArgumentList "/quiet", "`"$vsixPath`"" -Wait -NoNewWindow + Start-Sleep -Seconds 20 +} catch { + Log "Error: $_" + throw "Failed to install the Checkmarx extension." +} + +# Step 5: Run UI Tests +try { + Log "Running UI Tests..." + $testDllPath = "$(Get-Location)/UITests/bin/Release/UITests.dll" + Start-Process -FilePath $vsTestPath -ArgumentList "/InIsolation", "`"$testDllPath`"" -Wait -NoNewWindow +} catch { + Log "Error: $_" + throw "Failed to run UI tests." +} + +# Final message +Log "Script execution completed successfully." diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a12b8137..626c4c24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,5 +34,45 @@ jobs: env: CX_APIKEY: ${{ secrets.CX_APIKEY }} run: vstest.console.exe /InIsolation .\ast-visual-studio-extension-tests\bin\Release\net60-windows\ast-visual-studio-extension-tests.dll - - + + UI-tests: + runs-on: windows-latest + steps: + # Step 1: Checkout the repository + - name: Checkout code + uses: actions/checkout@v3 + + # Step 2: Set up Visual Studio + - name: Set up Visual Studio + uses: microsoft/setup-msbuild@v2 + with: + msbuild-architecture: x64 + + # Step 3: Restore dependencies + - name: Restore NuGet packages + run: nuget restore + + # Step 4: Build the solution + - name: Build solution + run: msbuild ast-visual-studio-extension.sln /p:Configuration=Release + + + # Step 7: Install Checkmarx Extension + - name: Install Checkmarx Extension + run: | + & "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\VSIXInstaller.exe" /quiet "D:\a\ast-visual-studio-extension\ast-visual-studio-extension\ast-visual-studio-extension\bin\Release\ast-visual-studio-extension.vsix" + Start-Sleep -Seconds 20 + + # Step 8: Run UI Tests + - name: Run UI Tests + run: | + & "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" /InIsolation .\UITests\bin\Release\UITests.dll + continue-on-error: true + + - name: Upload Descendants File + uses: actions/upload-artifact@v4 + with: + name: screenshot + path: ${{ github.workspace }}\Screenshots + + diff --git a/UITests/BaseTest.cs b/UITests/BaseTest.cs index c2c08020..500dfda4 100644 --- a/UITests/BaseTest.cs +++ b/UITests/BaseTest.cs @@ -2,90 +2,114 @@ using FlaUI.UIA3; using FlaUI.Core; using System; +using System.IO; using System.Threading.Tasks; using EnvDTE; using AutomationWindow = FlaUI.Core.AutomationElements.Window; +using FlaUI.Core.Capturing; namespace UITests { - [TestClass] - public class BaseTest - { - protected static UIA3Automation _automation; - protected static Application _app; - protected static AutomationWindow _mainWindow; - protected static DTE _dte; + [TestClass] + public class BaseTest + { + protected static UIA3Automation _automation; + protected static Application _app; + protected static AutomationWindow _mainWindow; + protected static DTE _dte; - [ClassInitialize] - public static void ClassInitialize(TestContext context) - { - // Initialize automation and launch VS - _automation = new UIA3Automation(); - _app = Application.Launch("devenv.exe"); + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + // Initialize automation and launch VS + _automation = new UIA3Automation(); + _app = Application.Launch("devenv.exe","/ResetSettings General"); // Wait for launch VS Task.Delay(15000).Wait(); _mainWindow = WaitForMainWindow(); - // Handle initial setup - SetupVisualStudio().Wait(); - } + // Handle initial setup + SetupVisualStudio().Wait(); + } - private static async Task SetupVisualStudio() + private static async Task SetupVisualStudio() { // Find and click the "Continue without code" button var continueWithoutCodeButton = _mainWindow.FindFirstDescendant(cf => cf.ByName("Continue without code")); - if (continueWithoutCodeButton != null) - { - var invokePattern = continueWithoutCodeButton.Patterns.Invoke.Pattern; - invokePattern.Invoke(); - _mainWindow = WaitForMainWindow(); - } - } + if (continueWithoutCodeButton != null) + { + var invokePattern = continueWithoutCodeButton.Patterns.Invoke.Pattern; + invokePattern.Invoke(); + _mainWindow = WaitForMainWindow(); + } + else + { + Console.WriteLine("Continue without code button not found"); + _mainWindow = WaitForMainWindow(); + } + + var dkipThis = _mainWindow.FindFirstDescendant(cf => cf.ByName("Skip this for now.")); + if (dkipThis != null) + { + var invokePattern = dkipThis.Patterns.Invoke.Pattern; + Console.WriteLine("Skip this for now button FOUND"); + invokePattern.Invoke(); + _mainWindow = WaitForMainWindow(); + } + else + { + Console.WriteLine("Skip this for now button not found"); + _mainWindow = WaitForMainWindow(); + } + } - public static AutomationWindow WaitForMainWindow(int timeoutInSeconds = 30) - { - var startTime = DateTime.Now; - while ((DateTime.Now - startTime).TotalSeconds < timeoutInSeconds) - { - try - { + public static AutomationWindow WaitForMainWindow(int timeoutInSeconds = 30) + { + var startTime = DateTime.Now; + while ((DateTime.Now - startTime).TotalSeconds < timeoutInSeconds) + { + try + { // Wait until the main window is available Task.Delay(5000).Wait(); - var window = _app.GetMainWindow(_automation); - if (window != null && window.IsAvailable) - { - return window; - } - } - catch (Exception) - { - // Ignore exception, retry until timeout - } - Task.Delay(500).Wait(); - } - throw new TimeoutException("Main window did not appear within the timeout period."); - } + var window = _app.GetMainWindow(_automation); + if (window != null && window.IsAvailable) + { + return window; + } + } + catch (Exception) + { + // Ignore exception, retry until timeout + } + + Task.Delay(500).Wait(); + } + + throw new TimeoutException("Main window did not appear within the timeout period."); + } + + [ClassCleanup] + public static void ClassCleanup() + { + try + { + if (_app != null) + { + _app.Close(); + _app.Dispose(); + } + } + finally + { + if (_automation != null) + { + _automation.Dispose(); + } - [ClassCleanup] - public static void ClassCleanup() - { - try - { - if (_app != null) - { - _app.Close(); - _app.Dispose(); - } - } - finally - { - if (_automation != null) - { - _automation.Dispose(); - } - _mainWindow = null; - } - } - } + _mainWindow = null; + } + } + } } \ No newline at end of file diff --git a/UITests/CheckmarxTests.cs b/UITests/CheckmarxTests.cs index 0ad75440..7f4a8e4a 100644 --- a/UITests/CheckmarxTests.cs +++ b/UITests/CheckmarxTests.cs @@ -1,6 +1,8 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; using FlaUI.Core.AutomationElements; using System.Threading.Tasks; +using System.IO; namespace UITests { @@ -18,6 +20,8 @@ public async Task OpenCheckmarxWindow() { // Find the View menu var viewMenu = _mainWindow.FindFirstDescendant(cf => cf.ByName("View")); + + // Assert View menu is not null Assert.IsNotNull(viewMenu, "View menu not found"); // Open the "View" menu by clicking it @@ -25,10 +29,9 @@ public async Task OpenCheckmarxWindow() await Task.Delay(500); var allMenuItems = _mainWindow.FindAllDescendants(cf => - cf.ByControlType(FlaUI.Core.Definitions.ControlType.MenuItem)); + cf.ByControlType(FlaUI.Core.Definitions.ControlType.MenuItem)); bool foundOtherWindows = false; - foreach (var menuItem in allMenuItems) { if (menuItem.Name == "Other Windows") @@ -37,7 +40,7 @@ public async Task OpenCheckmarxWindow() menuItem.WaitUntilEnabled().Click(); await Task.Delay(1000); - // Now select a specific window from the list "Checkmarx" + // Select a specific window from the list "Checkmarx" var checkmarxOption = _mainWindow.FindFirstDescendant(cf => cf.ByName("Checkmarx")); Assert.IsNotNull(checkmarxOption, "Checkmarx option not found in Other Windows menu"); checkmarxOption.WaitUntilEnabled().Click(); @@ -45,7 +48,7 @@ public async Task OpenCheckmarxWindow() } } Assert.IsTrue(foundOtherWindows, "Other Windows menu item not found"); - } + } }