2

I have the following code that uses selenium webdriver to get the text of an element:

async function getText(driver, locator) {
    return await (await driver.findElement(locator)).getText();
}

Probably some brain fog on my part, but is there a cleaner way to write this code?

I've got some other functions which will require a few more promise chains - its going to get messy, so I want to find a nice, concise way to write the functions.

The function just needs to return the text, I don't want it to return a promise.

GWed
  • 15,167
  • 5
  • 62
  • 99

1 Answers1

3

A cleaner and more readable way for promises in general is to use temporary variables:

async function getText(driver, locator) {   
    const el = await driver.findElement(locator);
    return el.getText();
}

It's unnecessary to use return await, unless you wrap it with try.

Selenium uses decorated promises that allow to schedule promise chains internally. It's possible to schedule getText action on WebElementPromise, and the result will be a promise of getText:

function getText(driver, locator) {
    return driver.findElement(locator).getText();
}

Selenium was designed this way to write synchronous-like code before the emergence of async..await. The code remains asynchronous.

The function just needs to return the text, I don't want it to return a promise.

This is a special case of this problem. Once a code is asynchronous, it cannot be made synchronous again. Once promises are involved, all call stack should use promises for correct control flow.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • If `async` function returns a promise, it is taken into account in function return. The only case it's different is when you handle errors in returned promise with `try`. – Estus Flask Feb 15 '19 at 10:44
  • It isn't the same thing. If `findVisibleElement(driver, locator)` is raw undecorated promise and doesn't have `getText` property, it won't work. If it was specifically designed to chain promises internally, it will work. I didn't check how Selenium works in this case, also I wasn't able to find the documentation on findVisibleElement to confirm this. – Estus Flask Feb 15 '19 at 10:51
  • It wasn't addressed to you in person. I would expect that `return findVisibleElement(driver, locator).getText()` work, but only because it's not regular promise that findVisibleElement returns but it was designed as a proxy. https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/webdriver_exports_WebElementPromise.html . For promises in general the answer is still applicable. – Estus Flask Feb 15 '19 at 11:01
  • i edited your answer slightly to make it clearer for anyone else that comes here. Ive removed my self written function findVisibleElement from my question to make it clearer for webdriver users – GWed Feb 15 '19 at 11:11
  • 1
    I suggest to leave the first part for completeness, since the question says about promises in general, it could be read by users who aren't interested in Selenium specifically. – Estus Flask Feb 15 '19 at 11:23