Reputation: 89
I realize this question has been asked before, but I haven't found an answer that I understand yet. I am still new to asynchronous programming, and I'm having a difficult time trying to figure out how to do the simplest things in Protractor/Javascript.
For example, how do I construct the function "isVisible" following this algorithm:
// Given an on-screen element:
function isVisible(element) {
if (element does NOT exist) {
return false; // If the element doesn't exist, it isn't visible
} else {
if (element is currently visible) {
// For simplicity, I don't care at this point if it's visible on screen
return true;
} else {
return false;
}
}
}
This function should NEVER, EVER, UNDER ANY CIRCUMSTANCES return an error, exception, or fail in any way.
Further restrictions, do not incorporate an "expect" clause, because that is the province of whatever function is calling "isVisible". The function should return a Promise.
jQuery is also not an option.
Please help, because I'm just not getting it. Also, if you could please explain why you construct your solution as you do, that would be immensely helpful.
Thanks in advance, Dave
Upvotes: 0
Views: 338
Reputation: 89
Thank you Gunderson, your solution is essentially the same as the one I figured out:
exports.isVisible = (element) => {
return new Promise((resolve) => {
element.isPresent().then((elmPresent) => {
if (!elmPresent) {
resolve(false);
} else {
element.isDisplayed().then((elmDisplayed) => {
resolve(elmDisplayed);
});
}
});
});
}
Like I said, I'm still fairly new to Protractor, Promises, etc. I didn't realize that I could return the result of isPresent as my promise (although it makes perfect sense now that you've shown me), and I didn't know that I could return a scalar value without using resolve.
In response to your follow up question, isDisplayed() throws an error if the element does not exist (at least that's what it is doing in our framework). In our application, sometimes the target element is hidden, and other times it just hasn't been added to the DOM (yet). I don't want it to fail just because it isn't defined in the DOM.
I would have bumped the score on your answer, but SO won't let me. I don't have any reputation
Upvotes: 0
Reputation: 3268
I'm still not following how this will be used reliably, but here's the protractor equivalent of your pseudo code:
isVisible(el) {
return el.isPresent().then((present) => {
if (!present) {
console.log('block 1: el does not exist');
return false; // If the element doesn't exist, it isn't visible
} else {
return el.isDisplayed().then((displayed) => {
if (displayed) {
console.log('block 2: el exists AND visible');
// For simplicity, I don't care at this point if it's visible on screen
return true;
} else {
console.log('block 3: el exists but NOT visible');
return false;
}
})
}
});
};
I tried it with an element that (1) did not exist at all, (2) existed AND visible, (3) existed but NOT visible. This function hits all 3 blocks. And since isPresent
and isDisplayed
both return promises, this function also returns a promise by returning those.
The reason I dont really understand what you want this for is because, as you can see, my solution is based purely on protractor functions. That is essentially the equivalent of this:
// this exists but is not visible
expect(el.isPresent()).toBe(true);
expect(el.isDisplayed()).toBe(false);
// this exists AND visible
expect(el.isDisplayed()).toBe(true);
// this does not exist at all
expect(el.isPresent()).toBe(false);
Upvotes: 0
Reputation: 495
If you have jQuery in your project the solution is easy:
function isVisible(element){
var $el = $(element);
if (!$el.length)
return false;
else
if (!$el.is(":visible"))
return false;
return true;
}
Upvotes: 1