I'm using Protractor with Chai-as-promised for my newest Angular 4 app. I have only 2 e2e tests for now. One logging in an existant user, another signing up a new one. My signup logic will also login the newly created user if signup succeeds.
Here's html the code:
<ul class="navbar-nav my-2 my-lg-0">
<li *ngIf="!isAuthenticated()" class="nav-item">
<button id="loginLink" class="btn btn-link nav-link" style="line-height: inherit" type="button" role="button" (click)="openLoginModal()">Login</button>
</li>
<li *ngIf="!isAuthenticated() && signupAllowed()" class="nav-item">
<button id="signupLink" class="btn btn-link nav-link" style="line-height: inherit" type="button" role="button" (click)="openSignupModal()">Sign up</button>
</li>
<li *ngIf="isAuthenticated()" class="nav-item">
<a id="logoutLink" class="nav-link" role="button" (click)="logout()">Logout</a>
</li>
</ul>
And here's the e2e tests code:
import { browser, by, element } from "protractor";
const expect = global[ 'chai' ].expect;
describe('Auth', () => {
describe('login/logout', () => {
it('should login successfully with valid username and password tuple', () => {
// arrange
browser.get('/');
expect(element(by.id('loginLink')).isPresent()).to.eventually.be.true;
element(by.id('loginLink')).click();
// act
element(by.id('usernameInput')).sendKeys('jeep87c');
element(by.id('passwordInput')).sendKeys('1111');
element(by.id('loginBtn')).click();
// assert
expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true;
element(by.id('logoutLink')).click();
expect(element(by.id('loginLink')).isPresent().to.eventually.be.true;
});
});
describe('signup/logout', () => {
it('should succeeds with unused username and matching passwords and login', () => {
// arrange
browser.get('/');
expect(element(by.id('signupLink')).isPresent()).to.eventually.be.true;
element(by.id('signupLink')).click();
// act
element(by.id('usernameInput')).sendKeys('test');
element(by.id('passwordInput')).sendKeys('1111');
element(by.id('confirmPasswordInput')).sendKeys('1111');
element(by.id('signupBtn')).click();
// assert
expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true;
element(by.id('logoutLink')).click();
});
});
});
As you can see, both test are pretty similar. But, the signup/logout
fails on expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true;
, which is also present in the login/logout
test, which succeeds.
What am I missing? It feels like it doesn't wait at all. But it works for the login/logout
(meaning the test succeeds).
Both login & signup requests to the API are taking around 200ms to complete each. Important to note that when a user submit the signup form, it will trigger first a signup request to the api and if it succeeds, then a login request. So it will take around 400ms to complete. Which, I'm guessing, is above what eventually
will poll/wait for.
EDIT:
Some expect(...).to.eventually
were missing in the code above, which I fixed.
As a FYI, here's the assertion failure:
Auth signup/logout should succeeds with unused username and matching passwords and login:
AssertionError: expected false to be true
It really feels like the promise resolve before the element is actually present in the dom and fail the assertion. Instead of polling for it again until it's true or timeout.
EDIT #2: Just tried the exact same code but, waiting 5 seconds before executing the last two lines and it passed successfully...
setTimeout(function() {
expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true;
element(by.id('logoutLink')).click();
}, 5000);
So it's definitely expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true;
promise resolving to fast to false and failing the test. How do I fix this?
Any help will be appreciated.
I'm not sure it was the issue causing this but, once I change my signup code from :
To:
The test succeeded. I'm using ng2-ui-auth being a Angular 2+ port of original Satellizer for AngularJs.
It could be related to how I used the Obsersables returned by those auth service's methods.
If anybody could explain, I would be happy to truly understand what happened here.