From a7547999ab9483b1284e8961f29eb0b0caf8aaeb Mon Sep 17 00:00:00 2001 From: Neil Walker Date: Thu, 17 Jun 2021 21:00:10 +0100 Subject: [PATCH 01/14] added logic to support multiple as admin users --- .../Configuration/TestConfiguration.cs | 24 ++++++++++++++++++- ....PowerApps.SpecFlowBindings.UiTests.csproj | 4 ++-- .../power-apps-bindings.yml | 6 +++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs index 0c4a1b7..25650e0 100644 --- a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs +++ b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs @@ -19,12 +19,16 @@ public class TestConfiguration private const string GetUserException = "Unable to retrieve user configuration. Please ensure a user with the given alias exists in the config."; + private int aliasIndex; + private UserConfiguration currentUser; + /// /// Initializes a new instance of the class. /// public TestConfiguration() { this.BrowserOptions = new BrowserOptions(); + this.aliasIndex = 0; } /// @@ -69,7 +73,24 @@ public UserConfiguration GetUser(string userAlias) { try { - return this.Users.First(u => u.Alias == userAlias); + if (this.Users.Count > 1) + { + if (this.Users.Count - 1 == this.aliasIndex) + { + this.aliasIndex = 0; + } + else + { + this.currentUser = this.Users[this.aliasIndex]; + this.aliasIndex++; + } + + return this.currentUser; + } + else + { + return this.Users.First(u => u.Alias == userAlias); + } } catch (Exception ex) { @@ -78,3 +99,4 @@ public UserConfiguration GetUser(string userAlias) } } } + diff --git a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj index d159135..8cb9eb5 100644 --- a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj +++ b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj @@ -38,8 +38,8 @@ - - + + diff --git a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/power-apps-bindings.yml b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/power-apps-bindings.yml index 18cb9ef..c1022a5 100644 --- a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/power-apps-bindings.yml +++ b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/power-apps-bindings.yml @@ -14,5 +14,11 @@ users: - username: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_USERNAME password: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_PASSWORD alias: an admin + - username: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_USERNAME2 + password: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_PASSWORD2 + alias: an admin + - username: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_USERNAME3 + password: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_PASSWORD3 + alias: an admin - username: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_USERNAME alias: an aliased user \ No newline at end of file From 7897115b82fd78c9b1c594d1f784b895405026f8 Mon Sep 17 00:00:00 2001 From: Neil Walker Date: Fri, 18 Jun 2021 11:22:12 +0100 Subject: [PATCH 02/14] Includes PR suggestions --- .../Configuration/TestConfiguration.cs | 54 ++++++++++++------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs index 25650e0..f9cb944 100644 --- a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs +++ b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs @@ -19,8 +19,8 @@ public class TestConfiguration private const string GetUserException = "Unable to retrieve user configuration. Please ensure a user with the given alias exists in the config."; - private int aliasIndex; - private UserConfiguration currentUser; + private object userEnumeratorsLock = new object(); + private Dictionary> userEnumerators; /// /// Initializes a new instance of the class. @@ -28,7 +28,6 @@ public class TestConfiguration public TestConfiguration() { this.BrowserOptions = new BrowserOptions(); - this.aliasIndex = 0; } /// @@ -55,6 +54,28 @@ public TestConfiguration() [YamlMember(Alias = "applicationUser")] public ClientCredentials ApplicationUser { get; set; } + [YamlIgnore] + private Dictionary> UserEnumerators + { + get + { + lock (this.userEnumeratorsLock) + { + if (this.userEnumerators == null) + { + this.userEnumerators = this.Users + .Select(user => user.Alias) + .Distinct() + .ToDictionary( + alias => alias, + alias => this.Users.Where(u => u.Alias == alias).GetEnumerator()); + } + } + + return this.userEnumerators; + } + } + /// /// Gets the target URL. /// @@ -71,32 +92,29 @@ public Uri GetTestUrl() /// The user configuration. public UserConfiguration GetUser(string userAlias) { + UserConfiguration user; + try { - if (this.Users.Count > 1) + lock (this.userEnumeratorsLock) { - if (this.Users.Count - 1 == this.aliasIndex) - { - this.aliasIndex = 0; - } - else + var aliasEnumerator = this.UserEnumerators[userAlias]; + if (!aliasEnumerator.MoveNext()) { - this.currentUser = this.Users[this.aliasIndex]; - this.aliasIndex++; + this.UserEnumerators[userAlias] = this.Users.Where(u => u.Alias == userAlias).GetEnumerator(); + aliasEnumerator = this.UserEnumerators[userAlias]; + aliasEnumerator.MoveNext(); } - return this.currentUser; - } - else - { - return this.Users.First(u => u.Alias == userAlias); + user = aliasEnumerator.Current; } } catch (Exception ex) { throw new ConfigurationErrorsException($"{GetUserException} User: {userAlias}", ex); } + + return user; } } -} - +} \ No newline at end of file From 17ea6024c7fbbb7bb297fa335f99ee4144d3a929 Mon Sep 17 00:00:00 2001 From: Neil Walker Date: Fri, 18 Jun 2021 15:01:28 +0100 Subject: [PATCH 03/14] Resolved additional white space --- .../Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj index 8cb9eb5..a9eaddf 100644 --- a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj +++ b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj @@ -38,8 +38,8 @@ - - + + From 3e4930becee58b75074f3cc5f301a8bb0c7ad242 Mon Sep 17 00:00:00 2001 From: Neil Walker Date: Fri, 18 Jun 2021 15:10:47 +0100 Subject: [PATCH 04/14] Updated configuration example for additional users --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b1b05a..92fc7e3 100644 --- a/README.md +++ b/README.md @@ -65,10 +65,15 @@ applicationUser: # optional - populate if creating test data for users other tha tenantId: SPECFLOW_POWERAPPS_TENANTID optional # mandatory clientId: SPECFLOW_POWERAPPS_CLIENTID # mandatory clientSecret: SPECFLOW_POWERAPPS_CLIENTSECRET # mandatory -users: # mandatory +users: + # Mandatory - one user is required - username: SPECFLOW_POWERAPPS_USERNAME_SALESPERSON # mandatory password: SPECFLOW_POWERAPPS_PASSWORD_SALESPERSON # optional - populate if this user will be logging in for tests alias: a salesperson # mandatory + # Optional - additional users are optional + - username: SPECFLOW_POWERAPPS_USERNAME_SALESPERSON_2 # mandatory - Supports multiple users to assist load balancing tests + password: SPECFLOW_POWERAPPS_PASSWORD_SALESPERSON_2 # optional - populate if this user will be logging in for tests + alias: a salesperson # mandatory - Supports multiple users with identical alias names to assist load balancing tests ``` The URL, driversPath, usernames, passwords, and application user details will be set from environment variable (if found). Otherwise, the value from the config file will be used. The browserOptions node supports anything in the EasyRepro `BrowserOptions` class. From 955ae979f213090ca445c03a0fad099b95bdc681 Mon Sep 17 00:00:00 2001 From: Neil Walker Date: Fri, 18 Jun 2021 15:13:59 +0100 Subject: [PATCH 05/14] Edited Configuration example --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 92fc7e3..482ee3d 100644 --- a/README.md +++ b/README.md @@ -65,12 +65,10 @@ applicationUser: # optional - populate if creating test data for users other tha tenantId: SPECFLOW_POWERAPPS_TENANTID optional # mandatory clientId: SPECFLOW_POWERAPPS_CLIENTID # mandatory clientSecret: SPECFLOW_POWERAPPS_CLIENTSECRET # mandatory -users: - # Mandatory - one user is required +users: # One user is mandatory, additional users are optional - username: SPECFLOW_POWERAPPS_USERNAME_SALESPERSON # mandatory password: SPECFLOW_POWERAPPS_PASSWORD_SALESPERSON # optional - populate if this user will be logging in for tests alias: a salesperson # mandatory - # Optional - additional users are optional - username: SPECFLOW_POWERAPPS_USERNAME_SALESPERSON_2 # mandatory - Supports multiple users to assist load balancing tests password: SPECFLOW_POWERAPPS_PASSWORD_SALESPERSON_2 # optional - populate if this user will be logging in for tests alias: a salesperson # mandatory - Supports multiple users with identical alias names to assist load balancing tests From 168e3646599cd5fefd265058fd97c47a05402f83 Mon Sep 17 00:00:00 2001 From: Neil Walker Date: Mon, 21 Jun 2021 11:11:18 +0100 Subject: [PATCH 06/14] Update README.md Co-authored-by: Max Ewing --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 482ee3d..5b1b05a 100644 --- a/README.md +++ b/README.md @@ -65,13 +65,10 @@ applicationUser: # optional - populate if creating test data for users other tha tenantId: SPECFLOW_POWERAPPS_TENANTID optional # mandatory clientId: SPECFLOW_POWERAPPS_CLIENTID # mandatory clientSecret: SPECFLOW_POWERAPPS_CLIENTSECRET # mandatory -users: # One user is mandatory, additional users are optional +users: # mandatory - username: SPECFLOW_POWERAPPS_USERNAME_SALESPERSON # mandatory password: SPECFLOW_POWERAPPS_PASSWORD_SALESPERSON # optional - populate if this user will be logging in for tests alias: a salesperson # mandatory - - username: SPECFLOW_POWERAPPS_USERNAME_SALESPERSON_2 # mandatory - Supports multiple users to assist load balancing tests - password: SPECFLOW_POWERAPPS_PASSWORD_SALESPERSON_2 # optional - populate if this user will be logging in for tests - alias: a salesperson # mandatory - Supports multiple users with identical alias names to assist load balancing tests ``` The URL, driversPath, usernames, passwords, and application user details will be set from environment variable (if found). Otherwise, the value from the config file will be used. The browserOptions node supports anything in the EasyRepro `BrowserOptions` class. From b0434a9153f01012a7620a3c3a1479e93e46d6d1 Mon Sep 17 00:00:00 2001 From: Neil Walker Date: Mon, 21 Jun 2021 11:15:56 +0100 Subject: [PATCH 07/14] Update bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs Co-authored-by: Max Ewing --- .../Configuration/TestConfiguration.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs index f9cb944..92fbdaf 100644 --- a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs +++ b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs @@ -90,7 +90,7 @@ public Uri GetTestUrl() /// /// The alias of the user. /// The user configuration. - public UserConfiguration GetUser(string userAlias) + public UserConfiguration GetUser(string userAlias, bool currentUser = true) { UserConfiguration user; @@ -117,4 +117,4 @@ public UserConfiguration GetUser(string userAlias) return user; } } -} \ No newline at end of file +} From e4684c907bb048e3a44aa3eecba428dad30fabd3 Mon Sep 17 00:00:00 2001 From: Alex Bance Date: Wed, 23 Jun 2021 16:32:37 +0100 Subject: [PATCH 08/14] fix: updated to avoid breaking changes & updated docs --- .../Configuration/TestConfiguration.cs | 16 +++++++++++----- ...ini.PowerApps.SpecFlowBindings.UiTests.csproj | 4 ++-- .../power-apps-bindings.yml | 3 --- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs index 92fbdaf..ec39384 100644 --- a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs +++ b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs @@ -19,7 +19,9 @@ public class TestConfiguration private const string GetUserException = "Unable to retrieve user configuration. Please ensure a user with the given alias exists in the config."; - private object userEnumeratorsLock = new object(); + private readonly object userEnumeratorsLock = new object(); + [ThreadStatic] + private UserConfiguration currentUser; private Dictionary> userEnumerators; /// @@ -89,10 +91,14 @@ public Uri GetTestUrl() /// Retrieves the configuration for a user. /// /// The alias of the user. + /// Indicates whether to return the current user or get the next available. /// The user configuration. - public UserConfiguration GetUser(string userAlias, bool currentUser = true) + public UserConfiguration GetUser(string userAlias, bool useCurrentUser = true) { - UserConfiguration user; + if (useCurrentUser && this.currentUser != null) + { + return this.currentUser; + } try { @@ -106,7 +112,7 @@ public UserConfiguration GetUser(string userAlias, bool currentUser = true) aliasEnumerator.MoveNext(); } - user = aliasEnumerator.Current; + this.currentUser = aliasEnumerator.Current; } } catch (Exception ex) @@ -114,7 +120,7 @@ public UserConfiguration GetUser(string userAlias, bool currentUser = true) throw new ConfigurationErrorsException($"{GetUserException} User: {userAlias}", ex); } - return user; + return this.currentUser; } } } diff --git a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj index a9eaddf..8cb9eb5 100644 --- a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj +++ b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj @@ -38,8 +38,8 @@ - - + + diff --git a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/power-apps-bindings.yml b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/power-apps-bindings.yml index c1022a5..eb85aca 100644 --- a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/power-apps-bindings.yml +++ b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/power-apps-bindings.yml @@ -17,8 +17,5 @@ users: - username: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_USERNAME2 password: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_PASSWORD2 alias: an admin - - username: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_USERNAME3 - password: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_PASSWORD3 - alias: an admin - username: POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_USERNAME alias: an aliased user \ No newline at end of file From ed3962cfe8464bdf31779421c7679e96faeb1002 Mon Sep 17 00:00:00 2001 From: Alex Bance Date: Wed, 23 Jun 2021 16:34:48 +0100 Subject: [PATCH 09/14] fix: updated readme & fixed whitespace issue --- README.md | 4 +++- .../Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5b1b05a..5ed8c7c 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ applicationUser: # optional - populate if creating test data for users other tha tenantId: SPECFLOW_POWERAPPS_TENANTID optional # mandatory clientId: SPECFLOW_POWERAPPS_CLIENTID # mandatory clientSecret: SPECFLOW_POWERAPPS_CLIENTSECRET # mandatory -users: # mandatory +users: # One user is mandatory, additional users are optional - username: SPECFLOW_POWERAPPS_USERNAME_SALESPERSON # mandatory password: SPECFLOW_POWERAPPS_PASSWORD_SALESPERSON # optional - populate if this user will be logging in for tests alias: a salesperson # mandatory @@ -73,6 +73,8 @@ users: # mandatory The URL, driversPath, usernames, passwords, and application user details will be set from environment variable (if found). Otherwise, the value from the config file will be used. The browserOptions node supports anything in the EasyRepro `BrowserOptions` class. +Tests will be distributed evenly between the users if multiple users are configured with the same alias. This can be helpful when you run a large number of tests in parallel and are encountering errors due to user-level platform API limits. + ### Writing feature files You can use the predefined step bindings to write your tests. diff --git a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj index 8cb9eb5..e066de5 100644 --- a/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj +++ b/bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj @@ -38,8 +38,8 @@ - - + + From 2a32b572e0e178a84dd9c50b420ac29cc870d4e2 Mon Sep 17 00:00:00 2001 From: Alex Bance Date: Wed, 23 Jun 2021 16:39:20 +0100 Subject: [PATCH 10/14] updated pipeline to pass additional user details --- templates/include-build-and-test-steps.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/include-build-and-test-steps.yml b/templates/include-build-and-test-steps.yml index ee2f992..4d844e4 100644 --- a/templates/include-build-and-test-steps.yml +++ b/templates/include-build-and-test-steps.yml @@ -92,7 +92,9 @@ jobs: POWERAPPS_SPECFLOW_BINDINGS_TEST_CLIENTSECRET: $(Application User Client Secret) POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_USERNAME: $(User ADO Integration Username) POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_PASSWORD: $(User ADO Integration Password) - POWERAPPS_SPECFLOW_BINDINGS_TEST_URL: $(URL) + POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_USERNAME2: $(Extra Admin User Username) + POWERAPPS_SPECFLOW_BINDINGS_TEST_ADMIN_PASSWORD2: $(Extra Admin User Password) + POWERAPPS_SPECFLOW_BINDINGS_TEST_URL: $(URL) - task: SonarCloudAnalyze@1 displayName: Analyse with SonarCloud - task: SonarCloudPublish@1 From 9e458e44241dd770450dcdd08ad52daef876c209 Mon Sep 17 00:00:00 2001 From: Alex Bance Date: Thu, 24 Jun 2021 07:22:47 +0100 Subject: [PATCH 11/14] Swapped threadstatic for thread local --- .../Configuration/TestConfiguration.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs index ec39384..e4ae789 100644 --- a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs +++ b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Configuration; using System.Linq; + using System.Threading; using Microsoft.Dynamics365.UIAutomation.Browser; using YamlDotNet.Serialization; @@ -20,8 +21,7 @@ public class TestConfiguration private const string GetUserException = "Unable to retrieve user configuration. Please ensure a user with the given alias exists in the config."; private readonly object userEnumeratorsLock = new object(); - [ThreadStatic] - private UserConfiguration currentUser; + private ThreadLocal currentUser = new ThreadLocal(); private Dictionary> userEnumerators; /// @@ -95,9 +95,9 @@ public Uri GetTestUrl() /// The user configuration. public UserConfiguration GetUser(string userAlias, bool useCurrentUser = true) { - if (useCurrentUser && this.currentUser != null) + if (useCurrentUser && this.currentUser.Value != null) { - return this.currentUser; + return this.currentUser.Value; } try @@ -112,7 +112,7 @@ public UserConfiguration GetUser(string userAlias, bool useCurrentUser = true) aliasEnumerator.MoveNext(); } - this.currentUser = aliasEnumerator.Current; + this.currentUser.Value = aliasEnumerator.Current; } } catch (Exception ex) @@ -120,7 +120,7 @@ public UserConfiguration GetUser(string userAlias, bool useCurrentUser = true) throw new ConfigurationErrorsException($"{GetUserException} User: {userAlias}", ex); } - return this.currentUser; + return this.currentUser.Value; } } } From d435ede97d8214e6f962cf3b497249cfae621b7d Mon Sep 17 00:00:00 2001 From: Alex Bance Date: Thu, 24 Jun 2021 11:44:17 +0100 Subject: [PATCH 12/14] fix: updated logic steps to actually utilise the new logic --- .../Capgemini.PowerApps.SpecFlowBindings/Steps/LoginSteps.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Steps/LoginSteps.cs b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Steps/LoginSteps.cs index 4f728a1..9a17eb4 100644 --- a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Steps/LoginSteps.cs +++ b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Steps/LoginSteps.cs @@ -56,7 +56,7 @@ public static void Login(IWebDriver driver, Uri orgUrl, string username, string [Given("I am logged in to the '(.*)' app as '(.*)'")] public static void GivenIAmLoggedInToTheAppAs(string appName, string userAlias) { - var user = TestConfig.GetUser(userAlias); + var user = TestConfig.GetUser(userAlias, useCurrentUser: false); if (TestConfig.UseProfiles && TestConfig.BrowserOptions.BrowserType.SupportsProfiles()) { From 39fde6ec78f26da94a1afdc330239569c97cd06d Mon Sep 17 00:00:00 2001 From: Max Ewing Date: Thu, 24 Jun 2021 13:12:37 +0100 Subject: [PATCH 13/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb8b881..742539a 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ applicationUser: # optional - populate if creating test data for users other tha tenantId: SPECFLOW_POWERAPPS_TENANTID optional # mandatory clientId: SPECFLOW_POWERAPPS_CLIENTID # mandatory clientSecret: SPECFLOW_POWERAPPS_CLIENTSECRET # mandatory -users: # One user is mandatory, additional users are optional +users: # mandatory - username: SPECFLOW_POWERAPPS_USERNAME_SALESPERSON # mandatory password: SPECFLOW_POWERAPPS_PASSWORD_SALESPERSON # optional - populate if this user will be logging in for tests alias: a salesperson # mandatory From 114898a6dde304e6109ea782cadb70744ad89ed7 Mon Sep 17 00:00:00 2001 From: Max Ewing Date: Thu, 24 Jun 2021 13:12:45 +0100 Subject: [PATCH 14/14] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 742539a..937b629 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ users: # mandatory The URL, driversPath, usernames, passwords, and application user details will be set from environment variable (if found). Otherwise, the value from the config file will be used. The browserOptions node supports anything in the EasyRepro `BrowserOptions` class. Tests will be distributed evenly between the users if multiple users are configured with the same alias. This can be helpful when you run a large number of tests in parallel and are encountering errors due to user-level platform API limits. + #### User profiles Setting the `useProfiles` property to true causes the solution to create and use a unique [profile](https://support.google.com/chrome/answer/2364824?co=GENIE.Platform%3DDesktop&hl=en) for each user listed in the config file. This currently only works in Chrome & Firefox and attempting to use it with Edge or IE will cause an exception to be thrown. By using profiles test runs for the same user will not be required to re-authenticate, this saves time during test runs. [To take full advantage of this you will need to have the "Stay Signed In" prompt enabled.](https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/keep-me-signed-in)