【问题标题】:Selemium webdriver: How many times does a driver try to find element with an implicit wait timeout?Selenium webdriver:驱动程序尝试查找具有隐式等待超时的元素多少次?
【发布时间】:2015-10-11 14:28:27
【问题描述】:

假设我有这样的代码:

Webdriver driver = new ChromeDriver();
driver.manage().timeout().implicitWait(10, TimeUnit.SECONDS);
driver.findElement(By.id("nothing"));

我很难理解 Selenium 文档中的这一行:隐式等待是告诉 WebDriver 在尝试查找一个或多个元素(如果它们不是立即可用)时轮询 DOM 一段时间。

这是否意味着驱动程序会在第一次尝试查找元素之前等待 10 秒?或者这是否意味着驱动程序会先找到元素,如果没有找到,等待 10 秒,然后再次找到,如果没有找到则抛出超时异常?驱动程序总共尝试查找元素两次?

【问题讨论】:

  • 看看QAArdesco的回答;隐式超时指定驱动程序在搜索元素时应等待的时间(如果该元素没有立即出现)。

标签: java selenium selenium-webdriver webdriver


【解决方案1】:

您实际上可以通过将JSON Wire protocol commands 记录到Chrome 服务日志 来解决问题。假设我们有这个 Python 代码(为了举例):

from selenium import webdriver

driver = webdriver.Chrome(service_log_path="/tmp/log")
driver.get("http://www.google.com")

driver.find_element_by_css_selector("strange.non.existing.element")

driver.quit()

这里我们立即得到一个NoSuchElementException,在/tmp/log 中我们有:

[2.134][INFO]: COMMAND Navigate {
   "sessionId": "920fbde18d13995672cbbdd0a15e905a",
   "url": "http://www.google.com"
}
[2.195][INFO]: Waiting for pending navigations...
[2.239][INFO]: Done waiting for pending navigations
[2.593][INFO]: Waiting for pending navigations...
[3.704][INFO]: Done waiting for pending navigations
[3.704][INFO]: RESPONSE Navigate
[3.706][INFO]: COMMAND FindElement {
   "sessionId": "920fbde18d13995672cbbdd0a15e905a",
   "using": "css selector",
   "value": "strange.non.existing.element"
}
[3.706][INFO]: Waiting for pending navigations...
[3.706][INFO]: Done waiting for pending navigations
[3.720][INFO]: Waiting for pending navigations...
[3.720][INFO]: Done waiting for pending navigations
[3.720][INFO]: RESPONSE FindElement no such element
  (Session info: chrome=43.0.2357.134)

现在,让我们将隐式等待设置为 10 秒:

from selenium import webdriver

driver = webdriver.Chrome(service_log_path="/tmp/log")
driver.get("http://www.google.com")

# setting the implicit wait
driver.implicitly_wait(10)

driver.find_element_by_css_selector("strange.non.existing.element")

driver.quit()

现在,如果我们要查看日志:

[1.996][INFO]: COMMAND Navigate {
   "sessionId": "657700804d0d8f71b2bfee6dc222c289",
   "url": "http://www.google.com"
}
[2.073][INFO]: Waiting for pending navigations...
[2.106][INFO]: Done waiting for pending navigations
[2.477][INFO]: Waiting for pending navigations...
[3.371][INFO]: Done waiting for pending navigations
[3.371][INFO]: RESPONSE Navigate
[3.374][INFO]: COMMAND SetImplicitWait {
   "ms": 10000.0,
   "sessionId": "657700804d0d8f71b2bfee6dc222c289"
}
[3.374][INFO]: RESPONSE SetImplicitWait
[3.376][INFO]: COMMAND FindElement {
   "sessionId": "657700804d0d8f71b2bfee6dc222c289",
   "using": "css selector",
   "value": "strange.non.existing.element"
}
[3.376][INFO]: Waiting for pending navigations...
[3.376][INFO]: Done waiting for pending navigations
[13.410][INFO]: Waiting for pending navigations...
[13.410][INFO]: Done waiting for pending navigations
[13.410][INFO]: RESPONSE FindElement no such element
  (Session info: chrome=43.0.2357.134)

您可以看到只有一个FindElement 命令发送到WebDriver,但响应得到了回复,NoSuchElementException 在延迟 10 秒后才被抛出。


内部发生的是described in the docs here:在 10 秒内它轮询 DOM 试图找到所需的元素而忽略 NoSuchElementException。当时间到了但还没有找到元素时,它会抛出NoSuchElementException

隐式等待是告诉 WebDriver 轮询 DOM 尝试查找一个或多个元素(如果它们是)时的时间量 无法立即使用。默认设置为 0。一旦设置, 为 WebDriver 对象实例的生命周期设置了隐式等待。

【讨论】:

  • 所以隐式等待只是编写 Thread.sleep() 的更好方法吧?
  • 感谢您的详细回答,监控 Json 协议日志看起来非常有助于了解幕后发生的事情!
  • @nieschumi 很高兴为您提供帮助!谢谢!
  • Anand Somani 在这个线程中的回答 stackoverflow.com/questions/13975556/… 说如果在超时内找到一个元素,脚本将继续执行,但是在您上面发布的日志中,我们没有看到任何其他 findElement 命令之后先试试,那浏览器怎么知道有没有元素出现?
  • @nieschumi 日志在这里帮助我们了解FindElement 命令的响应是在 10 秒内收到的。在这 10 秒内发生了什么,我们不会在日志中看到。我的理解是 webdriver 等待了 10 秒,然后试图找到一个元素。不过,我还没有找到描述隐式等待工作的文档。
【解决方案2】:

如果元素 driver.findElement(By.id("nothing"));在您的网页中可用,它将找到 webelement 并继续下一个代码。如果网页中不存在该 web 元素,则驱动程序将等待 10 秒,因为您给出的隐式等待 10 秒。 atlast 测试将失败,因为未找到元素。所以只有一次驱动程序试图找到网络元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-28
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 2018-05-20
    • 1970-01-01
    相关资源
    最近更新 更多