Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
fix(element): return not present when an element disappears
Browse files Browse the repository at this point in the history
  • Loading branch information
hankduan committed Mar 8, 2015
1 parent 8a3412e commit 2a765c7
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
18 changes: 17 additions & 1 deletion lib/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,23 @@ ElementArrayFinder.prototype.toElementFinder_ = function() {
*/
ElementArrayFinder.prototype.count = function() {
return this.getWebElements().then(function(arr) {
return arr.length;
var list = arr.map(function(webElem) {
// Calling any method forces a staleness check
return webElem.isEnabled().then(function() {
return 1; // is present
}, function(err) {
if (err.code == webdriver.error.ErrorCode.STALE_ELEMENT_REFERENCE) {
return 0; // not present
} else {
throw err;
}
});
});
return webdriver.promise.all(list).then(function(presenceArr) {
return presenceArr.reduce(function(acc, isPresent) {
return acc + isPresent;
}, 0);
});
}, function(err) {
if (err.code == webdriver.error.ErrorCode.NO_SUCH_ELEMENT) {
return 0;
Expand Down
11 changes: 11 additions & 0 deletions spec/basic/elements_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,17 @@ describe('ElementArrayFinder', function() {
expect(element.all(by.binding('doesnotexist')).count()).toEqual(0);
});

it('should return not present when an element disappears within an array',
function() {
browser.get('index.html#/form');
element.all(by.model('color')).then(function(elements) {
var disappearingElem = elements[0];
expect(disappearingElem.isPresent()).toBeTruthy();
browser.get('index.html#/bindings');
expect(disappearingElem.isPresent()).toBeFalsy();
});
});

This comment has been minimized.

Copy link
@Droogans

Droogans Jul 20, 2015

Why are you calling .then on an ElementArrayFinder without invoking some method on it first? This is typically how ElementFinders are used. What's the difference here?

This comment has been minimized.

Copy link
@hankduan

hankduan Jul 20, 2015

Author Contributor

This is an implementation-specific test. Calling .then on elementArrayFinder returns a list of raw webElements, wrapped in elementFinders. This test makes sure that isPresent returns false.
See #1903

This comment has been minimized.

Copy link
@Droogans

Droogans Jul 20, 2015

I read the issue thread. Is this the direction that the project will be taking, where protractor will be responsible for continuously re-fetching web elements on behalf of the user to avoid stale element reference errors?

This comment has been minimized.

Copy link
@hankduan

hankduan Jul 20, 2015

Author Contributor

Actually I'm not sure where this is going. No, protractor never re-fetches web elements for the user. But, if you use elementFinder/elementArrayFinder, protractor will retrieve your webelement only when you perform the action. If you have a specific issues, where this 're-fetching' thing you're talking about is causing a problem, please file an issue.

This comment has been minimized.

Copy link
@Droogans
it('should get an element from an array', function() {
var colorList = element.all(by.model('color'));

Expand Down

0 comments on commit 2a765c7

Please sign in to comment.