5
votes

How do I use async and await in protractor tests?

it('test async', function(){
    var value = 0;
    function asyncAction() {
        return browser.driver.wait(()=>true)
            .then(function () {
                console.log('a');
                return value++;
            });
    }
    //-Problem Area-
    async function doAwait(){
        await asyncAction();
        return asyncAction();
    }

    doAwait();

    protractor.promise.controlFlow().execute( () => {
        console.log('b');
        expect(value).toBe(2);
    });
});

output here is

  • a
  • b
  • a

and value is 1 at time of expect function doAwait(){ await asyncAction(); return asyncAction(); }

I like to think of this as similar to

function doAwait(){
  asyncAction().then(()=>asyncAction());
}

Which works but the above async doAwait does not. I believe this is because the generator breaks the ControlFlow of selenium.

2
You already got this "I believe this is because the generator breaks the ControlFlow of selenium." - nilesh
I'm curious to know how you tested this. My IDE only supports until ECMA 6 - nilesh
require('babel-register')({ plugins: ['transform-async-to-generator'] }); - TrevDev

2 Answers

4
votes

Adding this to the protractor configuration works:

var webdriver = require.main.require('selenium-webdriver');
Promise = webdriver.promise.Promise;
Object.assign(Promise, webdriver.promise);
Promise.resolve = Promise.fulfilled;
Promise.reject = Promise.rejected;

Though maybe not all promises are supposed to be managed promises?

Worth noting that the other solution requires wrapping each async function:

protractor.promise.controlFlow().execute( async () => {
    await asyncAction();
    return asyncAction();
});
0
votes

See https://github.com/angular/jasminewd#async-functions--await:

async functions / await

async functions and the await keyword are likely coming in ES2017 (ES8), and available via several compilers. At the moment, they often break the WebDriver control flow. (GitHub issue). You can still use them, but if you do then you will have to use await/Promises for almost all your synchronization. See spec/asyncAwaitAdapterSpec.ts and spec/asyncAwaitErrorSpec.ts for examples.