+3 votes
1 view
in Devops and Agile by (22.5k points)

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?

4 Answers

+4 votes
by (57.5k points)
selected by
 
Best answer

 Two conditions can be used to check if the page is loaded before finding any element on the page:

WebDriverWait wait = new WebDriverWait(driver, 50);

Using below readyState will wait till page load

wait.until((ExpectedCondition<Boolean>) wd -> ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete")); 

Below JQuery will wait till data has not been loaded

int count =0; if((Boolean) executor.executeScript("return window.jQuery != undefined")){ while(!(Boolean) executor.executeScript("return jQuery.active == 0")){ Thread.sleep(4000); if(count>4) break; count++; } } 

After these JavaScriptCode try to findOut webElement.

WebElement we = wait.until(ExpectedConditions.presenceOfElementLocated(by)); 

Hope this helps! 

 

by (22.5k points)
I use JQuery, this solution worked for me!
by (32.8k points)
It worked for me.
Thanks!
by (42.4k points)
Good solution.
by (39.1k points)
findElement waits for an element to be available, but sometimes the element is available before the javascript code is initialized completely, that's why it's not an option
by (10.5k points)
Thank you for this detailed solution.
by (25.5k points)
Thanks for adding the comment. That made me understand the answer
+2 votes
by (57.2k points)

You just need to wait for Javascript and jQuery to finish loading. Execute Javascript to check if jQuery.active is 0 and document.readyState is complete, which means the JS and jQuery load is complete.

public boolean waitForJStoLoad() {

    WebDriverWait wait = new WebDriverWait(driver, 30);

    // wait for jQuery to load

    ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {

      @Override

      public Boolean apply(WebDriver driver) {

        try {

          return ((Long)executeJavaScript("return jQuery.active") == 0);

        }

        catch (Exception e) {

          return true;

        }

      }

    };

    // wait for Javascript to load

    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {

      @Override

      public Boolean apply(WebDriver driver) {

        return executeJavaScript("return document.readyState")

            .toString().equals("complete");

      }

    };

  return wait.until(jQueryLoad) && wait.until(jsLoad);

}

+1 vote
by (27.7k points)

Hi basically you need wait for a jquery plugin execution in some element. try using the following

wait.until( new Predicate<WebDriver>() {

            public boolean apply(WebDriver driver) {
                return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
            }
        }
    );

+2 votes
by (40.3k points)

You just need to check whether the JS library defines/initialize any known variable on the window or not.

If it does then you just need to wait for the variable to appear. Try using the code given below:

((JavascriptExecutor)driver).executeScript(String script, Object... args)

To test the condition like :

window.SomeClass && window.SomeClass.variable != null

and return a boolean true/false. Try wrapping this in a WebDriverWait, and wait until the script returns true.

Welcome to Intellipaat Community. Get your technical queries answered by top developers !


Categories

...