Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python selenium : Explicitly wait for one of two elements to be loaded

Is there a way using which I can wait for one of two elements to get loaded in selenium. I am using explicit waits and so far, haven't been able to figure out the solution.

Simply doing

WebDriverWait(driver,5).until(lambda driver : driver.find_element(By.ID,"a") or driver.find_element(By.ID,"b"))

doesn't seem to work. It just looks for element with id ="a".

Thanks!

like image 682
sudshekhar Avatar asked Dec 22 '14 15:12

sudshekhar


People also ask

How do you make Selenium wait for an element to appear?

Selenium: Waiting Until the Element Is Visiblevar wait = new WebDriverWait(driver, TimeSpan. FromSeconds(20)); As you can see, we give the WebDriverWait object two parameters: the driver itself and a TimeSpan object that represents the timeout for trying to locate the element.

How do I make Selenium wait 10 seconds?

We can make Selenium wait for 10 seconds. This can be done by using the Thread. sleep method. Here, the wait time (10 seconds) is passed as a parameter to the method.

How do I make Selenium wait a few seconds?

How can I ask the Selenium-WebDriver to wait for few seconds in Java? To tell the Selenium WebDriver to wait for a specified amount of time use Thread. sleep. This will tell Java to pause execution of the test for the specified number of milliseconds.

Does Selenium wait for page to load python?

For Python, you will have to implement Selenium Wait for page to load in order to ensure that tests are performed with the necessary WebElements in the DOM. Certain websites have some components or elements hidden, or not visible at an initial stage.


2 Answers

find_element raises NoSuchElementException exception if no element is found.

If element with the id a does not exist, driver.find_element(By.ID,"a") will raises the exception and the driver.find_element(By.ID,"b") will not be executed.

A simple way to solve the problem is using find_elements which return empty list instead of raising the exception:

WebDriverWait(driver,5).until(
    lambda driver: driver.find_elements(By.ID,"a") or driver.find_elements(By.ID,"b"))
like image 112
falsetru Avatar answered Nov 05 '22 06:11

falsetru


As falsetru explained if your first find_element call fails to find an element, it will raise NoSuchElementException and the 2nd part of your test won't execute.

I would suggest using a CSS selector that matches either IDs you are looking for:

WebDriverWait(driver, 5).until(
    lambda driver : driver.find_element_by_css_selector("#a, #b"))

This has an advantage over performing two find_elements calls becayse this will make only one roundtrip between your Selenium client (your script) and the Selenium server. This should always be faster than performing two find_elements calls. When performing tests locally, the difference won't be much but if you perform tests remotely, for instance using Sauce Labs or Browser Stack, the difference will be significant.

like image 32
Louis Avatar answered Nov 05 '22 07:11

Louis