Skip to content

Overview (English)

knysh edited this page Apr 15, 2020 · 7 revisions

Aquality Selenium for .NET

Aquality Selenium is a wrapper over Selenium WebDriver tool that allows to automate work with web browsers. Selenium WebDriver requires some skill and experience. So, Aquality Selenium suggests simplified and most importantly safer and more stable way to work with Selenium WebDriver.

1. PLATFORM SUPPORT

At the moment Aquality Selenium allows to automate web tests for Chrome, Firefox, Safari, IExplorer and Edge. Also you can implement support of new browsers that Selenium supports (more details here). Tests can be executed on any operating system with installed .NET Core SDK 2.1 and higher.

2. CONFIGURATIONS

Aquality Selenium provides flexible configuration to run tests by editing settings.json file. Most of the settings are clear without further explanation but major points are highlighted below. There is a possibility to implement your own configuration.

2.1. SETTINGS

The library uses settings.json file or its copies to store all necessary configurations for test runs. By default settings.json from dll Embedded Resources is using. If you need to change some options from this file you have to create your own copy of this file in Resources folder in your project and change them in this copy. Also you can create several copies of this file with different settings and store in the same folder. The names of the copies should match the following pattern settings.{profile}.json. It is useful if you need to run tests on different operating systems, machines, browsers, etc. For example, the Aquality Selenium dev team has two configurations - settings.json and settings.local.json - to run tests in Circle CI docker container and on personal infrastructure. To change the settings you can set environment variable with name profile and value of desired settings (for example, local). By default file with name settings.json is using.

Any parameter from settings.json also can be overridden through environment variables. You just need to set jsonPath to the desired parameter and its value in environment variable: driverSettings.chrome.webDriverVersion: 77.0.3865.10.

Settings file contains several sections the purpose of which is described below.

2.2. BROWSER

browserName parameter defines the web browser which will be used for test run. For example, browserName: chrome means that tests will be run on Google Chrome.

isRemote parameter defines whether tests will be run on the same machine where .NET process is running or remote server will be using which is defined in parameter remoteConnectionUrl.

2.3. DRIVER SETTINGS

Section driverSettings from settings.json provides an ability to set up necessary capabilities, options and start arguments for web driver.

NOTE: Use official sources from web browser developers to get list of available arguments. For example, for Chrome: run-chromium-with-flags

Here we tried to described some points of work with IExplorer because of different information in the Internet.

2.4. TIMEOUTS

settings.json contains timeouts section which includes a set of parameters related to different timeouts that are using in the library.

All these parameters are using to initialize object of TimeoutConfiguration which is accessible throught AqualityServices.Get<ITimeoutConfiguration>().

The following are the parameters from timeouts section:

  • timeoutImplicit = 0 seconds - web driver implicit wait timeout Selenium Implicit Wait
  • timeoutCondition = 15 seconds - events with desired conditions timeout. Events include waiting for elements or their state
  • timeoutScript = 10 seconds - it is a limit of scripts execution using WebDriver's method ExecuteAsyncScript
  • timeoutPageLoad = 30 seconds - web page load timeout
  • timeoutPollingInterval = 300 milliseconds - polling interval for explicit waits
  • timeoutCommand = 60 seconds - maximum timeout of each WebDriver command

As part of the solution, all elements waits are met using Explicit Wait. The use of two wait types (implicit and explicit) is not recommended, as it can lead to incorrect behavior. So, the value of implicit wait will be set to zero forcibly before each explicit wait, regardless of what is in the configuration.

2.5 RETRY POLICY

retry section from settings.json file is responsible for configuration the number of retries of actions on elements. All the actions such as clicking, typing, ect., can be performed repeatedly in case of exception. The ElementActionRetrier class which is used for any actions on elements is responsible for this logic.

The number parameter means the number of retries of action before exception is thrown.

The pollingInterval parameter means the interval in milliseconds between the retries.

The ElementActionRetrier handles StaleElementReferenceException and InvalidElementStateException by default and does the retries.

2.6. LOGGING

The solution supports logging of operations (interaction with the browser, page elements). Logging Example:

2019-07-18 10:14:08 INFO - Label 'First product' :: Moving mouse to element

Supported languages:

  • en - English
  • ru - Russian

The value of logging language is set in the logger.language parameter.

2.7. CLOUD USAGE

To set up the run on the remote server with Selenium Grid (Selenoid, Zalenium) or on such platforms as BrowserStack, Saucelabs, etc., it is required to set correct value of URL for connection to the service in remoteConnectionUrl parameter in settings.json file. Also make sure that isRemote parameter has value true. For example, URL for BrowserStack can be the following https://USERNAME:AUTOMATE_KEY@hub-cloud.browserstack.com/wd/hub.

2.8. ACTIONS HIGHLIGHTING

isElementHighlightEnabled option is responsible for the need to highlight the elements of the web page with which the work is performed. Enabling the option allows you to more clearly observe the actions of the test.

2.9. ACCESS FROM THE CODE

You can get an access to the settings using instance of Configuration class. For example:

var browserName = AqualityServices.Get<IBrowserProfile>().BrowserName;

This construction returns value of browserName from settings.json file.

3. AQUALITY SERVICES

The solution is based on dependency injection technique where class AqualityServices provides us all registered services. For example, if you need to get browser instance:

var browser = AqualityServices.Browser;

Or you can use public static T Get<T>() method to get some specific service, for example:

var browserProfile = AqualityServices.Get<IBrowserProfile>();

All aquality services are registered in BrowserStartup class.

4. BROWSER

The Browser class is a kind of facade for Selenium WebDriver which contains methods for working with browser window and directly with WebDriver (for example, navigate, maximize, etc.). Writing a test script starts by creating an instance of Browser - more on this below.

4.1. PARALLEL RUNS

The solution assumes the existence of only one instance of Browser class (has a property of RemoteWebDriver type) in the executing thread. Usually tests work with only one instance of browser and this approach is optimal.

If you are working on the task when more than one instance of browser per test is necessary, each browser has to be created in a separate thread. You can find an example of multi-threading usage here: BrowserConcurrencyTests.cs.

If you are using standard ways of multi-threading from such tools as NUnit, MSTest, etc., every new thread will work with its own instance of Browser class.

4.2. BROWSER INITIALIZATION

There are several ways how to initialize Browser. The main one is based on the usage of AqualityServices class which has static property Browser. Below are the options of AqualityServices usage.

If you need to get the browser with configuration from settings file you just have to do:

var browser = AqualityServices.Browser;

The first call of Browser creates the necessary instance with WebDriver (it opens web browser window, if it is not headless mode). All the following calls in the current thread will work with this instance.

4.3. BROWSER FACTORY

AqualityServices uses browser factory to create an instance of Browser. There are two implementations of browser factory in the solution:

Each factory implements IBrowserFactory interface which has only one property Browser. It allows you to create your own factory. If you want to use your own implementation of browser factory you have to set it in BrowserManager using method SetFactory(IBrowserFactory browserFactory) before the very first call of Browser property. The examples with custom factory can be found in CustomBrowserFactoryTests class.

If you don't want to use factories you have an option to create an instance of Browser by yourself and set it as value of AqualityServices.Browser property. Browser class has a public constructor public Browser(RemoteWebDriver webDriver). You can still use existing implementations of IDriverSettings, ITimeoutConfiguration, ect., during the creation of your own IConfiguration.

4.4. DRIVER OPTIONS

Implementation of IDriverSettings is using during the creation process of Browser and in particular WebDriver. IDriverSettings includes property DriverOptions which is set to WebDriver during its instantiating. If you use default BrowserFactory, the list of options will be created based on the information from settings.json file.

You can find the example with user options here: Should_BePossibleToUse_CustomFactory.

4.5. DOWNLOAD DIRECTORY

It is often necessary to download files from browser and then perform some actions with them. To get the current download directory you can use property DownloadDirectory of Browser class.

To support this functionality IDriverSettings interface obliges to implement property string DownloadDir { get; }. You if use one of the existing BrowserFactory you can set download directory in settings.json file. For example:

{
  "download.default_directory": "//home//selenium//downloads"
}

NOTE: Key download.default_directory is differ for different browser. You can get the name of this key in appropriate classes:

At the moment the library supports file downloading only in Chrome, Firefox, Safari browsers.

4.6. ALERTS

Browser class provides methods to work with Alerts:

AqualityServices.Browser.HandleAlert(AlertAction.Accept);

You can find more examples in AlertTests.

4.7. SCREENSHOTS

Browser class has the method to get screenshot of web page:

var screenshot = AqualityServices.Browser.GetScreenshot();

For details please see the following test: Should_BePossibleTo_TakeScreenshot.

4.8. TABS

Browser class provides methods to work with tabs:

AqualityServices.Browser.Tabs().SwitchToLastTab();

You can find more examples in BrowserTabsTests.

5. ELEMENTS

When Browser is initialized and desired web page is opened you can start to work with its elements.

5.1. ELEMENT FACTORY

There is an ElementFactory class in the library which is responsible for creating elements of desired type. Below is the example of getting ITextBox element:

var elementFactory = AqualityServices.Get<IElementFactory>();
var usernameTextBox = elementFactory.GetTextBox(By.Id("username"), "Username");

Using ElementFactory you can create an instance of any class that implements IElement interface. There are a set of methods in ElementFactory which returns implementations of IElement that library has (IButton, ITextBox, ICheckBox, etc.). Please use interfaces as much as possible.

5.2. CUSTOM ELEMENTS

The user is able to create his own element or extend the existing one. ElementFactory provides method T GetCustomElement<T> for this purpose. You need just to implement IElement interface or extend the class of existing element. An example of extension and use can be found in CustomElementTests class.

5.3. LIST OF ELEMENTS

ElementFactory provides method FindElements to get the list of desired elements, the usage of which is demonstrated below:

var checkBoxes = elementFactory.FindElements<ICheckBox>(By.XPath("//*[@class='checkbox']"));

You can find other examples with ElementFactory and elements in Element Tests.

5.4. STATES OF ELEMENTS

Depending on the task you may need to find only Displayed elements on the page or elements which at least exist in the source html (ExistsInAnyState).

To get such elements and work with them methods from ElementFactory have optional parameter state. For example:

var link = elementFactory.GetLink(By.Id("redirect"), "Link", state: ElementState.Displayed);

The often situation during the work with elements is to check element state or waiting for desired element state. ElementStateProvider class helps to do this. Element has State property which provides an access to the instance of this class:

UserNameTextBox.State.WaitForEnabled();
var isDisplayed = UserNameTextBox.State.IsDisplayed;

You can get more examples in ElementStateTests class.

6. FORMS

The main goal of this library is to help with test automation of web applications. There is a popular practice using Page Objects approach in test automation. To support and extend this approach solution provides Form class which can be used as a parent for all pages and forms of the application under test. Example of usage:

public class SliderForm : Form 
{
    public SliderForm() : base(By.Id("slider_row"), "Slider") 
    {
    }
}

Id = "slider_row" is a locator which will be used when checking the opening of the page/form using IsDisplayed property from Form class.

Example of test with Page Objects: ShoppingCartTests.

7. JAVASCRIPT EXECUTION

If you need to execute JavaScript on opened web page you can use one of ExecuteScript methods from Browser class. The solution contains a sufficient amount of most popular JS scripts which are using in test automation. The list of available scripts is represented by JavaScript enum. The scripts are located in resource directory JavaScripts. The examples of methods usages are defined in BrowserTests class.

There are also an overridden methods to pass JavaScript directly from file or as string in Browser class.

8. CONDITIONAL WAIT

If you need to wait for any condition to be met, you can use the IConditionalWait, which is implemented here by default. You are able to get this implementation by using following code:

AqualityServices.ConditionalWait

All class methods wait for the condition to be met, but return values and handle exceptions differently:

  1. public void WaitForTrue - throws an exception if the condition is not met, returns nothing. Note that the method doesn't use WebDriver's wait.
  2. bool WaitFor - returns true if the condition is fulfilled or false otherwise. Method does not throw any exception.
  3. public T WaitFor<T> - uses the WebDriver's wait, returns a T object or an exception if the condition is not met.