Does Selenium wait for JavaScript to complete? Does Selenium wait for JavaScript to complete? selenium selenium

Does Selenium wait for JavaScript to complete?


You can easily ask Selenium to wait until a particular condition is true; in exactly what you have, one alternative would be:

new FluentWait<JavascriptExecutor>(executor) {  protected RuntimeException timeoutException(      String message, Throwable lastException) {    Assert.fail("name was never set");  }}.withTimeout(10, SECONDS).until(new Predicate<JavascriptExecutor>() {  public boolean apply(JavascriptExecutor e) {    return (Boolean)executor.executeScript("return ('Hello' === getName());");  }});

However, then you're basically testing exactly what you just coded, and that has the disadvantage that if name were set before you called setName, you haven't necessarily waited setName to finish. One thing I've done in the past for similar things is this:

In my testing library (which replaces real async calls with setTimeout shims), I have this:

window._junit_testid_ = '*none*';window._junit_async_calls_ = {};function _setJunitTestid_(testId) {  window._junit_testid_ = testId;}function _setTimeout_(cont, timeout) {  var callId = Math.random().toString(36).substr(2);  var testId = window._junit_testid_;  window._junit_async_calls_[testId] |= {};  window._junit_async_calls_[testId][callId] = 1;  window.setTimeout(function(){    cont();    delete(window._junit_async_calls_[testId][callId]);  }, timeout);}function _isTestDone_(testId) {  if (window._junit_async_calls_[testId]) {    var thing = window._junit_async_calls_[testId];    for (var prop in thing) {      if (thing.hasOwnProperty(prop)) return false;    }    delete(window._junit_async_calls_[testId]);  }  return true;}

In the rest of my library, I use _setTimeout_ instead of window.setTimeout whenever I need to set something up to happen later. Then, in my selenium test, I do something like this:

// First, this routine is in a library somewherepublic void waitForTest(JavascriptExecutor executor, String testId) {  new FluentWait<JavascriptExecutor>(executor) {    protected RuntimeException timeoutException(        String message, Throwable lastException) {      Assert.fail(testId + " did not finish async calls");    }  }.withTimeout(10, SECONDS)  .until(new Predicate<JavascriptExecutor>() {    public boolean apply(JavascriptExecutor e) {      return (Boolean)executor.executeScript(          "_isTestDone_('" + testId + "');");    }  });}// Inside an actual test:@Test public void serverPingTest() {  // Do stuff to grab my WebDriver instance  // Do this before any interaction with the app  driver.executeScript("_setJunitTestid_('MainAppTest.serverPingTest');");  // Do other stuff including things that fire off what would be async calls  // but now call stuff in my testing library instead.  // ...  // Now I need to wait for all the async stuff to finish:  waitForTest(driver, "MainAppTest.serverPingTest");  // Now query stuff about the app, assert things if needed}

Note that you can call waitForTest multiple times if needed, any time you need that test to pause until all async operations are finished.


I doubt selenium does. It only waits for page to be completely loaded, but not a script to finish. You may wish to define your own 'test step' for waiting for result (and constantly polling the page contents/script state), but be sure to setup reasonable timout not to male your tests hang forever on script error.