-
Notifications
You must be signed in to change notification settings - Fork 14
Overview (English)
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
- 2. CONFIGURATIONS
- 3. AQUALITY SERVICES
- 4. BROWSER
- 5. ELEMENTS
- 6. FORMS
- 7. JAVASCRIPT EXECUTION
- 8. CONDITIONAL WAIT
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.
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.
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.
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
.
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.
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.
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.
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:
The value of logging language is set in the logger.language parameter.
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:[email protected]/wd/hub.
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.
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.
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.
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.
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.
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.
AqualityServices
uses browser factory to create an instance of Browser
. There are two implementations of browser factory in the solution:
-
LocalBrowserFactory - for creating browser in case of
isRemote=false
parameter. -
RemoteBrowserFactory - for creating browser in case of
isRemote=true
parameter.
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
.
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.
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.
Browser
class provides methods to work with Alerts:
AqualityServices.Browser.HandleAlert(AlertAction.Accept);
You can find more examples in AlertTests.
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.
Browser
class provides methods to work with tabs:
AqualityServices.Browser.Tabs().SwitchToLastTab();
You can find more examples in BrowserTabsTests.
When Browser
is initialized and desired web page is opened you can start to work with its elements.
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.
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.
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.
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.
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.
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.
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:
-
public void WaitForTrue
- throws an exception if the condition is not met, returns nothing. Note that the method doesn't use WebDriver's wait. -
bool WaitFor
- returns true if the condition is fulfilled or false otherwise. Method does not throw any exception. -
public T WaitFor<T>
- uses the WebDriver's wait, returns a T object or an exception if the condition is not met.