Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in DevOps and Agile by (19.7k points)

Some of the sites I deal with have heavy ajax requests. I plan to wait for Ajax request completion before clicking for asserting for element. Currently I use

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);

}

But it works well for Ajax requests but not for any similar requests with variants of jQuery libraries.

Note:

document.readyState == 'complete'

It doesn't work for Ajax requests or any other similar alternatives. Neither tests are written by me or belong to single webapp. So I can't edit the webapp.

1 Answer

0 votes
by (62.9k points)

I found the solution and it worked for a few ajax and non-ajax sites which I checked.

After this patch I now not ought to do implicit waits even for ajax heavy pages, You can use the following code :

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's not a number, the page might have been reloaded that indicates that the monkey

                    // patch is being replaced or we haven't yet done the patch.

                    monkeyPatchXMLHttpRequest(driver);

                }

                Thread.sleep(1000);

            }

        }

        else {

           System.out.println( driver + "  web driver" + "can't perform 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(driver + "  web driver" + "can't perform javascript");

        }

    }

    catch (Exception e) {

        System.out.println(e);

    }

}

After every step, you would need to call the following function:

 checkPendingRequests(driver);

Browse Categories

...