1

Say I have a code like this:

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

I have trouble understand this line in Selenium doc: An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available.

So does it mean the driver will wait 10 seconds before first try to find the element? Or does it mean the driver will find the element first, if nothing found, wait 10 seconds, then find again, if not found throw an timeoutexception? The driver tries to find the element twice in total?

nieschumi
  • 551
  • 1
  • 5
  • 21
  • Have a look at [QA](http://sqa.stackexchange.com/questions/2606/what-is-seleniums-default-timeout-for-page-loading). [Ardesco](http://sqa.stackexchange.com/users/540/ardesco)'s answer; Implicit timeout Specifies the amount of time the driver should wait when searching for an element if it is not immediately present. – lloyd Jul 22 '15 at 00:21

2 Answers2

1

You can actually clear things up by logging the JSON Wire protocol commands into the Chrome service logs. Let's say we have this Python code (for the sake of an example):

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

Here we get a NoSuchElementException instantly and in /tmp/log we have:

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

Now, let's set the Implicit Wait to 10 seconds:

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

Now, if we would look into logs:

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

As, you can see there was only one FindElement command sent to the WebDriver, but the response got back and the NoSuchElementException was thrown only after a 10 seconds delay.


What happens internally is described in the docs here: for the 10 seconds it polls the DOM trying to find the desired element ignoring NoSuchElementException. When time is up and no element found yet it would throw NoSuchElementException:

An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • So implicit wait is just a better way to write Thread.sleep() right? – nieschumi Jul 22 '15 at 16:12
  • Thank you for the detailed answer, monitor Json protocol logs looks really helpful in get to know what's going on behind the scene! – nieschumi Jul 22 '15 at 16:21
  • @nieschumi glad to help! Thanks! – alecxe Jul 22 '15 at 16:21
  • Anand Somani's answer in this thread http://stackoverflow.com/questions/13975556/selenium-implicit-wait-vs-thread-sleep saying that the script will continue executing if an element is found within timeout, but in logs you posted above we didn't see any other findElement command after the very first try, then how does the browser know if an element appears? – nieschumi Jul 22 '15 at 16:56
  • @nieschumi logs here help us to understand that the `FindElement` command's response was received in 10 seconds. What happened during these 10 seconds, we would not see in logs. My understanding is that the webdriver waited 10 seconds and then tried to find an element. Though, I haven't found a documentation describing the work of implicit wait. – alecxe Jul 22 '15 at 18:46
0

If the element driver.findElement(By.id("nothing")); is available in your webpage it will find the webelement and continues to the next code. If that webelement is not present in the webpage then driver will wait for 10seconds as you given as implicit wait for 10 seconds. atlast the test will fail, because of element is not found. so only one time driver tries to find the webelement.

snigdha
  • 26
  • 4