How to create a condition in protractor for when an element exists or not
The problem is that isDisplayed()
, as a lot of methods in WebDriverJS/Protractor, returns a promise which by definition is "truthy" which makes it difficult to debug problems like this.
Let's work through an example to get a better understanding.
Imagine, you have the following code, which may look okay at the first glance:
var elm = $("#myid");
if (elm.isDisplayed()) {
// do smth
} else {
// do smth else
}
Now, it has a serious problem. do smth else
part will never be reached, since elm.isDisplayed()
is not a boolean value - it is a promise. Even if the element is not displayed, you would still have // do smth
part executed.
Instead, if you need to check the value of isDisplayed()
to use inside a conditional expression, you have to resolve the promise with then()
explicitly:
var elm = $("#myid");
elm.isDisplayed().then(function (isDisplayed) {
if (isDisplayed) {
// do smth
} else {
// do smth else
}
});
There is also a way to catch these kind of errors without even running the code - statically with ESLint
and eslint-plugin-protractor
plugin. There is a relevant rule that watches if certain Protractor methods are used inside if
conditions directly.
Here is what it would output for the code above:
$ eslint test.js
test.js
2:1 warning Unexpected "isDisplayed()" inside if condition protractor/no-promise-in-if
isDisplayed()
did not work for me. The API may have been changed. isPresent()
is my solution:
var logoutButton = element(by.css('[ng-click="log_out()"]'));
logoutButton.isPresent().then(function(result) {
if ( result ) {
logoutButton.click();
} else {
//do nothing
}
});
Remember that isDisplayed()
returns a promise, you can try with:
element(anyFinder).isDisplayed().then(function(result) {
if ( result ) {
//Whatever if it is true (displayed)
} else {
//Whatever if it is false (not displayed)
}
});