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

Commit

Permalink
feat(locators) Improve the map() function in element.all to resolve m…
Browse files Browse the repository at this point in the history
…ultiple promises

Resolve promises if there is an object that contains multiple promises.
Added index as a second argument to the map function callback.

Closes #392
  • Loading branch information
andresdominguez authored and juliemr committed Jan 22, 2014
1 parent 3a83f20 commit 3151ca7
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 15 deletions.
48 changes: 36 additions & 12 deletions lib/protractor.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,26 +139,50 @@ var buildElementHelper = function(ptor) {
});
};

elementArrayFinder.map = function(fn) {
/**
* Apply a map function to each element found using the locator. The
* callback receives the web element as the first argument and the index as
* a second arg.
*
* Usage:
* <ul class="menu">
* <li class="one">1</li>
* <li class="two">2</li>
* </ul>
*
* var items = element.all(by.css('.menu li')).map(function(elm, index) {
* return {
* index: index,
* text: elm.getText(),
* class: elm.getAttribute('class')
* };
* });
* expect(items).toEqual([
* {index: 0, text: '1', class: 'one'},
* {index: 0, text: '1', class: 'one'},
* ]);
*
* @param {function(webdriver.WebElement, number)} mapFn Map function that
* will be applied to each element.
* @return {!webdriver.promise.Promise} A promise that resolves to an array
* of values returned by the map function.
*/
elementArrayFinder.map = function(mapFn) {
return ptor.findElements(locator).then(function(arr) {
var list = [];
arr.forEach(function(webElem) {
var mapResult = fn(webElem);
// Is the result a promise?
if (mapResult.then) {
mapResult.then(function(value) {
list.push(value);
});
} else {
list.push(mapResult);
}
arr.forEach(function(webElem, index) {
var mapResult = mapFn(webElem, index);
// All nested arrays and objects will also be fully resolved.
webdriver.promise.fullyResolved(mapResult).then(function(resolved) {
list.push(resolved);
});
});
return list;
});
};

return elementArrayFinder;
}
};

return element;
};
Expand Down
43 changes: 40 additions & 3 deletions spec/basic/findelements_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -415,13 +415,50 @@ describe('global element function', function() {
});

it('should map each element on array and with promises', function() {
var labels = element.all(by.css('.menu li a')).map(function(elm, index) {
return {
index: index,
text: elm.getText()
};
});
browser.get('index.html#/form');

expect(labels).toEqual([
{index: 0, text: 'repeater'},
{index: 1, text: 'bindings'},
{index: 2, text: 'form'},
{index: 3, text: 'async'},
{index: 4, text: 'conflict'},
{index: 5, text: 'polling'}
]);
});

it('should map and resolve multiple promises', function() {
var labels = element.all(by.css('.menu li a')).map(function(elm) {
return elm.getText();
return {
text: elm.getText(),
inner: elm.getInnerHtml(),
outer: elm.getOuterHtml()
};
});
browser.get('index.html#/form');

expect(labels).toEqual(
['repeater', 'bindings', 'form', 'async', 'conflict', 'polling']);
var newExpected = function(expectedLabel) {
return {
text: expectedLabel,
inner: expectedLabel,
outer: '<a href="#/' + expectedLabel + '">' + expectedLabel + '</a>'
};
};

expect(labels).toEqual([
newExpected('repeater'),
newExpected('bindings'),
newExpected('form'),
newExpected('async'),
newExpected('conflict'),
newExpected('polling')
]);
});

it('should map each element from a literal and promise array', function() {
Expand Down

0 comments on commit 3151ca7

Please sign in to comment.