Migrate Protractor E2E tests to async / await
I'm really tired of long chains of .then() in Protractor E2E tests, especially when loops and checking conditions in loops are needed. Decided I need some motivation so took a look to the future: tried to migrate a small set of tests writing in async / await style.
Installed latest Node.js (7.9.0) and Protractor (5.1.1). Here comes the first surprise. "Nothing works" after disabling Selenium promise manager in Protractor config. That's why:
Fortunately, the issue is fixed a few days ago here:
Apply this fix to my local version of jasminewd and try again. "Everything works!" Well, at least browser opens the page.
Lessons learned while rewriting code:
What I have now for 3 simple tests (open web page -> validate fields and their values -> validate values can be changed; the page has 12 drop downs, a table with 13 lines / 5 fields each):
Waiting:
Happy:
Installed latest Node.js (7.9.0) and Protractor (5.1.1). Here comes the first surprise. "Nothing works" after disabling Selenium promise manager in Protractor config. That's why:
Fortunately, the issue is fixed a few days ago here:
Apply this fix to my local version of jasminewd and try again. "Everything works!" Well, at least browser opens the page.
Lessons learned while rewriting code:
- Async / await is good! The code becomes much more readable and much more easier to maintain.
- Try / catch in async / await structures allow better error message handling, which is so important for E2E tests.
- Don't try to reuse external libraries which are using callbacks. Search for alternatives using plain promises. E.g., in my case "request" had to be changed to "request-promise". If you really need to reuse same library, guess you'll need to write some wrapper functions.
- Some useful tips by Daniel Brain are a good start.
- Async / await might be a bit "mystical" if you haven't spent lots of time using plain promise chaining.
- Possibility to choose when to use Promise.all and when -- await -- this is what can be a huge benefit when writing E2E tests. Combining both allows to run in asynchronous mode what can bring value in doing so, and to wait for results "now" when needed without using lots of complex promise structures.
What I have now for 3 simple tests (open web page -> validate fields and their values -> validate values can be changed; the page has 12 drop downs, a table with 13 lines / 5 fields each):
- Test code amount changed from 209 lines to 157 lines. In both cases about 60 lines are used for user input data, rest are actual code. Haven't counted code changes in libraries, but in general - much smaller amounts.
- Test run time changed from average 37 seconds to average 30 seconds.
- No synchronizing with browser control flow steps. The code is so much easier to read.
- No additional promise arrays to control results from "for" loops. Await helps here -- resolving values and checking them can be done in same loop most of the time.
- Some error "Failed: Error: ECONNREFUSED connect ECONNREFUSED 127.0.0.1" appears sometimes. Might be related to webdriver-manager, might be related to some functions which I've migrated in incorrect way (or just forgot). I'm just not willing to investigate this today.
Waiting:
- For next Protractor build with jasminewd bugfix included. Hope we can migrate our current project if it happens soon enough.
Happy:
- We have only a few callback usages in our tests. Migration to async / await will be much easier some day. Think we'll try to get rid of callbacks before migrating.
Hi Team,
ReplyDeleteM new to protractor, and I have scenario where I want to select date from date picker,send key's don't work. Please help to solve the problem post code