Explicit wait in Python Selenium with page object model

旧时模样 提交于 2019-12-11 06:00:55

问题


My explicit wait isn't waiting until the element is present. It literally waits the amount of seconds I declared and then the tests still fails. If I place a implicit wait in the exact same place the test passes. From what I'm reading, it's best practise to avoid implicit waits as much as possible. Am I doing something wrong?

I have made a method in the base_page like so:

def _wait_for_is_displayed(self, locator, timeout):
        try:
            wait = WebDriverWait(self.driver, timeout)
            wait.until(expected_conditions.visibility_of_element_located((locator["by"], locator["value"])))
        except TimeoutException:
            return False
        return True

then i call the _wait_for_is_displayed method in a page object like so, but fails:

 def relatie_page_present(self):
     self._wait_for_is_displayed(self._open_actieve_polissen_tab, 10)

 def relatie_page_(self):
     self._click(self._open_relatie_details)
     self.relatie_page_present()

The error I get is:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"td.first > a"}

This passes:

 def relatie_page_present(self):
        self.driver.implicitly_wait(10)

def relatie_page_(self):
    self._click(self._open_relatie_details)
    self.relatie_page_present()

Lastly in my test suite i call the relatie_page_present and relatie_page_ methods.


回答1:


To clarify how implicit wait works, it is set one time on the driver and then is applied for the life of the driver instance. So calling self.driver.implicitly_wait(10) doesn't actually wait at that moment... it just sets the driver to wait from that point on when an element is located. I think this confuses a lot of people because I see it quite a bit.

Anyway, if I were you, I would use a function like the below that waits for the element to be clickable and then clicks it. You can call it any time you need to potentially wait for an element to be clicked.

def _wait_and_click(self, locator, timeout):
    try:
        wait = WebDriverWait(self.driver, timeout)
        wait.until(expected_conditions.element_to_be_clickable((locator["by"], locator["value"]))).click()
    except TimeoutException:
        return False
    return True



回答2:


Moving forward as you are trying to invoke click() so instead of using expected_conditions as visibility_of_element_located() you should have been using element_to_be_clickable() as follows :

try:
    wait = WebDriverWait(self.driver, timeout)
    wait.until(expected_conditions.element_to_be_clickable((locator["by"], locator["value"])))
  • Element is Clickable - WebElement is Displayed and Enabled.

Avoid mixing up implicit wait and explicit wait as the documentation clearly mentions :

WARNING: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10 seconds and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds.




回答3:


Implicit wait is to set the timeout for find element API, like find_element_by_xxx and find_elements_by_xxx. Its default value is 10 seconds.

It's a global setting. Once you change the implicit wait, all code place where call find element API will take the same time out value.

If you feel most page/response of your website slow, you can change it with increased time out value until meet next implicit wait.

But it's not equivalent to say the implicit wait time out value is more large more better.

Assume your website UI has huge changes or many page fail to open/load, if the implicit wait time out value large, it will increase the durtion time of whole running. Because every time of find element have to wait that large number seconds then throw timeout exception.

Explicit wait only impact the code which use it, it's global impact.

I see you set explicit wait time out is 10 seconds, it's no longer than the default value of Implicit wait.

In general, Explicit wait should longer than the Implicit wait, otherwise no need to use it, using find element API can archive same effect.



来源:https://stackoverflow.com/questions/48688453/explicit-wait-in-python-selenium-with-page-object-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!