Reputation: 13
I am pretty new to Protractor and I am using it with conjunction with chai and chai-as-promised. Currently I am trying to figure out how to best handle a situation, when my ElementArrayFinder
doesn't contain the elements that I need.
For an ElementFinder
(no Array) it seems pretty simple:
element(by.css('.neverthere')).isPresent().then(function(value){
console.log('IsPresent() for .neverthere is: ', value, '\n');
});
The code above doesn't throw an exception and isPresent()
returns false
, once the promise is evaluated.
Once I start using ElementArrayFinders
, it gets more complicated:
var el = element.all(by.repeater(
'property in propertyPanel.properties'))
.first()
.all(by.css('.neverthere'))
.first();
el.isPresent().then(function(value){
console.log('IsPresent() for ', name, ' is: ', value, '\n');
});
The code above throws an Error: Index out of bound.
exception for the evaluation of isPresent()
, when the array, on which first()
is evaluated, is empty.
Is there a way to access elements from an ElementArrayFinder
, so that - if the element isn't present - an ElementFinder
is returned that answers 'false' to isPresent()
, instead of throwing an exception?
Upvotes: 1
Views: 2862
Reputation: 76
Maybe it is a bit late, but anyway will put it there. Yesterday I faced exactly the same issue, and after brief investigation of protractor's sources found one interesting method:
ElementArrayFinder.prototype.toElementFinder_ = function() {
return new ElementFinder(this.ptor_, this);
};
And realized that all ElementFinder instances being costracted from ElementArrayFinder instances and just tooks first element from it, throws "No element found using locator" in case if ElementArrayFinder doesn't contain any elements and puts a warning "more than one element found for locator" in case there are more than one element in ElementArrayFinder.
So, as a workaround for "Error: Index out of bound." in isPresent() on element received from ElementArrayFinder.prototype.first we can use internal method ElementArrayFinder.prototype.toElementFinder_ like this:
var el = element.all(by.repeater(
'property in propertyPanel.properties'))
.first()
.all(by.css('.neverthere'))
.toElementFinder_();
el.isPresent().then(function(value){
console.log('IsPresent() for ', name, ' is: ', value, '\n');
});
Example above will work as expected: exactly as
element(by.css('.neverthere')).isPresent().then(function(value){})
does.
Upvotes: 1
Reputation: 473903
If I understand correctly, you can just assert that the count of elements found is 0:
var elements = element.all(by.repeater('property in propertyPanel.properties')).all(by.css('.neverthere'));
expect(elements.count()).toBe(0);
Using first()
in conjunction with browser.isElementPresent()
:
var elements = element.all(by.repeater('property in propertyPanel.properties')).all(by.css('.neverthere'));
expect(browser.isElementPresent(elements.first()).toBe(false);
Upvotes: 1
Reputation: 5274
syntext error in your code, you have add the index for second element finder
var el = element.all(by.repeater(
'property in propertyPanel.properties')).get(0)
.all(by.css('.neverthere'))
.first();
Upvotes: 0