Combining Implicit Wait and Explicit Wait Together Results in Unexpected Wait Times

Combining implicit wait and explicit wait together results in unexpected wait times

Don't mix implicit and explicit waits. Part of the problem is that implicit waits are often (but may not always be!) implemented on the "remote" side of the WebDriver system. That means they're "baked in" to IEDriverServer.exe, chromedriver.exe, the WebDriver Firefox extension that gets installed into the anonymous Firefox profile, and the Java remote WebDriver server (selenium-server-standalone.jar). Explicit waits are implemented exclusively in the "local" language bindings. Things get much more complicated when using RemoteWebDriver, because you could be using both the local and remote sides of the system multiple times.

This is how that would work: local code -> Java remote server -> local Java language bindings on the remote server -> "remote" component like the Firefox extension, chromedriver.exe or IEDriverServer.exe. It's even more complex in the grid case, since there could be other hops in between.

Thus, when you try to mix implicit and explicit waits, you've strayed into "undefined behavior". You might be able to figure out what the rules of that behavior are, but they'll be subject to change as the implementation details of the drivers change. So don't do it.

You shouldn't be experiencing "hangs" when an element can't be found if you're not using implicit waits. The driver should throw a NoSuchElement exception immediately.

What if Implicit and Explicit wait, both are used in Framework

First understand the concepts of Explicit and Implicit wait

Implicit Wait: 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.
For Example:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));

Explicit Wait:

  1. An explicit waits is code you define to wait for a certain condition to occur before proceeding further in the code.
  2. There are some cases where the explicit wait is functionally equivalent to implicit wait, means
    a) Where waiting time is not predefined like below (please note they were distinct by method category they belong explicit or implicit)

    WebDriverWait wait = new WebDriverWait(driver, 10);

    WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

    b) Cases where the webdriver has a time to wait 10 seconds but at the 5 second the element was found then the webdriver will proceed.

Answer of your Question:
1) Suppose you have defined 10 seconds then driver waits for 10 maximum but at minimum it can wait for 0.001 seconds means in cases of implicit wait we have to give maximum limit for wait while minimum limit depends on the finding the element or getting the condition done.

2) While in explicit wait except some case webdriver has to wait for maximum limit.


So, as a answer your webdriver first will follow the implicit wait and then follow the explicit wait since browser behavior will be sequential like other programing languages due single thread usage.


Reference :

Selenium Explicit and Implicit wait

Mixing implicit and explicit waits

Since I know there are times I'll definitely need WebDriverWait, does this mean I need to get rid of implicit_wait in my unittest setUp method and instead employ WebDriverWait every single time I use any find_element_by_ method?

Yes. As you've seen in the question you link to, if you use both types of waits, you're going to run into undesirable behavior. It's not just theoretical. I've experienced that behavior first hand, tried to debug it, found the question you linked to and then removed all implicit waits from my test suites.

I developed a library to help with setting up the explicit waits (and do a bunch of other things). Assuming you already have a driver object that has the selenium web driver:

from selenium.webdriver.common.by import By
import selenic.util

util = selenic.util.Util(driver)

# This goes through util and uses the explicit wait set by util.
foo = util.find_element((By.CSS_SELECTOR, "..."))

# For special cases that take longer to give results.
with util.local_timeout(10):
# The timeout is set to 10 for calls in this with block.
bar = util.find_element(...)
# The timeout is restored to what it was just before the with.

There are some times when you don't need to use waits at all because logically if element A is present then B is also present, so you don't have to wait for it. For instance. if you want the parent of an element you've already obtained from Selenium, you can do parent = foo.find_element_by_xpath("..").

As for the behavior of find_elements, it returns as soon as it determines that there is a result to return. This could mean getting only one element if later elements do show up after find_elements has found something to return.

Probable impact of implicit wait removal

You saw it right. @JimEvans in this discussion clearly states that:

Part of the problem is that implicit waits are often (but may not always be!) implemented on the "remote" side of the WebDriver system. That means they're "baked in" to IEDriverServer.exe, chromedriver.exe, the WebDriver Firefox extension that gets installed into the anonymous Firefox profile, and the Java remote WebDriver server (selenium-server-standalone.jar). Explicit waits are implemented exclusively in the "local" language bindings. Things get much more complicated when using RemoteWebDriver, because you could be using both the local and remote sides of the system multiple times.

So, while interacting with an element Explicit Wait is the mandate.


Now, as per the constructors of WebDriverWait:

  • public WebDriverWait(WebDriver driver, long timeOutInSeconds): Wait will ignore instances of NotFoundException that are encountered (thrown) by default in the 'until' condition, and immediately propagate all others. You can add more to the ignore list by calling ignoring(exceptions to add).
  • WebDriverWait(WebDriver driver, long timeOutInSeconds, long sleepInMillis): Wait will ignore instances of NotFoundException that are encountered (thrown) by default in the 'until' condition, and immediately propagate all others. You can add more to the ignore list by calling ignoring(exceptions to add).

So, WebDriverWait() by default ignores NotFoundException and the direct known subclasses are:

  • NoAlertPresentException
  • NoSuchContextException
  • NoSuchCookieException
  • NoSuchElementException
  • NoSuchFrameException
  • NoSuchWindowException

From the source code of WebDriverWait.java:

/**
* Wait will ignore instances of NotFoundException that are encountered (thrown) by default in
* the 'until' condition, and immediately propagate all others. You can add more to the ignore
* list by calling ignoring(exceptions to add).
*
* @param driver The WebDriver instance to pass to the expected conditions
* @param timeOutInSeconds The timeout in seconds when an expectation is called
* @param sleepInMillis The duration in milliseconds to sleep between polls.
* @see WebDriverWait#ignoring(java.lang.Class)
*/

So, while using WebDriverWait you won't face NoSuchElementException. Incase the desired element is not returned till the WebDriverWait expires you will face timeoutException.



Related Topics



Leave a reply



Submit