Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nightwatchjs - how to wait till ajax call is completed

I am using nightwatchJS for browser automation. One common usecase I am seeing is, most of the content in my webpage are updated through data from ajax call. So, in my testing, i am looking for a way to hold my testing until i get result from Ajax. I could not find any api in nightwatch or selenium for this.

I have tried with waitForElementVisible, but I feel this will not be suffice. What will happen if my ajax call doesn't return any data.

Has anybody tried this before?

like image 983
Saravanan S Avatar asked Sep 30 '15 10:09

Saravanan S


People also ask

Is there a way to limit the time an Ajax call will run?

Not possible. It's the browser's responsibility.

How do I make jQuery wait for an Ajax call to finish before it returns?

ajax({ url: $(this). attr('href'), type: 'GET', async: false, cache: false, timeout: 30000, fail: function(){ return true; }, done: function(msg){ if (parseFloat(msg)){ return false; } else { return true; } } }); });

How do I know Ajax call is complete?

The ajaxStop() method specifies a function to run when ALL AJAX requests have completed. When an AJAX request completes, jQuery checks if there are any more AJAX requests. The function specified with the ajaxStop() method will run if no other requests are pending.

How check Ajax request is successful jQuery?

$. ajax({ url: "page. php", data: stuff, success: function(response){ console. log("success"); } });


1 Answers

If you know ajax path here is the way how it can be solved, the idea is to attach 'ajaxComplete' event to client and match executed request path:

client
    .timeoutsAsyncScript(15000) // set async exec timeout
    .click('.btn-submit') // ajax form submit
    .executeAsync(
        function(targetUrl, done){
            var nightwatchAjaxCallback = function(ajaxUrl) {
                if(ajaxUrl.indexOf(targetUrl) === 0) { // if url match notify script that xhr is done
                    done(true);
                }
            };

            if(!window.nightwatchAjaxInited) { // make sure ajaxComplete is attached only once

                window.nightwatchAjaxInited = true;

                $(document).ajaxComplete(function(e, res, req) {
                    nightwatchAjaxCallback(req.url);
                });
            }
        },
        ['/ajaxpath'], // expected xhr request path
        function(status){
            // executes once ajax is done
            client.verify.containsText('.entry', 'lorem ipsup...') // verify post is created
        }
    );

Here is command named 'ajaxWait' created from the code above:

exports.command = function(targetUrl, action, callback) {

    this.timeoutsAsyncScript(15000);

    action();

    this.executeAsync(function(targetUrl, done){

        var nightwatchAjaxCallback = function(ajaxUrl) {
            if(ajaxUrl.indexOf(targetUrl) === 0) {
                done(true);
            }
        };

        if(!window.nightwatchAjaxInited) {

            window.nightwatchAjaxInited = true;

            $(document).ajaxComplete(function(e, res, req) {
                nightwatchAjaxCallback(req.url);
            });
        }

    }, [targetUrl], function(status){

        callback();
    });
};

and call should look like this:

client.ajaxWait('/ajaxpath', function(){
    // ajax form submit
    client.click('.btn-submit') // ajax form submit
}, function(){
    // executes once ajax is done
    client.verify.containsText('.entry', 'lorem ipsup...') // verify post is created
})
like image 124
Brankodd Avatar answered Oct 16 '22 23:10

Brankodd