Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protractor testing angular $http interceptors

I am trying to make an angular protractor test which on submit sends a regular ajax request which is then intercepted on the response leg. The $http interceptor opens up a custom dialog waiting for user input (user / password) for further authentication.

The issue is that protractor sits there waiting for the HTTP response to complete but never does because it has been intercepted and simply times out. I cannot find a way to have protractor sendKeys to these dialogs since it is still waiting for the HTTP request to finish (it never will since it was intercepted).

So essentially, can the protractor framework handle $http intercepted responses and provide additional browser input when needed? Or is there any workarounds?

Thanks!!

like image 408
Kiwi man Avatar asked Nov 01 '22 17:11

Kiwi man


1 Answers

You can intercept all xhr calls in your application by injecting this script to your browser. And store response to some global variable like, i am saving in windows variable.

(function(XHR) {
    "use strict";

    var open = XHR.prototype.open;
    var send = XHR.prototype.send;

    XHR.prototype.open = function(method, url, async, user, pass) {
        this._url = url;
        open.call(this, method, url, async, user, pass);
    };

    XHR.prototype.send = function(data) {
        var self = this;
        var oldOnReadyStateChange;
        var url = this._url;

        function onReadyStateChange() {
            if(self.readyState == 4 /* complete */) {
                /* This is where you can put code that you want to execute post-complete*/
                /* URL is kept in this._url */

                if(self._url=='api/v1/groups')
                {
                    var request=JSON.parse(data);
                    if(request.method=='createGroup') {

                        var XHRInterceptObj=new Object();
                        XHRInterceptObj.request=request;
                        XHRInterceptObj.response=self;
                        window._groupCreation =XHRInterceptObj;

                    }
                    else if(request.method=='getGroupDetails') {
                        var XHRInterceptObj=new Object();
                        XHRInterceptObj.request=request;
                        XHRInterceptObj.response=self;
                        window._groupDetails =XHRInterceptObj;
                    }
                }

            }

            if(oldOnReadyStateChange) {
                oldOnReadyStateChange();
            }
        }

        /* Set xhr.noIntercept to true to disable the interceptor for a particular call */
        if(!this.noIntercept) {
            if(this.addEventListener) {
                this.addEventListener("readystatechange", onReadyStateChange, false);
            } else {
                oldOnReadyStateChange = this.onreadystatechange;
                this.onreadystatechange = onReadyStateChange;
            }
        }
        //console.log('data',data);
        send.call(this, data);
    }
})(XMLHttpRequest);

and you can get response data from global variable like this.

browser.executeScript('return window._groupCreation;').then(function(obj){
        console.log(obj.responseText);
    });

In this script we are actually adding additional functionality to XHR object using prototype and intercepting calls.

like image 82
A Qadeer Qureshi Avatar answered Nov 08 '22 04:11

A Qadeer Qureshi