如何在Selenium IDE中等待所有ajax请求完成?

时间:2022-08-23 19:39:30

I have a rather ajax-heavy web application that I am testing with Selenium, and Selenium IDE. Everything works fine until the final submit. Usually it errors out due to the outstanding number of ajax requests that are still in process (usually around 20). Is there any way to have selenium wait for all ajax requests to be complete? I have tried waitForEval Value = "$.active==0" (pictured below) but that doesn't seem to do anything 如何在Selenium IDE中等待所有ajax请求完成?

我有一个相当ajax-heavy的Web应用程序,我正在使用Selenium和Selenium IDE进行测试。一切正常,直到最终提交。通常由于仍在进行中的ajax请求的数量(通常在20左右),它会出错。有没有办法让selenium等待所有ajax请求完成?我试过waitForEval Value =“$ .active == 0”(如下图所示),但似乎没有做任何事情

Is this something that is possible with Selenium IDE?

这是Selenium IDE可以实现的吗?

Note - I do have to use the IDE due to the fact that the business types and I are passing the scripts back and forth.

注意 - 我必须使用IDE,因为业务类型和我来回传递脚本。

3 个解决方案

#1


5  

The answer turned out to be rather simple - all you have to do is check the number of active requests (selenium.browserbot.getUserWindow().$.active) with the waitForEval command, and set the value to 0 - and it all happens in the ide.

答案结果相当简单 - 您所要做的就是使用waitForEval命令检查活动请求的数量(selenium.browserbot.getUserWindow()。$。active),并将值设置为0 - 这一切都发生了在ide。

#2


1  

I haven't used IDE in a while. This is what I use for WebDriver. But the algorithms translate; JavaScript is JavaScript. That being said, it depends on your framework.

我有一段时间没用过IDE。这就是我用于WebDriver的内容。但算法转换; JavaScript是JavaScript。话虽这么说,这取决于你的框架。

For Angular, I use this:

对于Angular,我用这个:

public boolean waitForAngularToLoad(WebDriver driver, int waitTimeInSeconds) {

    WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);

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

      public Boolean apply(WebDriver driver) {
        try {
          return ((Boolean)((JavascriptExecutor)driver).executeScript(
                  "return angular.element(document.body).injector().get(\'$http\').pendingRequests.length == 0;"
                  ));
        }
        catch (Exception e) {
            // Angular not found
            log.info("Not found: " + "return angular.element(document.body).injector().get(\'$http\').pendingRequests.length == 0;");
            return true;
        }
      }
    };

    // wait for browser readystate complete; it is arguable if selenium does this all the time
    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {

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

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

}

For Prototype I use:

对于Prototype我使用:

public boolean waitForPrototypeToLoad(WebDriver driver, int waitTimeInSeconds) {

    WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);

    // wait for jQuery to load
    ExpectedCondition<Boolean> libraryLoad = new ExpectedCondition<Boolean>() {

      public Boolean apply(WebDriver driver) {
        try {
          return ((Boolean)((JavascriptExecutor)driver).executeScript("return Ajax.activeRequestCount == 0;"));
        }
        catch (Exception e) {
            // Prototype  not found
            log.info("Not found: " + "return Ajax.activeRequestCount == 0;");
            return true;
        }
      }
    };

    // wait for browser readystate complete; it is arguable if selenium does this all the time
    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {

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

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

}

For jQuery, I use this (you have to customize the wait for spinner logic, everybody does it differently):

对于jQuery,我使用它(您必须自定义等待微调器逻辑,每个人都以不同方式执行):

public boolean waitForJSandJQueryToLoad(WebDriver driver, long waitTimeInSeconds) {

    WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);

    /*
     * If you are curious about what follows see:
     *  http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/ui/ExpectedCondition.html
     * 
     * We are creating an anonymous class that inherits from ExpectedCondition and then implements interface
     * method apply(...)
     */
    ExpectedCondition<Boolean> libraryLoad = new ExpectedCondition<Boolean>() {

      public Boolean apply(WebDriver driver) {
        boolean isAjaxFinished = false;
        boolean isLoaderSpinning = false;
        boolean isPageLoadComplete = false;
        try {
          isAjaxFinished = ((Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0;"));
        } catch (Exception e) {
            // no Javascript library not found
            isAjaxFinished = true;
        }
        try { // Check your page, not everyone uses class=spinner
            // Reduce implicit wait time for spinner
            driver.manage().timeouts().implicitlyWait(10L, TimeUnit.SECONDS);

//              isLoaderSpinning = driver.findElement(By.className("spinner")).isDisplayed(); // This is the default
            // Next was modified for GoComics
            isLoaderSpinning = driver.findElement(By.cssSelector("#progress_throbber > ul > li:nth-child(1) > img[alt='spinner']")).isDisplayed();

            if (isLoaderSpinning)
                log.info("jquery loader is spinning");
        } catch (Exception f) {
            // no loading spinner found
            isLoaderSpinning = false;
        } finally { // Restore implicit wait time to default
            driver.manage().timeouts().implicitlyWait(new DriverFactory().getImplicitWait(), TimeUnit.SECONDS);
        }
        isPageLoadComplete = ((JavascriptExecutor)driver).executeScript("return document.readyState;")
                .toString().equals("complete");
        if (!(isAjaxFinished & !(isLoaderSpinning) & isPageLoadComplete))
            log.info(isAjaxFinished + ", " + !(isLoaderSpinning) +", " + isPageLoadComplete);

        return isAjaxFinished & !(isLoaderSpinning) & isPageLoadComplete;
      }
    }; // Terminates statement started by ExpectedCondition<Boolean> libraryLoad = ...

  return wait.until(libraryLoad); 
}

#3


0  

In the end, solving the problem arose addition of AJAX. I'm testing it for a few days - an ingenious solution. Appendix on that at every step made selenium automatically waits for the execution of AJAX.

最后,解决问题的原因是增加了AJAX。我正在测试它几天 - 一个巧妙的解决方案。关于每一步的附录,selenium会自动等待AJAX​​的执行。

https://addons.mozilla.org/pl/firefox/addon/sideex/

#1


5  

The answer turned out to be rather simple - all you have to do is check the number of active requests (selenium.browserbot.getUserWindow().$.active) with the waitForEval command, and set the value to 0 - and it all happens in the ide.

答案结果相当简单 - 您所要做的就是使用waitForEval命令检查活动请求的数量(selenium.browserbot.getUserWindow()。$。active),并将值设置为0 - 这一切都发生了在ide。

#2


1  

I haven't used IDE in a while. This is what I use for WebDriver. But the algorithms translate; JavaScript is JavaScript. That being said, it depends on your framework.

我有一段时间没用过IDE。这就是我用于WebDriver的内容。但算法转换; JavaScript是JavaScript。话虽这么说,这取决于你的框架。

For Angular, I use this:

对于Angular,我用这个:

public boolean waitForAngularToLoad(WebDriver driver, int waitTimeInSeconds) {

    WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);

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

      public Boolean apply(WebDriver driver) {
        try {
          return ((Boolean)((JavascriptExecutor)driver).executeScript(
                  "return angular.element(document.body).injector().get(\'$http\').pendingRequests.length == 0;"
                  ));
        }
        catch (Exception e) {
            // Angular not found
            log.info("Not found: " + "return angular.element(document.body).injector().get(\'$http\').pendingRequests.length == 0;");
            return true;
        }
      }
    };

    // wait for browser readystate complete; it is arguable if selenium does this all the time
    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {

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

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

}

For Prototype I use:

对于Prototype我使用:

public boolean waitForPrototypeToLoad(WebDriver driver, int waitTimeInSeconds) {

    WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);

    // wait for jQuery to load
    ExpectedCondition<Boolean> libraryLoad = new ExpectedCondition<Boolean>() {

      public Boolean apply(WebDriver driver) {
        try {
          return ((Boolean)((JavascriptExecutor)driver).executeScript("return Ajax.activeRequestCount == 0;"));
        }
        catch (Exception e) {
            // Prototype  not found
            log.info("Not found: " + "return Ajax.activeRequestCount == 0;");
            return true;
        }
      }
    };

    // wait for browser readystate complete; it is arguable if selenium does this all the time
    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {

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

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

}

For jQuery, I use this (you have to customize the wait for spinner logic, everybody does it differently):

对于jQuery,我使用它(您必须自定义等待微调器逻辑,每个人都以不同方式执行):

public boolean waitForJSandJQueryToLoad(WebDriver driver, long waitTimeInSeconds) {

    WebDriverWait wait = new WebDriverWait(driver, waitTimeInSeconds, 2000L);

    /*
     * If you are curious about what follows see:
     *  http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/ui/ExpectedCondition.html
     * 
     * We are creating an anonymous class that inherits from ExpectedCondition and then implements interface
     * method apply(...)
     */
    ExpectedCondition<Boolean> libraryLoad = new ExpectedCondition<Boolean>() {

      public Boolean apply(WebDriver driver) {
        boolean isAjaxFinished = false;
        boolean isLoaderSpinning = false;
        boolean isPageLoadComplete = false;
        try {
          isAjaxFinished = ((Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0;"));
        } catch (Exception e) {
            // no Javascript library not found
            isAjaxFinished = true;
        }
        try { // Check your page, not everyone uses class=spinner
            // Reduce implicit wait time for spinner
            driver.manage().timeouts().implicitlyWait(10L, TimeUnit.SECONDS);

//              isLoaderSpinning = driver.findElement(By.className("spinner")).isDisplayed(); // This is the default
            // Next was modified for GoComics
            isLoaderSpinning = driver.findElement(By.cssSelector("#progress_throbber > ul > li:nth-child(1) > img[alt='spinner']")).isDisplayed();

            if (isLoaderSpinning)
                log.info("jquery loader is spinning");
        } catch (Exception f) {
            // no loading spinner found
            isLoaderSpinning = false;
        } finally { // Restore implicit wait time to default
            driver.manage().timeouts().implicitlyWait(new DriverFactory().getImplicitWait(), TimeUnit.SECONDS);
        }
        isPageLoadComplete = ((JavascriptExecutor)driver).executeScript("return document.readyState;")
                .toString().equals("complete");
        if (!(isAjaxFinished & !(isLoaderSpinning) & isPageLoadComplete))
            log.info(isAjaxFinished + ", " + !(isLoaderSpinning) +", " + isPageLoadComplete);

        return isAjaxFinished & !(isLoaderSpinning) & isPageLoadComplete;
      }
    }; // Terminates statement started by ExpectedCondition<Boolean> libraryLoad = ...

  return wait.until(libraryLoad); 
}

#3


0  

In the end, solving the problem arose addition of AJAX. I'm testing it for a few days - an ingenious solution. Appendix on that at every step made selenium automatically waits for the execution of AJAX.

最后,解决问题的原因是增加了AJAX。我正在测试它几天 - 一个巧妙的解决方案。关于每一步的附录,selenium会自动等待AJAX​​的执行。

https://addons.mozilla.org/pl/firefox/addon/sideex/