Search code examples
pythonseleniumtuplesappiumwebdriverwait

Why tuples unpacking is not working with Selenium WebDriverWait?


How is it possible to unpack tuples with Selenium WebDriverWait?

Why this code is not working?

class Test:

    def __init__(self, driver):
        self.driver = driver
        
    editprofile_button = (By.XPATH, "//android.widget.TextView[@text=\"Edit profile info\"]")
    
    def profile_page_should_be_visible(self):
        wait = WebDriverWait(self.driver,20)
        wait.until(EC.presence_of_element_located(*Test.editprofile_button))
        assert self.driver.find_element(*Test.editprofile_button).is_displayed()

But if I write the function like this, then everything is working with WebdriverWait:

def profile_page_should_be_visible(self):
    wait = WebDriverWait(self.driver,20)
    wait.until(EC.presence_of_element_located((By.XPATH, "//android.widget.TextView[@text=\"Edit profile info\"]")))
    assert self.driver.find_element(*Test.editprofile_button).is_displayed()

Solution

  • presence_of_element_located, as most of the other expected conditions, is locating the WebElement on __call__

    class presence_of_element_located(object):
        def __init__(self, locator):
            self.locator = locator
    
        def __call__(self, driver):
            return _find_element(driver, self.locator)
    

    where self.locator is the tuple.

    def _find_element(driver, by):
        try:
            return driver.find_element(*by)
        except NoSuchElementException as e:
            raise e
    

    _find_element is using driver.find_element(*by) where by is the tuple. As you can see, the tuple is already being unpacked internally.

    You can use Test.editprofile_button without unpacking it

    wait.until(EC.presence_of_element_located(Test.editprofile_button))