webdriver wait for one of a multiple elements to appear

python, selenium, selenium-webdriver, wait, webdriver

Solution

Create a function that takes a map of identifiers to xpath queries and returns the identifier that was matched.

def wait_for_one(self, elements):
    self.waitForElement("|".join(elements.values())
    for (key, value) in elements.iteritems():
        try:
            self.driver.find_element_by_xpath(value)
        except NoSuchElementException:
            pass
        else:
            return key

def othermethod(self):

    found = self.wait_for_one({
        "mime": "//a[contains(text(), '%s')]",
        "exists_error": "//li[contains(text(), 'That file already exists')]"
    })

    if found == 'mime':
        do stuff ...
    elif found == 'exists_error':
        do other stuff ...

Problem

Is there a way to get a `webDriverWait` to wait for one of a number of elements to appear and to act accordingly based on which element appears? At the moment I do a `WebDriverWait` within a try loop and if a timeout exception occurs I run the alternative code which waits for the other element to appear. This seems clumsy. Is there a better way? Here is my (clumsy) code: ``` try: self.waitForElement("//a[contains(text(), '%s')]" % mime) do stuff .... except TimeoutException: self.waitForElement("//li[contains(text(), 'That file already exists')]") do other stuff ... ``` It involves waiting an entire 10 seconds before it looks to see if the message that the file already exists on the system. The function `waitForElement` just does a number of `WebDriverWait` calls like so: ``` def waitForElement(self, xPathLocator, untilElementAppears=True): self.log.debug("Waiting for element located by:\n%s\nwhen untilElementAppears is set to %s" % (xPathLocator,untilElementAppears)) if untilElementAppears: if xPathLocator.startswith("//title"): WebDriverWait(self.driver, 10).until(lambda driver : self.driver.find_element_by_xpath(xPathLocator)) else: WebDriverWait(self.driver, 10).until(lambda driver : self.driver.find_element_by_xpath(xPathLocator).is_displayed()) else: WebDriverWait(self.driver, 10).until(lambda driver : len(self.driver.find_elements_by_xpath(xPathLocator))==0) ``` Anybody got any suggestions to accomplish this in a more efficient way?

Original source