Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protractor not waiting for login redirect before continuing tests in AngularJS, any suggestion?

I have a standard username/password/submit button form, when the user clicks on the button the form submits with ng-submit="login.submit()" which does the login and on success redirects to the main page using ui.router ($state.go("main")).

The following test fails:

  describe("login", function() {
    beforeEach(function() {
      var email = element(by.model("login.email"));
      email.clear().sendKeys("mail");

      var password =  element(by.model("login.password"));
      password.clear().sendKeys("pass");

      var submit = element(by.id("submit"));
      submit.click();
    });

    it("should be able to login", function() {
      expect(element(by.css(".loginPage")).isPresent()).toBe(false);
      expect(element(by.css(".mainPage")).isPresent()).toBe(true);
    });
  });

and if I try to add wait times around, I can see that the browser stays on the login page the whole time (after clicking on the button) - then I get a timeout.

After a successful login the browser receives a cookie with a token for authenticating each following request.

EDIT: with some tinkering I found out where it fails..

function login(email, pass) {
  alert("it gets here");
  return _auth.post({ username: email, password: pass }).then(function(data) {
    alert("does not get here");
    console.log("loginok, token:" +$browser.cookies().apiToken); //this should be the received token
    return data;
  });
}

EDIT2: the Auth service

var _auth = Restangular.withConfig(function(Configurer) {
  Configurer.setBaseUrl("/");
}).service("auth/simple");

return {
  login: login,
};

function login(email, pass) {
  return _auth.post({ username: email, password: pass });
}

Manually everything works as expected.

like image 211
fusio Avatar asked Nov 14 '14 14:11

fusio


People also ask

How do you set the wait time on a protractor?

Setting the wait timeout to 0 (its default value) disables implicit waiting, but is not recommended. The implicitly wait method accepts the int parameter, which specifies the amount of time the protractor should wait when searching for an element if it is not immediately present.

How does protractor wait for angular?

For Angular apps, Protractor will wait until the Angular Zone stabilizes. This means long running async operations will block your test from continuing. To work around this, run these tasks outside the Angular zone.

What is expected conditions in protractor?

ExpectedConditions View code Represents a library of canned expected conditions that are useful for protractor, especially when dealing with non-angular apps. Each condition returns a function that evaluates to a promise. You may mix multiple conditions using and , or , and/or not .


2 Answers

@JoMendez's answer was very close but didn't work in my case. Used @DaveGray's here.

Had to wrap the isPresent() call in a function.

browser.wait(function() {
  return element(by.css('.mainPage')).isPresent();
});
like image 73
Nelu Avatar answered Sep 26 '22 05:09

Nelu


Try this:

it("should be able to login", function() {

  browser.wait(element(by.css(".mainPage")).isPresent);//this is different from sleep, this will stop the excecution of all the protractor code that is after it, until the element is present, but it won't prevent the application of loading or if is redirecting, it will keep working.

  expect(element(by.css(".loginPage")).isPresent()).toBe(false);
  expect(element(by.css(".mainPage")).isPresent()).toBe(true);
});

});

like image 26
JoMendez Avatar answered Sep 24 '22 05:09

JoMendez