Explain about async/ await in Protractor
Asked Answered
K

1

13

I'm new to protractor. How does async/await in this function works? Can anybody explain it to me?

it('TC_01 - Verify Home page title', async () => {
    await headerPage.waitForTitleContain('Homepage', 30000);
    await expect(headerPage.getTitle()).toEqual('Homepage');
});
Kerianne answered 22/6, 2017 at 6:39 Comment(0)
S
23

This is all about asynchronous nature of JavaScript.

Currently protractor proposes several ways to handle asynchronous actions, (I didn't describe direct promise chaining, and generators here):

1) Promise Manager/ Control Flow

https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs#control-flows

This is abstraction that makes all your actions to be called one by one, like a queue. Each action returns a special object - a Promise. It represents result of async operation, that will be received in future.

2) Second way - async/await

https://ponyfoo.com/articles/understanding-javascript-async-await#using-async-await

It is new abstraction around promises objects and allows to easily chain actions one by one. Advantage is this is native language construction, instead of Promise Manager, and makes your code look like synchronized, with try/catch and other familiar constructions.

You can think of await like "suspend code execution until promise that returned from action is resolved"

But async/await still works with promises inside.

Couple of advices when using async/await with protractorJS:

  1. Make sure you disabled control flow / promise manager: https://github.com/angular/protractor/blob/master/lib/config.ts#L714 Mixing awaits with enabled control flow may lead to unpredictable results.

  2. Do not forget to prepend ALL your async actions with await (usually this is all protractor api methods). If you will forgot to do this - action without await won't be queued with other actions, so order of actions will be broken

  3. Make sure you are using nodejs that supports this - at least nodejs 7.8.x (or newer). If TypeScript is used, set compile target as "target": "es2017"

  4. To not forget where await should be used, and where is not, i can suggest to setup eslint with plugin - https://www.npmjs.com/package/eslint-plugin-no-floating-promise and configure eslint to throw errors for this rule: https://eslint.org/docs/user-guide/configuring/rules#configuring-rules

More to read: https://github.com/angular/protractor/blob/master/docs/control-flow.md

https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs#option-3-migrate-to-asyncawait

Saltpeter answered 22/6, 2017 at 13:59 Comment(2)
Step one is setting SELENIUM_PROMISE_MANAGER: false: github.com/angular/protractor/blob/5.3.0/lib/config.ts#L692. More info here: github.com/angular/protractor/blob/master/docs/async-await.mdCataphyll
a bit late to the party, but, considering OP's example: expect(); isn't a protractor action, so it might be better putting the await inside the expect: expect(await headerPage.getTitle()).toEqual('Homepage');Ramey

© 2022 - 2024 — McMap. All rights reserved.