Create Selenium Grid on Azure DevTest Labs VMs

Azure DevTest Labs is a way to easily spin up VMs being used as developer and test machines.

Here are a Microsoft ready made json template to spin up an Azure Selenium Grid (x number of Selenium node servers) allowing automated UI testing for web sites.

https://github.com/Azure/azure-devtestlab/tree/master/Samples/201-dtl-create-lab-with-seleniumgrid

How to solve Selenium error Element is not clickable at point (x, y) Other element would receive the click

The error message looks like this:

System.InvalidOperationException : unknown error: Element <... (html) ...> is not clickable at point (x, y). Other element would receive the click: <...(html)...>

Stack trace
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Remote.RemoteWebElement.Click()

Solution:
The clickable element is not ready, it might not be visible or clickable.
Sometimes the element is covered by another html element. (hide the covering element first).

Steps:
1. Wait for element to be visible
2. Wait for element to be clickable
3. Click with javascript

If this still this doesn’t work insert an implicit wait between step 1 and 2. (Thread.Sleep() in c#)

C# driver code to solve problems:
Wait for element to be visible and clickable (ElementToBeClickable = element is visible AND enabled.)

        public IWebElement WaitUntilElementIsClickable(By findElementsBy)
        {
            var wait = new WebDriverWait(driver, timeoutForElementShouldBeVisibleInSeconds);

            try
            {
                var element = wait.Until(ExpectedConditions.ElementToBeClickable(findElementsBy));
                return element;
            }
            catch (Exception exception)
            {
                string message = exception.Message + " at findElementsBy " + findElementsBy.ToString();
                Exception customException = new Exception(message, exception);
                throw customException;
            }
        }        public IWebElement WaitUntilElementIsClickable(By findElementsBy)
        {
            var wait = new WebDriverWait(driver, timeoutForElementShouldBeVisibleInSeconds);

            try
            {
                var element = wait.Until(ExpectedConditions.ElementToBeClickable(findElementsBy));
                return element;
            }
            catch (Exception exception)
            {
                string message = exception.Message + " at findElementsBy " + findElementsBy.ToString();
                Exception customException = new Exception(message, exception);
                throw customException;
            }
        }

Click with javascript:

        public void ClickOnElement(string cssElementSelector)
        {
            string js = $"document.querySelector(\"{cssElementSelector}\").click()";
            ExecuteJavascript(js);
        }
		
		        public string ExecuteJavascript(string script)
        {
            return ExecuteJavascript<string>(script);
        }

        /// <summary>
        /// Executes JavaScript in the context of the currently selected frame or window.
        /// </summary>
        /// <typeparam name="T">The converted return type</typeparam>
        /// <param name="script">The JavaScript code to execute.</param>
        /// <param name="args">The arguments to the script.</param>
        /// <returns></returns>
        public T ExecuteJavascript<T>(string script, object[] args = null)
        {
            IJavaScriptExecutor javaScriptExecutor = uiTests.Driver as IJavaScriptExecutor;
            object result = null;

            var wait = new WebDriverWait(uiTests.Driver, timeout: TimeSpan.FromMinutes(3));
            wait.Until(ExpectedConditions.ElementIsVisible(By.TagName("body")));

            result = javaScriptExecutor.ExecuteScript(script, args);
            T typedResult = (T) result;
            return typedResult;
        }

 

How To Automatically Retry Failed Tests in Nunit

If you have some randomly failing tests, such as Selenium driver based tests and are using Nunit as testing framework, here is one way to enable automatic re-run of the those failing tests. (Works with Nunit 3+ adding a custom method attribute)

Source: How To Automatically Retry Failed Tests in Nunit – Testing repository

Problem with remote Selenium IE driver “Unable to find element with css selector”

Running my Selenium tests locally against IE11 works fine, but when calling remote Selenium server running the same browser and Selenium drivers setup I get this:

System.Exception : Timed out after 10 seconds, could not find visible element 'By.CssSelector: body'
 ----> OpenQA.Selenium.WebDriverTimeoutException : Timed out after 10 seconds
 ----> OpenQA.Selenium.NoSuchElementException : Unable to find element with css selector == body

The problem is connected to the fact that the IEDriverServer.exe runs the server IE11 version. In my case this is a Windows Server 2016 which has a higher security restriction.

For me the solution was to disable the Internet Explorer Enhanced Security Configuration. Follow this guide for the Windows Server 2016 version.

Disable Internet Explorer Enhanced Security Configuration in Windows Server 2016

The same error could also be caused by javascript not enabled for the driver:

options.AddAdditionalCapability("javascriptEnabled", "true");

or need driver to switch to the correct frame/window

webDriver.switchTo().defaultContent()

More info here:
https://github.com/SeleniumHQ/selenium/issues/3611

Coypu supports browser automation in .Net to help make tests readable, robust, fast to write and less tightly coupled to the UI

Based on Selenium WebDriver:
https://github.com/featurist/coypu/blob/master/README.md

A robust wrapper for browser automation tools on .Net, such as Selenium WebDriver that eases automating ajax-heavy websites and reduces coupling to the HTML, CSS & JS