Selenium wait until one of the two elements is present

Viewed 12259

A lot of times I want the webdriver to wait for presence of one of the two elements. Normally this happens when I am expecting the page to be showing either element1 in some cases or element 2. Currently I am doing this sequentially using two waits, but it's inefficient since I need to wait 2 times. Is there any way to combine the two waits into one? In other words I want to wait until element1 or element2 is present.

try: 
  element = WebDriverWait(self.browser, 15).until(EC.presence_of_element_located((By.ID, "elem1")))
  element.click()
  return "elem1"
except: 
  print "failed to find elem1"

try: 
  element = WebDriverWait(self.browser, 5).until(EC.presence_of_element_located((By.ID, "elem2")))  
  return "elem2"    
except:
  print "sth wrong!"
  raise  Exception("Sth Wrong!") 

return "Should not get here"      
4 Answers

This is an alternative solution while I was having problems with other solutions.

For example, if we only have 2 conditions, and 1st is never satisfied while the 2nd is already satisfied. Then the other solutions block until the end of wait_delay before return the result; while the following solution skip it:

WebDriverWait(driver, wait_delay).until(
  wait_for_any([
    EC.presence_of_element_located(locator)
    for locator in locators
]))

where

class wait_for_any:
    def __init__(self, methods):
        self.methods = methods

    def __call__(self, driver):
        for method in self.methods:
            try:
                if method(driver):
                    return True
            except Exception:
                pass
            
        return False
Related