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

Commit

Permalink
fix(element): update to selenium-webdriver@2.45.1 and remove element.…
Browse files Browse the repository at this point in the history
…then

This change updates the version of WebDriverJS (selenium-webdriver node
module) from 2.44 to 2.45.1. See the full changelog at
https://github.com/SeleniumHQ/selenium/blob/master/javascript/node/selenium-webdriver/CHANGES.md

To enable the update and remove confusion, this removes the `element().then`
function unless there is an action result. This function is completely
unnecessary, because it would always resolve to itself, but the removal
may cause breaking changes.

Before:
```js
element(by.css('foo')).then(function(el) {
  return el.getText().then(...);
});
```

After:
```js
element(by.css('foo')).getText().then(...);
```

In other words, an ElementFinder is now no longer a promise until an action
has been called.

Before:
```js
var el = element(by.css('foo'));

protractor.promise.isPromise(el); // true
protractor.promise.isPromise(el.click()); // true
```

After:
```js
var el = element(by.css('foo'));

protractor.promise.isPromise(el); // false
protractor.promise.isPromise(el.click()); // true
```

Also, fixes `filter` and `map` to work with the new WebDriverJS.
  • Loading branch information
juliemr committed Mar 16, 2015
1 parent 93ccca1 commit 34f0eeb
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 84 deletions.
92 changes: 39 additions & 53 deletions lib/element.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
var util = require('util');
var webdriver = require('selenium-webdriver');
var log = require('./logger.js');
var clientSideScripts = require('./clientsidescripts.js');

var WEB_ELEMENT_FUNCTIONS = [
'click', 'sendKeys', 'getTagName', 'getCssValue', 'getAttribute', 'getText',
'getSize', 'getLocation', 'isEnabled', 'isSelected', 'submit', 'clear',
'isDisplayed', 'getOuterHtml', 'getInnerHtml', 'getId'];
'isDisplayed', 'getOuterHtml', 'getInnerHtml', 'getId', 'getRawId'];

/**
* ElementArrayFinder is used for operations on an array of elements (as opposed
Expand Down Expand Up @@ -78,7 +77,6 @@ var ElementArrayFinder = function(ptor, getWebElements, locator, opt_actionResul
};
});
};
util.inherits(ElementArrayFinder, webdriver.promise.Promise);

exports.ElementArrayFinder = ElementArrayFinder;

Expand Down Expand Up @@ -209,18 +207,17 @@ ElementArrayFinder.prototype.filter = function(filterFn) {
var elementFinder =
ElementFinder.fromWebElement_(self.ptor_, parentWebElement, self.locator_);

var filterResults = filterFn(elementFinder, index);
if (filterResults instanceof webdriver.promise.Promise) {
filterResults.then(function(satisfies) {
if (satisfies) {
list.push(parentWebElements[index]);
}
});
} else if (filterResults) {
list.push(parentWebElements[index]);
}
list.push(filterFn(elementFinder, index));
});
return webdriver.promise.all(list).then(function(resolvedList) {
var filteredElementList = [];
resolvedList.forEach(function(result, index) {
if (result) {
filteredElementList.push(parentWebElements[index]);
}
});
return filteredElementList;
});
return list;
});
};
return new ElementArrayFinder(this.ptor_, getWebElements, this.locator_);
Expand Down Expand Up @@ -533,11 +530,9 @@ ElementArrayFinder.prototype.map = function(mapFn) {
arr.forEach(function(elementFinder, index) {
var mapResult = mapFn(elementFinder, index);
// All nested arrays and objects will also be fully resolved.
webdriver.promise.fullyResolved(mapResult).then(function(resolved) {
list.push(resolved);
});
list.push(webdriver.promise.fullyResolved(mapResult));
});
return list;
return webdriver.promise.all(list);
});
};

Expand Down Expand Up @@ -637,10 +632,10 @@ ElementArrayFinder.prototype.allowAnimations = function(value) {
*
* The ElementFinder can be treated as a WebElement for most purposes, in
* particular, you may perform actions (i.e. click, getText) on them as you
* would a WebElement. ElementFinders extend Promise, and once an action
* is performed on an ElementFinder, the latest result from the chain can be
* accessed using then. Unlike a WebElement, an ElementFinder will wait for
* angular to settle before performing finds or actions.
* would a WebElement. Once an action is performed on an ElementFinder, the
* latest result from the chain can be accessed using the then method.
* Unlike a WebElement, an ElementFinder will wait for angular to settle before
* performing finds or actions.
*
* ElementFinder can be used to build a chain of locators that is used to find
* an element. An ElementFinder does not actually attempt to find the element
Expand Down Expand Up @@ -680,6 +675,28 @@ var ElementFinder = function(ptor, elementArrayFinder) {
this.ptor_ = ptor;
this.parentElementArrayFinder = elementArrayFinder;

// Only have a `then` method if the parent element array finder
// has action results.
if (this.parentElementArrayFinder.actionResults_) {
/**
* Access the underlying actionResult of ElementFinder.
*
* @param {function(webdriver.promise.Promise)} fn Function which takes
* the value of the underlying actionResult.
*
* @return {webdriver.promise.Promise} Promise which contains the results of
* evaluating fn.
*/
this.then = function(fn, errorFn) {
return this.elementArrayFinder_.then(function(actionResults) {
if (!fn) {
return actionResults[0];
}
return fn(actionResults[0]);
}, errorFn);
};
}

// This filter verifies that there is only 1 element returned by the
// elementArrayFinder. It will warn if there are more than 1 element and
// throw an error if there are no elements.
Expand Down Expand Up @@ -717,7 +734,6 @@ var ElementFinder = function(ptor, elementArrayFinder) {
};
});
};
util.inherits(ElementFinder, webdriver.promise.Promise);

exports.ElementFinder = ElementFinder;

Expand Down Expand Up @@ -770,25 +786,6 @@ ElementFinder.prototype.getWebElement = function() {
return new webdriver.WebElementPromise(this.ptor_.driver, id);
};

/**
* Access the underlying actionResult of ElementFinder. Implementation allows
* ElementFinder to be used as a webdriver.promise.Promise
*
* @param {function(webdriver.promise.Promise)} fn Function which takes
* the value of the underlying actionResult.
*
* @return {webdriver.promise.Promise} Promise which contains the results of
* evaluating fn.
*/
ElementFinder.prototype.then = function(fn, errorFn) {
return this.elementArrayFinder_.then(function(actionResults) {
if (!fn) {
return actionResults[0];
}
return fn(actionResults[0]);
}, errorFn);
};

/**
* Calls to {@code all} may be chained to find an array of elements within a
* parent.
Expand Down Expand Up @@ -957,17 +954,6 @@ ElementFinder.prototype.allowAnimations = function(value) {
return this.elementArrayFinder_.allowAnimations(value).toElementFinder_();
};

/**
* Webdriver relies on this function to be present on Promises, so adding
* this dummy function as we inherited from webdriver.promise.Promise, but
* this function is irrelevant to our usage
*
* @return {boolean} Always false as ElementFinder is never in pending state.
*/
ElementFinder.prototype.isPending = function() {
return false;
};

/**
* Shortcut for querying the document directly with css.
*
Expand Down
2 changes: 1 addition & 1 deletion lib/protractor.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ Protractor.prototype.findElements = function(locator) {
* the element is present on the page.
*/
Protractor.prototype.isElementPresent = function(locatorOrElement) {
var element = (locatorOrElement instanceof webdriver.promise.Promise) ?
var element = (locatorOrElement.isPresent) ?
locatorOrElement : this.element(locatorOrElement);
return element.isPresent();
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"author": "Julie Ralph <ju.ralph@gmail.com>",
"dependencies": {
"request": "~2.36.0",
"selenium-webdriver": "2.44.0",
"selenium-webdriver": "2.45.1",
"minijasminenode": "1.1.1",
"jasminewd": "1.1.0",
"jasminewd2": "0.0.2",
Expand Down
33 changes: 5 additions & 28 deletions spec/basic/elements_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,36 +157,18 @@ describe('ElementFinder', function() {
expect(successful).toEqual(false);
});

it('then function should be equivalent to itself', function() {
browser.get('index.html#/form');
var elem = element(by.binding('greeting'));

elem.then(function(elem2) {
expect(elem.getId()).toEqual(elem2.getId());
});
});

it('should not resolve to itself', function() {
browser.get('index.html#/form');
var elem1 = element(by.binding('greeting'));

elem1.then(function(result) {
expect(result === elem1).toBe(false);
});
});

it('should be returned from a helper without infinite loops', function() {
browser.get('index.html#/form');
var helperPromise = element(by.binding('greeting')).then(function(result) {
return result;
var helperPromise = protractor.promise.when(true).then(function() {
return element(by.binding('greeting'));
});

helperPromise.then(function(finalResult) {
expect(finalResult.getText()).toEqual('Hiya');
});
});

it('should be usable in WebDriver functions', function() {
it('should be usable in WebDriver functions via getWebElement', function() {
// TODO(juliemr): should be able to do this without the getWebElement call
browser.get('index.html#/form');
var greeting = element(by.binding('greeting'));
Expand Down Expand Up @@ -509,16 +491,11 @@ describe('ElementArrayFinder', function() {
'4/5: small cat\n');
});

it('should always return a promise when calling then', function() {
browser.get('index.html#/form');
var e1 = element(by.tagName('body')).then(function() {});
expect(e1 instanceof protractor.promise.Promise).toBe(true);
});

it('should allow using protractor locator within map', function() {
browser.get('index.html#/repeater');

var expected = [{ first: 'M', second: 'Monday' },
var expected = [
{ first: 'M', second: 'Monday' },
{ first: 'T', second: 'Tuesday' },
{ first: 'W', second: 'Wednesday' },
{ first: 'Th', second: 'Thursday' },
Expand Down
6 changes: 6 additions & 0 deletions spec/basic/locators_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,4 +388,10 @@ describe('locators', function() {
expect(browser.isElementPresent(by.binding('greet'))).toBe(true);
expect(browser.isElementPresent(by.binding('nopenopenope'))).toBe(false);
});

it('should determine if an ElementFinder is present', function() {
expect(browser.isElementPresent(element(by.binding('greet')))).toBe(true);
expect(browser.isElementPresent(element(by.binding('nopenopenope'))))
.toBe(false);
})
});
2 changes: 1 addition & 1 deletion spec/withLoginConf.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ exports.config = {
browser.driver.wait(function() {
return browser.driver.getCurrentUrl().then(function(url) {
return /index/.test(url);
});
}, 10000);
});
}
};

0 comments on commit 34f0eeb

Please sign in to comment.