JoJo
JoJo

Reputation: 20115

Wait for Javascript file to load in Selenium 2

I'm using Selenium 2 to test the user interface of my website. I need to check that clicking a button yields some result. In 1 in every 10 or so test runs, Selenium fails to even click the button. There are no errors printed out. There is nothing wrong with the JS because I can manually click the button after Selenium fails to click it.

At the very simplest, my HTML looks like this:

<html>
<head></head>
<body>
   <a id="button" onclick="clickIt(); return false;"></a>
   <script type="text/javascript" src="javascript.js"></script>
</body>
</html>

JS is placed at the end of body so a slow loading JS file wouldn't block the entire page. The JS file defines the clickIt function.

function clickIt() {
   $('button').addClassName('beenClicked');
}

Java:

WebElement button = driver.findElement(By.xpath("//a[@id='button']"));
button.click();

My hypothesis on why it fails 1 out of 10 times is that Selenium is not waiting for the JS file to load before clicking the button. If this is true, how do I wait for this JS file to load and execute?

Upvotes: 1

Views: 4130

Answers (3)

mayur Oka
mayur Oka

Reputation: 1

public boolean waitForJStoLoad(WebDriver driver) {
    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)((JavascriptExecutor) driver)
                        .executeScript("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 ((JavascriptExecutor) driver)
                    .executeScript("return document.readyState")
                    .toString().equals("complete");
        }
    };
    return wait.until(jQueryLoad) && wait.until(jsLoad);
}

Upvotes: 0

hari om soni
hari om soni

Reputation: 1

JavascriptExecutor js = (JavascriptExecutor) driver; 
Boolean isLoaded = (Boolean)js.executeScript(
      "return typeof window.yourFunctionName === 'function'", null);

Upvotes: 0

epascarello
epascarello

Reputation: 207521

Look into WebDriverWait

Check to see if a function is there

JavascriptExecutor js = (JavascriptExecutor) driver; 
Boolean isLoaded = (Boolean)js.executeScript("return typeof window.yourFunctionName === 'function'", null);

Upvotes: 3

Related Questions