4

The docs say:

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.

Sub-question:

In the case of find_elements_by_ (plural), how many elements does implicit_wait wait for to exist before continuing with your script? Or does implicit_wait only work with find_element_by_ (singular)? If so what do the docs mean by "or elements"?

From an SO answer I read that it's best not to use both implicit and explicit waits in the same script, which I took notice of as I'd like the tests to be as robust as possible.

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?

(I'd rather not have to do this; although I suppose I could put each of the find_element_by_ methods in my own custom functions -each wrapped in their own WebDriverWait -it feels like I shouldn't have to).

So my main question is:

Can I instead keep my implicit_wait in my test setUp method, and then only use WebDriverWait when it comes to find_elements_by_ and other places where I know I need it?

Community
  • 1
  • 1
KnewB
  • 353
  • 4
  • 16
  • 1
    I wouldn't mix the two. I would use `WebDriverWait` each time. Selenium has no idea about when *you* need to wait for an element to be in a *specific* state before it's usable. That's why the option is there. Besides, an implicit is going to wait until the element is *found*. An element being *found* **is not** equal to an element being *usable*. – Arran Nov 28 '13 at 14:48
  • +1 I didn't know there was a distinction. I'm starting to wonder why `implicitly_wait` is in the API at all! How would you check for an element being usable? I see `expected_conditions.element_to_be_clickable` but not sure what else I'd use. – KnewB Dec 05 '13 at 17:49
  • possible duplicate of [selenium webdriver - explicit wait vs implicit wait](http://stackoverflow.com/questions/10404160/selenium-webdriver-explicit-wait-vs-implicit-wait) – Lesmana Jan 22 '15 at 08:42

1 Answers1

2

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.

Louis
  • 146,715
  • 28
  • 274
  • 320
  • re. your point about finding the parent of an element you've already obtained from Selenium, does that mean that all browsers always make the parent of an element DOM-ready and visible before the element itself? – KnewB Dec 03 '13 at 13:59
  • 1
    I was talking about mere existence. If element X exists in the DOM tree and it is not the root of the tree, X's parent must be present in the tree. I would expect this to be true also for visibility, but I'm not certain that it holds in all cases. However, if you start looking at things like clickability then you better use an explicit wait. Some of this also has to do with the logic of the software being tested. If the app creates a
      element by inserting it into the DOM tree in one operation, then when I have found the first
    • in it, I know the other
    • elements are also present.
    – Louis Dec 03 '13 at 14:11
  • Great thanks. Hope you don't mind another follow-up question. re. `find_elements` returning as soon as it determines that there is a result to return; If e.g. the page is still loading, or AJAX is loading some stuff, how do you go about getting `find_elements` to return the maximum/final number of matching elements? Do you always have to `WebDriverWait` `.until` `find_elements == known_expected_num_of_elements`? Or how else is `find_elements` normally used, given that presumably most web apps are very dynamic? – KnewB Dec 04 '13 at 19:34
  • 1
    Yeah, you have to look for a sign that the AJAX operation is over. What this sign may be depends on your application. It could be, as you suggest, checking a number of elements, or checking for the presence of an element which you know is the final one the AJAX operation puts out. (Like a footer at the end of a dynamic paginated table of data.) Sometimes this means designing your application for testability in mind. – Louis Dec 04 '13 at 20:38
  • I see from [the docs](http://docs.seleniumhq.org/docs/03_webdriver.jsp#fetching-a-page) that WebDriver may return control before the page has finished loading, so I'll apply your advice there too. – KnewB Dec 05 '13 at 17:06