Selenium WebDriver: Wait for complex page with JavaScript to load

psadac picture psadac · May 23, 2012 · Viewed 169.7k times · Source

I have a web application to test with Selenium. There is a lot of JavaScript running on page load.
This JavaScript code is not so well written but I can't change anything. So waiting for an element to appear in the DOM with findElement() method is not an option.
I want to create a generic function in Java to wait for a page to load, a possible solution would be:

  • run a JavaScript script form WebDriver and store the result of document.body.innerHTML in a string variable body.
  • compare the body variable to the previous version of body. if they are the same then set increment a counter notChangedCount otherwise set notChangedCount to zero.
  • wait for a litte time (50 ms for example).
  • if the page has not changed for some time (500 ms for example) so notChangedCount >= 10 then exit the loop otherwise loop to the first step.

Do you think it's a valid solution?

Answer

Petr Janeček picture Petr Janeček · May 23, 2012

If anyone actually knew a general and always-applicable answer, it would have been implemented everywhere ages ago and would make our lives SO much easier.

There are many things you can do, but every single one of them has a problem:

  1. As Ashwin Prabhu said, if you know the script well, you can observe its behaviour and track some of its variables on window or document etc. This solution, however, is not for everyone and can be used only by you and only on a limited set of pages.

  2. Your solution by observing the HTML code and whether it has or hasn't been changed for some time is not bad (also, there is a method to get the original and not-edited HTML directly by WebDriver), but:

    • It takes a long time to actually assert a page and could prolong the test significantly.
    • You never know what the right interval is. The script might be downloading something big that takes more than 500 ms. There are several scripts on our company's internal page that take several seconds in IE. Your computer may be temporarily short on resources - say that an antivirus will make your CPU work fully, then 500 ms may be too short even for a noncomplex scripts.
    • Some scripts are never done. They call themselves with some delay (setTimeout()) and work again and again and could possibly change the HTML every time they run. Seriously, every "Web 2.0" page does it. Even Stack Overflow. You could overwrite the most common methods used and consider the scripts that use them as completed, but ... you can't be sure.
    • What if the script does something other than changing the HTML? It could do thousands of things, not just some innerHTML fun.
  3. There are tools to help you on this. Namely Progress Listeners together with nsIWebProgressListener and some others. The browser support for this, however, is horrible. Firefox began to try to support it from FF4 onwards (still evolving), IE has basic support in IE9.

And I guess I could come up with another flawed solution soon. The fact is - there's no definite answer on when to say "now the page is complete" because of the everlasting scripts doing their work. Pick the one that serves you best, but beware of its shortcomings.