1

I feel like I'm missing something here, but can't quite figure it out even after reading all the other Stackoverflow questions on nested promises.

Using selenium to get a text value of an element, I use that text later, but it's null unless I manually put in a wait...

var someText = "";
await driver.findElement(By.css("span[title='crazyValue']")).then(function (element) {
    element.getText().then(function (text) {
        console.log("someText : " + text);
        someText = text;
    });
});

//Use someText variable immediately and it's blank...  My current solution adds an await new Promise(resolve => setTimeout(resolve, 2000)); to delay execution...

How do I make the findElement promise also wait on the inner getText promise?

Per comment, this works:

var someText = "";
await driver.findElement(By.css("span[title='crazyValue']")).then(function (element) {
    return element.getText().then(function (text) {
        console.log("someText : " + text);
        someText = text;
    });
});

But also, I think written better it should be this:

var someText = "";
await driver.findElement(By.css("span[title='crazyValue']")).then(function (element) {
    return element.getText();
}).then(function (text) {
        console.log("someText : " + text);
        someText = text;
});
Brad
  • 1,684
  • 4
  • 20
  • 36
  • 2
    1. use `return` in front of `element.getText()`, 2. (improvement) [don't treat promises as callbacks](https://stackoverflow.com/questions/22539815/arent-promises-just-callbacks) – VLAZ Feb 10 '22 at 17:04
  • Can you elaborate on how to implement the improvement in my code above? Implementing a return did work... – Brad Feb 10 '22 at 17:07
  • 2
    Don't use `.then()` nested inside another `.then()`. Promises are specifically designed to avoid that. `p.then(x => x.foo().then(y => y.bar())` is easier expressed as `p.then(x => x.foo()).then(y => y.bar())` eliminating the nested calls. – VLAZ Feb 10 '22 at 17:11
  • The combination of `.then` and `await` is a code-smell. If you're in an `async` function, then just use `await`. – Richard Deeming Feb 10 '22 at 17:27

1 Answers1

1

Since you're already in an async function, use await on all promises, rather than calling .then(...):

const element = await driver.findElement(By.css("span[title='crazyValue']"));
const someText = await element.getText();
console.log("someText:", someText);

async function - JavaScript | MDN

Richard Deeming
  • 29,830
  • 10
  • 79
  • 151