I’ve been immersed at work lately on a project and haven’t been able to post for the past few months. I wrote a blog last year about how to handle page loading times using C#. I also said in that blog that I wrote it java and some day will write about it. So today this is what I will post about and is long overdue.
So handling page loading times should be very important in all test automation frameworks. Especially when your AUT is not local or your accessing it through a VMware or something. The reason why from my experience is during writing your automation scripts, this is almost always a hurdle that you need to jump over multiple times. Often, this is why your scripts fail over and over in the initial phase of your automation script. Seeing that NoSuchElementException error can be hair pulling and I know exactly how you feel.
For my java projects that dealt with AUTs that were very ajax heavy, the sample code that I will share below was a life saver. Not only did they make my scripts stable, I saved a lot of time debugging those pesky inconsistent ‘Unable to locate element’ Exception errors that would pop up now and then. I would insert the method ‘WaitForPageLoad’ on all page transitions like from Login Page to Homepage or clicking a button that would trigger a pop up window, etc. It will be up to you to gauge where it will be needed for your automation scripts.
This is the main method to call within your scripts or modules. This will first wait for the DOM to be at readyState = complete. Then wait for ajax then back to the DOM readyState = complete.
public static void WaitForPageLoad(WebDriver driver) { waitForDocumentLoad(driver); waitForAjaxLoad(driver); waitForDocumentLoad(driver); }
This code will wait for DOM to be completed.
private static void waitForDocumentLoad(WebDriver driver) { WebDriverWait wait = new WebDriverWait(driver, 30); wait.until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");}}); }
And lastly, the code to wait for Ajax to load.
private static void waitForAjaxLoad(WebDriver driver) { WebDriverWait wait = new WebDriverWait(driver, 30); wait.until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return driver.findElements(By.cssSelector(".waiting, .tb-loading")).size() == 0;}}); }