From Sync to Async
Due to changes in V8 the WebdriverIO team announced to deprecate synchronous command execution by April 2023. The team has been working hard to make the transition as easy as possible. In this guide we explain how you can slowly migrate your test suite from sync to async. As an example project we use the Cucumber Boilerplate but the approach is the same with all other projects as well.
Promises in JavaScript
The reason why synchronous execution was popular in WebdriverIO is because it removes the complexity of dealing with promises. Particularly if you come from other languages where this concept doesn't exist this way, it can be confusing in the beginning. However Promises are a very powerful tool to deal with asynchronous code and today's JavaScript makes it actually easy to deal with it. If you never worked with Promises, we recommend to check out the MDN reference guide to it as it would be out of scope to explain it here.
Async Transition
The WebdriverIO testrunner can handle async and sync execution within the same test suite. This means that you can slowly migrate your tests and PageObjects step by step at your pace. For example, the Cucumber Boilerplate has defined a large set of step definition for you to copy into your project. We can go ahead and migrate one step definition or one file at a time.
WebdriverIO offers a codemod that allows to transform your sync code into async code almost full automatically. Run the codemod as described in the docs first and use this guide for manual migration if needed.
In many cases, everything that is necessary to do is to make the function in which you call WebdriverIO commands async
and add an await
in front of every command. Looking at the first file clearInputField.ts
to transform in the boilerplate project, we transform from:
export default (selector: Selector) => {
$(selector).clearValue();
};
to:
export default async (selector: Selector) => {
await $(selector).clearValue();
};
That's it. You can see the complete commit with all rewrite examples here:
Commits:
- transform all step definitions [af6625f]
This transition is independent of whether you use TypeScript or not. If you use TypeScript just make sure that you eventually change the types
property in your tsconfig.json
from webdriverio/sync
to @wdio/globals/types
. Also make sure that your compile target is set to at least ES2018
.
Special Cases
There are of course always special cases where you need to pay a bit more attention.