使用页面对象模型在Python Selenium中显式等待

时间:2018-02-08 14:59:00

标签: python selenium object wait explicit

我的明确等待不会等到元素存在。它确实等待我声明的秒数,然后测试仍然失败。如果我在测试通过的完全相同的位置放置一个隐式等待。从我阅读的内容来看,尽可能避免隐式等待是最好的做法。难道我做错了什么?

我在base_page中创建了一个方法,如下所示:

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

然后我在页面对象中调用_wait_for_is_displayed方法,但是失败了:

 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()

我得到的错误是:

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

通过:

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

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

最后在我的测试套件中,我调用了relatie_page_present和relatie_page_方法。

3 个答案:

答案 0 :(得分:0)

隐式等待是设置查找元素API的超时,例如find_element_by_xxxfind_elements_by_xxx。它的默认值是10秒。

这是一个全球性的环境。一旦你改变了隐式等待,调用find元素API的所有代码都会占用相同的超时值。

如果您觉得网站的大多数页面/响应都很慢,您可以使用增加的超时值来更改它,直到遇到下一次隐式等待。

但它不等于说the implicit wait time out value is more large more better.

假设您的网站UI发生巨大变化或许多页面无法打开/加载,如果隐式等待超时值大,则会增加整个运行的持续时间。因为每次find元素都要等待那么大的秒数然后抛出超时异常。

显式等待仅影响使用它的代码,这是全局影响。

我看到你设置显式等待超时为10秒,它不会超过隐式等待的默认值。

一般来说,明确等待应该比隐式等待更长,否则无需使用它,使用find element API可以归档相同的效果。

答案 1 :(得分:0)

在您尝试调用click()时向前移动,而不是将expected_conditions用作visibility_of_element_located(),您应该使用element_to_be_clickable(),如下所示:

try:
    wait = WebDriverWait(self.driver, timeout)
    wait.until(expected_conditions.element_to_be_clickable((locator["by"], locator["value"])))
  • 元素可点击 - 网页元素显示已启用

避免混淆隐式等待显式等待,因为documentation明确提到:

  

警告:不要混合隐式和显式等待。这样做会导致不可预测的等待时间。例如,设置10秒的隐式等待和15秒的显式等待可能会导致20秒后发生超时。

答案 2 :(得分:0)

为了阐明隐式等待是如何工作的,它在驱动程序上设置了一次,然后应用于驱动程序实例的生命周期。因此,调用self.driver.implicitly_wait(10)实际上并不等待 ... ...它只是将驱动程序设置为等待元素所在的那一点。我认为这让很多人感到困惑,因为我看到了很多。

无论如何,如果我是你,我会使用类似下面的函数来等待元素可点击然后点击它。您可以在需要等待单击元素时随时调用它。

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