From 97c12ac95e992e7626acb3eb9eef6862ea244697 Mon Sep 17 00:00:00 2001 From: Josh Lozensky <joshlozensky@microsoft.com> Date: Tue, 5 Nov 2024 14:23:41 -0800 Subject: [PATCH 1/2] Minor cleanup --- .../AnyOrgOrPersonalTest.cs | 17 +++--- UiTests/B2CUiTest/B2CUiTest.cs | 4 +- UiTests/Common/TestConstants.cs | 12 ++-- UiTests/Common/UiTestHelpers.cs | 57 +------------------ .../GraphUserTokenCacheTest.cs | 8 +-- UiTests/HybridFlowUiTest/HybridFlowTest.cs | 10 ++-- UiTests/PlaywrightTraces/.gitignore | 4 ++ 7 files changed, 31 insertions(+), 81 deletions(-) create mode 100644 UiTests/PlaywrightTraces/.gitignore diff --git a/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs b/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs index 3df45d55..b27019b0 100644 --- a/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs +++ b/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs @@ -1,33 +1,32 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using Common; +using Microsoft.Identity.Lab.Api; +using Microsoft.Playwright; using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Runtime.Versioning; using System.Text; using System.Threading.Tasks; -using Common; -using Microsoft.Identity.Lab.Api; -using Microsoft.Playwright; using Xunit; using Xunit.Abstractions; using Process = System.Diagnostics.Process; using TC = Common.TestConstants; -namespace MultipleApiUiTest +namespace AnyOrgOrPersonalUiTest { public class AnyOrgOrPersonalTest : IClassFixture<InstallPlaywrightBrowserFixture> { private const string SignOutPageUriPath = @"/MicrosoftIdentity/Account/SignedOut"; private const uint ClientPort = 44321; - private const string TraceFileClassName = "OpenIDConnect"; + private const string TraceFileClassName = "AnyOrgOrPersonalUiTest"; private const uint NumProcessRetries = 3; private const string SampleSlnFileName = "1-3-AnyOrgOrPersonal.sln"; private readonly LocatorAssertionsToBeVisibleOptions _assertVisibleOptions = new() { Timeout = 25000 }; - private readonly string _sampleAppPath = "1-WebApp-OIDC" + Path.DirectorySeparatorChar + "1-3-AnyOrgOrPersonal" + Path.DirectorySeparatorChar.ToString(); - private readonly string _testAppsettingsPath = "UiTests" + Path.DirectorySeparatorChar + "AnyOrgOrPersonalUiTest" + Path.DirectorySeparatorChar.ToString() + TC.AppSetttingsDotJson; + private readonly string _sampleAppPath = "1-WebApp-OIDC" + Path.DirectorySeparatorChar + "1-3-AnyOrgOrPersonal" + Path.DirectorySeparatorChar; + private readonly string _testAppsettingsPath = "UiTests" + Path.DirectorySeparatorChar + "AnyOrgOrPersonalUiTest" + Path.DirectorySeparatorChar + TC.AppSetttingsDotJson; private readonly string _testAssemblyLocation = typeof(AnyOrgOrPersonalTest).Assembly.Location; private readonly ITestOutputHelper _output; @@ -38,7 +37,7 @@ public AnyOrgOrPersonalTest(ITestOutputHelper output) [Fact] [SupportedOSPlatform("windows")] - public async Task ChallengeUser_MicrosoftIdFlow_LocalApp_ValidEmailPasswordCreds_LoginLogout() + public async Task LocalApp_ValidEmailPasswordCreds_LoginLogout() { // Setup web app and api environmental variables. var clientEnvVars = new Dictionary<string, string> diff --git a/UiTests/B2CUiTest/B2CUiTest.cs b/UiTests/B2CUiTest/B2CUiTest.cs index 10ca6c03..91200352 100644 --- a/UiTests/B2CUiTest/B2CUiTest.cs +++ b/UiTests/B2CUiTest/B2CUiTest.cs @@ -27,7 +27,7 @@ public class B2CUiTest : IClassFixture<InstallPlaywrightBrowserFixture> private const string SampleSolutionFileName = "4-2-B2C-Secured-API.sln"; private const uint TodoListClientPort = 5000; private const uint TodoListServicePort = 44332; - private const string TraceClassName = "B2C-Login"; + private const string TraceClassName = "B2C"; private readonly LocatorAssertionsToBeVisibleOptions _assertVisibleOptions = new() { Timeout = 25000 }; private readonly string _sampleClientAppPath; @@ -46,7 +46,7 @@ public B2CUiTest(ITestOutputHelper output) [Fact] [SupportedOSPlatform("windows")] - public async Task B2C_ValidCreds_LoginLogout() + public async Task LocalApp_ValidEmailPasswordCreds_LoginLogout() { // Web app and api environmental variable setup. Dictionary<string, Process>? processes = null; diff --git a/UiTests/Common/TestConstants.cs b/UiTests/Common/TestConstants.cs index 7662a2ec..5f478a58 100644 --- a/UiTests/Common/TestConstants.cs +++ b/UiTests/Common/TestConstants.cs @@ -28,11 +28,11 @@ public static class TestConstants public const string TodoTitle2 = "Testing edit todo item"; public const string WebAppCrashedString = $"The web app process has exited prematurely."; - public static readonly string s_oidcWebAppExe = Path.DirectorySeparatorChar.ToString() + "WebApp-OpenIDConnect-DotNet.exe"; - public static readonly string s_oidcWebAppPath = Path.DirectorySeparatorChar.ToString() + "WebApp-OpenIDConnect"; - public static readonly string s_todoListClientExe = Path.DirectorySeparatorChar.ToString() + "TodoListClient.exe"; - public static readonly string s_todoListClientPath = Path.DirectorySeparatorChar.ToString() + "Client"; - public static readonly string s_todoListServiceExe = Path.DirectorySeparatorChar.ToString() + "TodoListService.exe"; - public static readonly string s_todoListServicePath = Path.DirectorySeparatorChar.ToString() + "TodoListService"; + public static readonly string s_oidcWebAppExe = Path.DirectorySeparatorChar + "WebApp-OpenIDConnect-DotNet.exe"; + public static readonly string s_oidcWebAppPath = Path.DirectorySeparatorChar + "WebApp-OpenIDConnect"; + public static readonly string s_todoListClientExe = Path.DirectorySeparatorChar + "TodoListClient.exe"; + public static readonly string s_todoListClientPath = Path.DirectorySeparatorChar + "Client"; + public static readonly string s_todoListServiceExe = Path.DirectorySeparatorChar + "TodoListService.exe"; + public static readonly string s_todoListServicePath = Path.DirectorySeparatorChar + "TodoListService"; } } diff --git a/UiTests/Common/UiTestHelpers.cs b/UiTests/Common/UiTestHelpers.cs index 970dc3fd..48161840 100644 --- a/UiTests/Common/UiTestHelpers.cs +++ b/UiTests/Common/UiTestHelpers.cs @@ -6,8 +6,6 @@ using Microsoft.Data.SqlClient; using Microsoft.Playwright; using System.Diagnostics; -using System.Management; -using System.Runtime.Versioning; using System.Text; using Xunit.Abstractions; @@ -56,24 +54,6 @@ public static async Task FirstLogin_MicrosoftIdFlow_ValidEmailPassword(IPage pag await StaySignedIn_MicrosoftIdFlow(page, staySignedInText, output); } - /// <summary> - /// Login flow for anytime after the first time in a given browsing session. - /// </summary> - /// <param name="page">Playwright Page object the web app is accessed from</param> - /// <param name="email">email of the user to sign in</param> - /// <param name="password">password for sign in</param> - /// <param name="output">Used to communicate output to the test's Standard Output</param> - /// <param name="staySignedIn">Whether to select "stay signed in" on login</param> - public static async Task SuccessiveLogin_MicrosoftIdFlow_ValidEmailPassword(IPage page, string email, string password, ITestOutputHelper? output = null, bool staySignedIn = false) - { - string staySignedInText = staySignedIn ? "Yes" : "No"; - - WriteLine(output, $"Logging in again in this browsing session... selecting user via email: {email}."); - await SelectKnownAccountByEmail_MicrosoftIdFlow(page, email); - await EnterPasswordAsync(page, password, output); - await StaySignedIn_MicrosoftIdFlow(page, staySignedInText, output); - } - /// <summary> /// Enters the email of the user to sign in. /// </summary> @@ -155,21 +135,6 @@ private static void WriteLine(ITestOutputHelper? output, string message) } } - /// <summary> - /// This starts the recording of playwright trace files. The corresponding EndAndWritePlaywrightTrace method will also need to be used. - /// This is not used anywhere by default and will need to be added to the code if desired. - /// </summary> - /// <param name="page">The page object whose context the trace will record.</param> - public static async Task StartPlaywrightTrace(IPage page) - { - await page.Context.Tracing.StartAsync(new() - { - Screenshots = true, - Snapshots = true, - Sources = true - }); - } - /// <summary> /// Starts a process from an executable, sets its working directory, and redirects its output to the test's output. /// </summary> @@ -179,7 +144,7 @@ await page.Context.Tracing.StartAsync(new() /// <param name="portNumber">The port for the process to listen on.</param> /// <param name="isHttp">If the launch URL is http or https. Default is https.</param> /// <returns>The started process.</returns> - public static Process StartProcessLocally(string testAssemblyLocation, string appLocation, string executableName, Dictionary<string, string>? environmentVariables = null) + private static Process StartProcessLocally(string testAssemblyLocation, string appLocation, string executableName, Dictionary<string, string>? environmentVariables = null) { string applicationWorkingDirectory = GetApplicationWorkingDirectory(testAssemblyLocation, appLocation); ProcessStartInfo processStartInfo = new ProcessStartInfo(applicationWorkingDirectory + executableName) @@ -258,7 +223,7 @@ private static string GetAbsoluteAppDirectory(string testAssemblyLocation, strin /// <returns>An absolute path to a Playwright Trace zip folder</returns> public static string GetTracePath(string testAssemblyLocation, string traceName) { - const string traceParentFolder = "E2E Tests"; + const string traceParentFolder = "UiTests"; const string traceFolder = "PlaywrightTraces"; const string zipExtension = ".zip"; const int netVersionNumberLength = 3; @@ -323,24 +288,6 @@ private static void KillProcessTrees(Queue<Process> processQueue) #endif } - /// <summary> - /// Gets the child processes of a process on Windows - /// </summary> - /// <param name="process">The parent process</param> - /// <returns>A list of child processes</returns> - [SupportedOSPlatform("windows")] - public static IList<Process> GetChildProcesses(this Process process) - { - ManagementObjectSearcher processSearch = new ManagementObjectSearcher($"Select * From Win32_Process Where ParentProcessID={process.Id}"); - IList<Process> processList = processSearch.Get() - .Cast<ManagementObject>() - .Select(mo => - Process.GetProcessById(Convert.ToInt32(mo["ProcessID"], System.Globalization.CultureInfo.InvariantCulture))) - .ToList(); - processSearch.Dispose(); - return processList; - } - /// <summary> /// Checks if all processes in a list are alive /// </summary> diff --git a/UiTests/GraphUserTokenCache/GraphUserTokenCacheTest.cs b/UiTests/GraphUserTokenCache/GraphUserTokenCacheTest.cs index a1fe2dfd..4ef90584 100644 --- a/UiTests/GraphUserTokenCache/GraphUserTokenCacheTest.cs +++ b/UiTests/GraphUserTokenCache/GraphUserTokenCacheTest.cs @@ -22,11 +22,11 @@ public class GraphUserTokenCacheTest private const string SqlDbName = "MY_TOKEN_CACHE_DATABASE"; private const string SqlServerConnectionString = "Server=(localdb)\\mssqllocaldb;Integrated Security=true"; private const string SqlTableName = "TokenCache"; - private const string TraceFileClassName = "GraphUserTokenCacheTest"; + private const string TraceFileClassName = "GraphUserTokenCache"; private readonly LocatorAssertionsToBeVisibleOptions _assertVisibleOptions = new() { Timeout = 25000 }; private readonly ITestOutputHelper _output; - private readonly string _sampleAppPath = "2-WebApp-graph-user" + Path.DirectorySeparatorChar + "2-2-TokenCache" + Path.DirectorySeparatorChar.ToString(); - private readonly string _testAppsettingsPath = "UiTests" + Path.DirectorySeparatorChar + "GraphUserTokenCache" + Path.DirectorySeparatorChar.ToString() + TC.AppSetttingsDotJson; + private readonly string _sampleAppPath = "2-WebApp-graph-user" + Path.DirectorySeparatorChar + "2-2-TokenCache" + Path.DirectorySeparatorChar; + private readonly string _testAppsettingsPath = "UiTests" + Path.DirectorySeparatorChar + "GraphUserTokenCache" + Path.DirectorySeparatorChar + TC.AppSetttingsDotJson; private readonly string _testAssemblyLocation = typeof(GraphUserTokenCacheTest).Assembly.Location; public GraphUserTokenCacheTest(ITestOutputHelper output) @@ -35,7 +35,7 @@ public GraphUserTokenCacheTest(ITestOutputHelper output) } [Fact] - public async Task ChallengeUser_MicrosoftIdFlow_LocalApp_ValidEmailPasswordCreds_LoginLogoutAsync() + public async Task LocalApp_ValidEmailPasswordCreds_LoginLogout() { // Setup web app and api environmental variables. var clientEnvVars = new Dictionary<string, string> diff --git a/UiTests/HybridFlowUiTest/HybridFlowTest.cs b/UiTests/HybridFlowUiTest/HybridFlowTest.cs index bdab75bb..7fe8f5ff 100644 --- a/UiTests/HybridFlowUiTest/HybridFlowTest.cs +++ b/UiTests/HybridFlowUiTest/HybridFlowTest.cs @@ -21,13 +21,13 @@ public class HybridFlowTest : IClassFixture<InstallPlaywrightBrowserFixture> { private const string SignOutPageUriPath = @"/MicrosoftIdentity/Account/SignedOut"; private const uint ClientPort = 44321; - private const string TraceFileClassName = "OpenIDConnect-HybridFlow"; + private const string TraceFileClassName = "HybridFlow"; private const uint NumProcessRetries = 3; private const string SampleSlnFileName = "2-5-HybridFlow.sln"; private const string SampleExeFileName = "2-5-HybridFlow.exe"; private readonly LocatorAssertionsToBeVisibleOptions _assertVisibleOptions = new() { Timeout = 25000 }; - private readonly string _sampleAppPath = "2-WebApp-graph-user" + Path.DirectorySeparatorChar + "2-5-HybridFlow" + Path.DirectorySeparatorChar.ToString(); - private readonly string _testAppsettingsPath = "UiTests" + Path.DirectorySeparatorChar + "HybridFlowUiTest" + Path.DirectorySeparatorChar.ToString() + TC.AppSetttingsDotJson; + private readonly string _sampleAppPath = "2-WebApp-graph-user" + Path.DirectorySeparatorChar + "2-5-HybridFlow" + Path.DirectorySeparatorChar; + private readonly string _testAppsettingsPath = "UiTests" + Path.DirectorySeparatorChar + "HybridFlowUiTest" + Path.DirectorySeparatorChar + TC.AppSetttingsDotJson; private readonly string _testAssemblyLocation = typeof(HybridFlowTest).Assembly.Location; private readonly ITestOutputHelper _output; @@ -38,7 +38,7 @@ public HybridFlowTest(ITestOutputHelper output) [Fact] [SupportedOSPlatform("windows")] - public async Task ChallengeUser_MicrosoftIdFlow_LocalApp_ValidEmailPasswordCreds_LoginLogout() + public async Task LocalApp_ValidEmailPasswordCreds_LoginLogout() { // Setup web app and api environmental variables. var clientEnvVars = new Dictionary<string, string> @@ -68,7 +68,7 @@ public async Task ChallengeUser_MicrosoftIdFlow_LocalApp_ValidEmailPasswordCreds var clientProcessOptions = new ProcessStartOptions( _testAssemblyLocation, _sampleAppPath, - Path.DirectorySeparatorChar.ToString() + SampleExeFileName, + Path.DirectorySeparatorChar + SampleExeFileName, clientEnvVars ); diff --git a/UiTests/PlaywrightTraces/.gitignore b/UiTests/PlaywrightTraces/.gitignore new file mode 100644 index 00000000..91190fdc --- /dev/null +++ b/UiTests/PlaywrightTraces/.gitignore @@ -0,0 +1,4 @@ +# Ignore all files in this directory, which is needed for PR pipeline test traces +* +# Except this file +!.gitignore \ No newline at end of file From 30fd8cc06a4b2b613ae962cf2237501c7ba500c9 Mon Sep 17 00:00:00 2001 From: Josh Lozensky <joshlozensky@microsoft.com> Date: Tue, 5 Nov 2024 14:30:01 -0800 Subject: [PATCH 2/2] fix trace filename --- UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs b/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs index b27019b0..0d89a272 100644 --- a/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs +++ b/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs @@ -21,7 +21,7 @@ public class AnyOrgOrPersonalTest : IClassFixture<InstallPlaywrightBrowserFixtur { private const string SignOutPageUriPath = @"/MicrosoftIdentity/Account/SignedOut"; private const uint ClientPort = 44321; - private const string TraceFileClassName = "AnyOrgOrPersonalUiTest"; + private const string TraceFileClassName = "AnyOrgOrPersonal"; private const uint NumProcessRetries = 3; private const string SampleSlnFileName = "1-3-AnyOrgOrPersonal.sln"; private readonly LocatorAssertionsToBeVisibleOptions _assertVisibleOptions = new() { Timeout = 25000 };