Preparing to inject test configuration – Refactoring to use a configuration object.

Preparing to inject test configuration – Refactoring to use a configuration object.

This entry is part 6 of 9 in the series Launching WebDrivers in .NET Core the easy 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:

  1. Refactor calls with many arguments to take a standard WebDriver configuration object.
  2. Allow different ways to collect and override the test configuration.
  3. 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]

Series Navigation<< Testability, interfaces and unit tests for Dummies (and junior SDETs)Test Configuration with .NET Core and NUnit 3 >>

One thought on “Preparing to inject test configuration – Refactoring to use a configuration object.

  1. 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.

Comments are closed.