New problems like this with existing code are likely due to Protractor and Selenium evolving from Web Driver Control Flow and WebDriverJS Promise Manager to native promises. You used to be able to write code that looked like synchronous code and under the hood the toolkits would convert it to asynchronous code that waited for the DOM to load and JavaScript on the page to run. Going forward you need to convert your code to explicitly use async/await
or promises. (See the reasoning behind the Selenium change here.)
Unfortunately a lot of old (pre 2019) examples, even in the Protractor documentation, are written in synchronous style, so you should be careful about following them. Even more unfortunately, you cannot mix async
code with Control Flow code, and if you try, all the Control Flow will be disabled, and probably some of your tests that relied on it will start failing.
By the way, what is the value of bars
? A Protractor by
object works differently than a native WebDriver locator and I'm not sure they are reusable. Try using by.name('bars')
or whatever instead of bars
.
Your case is tricky because of all the promises involved. element.getCssValue
returns a promise. Since you are trying to get a true
or false
value out of this, I suggest using a reducer.
let nonZero = element.all(by.name('bars')).reduce((acc, elem) => {
return acc || elem.getCssValue('width').then( (width) => width > 0 );
}, false);
In a more complicated situation, you could use all().each()
but you have to be careful to ensure that nothing you do inside each
affects the DOM, because once it does, it potentially invalidates the rest of the array.
If you are potentially modifying the page with your ultimate action, then, as ugly as it may seem, you need to loop over finding the elements:
for (var i = 0; true; i++) {
let list = element.all(by.css('.items li'));
if (i >= await list.count();)
break;
list.get(i).click();
};
browser.wait(EC.invisibilityOf(element(loadingWrapper)), 6000);
– Isabellabrowser.wait
and only when it resolves do theelement.all(bars).each
loop. – trincotbrowser.wait
to resolve. – trincot