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

Commit

Permalink
feat(by.repeat) by.repeat support for multi ng-repeat
Browse files Browse the repository at this point in the history
Make by.repeat (and its column and row friends) work with ng-repeat-start
and ng-repeat-end elements.

Closes #366. Closes #182.
  • Loading branch information
juliemr committed Dec 23, 2013
1 parent 35d92a2 commit 6a73a25
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 25 deletions.
148 changes: 129 additions & 19 deletions lib/clientsidescripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,24 @@ clientSideScripts.findBindings = function() {
};

/**
* Find an array of elements matching a row within an ng-repeat. Always returns
* an array of only one element.
* Find an array of elements matching a row within an ng-repeat.
* Always returns an array of only one element for plain old ng-repeat.
* Returns an array of all the elements in one segment for ng-repeat-start.
*
* arguments[0] {Element} The scope of the search.
* arguments[1] {string} The text of the repeater, e.g. 'cat in cats'.
* arguments[2] {number} The row index.
*
* @return {Array.<Element>} An array of a single element, the row of the
* repeater.
* @return {Array.<Element>} The row of the repeater, or an array of elements
* in the first row in the case of ng-repeat-start.
*/
clientSideScripts.findRepeaterRows = function() {
var using = arguments[0] || document;
var repeater = arguments[1];
var index = arguments[2];

var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
var rows = [];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat';
var repeatElems = using.querySelectorAll('[' + attr + ']');
Expand All @@ -80,7 +81,29 @@ clientSideScripts.findBindings = function() {
}
}
}
return [rows[index]];
// multiRows is an array of arrays, where each inner array contains
// one row of elements.
var multiRows = [];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat-start';
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) {
var elem = repeatElems[i];
var row = [];
while (elem.nodeType != 8 ||
elem.nodeValue.indexOf(repeater) == -1) {
if (elem.nodeType == 1) {
row.push(elem);
}
elem = elem.nextSibling;
}
multiRows.push(row);
}
}
}
return [rows[index]].concat(multiRows[index]);
};

/**
Expand All @@ -107,6 +130,22 @@ clientSideScripts.findBindings = function() {
}
}
}
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat-start';
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) {
var elem = repeatElems[i];
var row = [];
while (elem.nodeType != 8 ||
elem.nodeValue.indexOf(repeater) == -1) {
rows.push(elem);
elem = elem.nextSibling;
}
}
}
}
return rows;
};

Expand Down Expand Up @@ -139,14 +178,51 @@ clientSideScripts.findRepeaterElement = function() {
}
}
}
// multiRows is an array of arrays, where each inner array contains
// one row of elements.
var multiRows = [];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat-start';
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) {
var elem = repeatElems[i];
var row = [];
while (elem.nodeType != 8 ||
(elem.nodeValue && elem.nodeValue.indexOf(repeater) == -1)) {
if (elem.nodeType == 1) {
row.push(elem);
}
elem = elem.nextSibling;
}
multiRows.push(row);
}
}
}
var row = rows[index];
var multiRow = multiRows[index];
var bindings = [];
if (row.className.indexOf('ng-binding') != -1) {
bindings.push(row);
if (row) {
if (row.className.indexOf('ng-binding') != -1) {
bindings.push(row);
}
var childBindings = row.getElementsByClassName('ng-binding');
for (var i = 0; i < childBindings.length; ++i) {
bindings.push(childBindings[i]);
}
}
var childBindings = row.getElementsByClassName('ng-binding');
for (var i = 0; i < childBindings.length; ++i) {
bindings.push(childBindings[i]);
if (multiRow) {
for (var i = 0; i < multiRow.length; ++i) {
rowElem = multiRow[i];
if (rowElem.className.indexOf('ng-binding') != -1) {
bindings.push(rowElem);
}
var childBindings = rowElem.getElementsByClassName('ng-binding');
for (var j = 0; j < childBindings.length; ++j) {
bindings.push(childBindings[j]);
}
}
}
for (var i = 0; i < bindings.length; ++i) {
var dataBinding = angular.element(bindings[i]).data('$binding');
Expand Down Expand Up @@ -187,22 +263,56 @@ clientSideScripts.findRepeaterColumn = function() {
}
}
}
// multiRows is an array of arrays, where each inner array contains
// one row of elements.
var multiRows = [];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat-start';
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) {
var elem = repeatElems[i];
var row = [];
while (elem.nodeType != 8 ||
(elem.nodeValue && elem.nodeValue.indexOf(repeater) == -1)) {
if (elem.nodeType == 1) {
row.push(elem);
}
elem = elem.nextSibling;
}
multiRows.push(row);
}
}
}
var bindings = [];
for (var i = 0; i < rows.length; ++i) {
var bindings = [];
if (rows[i].className.indexOf('ng-binding') != -1) {
bindings.push(rows[i]);
}
var childBindings = rows[i].getElementsByClassName('ng-binding');
for (var k = 0; k < childBindings.length; ++k) {
bindings.push(childBindings[k]);
}
for (var j = 0; j < bindings.length; ++j) {
var dataBinding = angular.element(bindings[j]).data('$binding');
if(dataBinding) {
var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[j]);
}
}
for (var i = 0; i < multiRows.length; ++i) {
for (var j = 0; j < multiRows[i].length; ++j) {
var elem = multiRows[i][j];
if (elem.className.indexOf('ng-binding') != -1) {
bindings.push(elem);
}
var childBindings = elem.getElementsByClassName('ng-binding');
for (var k = 0; k < childBindings.length; ++k) {
bindings.push(childBindings[k]);
}
}
}
for (var j = 0; j < bindings.length; ++j) {
var dataBinding = angular.element(bindings[j]).data('$binding');
if (dataBinding) {
var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[j]);
}
}
}
Expand Down
57 changes: 51 additions & 6 deletions spec/basic/findelements_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ describe('locators', function() {
expect(arr[2].getText()).toBe('blue');
});
});


});

describe('by repeater', function() {
Expand All @@ -153,7 +151,7 @@ describe('locators', function() {

it('should return all rows when unmodified', function() {
var all =
browser.findElements(by.repeater('allinfo in days'));
element.all(by.repeater('allinfo in days'));
all.then(function(arr) {
expect(arr.length).toEqual(5);
expect(arr[0].getText()).toEqual('M Monday');
Expand All @@ -163,7 +161,7 @@ describe('locators', function() {
});

it('should return a single column', function() {
var initials = browser.findElements(
var initials = element.all(
by.repeater('allinfo in days').column('initial'));
initials.then(function(arr) {
expect(arr.length).toEqual(5);
Expand All @@ -172,7 +170,7 @@ describe('locators', function() {
expect(arr[2].getText()).toEqual('W');
});

var names = browser.findElements(
var names = element.all(
by.repeater('allinfo in days').column('name'));
names.then(function(arr) {
expect(arr.length).toEqual(5);
Expand Down Expand Up @@ -253,7 +251,54 @@ describe('locators', function() {
// There are only 5 rows, so the 6th row is not present.
expect(element(by.repeater('allinfo in days').row(5)).isPresent()).
toBe(false);
})
});

describe('repeaters using ng-repeat-start and ng-repeat-end', function() {
it('should return all elements when unmodified', function() {
var all =
element.all(by.repeater('bloop in days'));

all.then(function(arr) {
expect(arr.length).toEqual(3 * 5);
expect(arr[0].getText()).toEqual('M');
expect(arr[1].getText()).toEqual('-');
expect(arr[2].getText()).toEqual('Monday');
expect(arr[3].getText()).toEqual('T');
expect(arr[4].getText()).toEqual('-');
expect(arr[5].getText()).toEqual('Tuesday');
});
});

it('should return a group of elements for a row', function() {
var firstRow = element.all(by.repeater('bloop in days').row(0));

firstRow.then(function(arr) {
expect(arr.length).toEqual(3);
expect(arr[0].getText()).toEqual('M');
expect(arr[1].getText()).toEqual('-');
expect(arr[2].getText()).toEqual('Monday');
});
});

it('should return a group of elements for a column', function() {
var nameColumn = element.all(
by.repeater('bloop in days').column('name'));

nameColumn.then(function(arr) {
expect(arr.length).toEqual(5);
expect(arr[0].getText()).toEqual('Monday');
expect(arr[1].getText()).toEqual('Tuesday');
});
});

it('should find an individual element', function() {
browser.debugger();
var firstInitial = element(
by.repeater('bloop in days').row(0).column('bloop.initial'));

expect(firstInitial.getText()).toEqual('M');
});
});
});

it('should determine if an element is present', function() {
Expand Down
7 changes: 7 additions & 0 deletions testapp/repeater/repeater.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@
<ul><li ng:repeat="bar in days">{{bar.initial}}</li></ul>
<ul><li ng_repeat="foo in days">{{foo.initial}}</li></ul>
<ul><li x-ng-repeat="qux in days">{{qux.initial}}</li></ul>
<div ng-repeat-start="bloop in days">
{{bloop.initial}}
</div>
<span>-</span>
<div ng-repeat-end>
{{bloop.name}}
</div>

0 comments on commit 6a73a25

Please sign in to comment.