Let’s understand this concept of asynchronous behavior with an example.
So, when the below code will be executed, all lines of code are executed sequentially whether the previous statement has returned result or not.
But when it comes to test automation, we need to run our code in synchronized way, so that each step is executed sequentially, as we do in Java, C#, and Python automation code.
- Callback Functions
Note — It is more complicated to write callback functions in test automation since callback functions pass as an argument to another function for later execution. Therefore, let’s ignore the callback functions for now.
Let’s understand the concept of Promise and Async/Await.
Upon successful completion of an asynchronous code, it either returns a value or an error (because of failure due to timeouts or any other reasons)
There are three possible states for a Promise:
- Pending — Initial state
- Fulfilled — Successful completion of asynchronous code
- Rejected — Failure occurs due to timeouts or any other reasons
In order to handle asynchronous code with promise, you need to return the promise object in each function. And each promise object will have a ‘then’ function which takes two functions as an argument:
- onfulfilled — The callback to execute when the Promise is resolved.
- onrejected — The callback to execute when the Promise is rejected.
Note — The then function will also return a promise, to allow chaining multiple calls as shown in the above workflow diagram.
See the below example of method chaining using then function.
One major challenge with writing code with Promise and then keywords is that you will end up writing too many then keywords to get the result. This makes your code look a bit complex to understand, read and maintain.
Let’s understand the concept of the Async/Await technique.
Async/Await is written on top of Promise to write beautiful and clean code without using then keyword.
The Async keyword is used to represent that function is asynchronous. Every async function returns a promise and with the help of await keyword, you can wait till the promise returns the success or error.
Let’s use await keyword which will wait for the promise to return a result (success or error) and then will print the result without using then keyword.
Note — The
await the keyword is only used inside the
async function to wait for the asynchronous operation.
Now let’s see how asynchronous codes are getting handled in automation tools like Cypress and Playwright.
Asynchronous Code in Cypress
Cypress commands are asynchronous and it has its own mechanism to run the enqueued asynchronous commands in sequence once the test function is completed which means you do not have to do anything additional to handle the async commands with the help of Promise, Callback, and Async/Await techniques.
Please refer to the official blog for more info.
But you might have seen ‘then’ keyword is still being used in Cypress test automation. This then keyword is not an actual promise, but it is implemented similarly and because of this reason, you can not use the async/await technique to wait for asynchronous codes to be completed.
As per Cypress blog, “After a test function is finished running, Cypress goes to work executing the commands that were enqueued using the
That’s why it is recommended to add custom wrapper methods in the custom command file as shown in below example:
And in the test script, you can call the custom added method with the help of cy instance.
Let’s see how Playwright handles async code.
Playwright uses the async/await keywords to handle the asynchronous operations in order to run the test steps sequentially. In this, you have to use the async keyword before every function and await keyword to wait for the promise to be completed.
With an example, let’s learn why Playwright uses async/await keywords.
I’ll run this code without the await keyword and see what happens.
Oh no! we got an error saying “Navigation failed because page was closed!”.
Let’s see what exactly the status of the promise is when page.goto(‘’) statement is getting executed.
As you can see, the promise is showing pending when “ let result = page.goto(“/");” statement is getting executed.
So, in order to handle asynchronous code, we need to use the await keyword to wait for the promise to be settled(success or error).
Hope you enjoyed this article !! See you in other posts.