1

I am beginner to wdio(version 7 onwards). My question is why we put await in front of $(...) or $$(...) commands? $ and $$ retuns element object and array of elements respectively. Then why we use await in front of them? Are they returning promises?

Which of the following is correct?:

async getValue(){

return await $(some_selector).getText();
}

OR

async getValue(){

return (await $(some_selector)).getText();  //Note the paranthesis

}
a Learner
  • 4,944
  • 10
  • 53
  • 89
  • 1
    Possibly related: https://v5.webdriver.io/docs/sync-vs-async.html. Also related: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#description – starball Feb 23 '23 at 02:42

2 Answers2

1

WebDriver I/O uses, by default, an asynchronous model where all functions will be async. This means that all invocations return a promise and will need to be awaited before the result is available.

In your comment on another user's answer you linked to the latest version (v8) of the docs where sync mode is officially deprecated but you tagged v6 in your question where sync mode is still supported but, again, not enabled by default.

So, I guess, the answer to your question is a bit of both. Depending on whether you have sync mode enabled or not the functions return the elements directly or a promise that will resolve to the elements. All the examples assume that sync mode is not enabled and therefore need the async/await keywords.

Promise Chaining

From v7.9 onwards, WDIO supports promise chaining: https://blog.kiprosh.com/webdriverio-elements-chaining/

With this in mind then example 1 would be the right implementation. Although version 2 could still be correct and returns the promise that will resolve eventually to the text contents but it doesn't looks right and should probably have an extra await in there, but the code is ugly with multiple awaits and it's not as easy to read the code.

async getValue(){
  return await (await $(some_selector)).getText();
}

There's more information on promise chaining in WebdriverIO in the docs.

phuzi
  • 12,078
  • 3
  • 26
  • 50
  • And what about second part of question: Which of the following is correct?: `async getValue(){ return await $(some_selector).getText(); } ` OR `async getValue(){ return (await $(some_selector)).getText(); //Note the parenthesis }` – a Learner Feb 23 '23 at 09:38
  • See my updated answer for a quick discussion on promise chaining – phuzi Feb 23 '23 at 10:04
  • one last question: in the statements like `await $(some_selector).getText();`, the methods `getText()` or like `isDisplayed()` also returns promise compatible object or a promise? – a Learner Feb 23 '23 at 11:43
  • Not sure what the difference between "promise compatible object" and "promise" are here. In JavaScript if looks like a duck then it is a duck, so... if it looks like a Promise, then it is a Promise! – phuzi Feb 23 '23 at 14:08
0

Making a function 'async' means it's going to return a Promise regardless of whether you even use 'await' or not. For example, in an 'async' function, if you do 'return 234', the function will actually return a Promise that resolved to the number 234, even without an 'await'.

Since '$' and '$$' don't return Promises, there's no reason for these functions to be 'async' unless there's a larger design reason dictating that they be 'async'. But you haven't said that there is.

avocadatoria
  • 493
  • 3
  • 9
  • 1
    This may be correct _if_ OP is using WDIO in sync mode but they may using in default async mode where these functions need to be awaited before the result is used. – phuzi Feb 23 '23 at 09:13
  • 1
    Actually i was refering to the docs at https://webdriver.io/docs/api/element/$. In this webpage all examples are using await eg. `const text = await $('#menu'); console.log(await text.$$('li')[2].$('a').getText());`. So because I am using `await` in my statement so I am using async function. I also referred https://webdriver.io/docs/async-migration/ but no where is mentioned that $ and $$ returns a promise. – a Learner Feb 23 '23 at 09:14