E2E Tracer Screen - Calling the Asynchronous Call API

I want to test a simple end-to-end flow - create a new account - using Protractor.

I have an AngularJS application that contains an account creation page where the user has to fill out a simple form and click the submit button.

When the submit button is clicked, a method is triggered that calls the async method to create an account on my server.

When this function returns, the user is redirected to another page.

Here is my test ( creatAccount.spec.js

):

describe('Create Account Page Tests', function() {

    it('createAccount success', function(){
        browser.get('http://localhost:9001/#/createAccount');
        element(by.model('user.organizationName')).sendKeys('Westeros');
        element(by.model('user.firstName')).sendKeys('John');
        element(by.model('user.lastName')).sendKeys('Snow');
        element(by.model('user.email')).sendKeys('johnSnow@westeros.com');
        element(by.model('user.password')).sendKeys('123');
        element(by.model('confirmPassword')).sendKeys('123');

        element(by.id('submitBtn')).click();

        expect(browser.getCurrentUrl()).toEqual('http://localhost:9001/#/userManagement');

    });

});

      

Here is my submit method:

  $scope.submit = function() {
        $scope.submitted = true;
        UserService.createAccount($scope.user)
            .then(function success(){
                $state.go('userManagement');
            }, function failure(){
                $log.error("something went wrong");
        });
    };

      

Here's my method UserService.createAccount

:

 function createAccount(user){
            var deferred = $q.defer();
            APIService.sendRequest(APIService.ACTION().createAccount, undefined, user)
                .then(function success(res) {
                    deferred.resolve();
                }, function failure(reason){
                    $log.debug('create account failed. reason: ', reason);
                    deferred.reject(reason);
                });

            return deferred.promise;
        }

      

And here is my method APIService.sendRequest

:

function sendRequest(action, params, data){
            var defferd = $q.defer();
            var request = $resource(action.url, {}, {send: {method: action.method, isArray: action.isArray ? action.isArray : false, withCredentials: true}});

            if (!params){
                params = {};
            }

            request.send(params, data, function(res) {
                defferd.resolve(res);
            }, function(error) {
                defferd.reject(getErrorReponseListError(error));
            });

            return defferd.promise;
        }

      

My test keeps failing as the page is not directed to the next page. It seems to me that the test doesn't wait for the async method to return, even thinking that it should ...

I tried calling browser.waitForAngular()

or browser.wait(5000)

, but nothing helps ...

+3


source to share


1 answer


This line:

expect(browser.getCurrentUrl()).toEqual('http://localhost:9001/#/userManagement');

      

expects the browser url to be exactly like this. It doesn't wait for the URL to change. click

before that line completes, but it all means that the click was delivered to the browser, and the handler in the browser did not complete (and call it asynchronously).



You need to teach your Protractor test to wait for the browser to reach the expected state. Something like this should work:

browser.wait(function() {
   return browser.getCurrentUrl().then(function(url) {
      return url === 'http://localhost:9001/#/userManagement';
   });
});

      

So, instead of expecting the url to be what you say, it expects the url to be what you want. After most interactions with the browser (for example, submitting something or any other interaction with the server), you need to wait for the page to transition to a new state.

+2


source







All Articles