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

Explicit wait in Python Selenium with page object model

我的明确等待不是等到元素出现。它实际上等待了我声明的秒数,然后测试仍然失败。如果我在完全相同的位置放置隐式等待,则测试通过。根据我正在阅读的内容,最好的做法是尽可能避免隐式等待。难道我做错了什么?

我在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_ 方法。

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

这是一个全局设置。更改隐式等待后,调用查找元素 API 的所有代码将采用相同的超时值。

如果您觉得网站的大部分 page/response 速度很慢,您可以通过增加超时值来更改它,直到遇到下一个隐式等待。

但这并不等同于the implicit wait time out value is more large more better.

假设您的网站UI发生了巨大的变化或许多页面无法访问open/load,如果隐式等待超时值很大,则会增加整个网站的持续时间运行。因为每次查找元素都必须等待大量秒然后抛出超时异常。

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

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

一般来说,显式等待应该比隐式等待长,否则不用,使用find element [=43] =] 可以存档一样的效果。

在您尝试调用 click() 时继续前进,因此您应该按如下方式使用 element_to_be_clickable(),而不是将 expected_conditions 用作 visibility_of_element_located()

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

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

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.

为了阐明隐式等待的工作原理,它在驱动程序上设置一次,然后在驱动程序实例的整个生命周期内应用。所以调用 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