I'm trying to use async
/ await
with protractor
in TypeScript
. I'm following the example at: https://github.com/angular/protractor/tree/master/exampleTypescript/asyncAwait
It's working fine in my experiments. However, I have to use await
on every calls related to browser interactions.
For example:
I have a page object for a login page:
login.ts:
import {browser, element, by, By, $, $$, ExpectedConditions} from "protractor";
import { DashboardPage } from "./dashboard";
export class LoginPage {
usernameInput = element(by.id("username"));
passwordInput = element(by.id("password"));
loginButton = element(by.id("login_button"));
async get() {
await browser.get(login_url);
return this;
}
async getTitle() {
let title = await browser.getTitle();
return title;
}
async typeUsername(username: string) {
await this.usernameInput.sendKeys(username);
}
async typePassword(password: string) {
await this.passwordInput.sendKeys(password);
}
async login() {
await this.loginButton.click();
return new DashboardPage();
}
}
LoginSpec.ts:
import {browser, element, by, By, $, $$, ExpectedConditions} from "protractor";
import { LoginPage } from "../pages/login";
describe("Login Page", function() {
beforeEach(() => {
// login page is not an angular page.
browser.ignoreSynchronization = true;
});
afterEach(() => {
browser.ignoreSynchronization = false;
});
it("should go to dashboard page after successfully login", async (): Promise<any> => {
let loginPage = new LoginPage();
await loginPage.get();
await loginPage.typeUsername(username);
await loginPage.typePassword(password);
let dashboard = await loginPage.login();
expect(await dashboard.getTitle()).toEqual(`Dashboard`);
});
});
In the above test spec, I have to use many await
for all the calls to browser interactions. That introduces a lot of boilerplate for await
.
The question is, is there any idea or way to reduce the boilerplate? Also, is this the right way to use async
/ await
with protractor
?
Unfortunately without all these awaits - your code won't be synchronized properly. There are couple of cases when you could omit pasting await - but most of the cases this is necessary, since awaits makes your promises schedule one by one.
Async/Await is still relying on Promises. So your await code works identically to this:
it("should go to dashboard page after successfully login", (): Promise<any> => {
let loginPage = new LoginPage();
return loginPage.get().then(() => {
return loginPage.typeUsername(username);
}).then(() => {
return loginPage.typePassword(password);
}).then(()=> {
return loginPage.login();
}).then((dashboard)=> {
return expect(dashboard.getTitle()).toEqual(`Dashboard`);
})
});
So consider awaits like a nice syntax sugar over promise chaining: https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs#option-1-use-classic-promise-chaining
But there is a way to synchronize without putting awaits\thens\generators\callbacks . It called 'fibers'. Unfortunately protractor does not support this, but WebdriverIO uses it to synchronize code: https://www.facebook.com/ProtractorAngularJS/posts/1950761568515087
You can easily run these in sequence without using await
, but I recommend sticking with await for readability.
Here is how your code might look without await
.
import { LoginPage } from "../pages/login";
describe("Login Page", function() {
// mutable crap
it("should go to dashboard page after successfully login", () => {
const loginPage = new LoginPage();
const asyncs = [
() => loginPage.get(),
() => loginPage.typeUsername(username),
() => loginPage.typePassword(password),
() => loginPage.login(),
(dashboard: Dashboard) => dashboard.getTitle()
];
const tilePromise = asyncs.reduce((promised, next) => promised.then(next));
// note the return. this is required
return titlePromise.then(dashboardTitle => {
expect(dashboardTitle).toEqual('Dashboard');
});
});
});
Again, I think await
is preferable from a readability point of view, but there is nothing in the language that mandates that you use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With