1

As it turns out, the WebDriverWait class does not allow for an "unconditional wait": you always have to specify a certain condition to wait for. However, for example when setting up a project and developing first tests, waiting unconditionally is a helpful feature. The usage of Thread.sleep() is often discouraged. Are there better solutions for the "just wait"-problem?

I'm using the latest Selenium/WebDriver release as of now - 2.44.0.

Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
zb226
  • 9,586
  • 6
  • 49
  • 79
  • What is the purpose of waiting without any proper condition (Which is same Static wait) ? btw, if you want to do something like that, Write a method to wait for an element which is not present in DOM and handle the exception properly. – Santoshsarma Feb 10 '15 at 13:08
  • As I said in my question, it is helpful for example when setting things up. What do you mean by "Which is same Static wait"? Waiting for a knowingly non-existent element would be a possibility, albeit not a completely portable one (I can't choose a non-existent element for *every* webpage). – zb226 Feb 10 '15 at 13:10
  • 1
    what is stopping you from Thread.sleep(), and who said that it's dirty solution. – Mrunal Gosar Feb 10 '15 at 13:27
  • This is also called an 'explicit' wait, and in general is not a good practice, as you know. There are ways that you can do more advanced waits using JavascriptExecutor, I have successfully used this method to wait for CSS3 animations to finish for example, I can dig it up if you think it may help – Steve Weaver Crawford Feb 10 '15 at 13:31
  • 3
    Just by reading your question I guess `Thread.sleep()` is the best thing you can do. No need to do anymore coding – Saifur Feb 10 '15 at 13:33
  • @MrunalGosar: I've read this more than once - and thought that it is because running Selenium tests is multi-threaded. I have no further rationale to back that claim up. – zb226 Feb 10 '15 at 13:45
  • @SteveCrawford: This sounds interesting, even though it's a conditional wait. If you've got the time, I'd be grateful if you'd share it! – zb226 Feb 10 '15 at 13:48

3 Answers3

4

If you just need to wait, then Sleep is fine.

The point of not using Sleep is not in the sleep itself, but in the just waiting as you described it. Just waiting is what you should not. Try changing your thinking, find some event you can attach the wait to. Make it conditional.

In web testing, you don't usually need to just wait. You wait until page loads, until animation finishes, until form sends, element is clickable, user logs in, script executes, data are processed... That's why Sleep is discouraged, but if you really don't have a single event you are waiting for and simply need to just wait, then using the Sleep is perfectly OK.

Qwerty
  • 29,062
  • 22
  • 108
  • 136
  • Again, sorry for the delay... Thanks for answering! I know what you're getting at. It's not as bad as [dont-parse-html-with-regex](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454), but this *is* sort of a religious issue :) – zb226 Jul 14 '15 at 00:26
  • What is this `Sleep`? – frnhr Apr 12 '20 at 22:16
  • @frnhr Depends on what testing tool you are using. It's any in-built mechanism that pauses the execution for a set time. Selenium itself doesn't have such a keyword as it's just a library that allows you to control the browser. in OP's context, the `Sleep` would be `Thread.sleep()`. – Qwerty Apr 15 '20 at 12:26
2

Qwerty's answer is correct insofar as the principle is, to paraphrase:

Do not "just wait" if you can actually wait for something significant to happen in the browser. In other words, you be waiting for a specific event rather than "just waiting".

Ok, but let's assume, for the sake of argument, that you're in a situation where there is absolutely positively no event you can wait for. I have large test suites that use Selenium and I've never been in this situation, but I'm not omniscient. There could be situations I'm not foreseeing. It is possible that Thread.sleep() is going to give you want you want, however:

  1. If you are running your browser on a remote provisioning service like Sauce Labs or Browser Stack, they may decide that your script is dead and shut down the browser. (Sauce Labs definitely does this. I've never used Browser Stack but I would expect the same.)

  2. If a network issue happens while you are waiting and it is such as to cause a test failure, you won't know it until you Thread.sleep() call is done. This, again, can happen if you use services like those I've mentioned above. It happens to my test suites once in a while.

  3. Or if you are testing locally: the browser crashes or enters an infinite loop. I've not experienced crashes but I've experienced infinite loops. Again, if you use Thread.sleep() you won't know about the issue until you are done waiting.

Of course, the longer you want to wait, the more of an issue it is. If you just want to wait for a second... then you should be fine with Thread.sleep(). Otherwise, if I were backed against the wall and had to "just wait" I'd still use Selenium's waiting facilities, I'd do something like:

try: 
    WebDriverWait(driver, timeout).until(
        lambda driver: driver.execute_script("return false"))
except TimeoutException:
    pass # Do nothing

This is Python code but the principle is the same in any language that Selenium supports: just wait for something that cannot ever occur. It is important that the wait executes a test that happens on the browser side because the whole point of doing this instead of using something like Thread.sleep() is so that the browser is contacted and we find issues as early as possible. The way WebDriverWait works, it will poll the browser every so often (every 0.5 seconds is the default in the Python implementation). The test could be a find_element method that searches for an element that cannot exist. I've used an execute_script that returns false. Since it is never going to return a true value, the wait will timeout. (Executing an empty script would also work, as it would return undefined which translates to a falsy value but return false looks deliberate whereas an empty script looks like a mistake.) Then you just need to ignore the exception raised due to timing out. If you do this often you can even wrap the whole thing in a utility function.

Community
  • 1
  • 1
Louis
  • 146,715
  • 28
  • 274
  • 320
  • Sorry for the delay - Totally forgot about this question... This was precisely what I was looking for. Works as advertised, in my case w/Java! – zb226 Jul 14 '15 at 00:29
0

If you want to stay Selenium-integral, you may use:

Sleeper.SYSTEM_SLEEPER.sleep(Duration.ofSeconds(3))

I can see a use case for that when you want to slow down the things a bit to see what is happening in the browser. So I make it conditional:

Sleeper.SYSTEM_SLEEPER.sleep(Duration.ofMillis(slowDownFactor * 100))

slowDownFactor 0 by default, or more when in a development profile (in my case, a Spring profile, through:

@Value("${debug.slowDownFactor:0}") private int slowDownFactor;
Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277