I\'m using Protractor JS. And the site is written in Angular JS.
So I have a toggle switch. And I noticed the value in the toggle switch goes from true to false and
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
}
});
Or try this solution implemented from the top of my head, Schedules a command to test if an element is present on the page. If any errors occur while evaluating the wait, they will be allowed to propagate.
function alwaysSwitchOn(element) {
browser.driver.isElementPresent(element).then(function(isPresent) {
if (isPresent) {
isPresent = true;
}
else {
browser.driver.wait(function () {
return browser.driver.isElementPresent(element);
}, 5000);
}
// to fail the test, then uncomment this line
//expect(isPresent).toBeTruthy();
}).then(function () {
if (element.getAttribute('value') === 'OFF') {
element.click();
}
else {
// turn it OFF
element.click();
// turn it back ON
element.click();
}
});
}
fn usage is to keep trying again and again for 5 seconds till it's true
. if the element cannot be found within 5 sec
then it'll result in an error code; No such an element is found.Note, If the condition is fulfilled before wait (5s
) it'll quickly move to then(...)
.
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)
}
});
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