Using selenium webdriver to wait for an element attribute to change the value

I have one element with a "aria-busy" attribute that changes from true to false when the data is searched and executed. How can I use selenium expect conditions and explicit waits to wait for the default time like 20 seconds if it reaches 20 seconds and the attribute does not change from true to false. throw exceptions. I have the following, but it doesn't actually work.

import selenium.webdriver.support.ui as ui
from selenium.webdriver.support import expected_conditions as EC

<div id="xxx" role="combobox" aria-busy="false" /div>
class Ele:
    def __init__(self, driver, locator)
        self.wait = ui.WebDriverWait(driver, timeout=20)

    def waitEle(self):
        try:
            e = self.driver.find_element_by_xpath('//div[@id='xxxx']')
            self.wait.until(EC.element_selection_state_to_be((e.get_attribute('aria-busy'), 'true')))
        expect:
            raise Exception('wait timeout')

      

+3


source to share


2 answers


The expected condition is simply callable, it can be defined as a simple function:

def not_busy(driver):
    try:
        element = driver.find_element_by_id("xxx")
    except NoSuchElementException:
        return False
    return element.get_attribute("aria-busy") == "false"

self.wait.until(not_busy)

      

Slightly more general and modular, however, was to follow the style of inline expect conditions and create the class using the magic overriden method__call__()

:



from selenium.webdriver.support import expected_conditions as EC

class wait_for_the_attribute_value(object):
    def __init__(self, locator, attribute, value):
        self.locator = locator
        self.attribute = attribute
        self.value = value

    def __call__(self, driver):
        try:
            element_attribute = EC._find_element(driver, self.locator).get_attribute(self.attribute)
            return element_attribute == self.value
        except StaleElementReferenceException:
            return False

      

Using:

self.wait.until(wait_for_the_attribute_value((By.ID, "xxx"), "aria-busy", "false"))

      

+2


source


Another approach would involve checking the value of the attribute with a custom locator, where you would not only check the value of the attribute id

, but also aria-busy

:



self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#xxx[aria-busy=false]")))

      

+1


source







All Articles