Selenium is a tool often used for automating web applications for testing purposes. When working with Selenium in Python, effectively managing waits and timeouts can be crucial in ensuring your tests do not become flaky due to timing issues. Two main types of waits are available in Selenium: implicit waits and explicit waits.
Implicit Waits
Implicit waits tell the WebDriver to poll the DOM for a certain number of seconds when trying to find any element. This type of wait is generally helpful when you're sure of the locators but need to occasionally wait for elements to become available.
Example of Implicit Wait
from selenium import webdriver
from selenium.webdriver.common.by import By
# Create a new instance of the Firefox driver
browser = webdriver.Firefox()
# Implicitly wait for up to 10 seconds
browser.implicitly_wait(10)
# Open a webpage
browser.get('http://example.com')
# Try to locate an element
element = browser.find_element(By.ID, 'myElement')In this example, the WebDriver waits up to 10 seconds for the element with the id 'myElement' to appear before throwing a NoSuchElementException.
Explicit Waits
Explicit waits are used to halt the execution until a specific condition is met. They are more flexible and widely recommended compared to implicit waits because they are based on individual elements that need to be observed.
Implementing Explicit Waits in Selenium
To use explicit waits, you need to leverage the WebDriverWait and expected_conditions modules.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Create a new instance of the Chrome driver
browser = webdriver.Chrome()
# Use WebDriverWait to wait up to 10 seconds
try:
# Navigate to the webpage
browser.get('http://example.com')
# Wait until the element is present
element = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.ID, 'myElement'))
)
finally:
browser.quit()In the code above, WebDriverWait is employed to wait until the element with the id 'myElement' becomes present in the DOM.
Fluently Waits
Fluent waits are another level of explicit waits with added control over the polling frequency and exception ignoring mechanisms. They are helpful when you want more control over how Selenium polls a specific condition to become true.
Example of Fluent Wait
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Create a new instance of the Safari driver
browser = webdriver.Safari()
# Using a WebDriverWait for a fluent wait
wait = WebDriverWait(browser, 12, poll_frequency=2, ignored_exceptions=[Exception])
try:
# Open desired webpage
browser.get('http://example.com')
# Perform fluent wait
element = wait.until(
EC.visibility_of_element_located((By.NAME, 'myElement'))
)
finally:
browser.quit()In this implementation, the WebDriver waits up to 12 seconds, polling every 2 seconds for the visibility of the element referenced by name 'myElement'.
Customization with Timeouts
Custom timeouts can be set by configuring specific waits for the element separately, based on your tests' unique requirements. This allows better fine-tuning of how and when you handle web elements. For example, while some elements might need a longer wait time to appear, others could do perfectly well with a shorter wait.
Combining different waits and timeouts wisely lets you write more reliable Selenium tests. Understanding the differences between implicit, explicit, and fluent waits, along with strategic timeout settings, is essential for every Selenium tester in Python.