How to wait for elements in Python Selenium WebDriver

The Blog To Learn Selenium and Test Automation

How to wait for elements in Python Selenium WebDriver

We all know and experimented that Selenium WebDriver can interact with web browser and simulate user actions. User actions could be click, select, type etc.. or combinations of these actions. However most of the user action requires some kind of wait before performing it.

Reasons could be many, including but not limited to below.

  1. Page is not loaded yet
  2. Element to interact with is not available in DOM yet
  3. AJAX is still loading and element will be created after AJAX
  4. Delay in page response etc…

In modern applications, elements within the page may load at different time intervals even after page is loaded. This makes locating elements difficult; if the element Selenium looking for is not present in the DOM, it will raise NoSuchElementException exception. There should be some kind of delay to wait for these elements. At the same time, this delay should not make test script execution longer.

Using waits, we can wait for an element to be available in DOM. Wait provides some time interval between actions performed like locating element or any other operation with the element.

Implicit Wait:

An implicit wait instructs Selenium WebDriver to poll DOM for a certain amount of time, this time can be specified, when trying to find an element or elements that are not available immediately. The default setting is 0 seconds which means WebDriver will not wait before any operations on element.

Once set, the implicit wait is set for the life of the WebDriver object i.e. all actions will be delayed by given time.

Syntax:
driver.implicitly_wait(10)

Pass number of seconds to wait as an argument

from selenium import webdriver

driver = webdriver.Firefox()
driver.implicitly_wait(15)
driver.get("http://url")
driver.find_element_by_id("id_of_element").click()

Explicit Wait:

Explicit wait is used to specify wait condition for a particular element. Here we define to wait for a certain condition to occur before proceeding further in the code.

There can be instance when a particular element takes more than usual time to load. In that case no need to set a huge time to Implicit wait, as this will make browser to wait for the same time for every element. To avoid that situation explicit wait is used by defining a separate wait time only on the required element.

There are some predefined methods provided that will help your script to wait only as long as required. WebDriverWait in combination with ExpectedCondition is one way this can be accomplished.

Following two packages are required to set explicit wait

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

driver = webdriver.Chrome()

driver.get("http://url")
driver.maximize_window()

# wait for element to appear, then hover it
wait = WebDriverWait(driver, 10)
men_menu = wait.until(ec.visibility_of_element_located((By.XPATH, "//a[@data-tracking-id='men']")))
ActionChains(driver).move_to_element(men_menu).perform()

# wait for Fastrack menu item to appear, then click it
fastrack = WebDriverWait(driver, 10).until(ec.visibility_of_element_located((By.XPATH, "//a[@data-tracking-id='0_Fastrack']")))
fastrack.click()

This waits up to 10 seconds before throwing a TimeoutException unless it finds the element to return within 10 seconds. WebDriverWait by default calls the ExpectedCondition every 500 milliseconds, which is called poll frequency, until it returns successfully. A successful return is for ExpectedCondition type is Boolean return true or not null return value for all other ExpectedCondition types.

We have the option to change the poll frequency by passing keyword argument ‘poll_frequency’ which accepts values in seconds. Default value is 0.5 second. For instance, lets change poll frequency to 1 second.

wait = WebDriverWait(driver, 10, poll_frequency=1)

The expected_conditions module contains a set of predefined conditions to use with WebDriverWait.

  • title_is
  • title_contains
  • presence_of_element_located
  • visibility_of_element_located
  • visibility_of
  • presence_of_all_elements_located
  • text_to_be_present_in_element
  • text_to_be_present_in_element_value
  • frame_to_be_available_and_switch_to_it
  • invisibility_of_element_located
  • element_to_be_clickable
  • staleness_of
  • element_to_be_selected
  • element_located_to_be_selected
  • element_selection_state_to_be
  • element_located_selection_state_to_be
  • alert_is_present

For more details about these in-built methods, visit our How to work with expected_conditions explicit waitpart-1 and part -2 articles. Please let us know your thoughts in comment section.

 

5 Responses

  1. prog_belka says:

    Here is the solution on C#. Hope someone will need it.
    IWebDriver driver = new ChromeDriver();
    driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); //driver will try to execute dom commands for 10 seconds in case of failure

  2. yoobooy says:

    thanks man

  3. […] our previous articles, we have seen basics of Implicit and Explicit wait; Also we have seen some of the in-built expected conditions provided by Python Selenium to make […]

  4. ron says:

    I’m not understanding what my issue is here. In testing, I can not get the wait to return when the expected_condition returns the element?

    This returns the element:
    ec.presence_of_element_located((By.XPATH, ‘//div[@onclick=”backToResults();’)))

    This returns the elememt:
    browser.find_element_by_xpath(‘//div[@onclick=”backToResults();”]’)

    But this when using the wait just times out:
    elem = WebDriverWait(browser, 3).until(ec.presence_of_element_located((By.XPATH, ‘//div[@onclick=”backToResults();’)))
    WebDriverWait(browser, 3).until(ec.element_to_be_clickable((By.XPATH, ‘//div[@onclick=”backToResults();’)))
    Traceback (most recent call last):
    File “”, line 1, in
    File “/usr/lib/python2.7/site-packages/selenium/webdriver/support/wait.py”, line 80, in until
    raise TimeoutException(message, screen, stacktrace)
    selenium.common.exceptions.TimeoutException: Message:

    Any ideas?

Leave a Reply

Your email address will not be published. Required fields are marked *