I'm writing a few E2E tests in an Angular application. A problem I'm having is that whenever I redirect to a new route, I'd like to verify that the correct component is being displayed. For some reason this is always resulting a failure with the following error:
- Failed: script timeout
I've been searching all over the web to try to find a solution but all the solutions I've found haven't worked for me.
Example
- Wait for Angular
browser.waitForAngular();
- Check the browser current URL and compare with the expected URL:
browser.driver.wait(() => {
browser.driver.getCurrentUrl().then((url) => {
return /expected-url/.test(url);
});
}, 10000);
Code Example
The following is a sample of the code that is testing the login functionality.
Login Page Object Class
import { browser, element, by } from 'protractor';
export class LoginPage {
private credentials: { username: string, password: string } = {
username: 'admin',
password: 'admin'
};
navigateTo() {
return browser.get(browser.baseUrl) as Promise<any>;
}
getLoginComponent() {
return element(by.css('ra-login'));
}
getUsernameTextbox() {
return element(by.css('ra-login [data-test-id="username"]'));
}
getPasswordTextbox() {
return element(by.css('ra-login [data-test-id="password"]'));
}
getLoginButton() {
return element(by.css('ra-login [data-test-id="login-btn"]'));
}
getSecurePage() {
return element(by.css('ra-secure-content'));
}
login(credentials: { username: string, password: string } = this.credentials) {
this.getUsernameTextbox().sendKeys(credentials.username);
this.getPasswordTextbox().sendKeys(credentials.password);
this.getLoginButton().click();
}
getErrorMessage() {
return element(by.css('ra-login [data-test-id="login-error"]'));
}
}
Login E2E Spec File
describe('Login Functionality', () => {
let loginPage: LoginPage;
beforeEach(() => {
loginPage = new LoginPage();
});
// Test runs successfully
it('should display login', () => {
loginPage.navigateTo();
expect(loginPage.getLoginComponent().isPresent()).toBeTruthy();
});
// Test runs successfully
it('should have the login button disabled', () => {
loginPage.navigateTo();
expect(loginPage.getLoginButton().isEnabled()).toBe(false);
});
// Test runs fails
it('should redirect to a secure page', () => {
loginPage.navigateTo();
loginPage.login();
expect(loginPage.getSecurePage().isPresent()).toBeTruthy();
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});
Using the above code the test 'should redirect to a secure page'
is failing. This test is trying to verify that after a successful login, the "secure content" component is displayed. This component is a wrapper component to host the pages that can only be displayed if a user is logged in.
The page redirect is always successful, and the correct page is being displayed. My suspicion is that somehow the test is trying to get the element being before actually redirecting?
I'm new to E2E so I'm not entirely sure if this is the issue.
Just in case here's the version number of the important packages:
- Angular: 8.2.14
- Angular CLI: 8.2.2
- Protractor: 5.4.2
- Jasmine: 2.8.0