-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: multiple users per alias #88
feat: multiple users per alias #88
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of changes suggested so that this works where there are multiple different user aliases. Suggestions not tested btw so may need some tweaks. Also just needs documenting in the README and it should be good to go 👍🏻 Thanks, @ngwalker!
...emini.PowerApps.SpecFlowBindings.UiTests/Capgemini.PowerApps.SpecFlowBindings.UiTests.csproj
Outdated
Show resolved
Hide resolved
bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs
Outdated
Show resolved
Hide resolved
bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs
Outdated
Show resolved
Hide resolved
bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs
Outdated
Show resolved
Hide resolved
bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs
Outdated
Show resolved
Hide resolved
OK so it's clear to me now from testing my suggested code that it's going to need a considerable amount of tweaks to get it working! 😄 Hopefully it's a bit clearer at least as to what he desired outcome is. |
I've tested this and I believe it's working - namespace Capgemini.PowerApps.SpecFlowBindings.Configuration
{
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using Microsoft.Dynamics365.UIAutomation.Browser;
using YamlDotNet.Serialization;
/// <summary>
/// Test configuration for Dynamics 365 automated UI testing.
/// </summary>
public class TestConfiguration
{
/// <summary>
/// The name of the file that stores the test configuration.
/// </summary>
public const string FileName = "power-apps-bindings.yml";
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 Dictionary<string, IEnumerator<UserConfiguration>> userEnumerators;
/// <summary>
/// Initializes a new instance of the <see cref="TestConfiguration"/> class.
/// </summary>
public TestConfiguration()
{
this.BrowserOptions = new BrowserOptions();
}
/// <summary>
/// Sets the URL of the target Dynamics 365 instance.
/// </summary>
[YamlMember(Alias = "url")]
public string Url { private get; set; }
/// <summary>
/// Gets or sets the browser options to use for running tests.
/// </summary>
[YamlMember(Alias = "browserOptions")]
public BrowserOptions BrowserOptions { get; set; }
/// <summary>
/// Gets or sets users that tests can be run as.
/// </summary>
[YamlMember(Alias = "users")]
public List<UserConfiguration> Users { get; set; }
/// <summary>
/// Gets or sets application user client ID and client secret for performing certain operations (e.g. impersonating other users during test data creation).
/// </summary>
[YamlMember(Alias = "applicationUser")]
public ClientCredentials ApplicationUser { get; set; }
[YamlIgnore]
private Dictionary<string, IEnumerator<UserConfiguration>> 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;
}
}
/// <summary>
/// Gets the target URL.
/// </summary>
/// <returns>The URL of the test environment.</returns>
public Uri GetTestUrl()
{
return new Uri(ConfigHelper.GetEnvironmentVariableIfExists(this.Url));
}
/// <summary>
/// Retrieves the configuration for a user.
/// </summary>
/// <param name="userAlias">The alias of the user.</param>
/// <returns>The user configuration.</returns>
public UserConfiguration GetUser(string userAlias)
{
UserConfiguration user;
try
{
lock (this.userEnumeratorsLock)
{
var aliasEnumerator = this.UserEnumerators[userAlias];
if (!aliasEnumerator.MoveNext())
{
this.UserEnumerators[userAlias] = this.Users.Where(u => u.Alias == userAlias).GetEnumerator();
aliasEnumerator = this.UserEnumerators[userAlias];
aliasEnumerator.MoveNext();
}
user = aliasEnumerator.Current;
}
}
catch (Exception ex)
{
throw new ConfigurationErrorsException($"{GetUserException} User: {userAlias}", ex);
}
return user;
}
}
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added suggested changes
bindings/tests/Capgemini.PowerApps.SpecFlowBindings.UiTests/power-apps-bindings.yml
Outdated
Show resolved
Hide resolved
bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more changes requested as I realised this might be a breaking change for some package consumers.
Co-authored-by: Max Ewing <max.ewing@outlook.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requested changes applied
…n/TestConfiguration.cs Co-authored-by: Max Ewing <max.ewing@outlook.com>
Still some more to be done to remove the surplus test user and use the new |
@@ -18,6 +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 readonly object userEnumeratorsLock = new object(); | |||
private readonly ThreadLocal<UserConfiguration> currentUser = new ThreadLocal<UserConfiguration>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency with what we've got in the PowerAppsStepDefiner
class I would've resolved the SonarCloud comment by adding the static
keyword that was missing rather than using a ThreadLocal<>
instance member.
Kudos, SonarCloud Quality Gate passed! |
Purpose
To enable the use of multiple "as an admin" alias' as the User
Approach
Added logic to the TestConfiguration class to iterate over the Users list, with conditional logic
Closes #83