This is the second article from the new series- Design & Architecture. In the first publication from the series I showed you how to start creating a Hybrid Test Automation Framework- creating core interfaces of the hybrid framework. In this post, I am going to show you how to build your first concrete implementation of these interfaces through Selenium WebDriver. Also, I am going to explain how to resolve the particular drivers and elements through Unity IoC Container.

Create Selenium Driver Implementation The first job you have is to create a new project named- HybridTestFramework.UITests.Selenium. After that, reference the previously created core project HybridTestFramework.UITests.Core that holds the hybrid framework's interfaces. You also need to install a couple of NuGets- Selenium.WebDriver and Unity. Below you can find how the projects should look like. For every core driver interface, we are going to create a new SeleniumDriver partial class. These partial classes are going to be placed under the Engine folder.

Implement IDriver Interface The main class definition is declared as partial and contains the constructor of the SeleniumDriver implementation. It requires an instance of the Unity IoC Container and BrowserSettings where different execution settings are placed. Based on the configured settings' browser type a new WebDriver instance is created in the ResolveBrowser method.

Implement IElementFinder Interface If you look closely at the solution's image, you will probably notice that most of the files under the Engine folder have the prefix 'SeleniumDriver.'. All of them are SeleniumDriver partial classes, but the file names are different because of the file structure. The code below is placed in the SeleniumDriver.ElementFinder class. You can always place all of the code in a single file but it will have an enormous size.

The methods call the ElementFinderService's implementations. The most important part is that the current search context is the IWebDriver (meaning that the driver will look for the elements in the whole page). ElementFinderService The point of creating a dedicated class for element localization is that you can once search in the whole page, but you can also use the different elements as a search context (div elements). The class exists because we do not want to have a code duplication. We pass the search context through the ISearchContext parameter. IWebDriver and IWebElement both Selenium interfaces implement the ISearchContext. You can use them both to search elements.

Another interesting part of the code is how we resolve the type of the searched element. All concrete Selenium implementations of the controls implement the IElement interface. Before we can determine the type of the element, we need to register its type in the Unity container. Also, because all elements require a couple of parameters, we pass them through resolve override (meaning that the Unity will inject the passed instances during the creation of the object). At the end of the article, you will find how to register the different types correctly.

Implement IElement Interface

There is almost nothing special about this concrete implementation of the IElement interface, except the find methods. Here the search context is the found element itself. Implement IBrowser Interface

The different methods in this class only wrap the WebDriver's native methods. You can find more about them in my advanced tips articles.

Implement ICookieService Interface

You can use the ICookieService interface in your pages or tests to work with cookies. WebDriver provides full cookies' support. Implement INavigationService Interface

Implicit and explicit waits should not be used in a test together that is why when using explicit we are removing the implicit. Also, another interesting part is that we are using the UrlDecode method of the HttpUtility class to decode URLs. After the page is loaded we rise the Navigated event, any subscribed code will be executed. For example, wait for a particular element to be displayed. Implement IJavaScriptInvoker Interface

You do not need to pass the whole IDriver interface to your pages, only the required parts of it. For example, if you need to execute a JavaScript code on the page, only then you will add the upper implementation. Selenium Driver Implementation in Tests Register Types and Instances- Unity IoC Container