Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Selenium: waiting for one element OR another element to load

I'm using this code for waiting for an element to load:

browser = webdriver.Chrome(executable_path=chromedriver,options=ChromeOpts, desired_capabilities=captain) 
wait = WebDriverWait(browser, 5)
openbrowser = browser.get(url) 
wait.until(EC.presence_of_element_located((By.ID, 'h1')))
browser.execute_script("window.stop();")

However, what I really need is to wait for one element OR another. So I can, for example, wait for 'h1' OR 'rf-footer'.

thanks,

like image 522
rafasalo Avatar asked Apr 28 '26 18:04

rafasalo


1 Answers

You can combine the two checks in a single wait() operation - by using a python's lambda expression, using the find_elements_*() methods glued together with an or:

element = wait.until(lambda x: x.find_elements_by_id("id1") or x.find_elements_by_css_selector("#id2"))[0]

You can use this approach even to get the element that is matched first - the [0] at the end.
This solution works, as find_elements_*() returns a list of all matched elements, or an empty one if there aren't such (a boolean false). So if the first call doesn't find anything, the second is evaluated; that repeats until either of them finds a match, or the time runs out.

This approach gives the benefit the wait.until() will stop immediately after one of the two passes - e.g. speed.


Versus a try-catch block - in it, the first condition has to fail (waited for up to X seconds, usually 10), for the second one even to be checked; so if the first is false, while the second true - the runtime/wait is going to be at least X seconds plus whatever time the second check takes.
In the worst case, when both are false, you are in for 2X wait, versus X in combining the two. If you add other conditions, you are only increasing the factor.

like image 117
Todor Minakov Avatar answered Apr 30 '26 07:04

Todor Minakov