Categories
Automated testing Python Selenium WebDriver

Waits – simple way to find all the desired elements

Each test run takes place under different conditions. The connection speed is always different. The site may or may not be under load. Even the computer that run tests may, for some reason, run slower than usual. Any of these circumstances can cause tests to fail due to lack of the elements immediately after opening the page.

The simplest solution in this situation is to use sleep so that the elements of the page have time to finish loading. But this solution has a very big drawback. Let’s say you’re testing a site with twenty pages. There are about 20 items on each page that you might need to wait for. If you make a two second sleep for each of these elements, then let’s calculate how long each run will take. 20 pages * 20 elements * 2 seconds and divide this by 60 to see the result in minutes. It turns out that more than 13 minutes will be spent just waiting. What if everything works fast today and you don’t need any sleep. In fact, you’ll just waste those 13 minutes.

Selenium has special tools that allow your tests to wait only when it is needed and only where it is needed.

Implicit wait

First, let’s look at the most versatile type of wait, which is called implicit wait. Based on the specifics of its use, we can say that this is a “smart” type of wait, which itself decides when it should work. More precisely, it fires every time we look for an element on the page, but stops waiting as soon as the element appears.

In order to take advantage of implicit wait, you just need to enable it for the entire test suite. For example, immediately after creating a driver instance.

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10)

The syntax is very simple. In parentheses, you must specify in seconds how long you need to wait until the element appears.

Now, every time Selenium searches for an element, it will make attempts to find it for 10 seconds. If during this time the element is not found, then only then Selenium WebDriver will return NoSuchElementException.

Explicit wait

However, the presence or absence of an element on the page is not the only thing that can make us wait. For example, you may need to wait for an element to become clickable. Also, you may want to wait until the expected text appears in the right place.

The main difference from implicit wait is that the element is already present on the page. And you want to wait for it to get into the desired state.

So let’s see how can we use this type of wait. First, you need to call the WebDriverWait class and initialize it by passing it the driver instance and the number of seconds to wait. Then you need to specify the condition or state to wait for. This can be done using the “until” method of the WebDriverWait class. To do this, you need to pass the expected condition to the method.

This is how it will look in code:

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable(driver.find_element(By.CLASS_NAME, 'bt_compare'))
    )

Expected conditions

There is a large collection of waiting conditions. You can view all of them without leaving the IDE. Type “EC” and put a dot. Finally, scroll through the list to see all available conditions.

expected conditions list

Also, you can learn more about each possible condition in the official selenium documentation on this page.

To sum up, Selenium provides powerful tools for stabilizing tests. Whether it’s implicitly waiting for an element to appear on the page, or explicitly waiting for an element’s state to change. For each situation, you can choose what is best suited for solving the problem.

In order to learn how to search for elements on the page, read my post Locate web elements on the sites easily. You may also find other articles about test automation with selenium helpful.

By Eugene Okulik