Подтвердить что ты не робот

Как проверить наличие ожидающих запросов (Ajax и его варианты) из браузера

Некоторые из сайтов, с которыми я имею дело, имеют тяжелые запросы ajax. Я планирую дождаться завершения запроса Ajax, прежде чем нажимать для утверждения для элемента. В настоящее время я использую

try {
    if (driver instanceof JavascriptExecutor) {
        JavascriptExecutor jsDriver = (JavascriptExecutor)driver;

        for (int i = 0; i< timeoutInSeconds; i++) 
        {
            Object numberOfAjaxConnections = jsDriver.executeScript("return jQuery.active");
            // return should be a number
            if (numberOfAjaxConnections instanceof Long) {
                Long n = (Long)numberOfAjaxConnections;
                System.out.println("Number of active jquery ajax calls: " + n);
                if (n.longValue() == 0L)  break;
            }
            Thread.sleep(1000);
        }
    }
    else {
       System.out.println("Web driver: " + driver + " cannot execute javascript");
    }
}
catch (InterruptedException e) {
    System.out.println(e);
}

Но он хорошо работает для запросов Ajax, но не для каких-либо похожих запросов с вариантами библиотек jQuery.

Примечание:

document.readyState == 'complete'

Он не работает для Ajax-запросов или других аналогичных альтернатив.

Ни те, ни другие тесты не написаны мной или не принадлежат одному webapp. Поэтому я не могу редактировать webapp.

4b9b3361

Ответ 1

Я нашел ответ, и он работал для нескольких сайтов Ajax и non-ajax, которые я проверил. После этого патча мне больше не нужно делать неявные ожидания даже для тяжелых страниц ajax, LeGac указал на следующий код в одном из своих комментариев к вопросу.

public static void checkPendingRequests(FirefoxDriver driver) {
    int timeoutInSeconds = 5;
    try {
        if (driver instanceof JavascriptExecutor) {
            JavascriptExecutor jsDriver = (JavascriptExecutor)driver;

            for (int i = 0; i< timeoutInSeconds; i++) 
            {
                Object numberOfAjaxConnections = jsDriver.executeScript("return window.openHTTPs");
                // return should be a number
                if (numberOfAjaxConnections instanceof Long) {
                    Long n = (Long)numberOfAjaxConnections;
                    System.out.println("Number of active calls: " + n);
                    if (n.longValue() == 0L)  break;
                } else{
                    // If it not a number, the page might have been freshly loaded indicating the monkey
                    // patch is replaced or we haven't yet done the patch.
                    monkeyPatchXMLHttpRequest(driver);
                }
                Thread.sleep(1000);
            }
        }
        else {
           System.out.println("Web driver: " + driver + " cannot execute javascript");
        }
    }
    catch (InterruptedException e) {
        System.out.println(e);
    }    
}



public static void monkeyPatchXMLHttpRequest(FirefoxDriver driver) {
    try {
        if (driver instanceof JavascriptExecutor) {
            JavascriptExecutor jsDriver = (JavascriptExecutor)driver;
            Object numberOfAjaxConnections = jsDriver.executeScript("return window.openHTTPs");
            if (numberOfAjaxConnections instanceof Long) {
                return;
            }
            String script = "  (function() {" +
                "var oldOpen = XMLHttpRequest.prototype.open;" +
                "window.openHTTPs = 0;" +
                "XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {" +
                "window.openHTTPs++;" +
                "this.addEventListener('readystatechange', function() {" +
                "if(this.readyState == 4) {" +
                "window.openHTTPs--;" +
                "}" +
                "}, false);" +
                "oldOpen.call(this, method, url, async, user, pass);" +
                "}" +
                "})();";
            jsDriver.executeScript(script);
        }
        else {
           System.out.println("Web driver: " + driver + " cannot execute javascript");
        }
    }
    catch (Exception e) {
        System.out.println(e);
    }
}

После каждого шага вам нужно будет позвонить

checkPendingRequests(driver);

Ответ 3

Если вы используете JSONP-запросы, вам нужно включить active обработку:

jQuery.ajaxPrefilter(function( options ) {
    options.global = true;
});

Я думаю, что использование active верное, но, возможно, способ, которым вы использовали, может возвращать false в условиях instanceof.

Необязательно видеть другой способ ожидания jQuery ajax-вызовов с использованием active в тегах Selenium:

browser.wait_for_condition("selenium.browserbot.getCurrentWindow().jQuery.active === 0;", '30000')

Ответ 4

Основываясь на нашем обсуждении комментариев, это может сработать для вас.

С prototype.js:

var ACTIVE_REQUESTS = 0; // GLOBAL

ACTIVE_REQUESTS++
new Ajax.Request('/your/url', {
  onSuccess: function(response) {
    ACTIVE_REQUESTS--;
    // Handle the response content...
  }
}));

console.log("there are " + ACTIVE_REQUESTS + " open AJAX requests pending");

С обычным script:

interValRef = 0;

interValRef = setInterval("checkState();",100)

function checkState(){
    if(document.readyState == 'complete'){
        clearInterval(interValRef);
        myFunc();
    }
}

Источник: Проверить ожидающие запросы AJAX или запрос HTTP GET/POST