Click here to Skip to main content
15,867,453 members
Articles / General Programming / Threads
Article

Framework – Your First Framework - Part 1

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
26 Aug 2018CPOL4 min read 5.7K   7  
In the last article, we discussed the definition of a framework and expanded on it. And we tried to understand that the idea of writing your own framework isn’t quite as scary as you might think.

In the last article, we discussed the definition of a framework and expanded on it. And we tried to understand that the idea of writing your own framework isn’t quite as scary as you might think.

So today, we’re going to take the first step to creating your first framework for testing web applications in Selenium. Before we begin, I recommend reading the ‘Selenium – What is it?’ article, so you at least understand the basics of Selenium and WebDriver code.

The most important part of any Selenium based framework is that it can launch a browser, and have the flexibility to launch a variety of browsers to cover cross browser testing. And that is what our first class is going to be. Rather than do what most sites do when they go through framework tutorials, I’m going to do an article per class, but make sure that by the end of the article, you understand what’s being done, why it’s being done and my thinking behind the way I’ve done. It’s all too easy to assume that you understand code when giving examples, but if I go and put 5 classes in an article and skim across all of them, and you don’t understand any of it, how will the next article be of any help? With that said, let’s begin:

C#
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.Net;
using NUnit.Framework;

namespace AutomationFramework.Engine
{
    public static partial class Driver
    {
        public static TimeSpan TimeOut = new TimeSpan(0, 1, 0);
        public static TimeSpan PollingInterval = new TimeSpan(0, 0, 2);

        public static void SetImplicitTimeout(TimeSpan timeout)
        {
            DriverBase.Instance.Manage().Timeouts().ImplicitWait = timeout;
        }
        
        public static void SetImplicitTimeout()
        {
            SetImplicitTimeout(TimeOut);
        }

        public enum DriverType
        {
            InternetExplorer,
            Chrome,
            Edge
        }

        public static void Initialise(DriverType driverType, TimeSpan? implicitWait)
        {
            var initialiseTimeout = implicitWait ?? TimeOut;

            try
            {
                switch (driverType)
                {
                    case DriverType.InternetExplorer:
                        var internetExplorerOptions = new InternetExplorerOptions 
                                { IntroduceInstabilityByIgnoringProtectedModeSettings = true, 
                                  AcceptInsecureCertificates = true };
                        DriverBase.Instance = new InternetExplorerDriver
                           (TestContext.CurrentContext.TestDirectory, internetExplorerOptions));
                        break;
                    case DriverType.Edge:
                        var edgeExplorerOptions = new EdgeOptions { AcceptInsecureCertificates = true };
                        DriverBase.Instance = new EdgeDriver(TestContext.CurrentContext.TestDirectory, 
                                                 edgeExplorerOptions));
                        break;
                    case DriverType.Chrome:
                        var chromeOptions = new ChromeOptions();
                        chromeOptions.AddArguments("test-type");
                        chromeOptions.AddArguments("chrome.switches", "--disable.extensions");
                        DriverBase.Instance = new ChromeDriver
                           (TestContext.CurrentContext.TestDirectory, chromeOptions, implicitWait);
                        break;
                }
            }
            catch (WebDriverException)
            {
                throw new WebDriverException($"Failed to initialise the 
                     {driverType.DescriptionAttribute()} web driver for Selenium");
            }

            DriverBase.Instance.Manage().Window.Maximize();
            
            if(null != implicitWait)
            {
                SetImplicitTimeout((TimeSpan)implicitWait);
            }
        }
    }
}

There are many ways to approach this, but the one we’re going to take in this example is to create our WebDriver instance via a switch statement that will take a parameter at another point in the framework. Depending on the parameter passed, we will create a browser specific WebDriver instance with some options. But let’s break each bit of code down into detail.

The first thing I should cover is the fact that our class is a partial class. The partial keyword is used to essentially break large classes down into smaller classes across several files, purely for readability and keeping tidy code. But this is part of a bigger class that is Driver. We’ll cover the other partial classes later on.

Once we get inside the class, we get to these few lines:

C#
public static TimeSpan TimeOut = new TimeSpan(0, 1, 0);
public static TimeSpan PollingInterval = new TimeSpan(0, 0, 2);

public static void SetImplicitTimeout(TimeSpan timeout)
{
    DriverBase.Instance.Manage().Timeouts().ImplicitWait = timeout;
}

public static void SetImplicitTimeout()
{
    SetImplicitTimeout(TimeOut);
}

These are variables that we will use to set our timeout value before our tests will give up waiting for an action to occur, and how often our framework will check for updates on an event that is possibly about to time out. There are two types of waits to keep in mind with test automation, explicit and implicit. Implicit is basically telling the test to wait for a set period of time, think of a Thread.Sleep. And an explicit wait is telling the test to wait depending on certain conditions. Explicit conditions are always the preferred waits to use when automated testing, purely because, the build up of implicit waits can unnecessarily add time to your test run. It is also considered lazy to overuse implicit waits.

After this, we create an enum for our different Driver types. Now this is purely a preference thing for me. You could just pass a string in to our initialise method, but it’s far tidier, and less error prone to just pass an enum type in.

On to the Initialise method:

C#
public static void Initialise(DriverType driverType, TimeSpan? implicitWait)
{
    var initialiseTimeout = implicitWait ?? TimeOut;

    try
    {
        switch (driverType)
        {
            case DriverType.InternetExplorer:
                var internetExplorerOptions = new InternetExplorerOptions
                        { IntroduceInstabilityByIgnoringProtectedModeSettings = true,
                          AcceptInsecureCertificates = true };
                DriverBase.Instance = new InternetExplorerDriver
                     (TestContext.CurrentContext.TestDirectory, internetExplorerOptions));
                break;
            case DriverType.Chrome:
                var edgeExplorerOptions =
                          new EdgeOptions { AcceptInsecureCertificates = true };
                DriverBase.Instance = new EdgeDriver
                          (TestContext.CurrentContext.TestDirectory, edgeExplorerOptions));
                break;
            case DriverType.Chrome:
                var chromeOptions = new ChromeOptions();
                chromeOptions.AddArguments("test-type");
                chromeOptions.AddArguments("chrome.switches", "--disable.extensions");
                DriverBase.Instance = new ChromeDriver
                  (TestContext.CurrentContext.TestDirectory, chromeOptions, implicitWait);
                break;
        }
    }
    catch (WebDriverException)
    {
        throw new WebDriverException($"Failed to initialise the
                       {driverType.DescriptionAttribute()} web driver for Selenium");
    }

    DriverBase.Instance.Manage().Window.Maximize();

    if(null != implicitWait)
    {
        SetImplicitTimeout((TimeSpan)implicitWait);
    }
}

This is where we are setting up which Driver version we will create based on the driverType that we pass in. It’s a simple switch statement that will go in and set up a new instance of the driver and configure any browser specific options that we may want.

These browser settings are completely optional. And you aren’t just limited to the ones that I’m using either. There are many that can be used, and the ones you need, if any, will totally depend on the environment you’re testing on as well as any requirements set in your testing. You can read more about browser specific capabilities and what they mean here.

Once we have set our browser up and done some basic exception checking to make sure it has been properly initialised, we do a basic call to the driver instance to maximise the window. I do it here as opposed to later on, just to make sure that before we’ve even left the initialised method, we have our browser window open and maximised.

It’s worth noting that at the moment, we are simply creating a local instance of WebDriver, but at some point, we will look into adding remote capabilities.

That’s it for our DriverFactory class. Simple, right? Now we need a class to wrap our WebDriver code. In the next article, I will cover the DriverBase class, as well as expanding on some of the other partial classes we have in Driver.

As a challenge, why not add Firefox driver capability and some browser options.

The post Framework – Your First Framework Part 1 appeared first on Learn Automation.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO Steed Solutions Ltd
United Kingdom United Kingdom
I’ve been in the software industry for over 10 years now. Graduating from university with a 1st in Computer Science, I accidentally found myself in a software testing career instead of the development career I intended. But that was no bad thing… I quickly learned that via test automation, I still got to do all the coding and technical things that I loved. And I’ve loved it since.

My first role was developing test scripts in VB in a QTP framework, and from there, quickly moved in to roles where I was developing frameworks in C# for companies that had no previous automation in place. Fast forward to where I am now and I am freelancing as an automation consultant, going in to companies to build frameworks or provide support and expertise to those who already have automation in place.

Comments and Discussions

 
-- There are no messages in this forum --