Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create custom wait until condition in Python

I tried to create a function with custom wait condition in Python. However, I get an error:

TypeError: 'bool' object is not callable

def waittest(driver, locator, attr, value):
    element = driver.find_element_by_xpath(locator)
    if element.get_attribute(attr) == value:
        return element
    else:
        return False
wait = WebDriverWait(driver, 10)
element = wait.until(waittest(driver, '//div[@id="text"]', "myCSSClass", "false"))    
like image 798
jacobcan118 Avatar asked Nov 21 '17 19:11

jacobcan118


People also ask

How do you add wait conditions in Python?

If you've got a Python program and you want to make it wait, you can use a simple function like this one: time. sleep(x) where x is the number of seconds that you want your program to wait.

What is implicit wait in Python?

An implicit wait tells WebDriver to poll the DOM for a certain amount of time when trying to find any element (or elements) not immediately available. The default setting is 0 (zero). Once set, the implicit wait is set for the life of the WebDriver object.

What is custom wait in Selenium?

The wait applies the condition which tries finding the web element, depending on its status. If the condition can find the element, it returns the element as result. If it cannot find the element, the wait tries the condition again after a short delay.


2 Answers

WebDriverWait(driver, 10).until() accepts a callable object which will accept an instance of a webdriver (driver is our example) as an argument. The simplest custom wait, which expects to see 2 elements, will look like

WebDriverWait(driver, 10).until(
    lambda wd: len(wd.find_elements(By.XPATH, 'an xpath')) == 2
)

The waittest function has to be rewritten as:

class waittest:
    def __init__(self, locator, attr, value):
        self._locator = locator
        self._attribute = attr
        self._attribute_value = value

    def __call__(self, driver):
        element = driver.find_element_by_xpath(self._locator)
        if element.get_attribute(self._attribute) == self._attribute_value:
            return element
        else:
            return False

And then it can be used as

element = WebDriverWait(driver, 10).until(
    waittest('//div[@id="text"]', "myCSSClass", "false")
)
like image 116
Dmytro Serdiuk Avatar answered Oct 23 '22 08:10

Dmytro Serdiuk


what I really end up to do is using lambda

self.wait.until(lambda x: waittest(driver, "//div[@id="text"]", "myCSSClass", "false"))
like image 41
jacobcan118 Avatar answered Oct 23 '22 10:10

jacobcan118