Preparing to inject test configuration – Refactoring to use a configuration object.
- Launching Selenium WebDriver in .NET Core the easy way
- Starting to build a (new) .net Core PageFactory
- Launching WebDrivers in .net Core
- Creating an internal WebDriverFactory
- Testability, interfaces and unit tests for Dummies (and junior SDETs)
- Preparing to inject test configuration – Refactoring to use a configuration object.
- Test Configuration with .NET Core and NUnit 3
- Applying a .runsettings file from the command line in .NET Core
- Dependency Injection the .NET Core way
After last time I can feel that I am getting close to being able to inject a configuration for my tests. Next I want to be able to use a configuration file to set the particular configuration that I want to use for any particular test run. So how do we go about doing that in .NET Core?
The next steps are:
- Refactor calls with many arguments to take a standard WebDriver configuration object.
- Allow different ways to collect and override the test configuration.
- Once I have that wired up I am then in a good place to set up Dependency Injection.
I never intended to write a post about this bit of refactoring alone. However, having originally written it as the start of a combined article that became WAAAAAY too long and rather than bin this, I’ll let this go live today.
Defining a ‘configuration’ object
Core package additions: IWebDriverConfiguration /
WebDriverConfiguration
In this case I am looking to be able to set the configuration (Browser, WindowSize etc.) One thing that writing my unit tests last time made clear was that the number of arguments required to specify the required WebDriver is too large. Ideally, there should be a single ‘configuration object’ passed in as an argument like:
var driver = webDriverFactory.GetWebDriver(webDriverConfiguration)
and therefore also the constructor for my WebDriverManager class.
var manager = new WebDriverManager(webDriverFactory, webDriverConfiguration)
Fortunately that is fairly simple, and can be added without making a breaking changes to the current public interfaces.
IWebDriverConfiguration
namespace AlexanderOnTest.NetCoreWebDriverFactory { public interface IWebDriverConfiguration { Browser Browser { get; set; } PlatformType PlatformType { get; set; } WindowSize WindowSize { get; set; } Uri GridUri { get; set; } bool IsLocal { get; set; } bool Headless { get; set; } } }
And implementation:
WebDriverConfiguration
namespace AlexanderOnTest.NetCoreWebDriverFactory { public class WebDriverConfiguration :IWebDriverConfiguration { [DefaultValue(Browser.Firefox)] [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] public Browser Browser { get; set; } [DefaultValue(PlatformType.Any)] [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] public PlatformType PlatformType { get; set; } [DefaultValue(WindowSize.Hd)] [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] public WindowSize WindowSize { get; set; } [DefaultValue("https://localhost:4400/wd/grid")] [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] public Uri GridUri { get; set; } [DefaultValue(true)] [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] public bool IsLocal { get; set; } [DefaultValue(false)] [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] public bool Headless { get; set; } } }
Then I can just wire in the new overloads: (I’ll share the implementation details)
DefaultWebDriverFactory
The intention is to refactor these as the primary methods called from the originals as overloads, but that’s too much for now.
public DefaultWebDriverFactory(DriverPath driverPath, IWebDriverConfiguration configuration, IDriverOptionsFactory driverOptionsFactory = null) : this(driverPath.PathString, configuration.GridUri, driverOptionsFactory) { } public IWebDriver GetRemoteWebDriver(IWebDriverConfiguration configuration) { if (configuration.IsLocal) { throw new ArgumentException("A Local WebDriver Instance cannot be generated by this method."); } return GetRemoteWebDriver( configuration.Browser, configuration.PlatformType, configuration.WindowSize, configuration.Headless ); } public IWebDriver GetLocalWebDriver(IWebDriverConfiguration configuration) { if (!configuration.IsLocal) { throw new ArgumentException("A RemoteWebDriver Instance cannot be generated by this method."); } return GetLocalWebDriver( configuration.Browser, configuration.WindowSize, configuration.Headless ); } public IWebDriver GetWebDriver(IWebDriverConfiguration configuration) { return GetWebDriver( configuration.Browser, configuration.WindowSize, configuration.IsLocal, configuration.PlatformType, configuration.Headless ); }
WebDriverManager
Just a new, simplified constructor
public WebDriverManager(IWebDriverFactory factory, IWebDriverConfiguration configuration) { this.webDriverConstructor = () => factory.GetWebDriver(configuration); }
[Edit 26/6/19 Moved into the new series: Launching WebDrivers in .NET Core the easy way]
One thought on “Preparing to inject test configuration – Refactoring to use a configuration object.”
Hi Alexander,
Thank you for sharing your thoughts on how to resolve the deprecated Page Factory. I hope on your next post, you will show us a sample Test Automation framework with your own version of the page factory. I am learning a lot from you. Looking forward on your next blog.
Comments are closed.