How to Get Fewer False Positives Using Wrappers for Selenium Calls

Many times we believe that we are completing some actions on a webpage, when in reality nothing has happened on the page and we simply didn’t notice it. We believe that we’ve clicked a button, but in reality the button is not clickable. We believe that some text has been entered into an input field, when that field doesn’t actually allow all of the characters that we have sent to it.

To ensure that these events don’t happen, we can easily create wrappers around the Selenium cells, which will create a better interaction with the DOM.

One of the best features in Selenium is Expected Conditions, which, when used with WebDriverWait, can create explicit waits that wait for different states of an element.

Below is an outline of how to create some wrappers over our most used Selenium calls using Expected Conditions. For future calls, we will be using the following imports and variables. These examples are given in Python, but similar calls are available in other programming languages as well.

from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

IMPLICIT_WAIT = 10
selector = (By.ID, 'element_id')
text = 'some text'

Below is a simple example of how WebDriverWait and Expected Conditions work:

wait = WebDriverWait(driver, IMPLICIT_WAIT)
element = wait.until(
    EC.visibility_of_element_located(
selector
)

WebDriverWait continually calls Expected Conditions every 500 milliseconds to check that the value is “true” until the condition is met or the time allotted has passed. If the condition is met in the IMPLICIT_WAIT time that has been given, then the found element is return. If not, the TimeoutException is raised.

Now it’s time to use this information in our tests.

The first example is our own click wrapper, which waits for the element to be clickable before clicking on it.

def click(selector):
    element = WebDriverWait(driver, IMPLICIT_WAIT).until(
        EC.element_to_be_clickable(
            selector
        )
    )
    element.click()

The EC.element_to_be_clickable() method returns the element if the element is clickable. If the element is unable to be located, or the element is not enabled in the given IMPLICIT_WAIT, then a TimeoutException will be raised. This way, we’re sure that the button or link we’re trying to click is actually there and clickable, instead of an empty space on the page.

Another commonly used example is the send_keys method. When using Selenium, a good method is finding the element, clicking on it, and then sending the text to it. Though this is good, we can improve upon it by going a bit further.

def enter_text(selector, text):
    element = WebDriverWait(driver, IMPLICIT_WAIT).until(
        EC.visibility_of_element_located(selector)
    )
    element.click()
    element.clear()
    element.send_keys(text)
    WebDriverWait(driver, IMPLICIT_WAIT).until(
        EC.text_to_be_present_in_element(selector, text)
    )

By doing this, we are initially ensuring that the element we’re interacting with is available. After this, we follow the usual steps of clicking the element, clearing the text from it so we know exactly what text we’re entering into that input field, entering the actual text we need, and finally checking that the entered text is present in our input field.

However, if we do not want to go through these steps all of the time, we can easily add flags to our method and remove some steps from the process.

def enter_text(selector, text, clear=True, verify=False):
    element = WebDriverWait(driver, IMPLICIT_WAIT).until(
        EC.visibility_of_element_located(selector)
    )
    element.click()
    if clear:
        element.clear()
    element.send_keys(text)
    if verify:
        WebDriverWait(driver, IMPLICIT_WAIT).until(
            EC.text_to_be_present_in_element(selector, text)
        )

Below is the final example used for handling alerts.

def accept_alert(accept=True):
    alert = WebDriverWait(
        driver, IMPLICIT_WAIT).until(
        EC.alert_is_present()
    )
    if accept:
        alert.accept()
    else:
        alert.dismiss()

Once we input this, we then wait for the alert to be present and then either accept or dismiss it. Just like before, if the webdriver doesn’t find the alert in the IMPLICIT_WAIT time that has been given, then a TimeoutException will be raised.

These wrappers are good practice when using Selenium and can be used for almost all interactions with the DOM. With them, you can reduce the number of false positives generated and create far better waits than when using time-based wrappers.

Additional information on this can be found here.

Cosmin Traistaru

Cosmin Traistaru

Quality Assurance Engineer

Cosmin Traistaru has been working as a Quality Assurance Engineer at the 3Pillar Global Timisoara location for over a year. He has experience with automated testing of web applications using Selenium and Python, as well as with designing test automation frameworks from scratch.

Leave a Reply

Related Posts

3Pillar CEO David DeWolf Quoted in Enterprise Mobility Excha... David DeWolf, Founder and CEO of 3Pillar Global, was recently quoted in a report by Enterprise Mobility Exchange on the necessity of understanding and...
High Availability and Automatic Failover in Hadoop Hadoop in Brief Hadoop is one of the most popular sets of big data processing technologies/frameworks in use today. From Adobe and eBay to Facebook a...
How the Right Tech Stack Fuels Innovation – The Innova... On this episode of The Innovation Engine podcast, we take a look at how choosing the right tech stack can fuel innovation in your company. We'll talk ...
The Road to AWS re:Invent 2018 – Weekly Predictions, P... For the last two weeks, I’ve been making predictions of what might be announced at AWS’ upcoming re:Invent conference. In week 1, I made some guesses ...
Building a Microservice Architecture with Spring Boot and Do... This is the fourth blog post in a 4-part series on building a microservice architecture with Spring Boot and Docker. If you would like to read the pre...