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

Commit

Permalink
fix(repeaters): allow finding all rows of a repeater
Browse files Browse the repository at this point in the history
Now, finding an element with the strategy 'protractor.By.repeater()' returns
a promise which will resolve to an array of WebElements, where each WebElement
is a row in the repeater. Closes #149.
  • Loading branch information
juliemr committed Oct 9, 2013
1 parent 8154adf commit e45ceaa
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 49 deletions.
27 changes: 27 additions & 0 deletions lib/clientsidescripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,33 @@ clientSideScripts.findBindings = function() {
return rows[index - 1];
};

/**
* Find all rows of an ng-repeat.
*
* arguments[0] {Element} The scope of the search.
* arguments[1] {string} The text of the repeater, e.g. 'cat in cats'.
*
* @return {Array.<Element>} All rows of the repeater.
*/
clientSideScripts.findAllRepeaterRows = function() {
var using = arguments[0] || document;
var repeater = arguments[1];

var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat';
var repeatElems = using.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeatElems[i].getAttribute(attr).indexOf(repeater) != -1) {
rows.push(repeatElems[i]);
}
}
}
return rows;
};

/**
* Find an element within an ng-repeat by its row and column.
*
Expand Down
17 changes: 17 additions & 0 deletions lib/locators.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,17 @@ ProtractorBy.prototype.textarea = function(model) {
* // Returns a promise that resolves to an array of WebElements from a column
* var ages = ptor.findElements(
* protractor.By.repeater("cat in pets").column("{{cat.age}}"));
* // Returns a promise that resolves to an array of WebElements containing
* // all rows of the repeater.
* var rows = ptor.findElements(protractor.By.repeater("cat in pets"));
*/
ProtractorBy.prototype.repeater = function(repeatDescriptor) {
return {
findArrayOverride: function(driver, using) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findAllRepeaterRows),
using, repeatDescriptor);
},
row: function(index) {
return {
findOverride: function(driver, using) {
Expand All @@ -137,6 +145,15 @@ ProtractorBy.prototype.repeater = function(repeatDescriptor) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findRepeaterColumn),
using, repeatDescriptor, binding);
},
row: function(index) {
return {
findOverride: function(driver, using) {
return driver.findElement(
webdriver.By.js(clientSideScripts.findRepeaterElement),
using, repeatDescriptor, index, binding);
}
};
}
};
}
Expand Down
143 changes: 94 additions & 49 deletions spec/findelements_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,63 +97,108 @@ describe('finding elements', function() {
});
});

it('should find a repeater by partial match', function() {
var fullMatch = ptor.findElement(
protractor.By.repeater('baz in days | filter:\'T\'').
row(1).column('{{baz}}'));
expect(fullMatch.getText()).toEqual('Tue');

var partialMatch = ptor.findElement(
protractor.By.repeater('baz in days').row(1).column('b'));
expect(partialMatch.getText()).toEqual('Tue');

var partialRowMatch = ptor.findElement(
protractor.By.repeater('baz in days').row(1));
expect(partialRowMatch.getText()).toEqual('Tue');
});
describe('by repeater', function() {
it('should find by partial match', function() {
var fullMatch = ptor.findElement(
protractor.By.repeater('baz in days | filter:\'T\'').
row(1).column('{{baz}}'));
expect(fullMatch.getText()).toEqual('Tue');

var partialMatch = ptor.findElement(
protractor.By.repeater('baz in days').row(1).column('b'));
expect(partialMatch.getText()).toEqual('Tue');

var partialRowMatch = ptor.findElement(
protractor.By.repeater('baz in days').row(1));
expect(partialRowMatch.getText()).toEqual('Tue');
});

it('should find a repeater using data-ng-repeat', function() {
var byRow =
ptor.findElement(protractor.By.repeater('day in days').row(3));
expect(byRow.getText()).toEqual('Wed');
it('should return all rows when unmodified', function() {
var all =
ptor.findElements(protractor.By.repeater('dayColor in dayColors'));
all.then(function(arr) {
expect(arr.length).toEqual(3);
expect(arr[0].getText()).toEqual('Mon red');
expect(arr[1].getText()).toEqual('Tue green');
expect(arr[2].getText()).toEqual('Wed blue');
});
});

var byCol =
ptor.findElement(protractor.By.repeater('day in days').row(3).
column('day'));
expect(byCol.getText()).toEqual('Wed');
});
it('should return a single column', function() {
var colors = ptor.findElements(
protractor.By.repeater('dayColor in dayColors').column('color'));
colors.then(function(arr) {
expect(arr.length).toEqual(3);
expect(arr[0].getText()).toEqual('red');
expect(arr[1].getText()).toEqual('green');
expect(arr[2].getText()).toEqual('blue');
});
});

it('should find a repeater using ng:repeat', function() {
var byRow =
ptor.findElement(protractor.By.repeater('bar in days').row(3));
expect(byRow.getText()).toEqual('Wed');
it('should return a single row', function() {
var secondRow = ptor.findElement(
protractor.By.repeater('dayColor in dayColors').row(2));
expect(secondRow.getText()).toEqual('Tue green');
});

var byCol =
ptor.findElement(protractor.By.repeater('bar in days').row(3).
column('bar'));
expect(byCol.getText()).toEqual('Wed');
});
it('should return an individual cell', function() {
var secondColor = ptor.findElement(
protractor.By.repeater('dayColor in dayColors').
row(2).
column('color'));

it('should find a repeater using ng_repeat', function() {
var byRow =
ptor.findElement(protractor.By.repeater('foo in days').row(3));
expect(byRow.getText()).toEqual('Wed');
var secondColorByColumnFirst = ptor.findElement(
protractor.By.repeater('dayColor in dayColors').
column('color').
row(2));

var byCol =
ptor.findElement(protractor.By.repeater('foo in days').row(3).
column('foo'));
expect(byCol.getText()).toEqual('Wed');
});
expect(secondColor.getText()).toEqual('green');
expect(secondColorByColumnFirst.getText()).toEqual('green');
});

it('should find a repeater using x-ng-repeat', function() {
var byRow =
ptor.findElement(protractor.By.repeater('qux in days').row(3));
expect(byRow.getText()).toEqual('Wed');
it('should find a using data-ng-repeat', function() {
var byRow =
ptor.findElement(protractor.By.repeater('day in days').row(3));
expect(byRow.getText()).toEqual('Wed');

var byCol =
ptor.findElement(protractor.By.repeater('qux in days').row(3).
column('qux'));
expect(byCol.getText()).toEqual('Wed');
var byCol =
ptor.findElement(protractor.By.repeater('day in days').row(3).
column('day'));
expect(byCol.getText()).toEqual('Wed');
});

it('should find using ng:repeat', function() {
var byRow =
ptor.findElement(protractor.By.repeater('bar in days').row(3));
expect(byRow.getText()).toEqual('Wed');

var byCol =
ptor.findElement(protractor.By.repeater('bar in days').row(3).
column('bar'));
expect(byCol.getText()).toEqual('Wed');
});

it('should find using ng_repeat', function() {
var byRow =
ptor.findElement(protractor.By.repeater('foo in days').row(3));
expect(byRow.getText()).toEqual('Wed');

var byCol =
ptor.findElement(protractor.By.repeater('foo in days').row(3).
column('foo'));
expect(byCol.getText()).toEqual('Wed');
});

it('should find using x-ng-repeat', function() {
var byRow =
ptor.findElement(protractor.By.repeater('qux in days').row(3));
expect(byRow.getText()).toEqual('Wed');

var byCol =
ptor.findElement(protractor.By.repeater('qux in days').row(3).
column('qux'));
expect(byCol.getText()).toEqual('Wed');
});
});

it('should determine if an element is present', function() {
Expand Down
4 changes: 4 additions & 0 deletions testapp/app/partials/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
<span id="letterlist">{{check.w}}{{check.x}}{{check.y}}{{check.z}}</span>

<ul><li ng-repeat="baz in days | filter:'T'">{{baz}}</li></ul>
<ul><li ng-repeat="dayColor in dayColors">
<span>{{dayColor.day}}</span>
<span>{{dayColor.color}}</span>
</li></ul>
<ul><li data-ng-repeat="day in days">{{day}}</li></ul>
<ul><li ng:repeat="bar in days">{{bar}}</li></ul>
<ul><li ng_repeat="foo in days">{{foo}}</li></ul>
Expand Down

0 comments on commit e45ceaa

Please sign in to comment.