I gave a presentation called ”Being good at waiting – Using Selenium to test Ajax-intensive pages” in an unconf session at the Selenium Conference in London.
The audience was great! Thanks everybody! I certainly didn’t know everything there’s to know about the subject, and that resulted in an interactive session where people from the audience would share their experience and answer some questions. That was so cool 🙂
Anyway, the point I wanted to make was this: when you google for Selenium/WebDriver and Ajax, you still find plenty of examples where the naïve approach, sleeping (as in
Thread.sleep() and similar constructs) is used. My main message was – don’t ever do that! Use a proper WebDriver wait, since it handles the sleeping correctly and plays well with ElementNotFoundExceptions.
I also mentioned implicit waits as something that can be used if you don’t have too many Ajax calls and want to hide that complexity behind a global timeout.
I actually never got the question why I ran all my code samples as unit tests. None of them actually verified anything; all they did was to print things to stderr. Apparently the reason wasn’t interesting enough, but if it made someone wonder: It was because I wanted my samples to be easy to turn into tests if necessary.
By the way… I totally forgot to mention the AjaxElementLocator* classes.
Some comments and suggestions from the audience:
- Implicit waits don’t help when waiting for elements that are not there
- You can check for non-presence of elements by waiting for the element to be present for 0 seconds and accepting the exception.
- Don’t rely on jQuery’s active variable to check for ongoing Ajax calls. It may indicate other activity as well. (True, but you would probably want to wait for that too in your test, so it may not be that big a problem.)
- There is a class called
org.openqa.selenium.support.ui.ExpectedConditions(in Java) that has a lot of static methods that can be used as predicates for
WebDriverWait. That way, you don’t have to implement them from scratch. (I simply didn’t know that.)
All in all, I think we had a productive session, in which we unfortunately didn’t find a sliver bullet for the asynchronicity challenges, but we managed to exchange a lot of knowledge and got a common view of where the API is, and what techniques we can use.
The slides are here, and I plan to post the code samples on Github soon. Stay tuned.