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

Commit 6a73a25

Browse files
committed
feat(by.repeat) by.repeat support for multi ng-repeat
Make by.repeat (and its column and row friends) work with ng-repeat-start and ng-repeat-end elements. Closes #366. Closes #182.
1 parent 35d92a2 commit 6a73a25

File tree

3 files changed

+187
-25
lines changed

3 files changed

+187
-25
lines changed

lib/clientsidescripts.js

+129-19
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,24 @@ clientSideScripts.findBindings = function() {
5353
};
5454

5555
/**
56-
* Find an array of elements matching a row within an ng-repeat. Always returns
57-
* an array of only one element.
56+
* Find an array of elements matching a row within an ng-repeat.
57+
* Always returns an array of only one element for plain old ng-repeat.
58+
* Returns an array of all the elements in one segment for ng-repeat-start.
5859
*
5960
* arguments[0] {Element} The scope of the search.
6061
* arguments[1] {string} The text of the repeater, e.g. 'cat in cats'.
6162
* arguments[2] {number} The row index.
6263
*
63-
* @return {Array.<Element>} An array of a single element, the row of the
64-
* repeater.
64+
* @return {Array.<Element>} The row of the repeater, or an array of elements
65+
* in the first row in the case of ng-repeat-start.
6566
*/
6667
clientSideScripts.findRepeaterRows = function() {
6768
var using = arguments[0] || document;
6869
var repeater = arguments[1];
6970
var index = arguments[2];
7071

71-
var rows = [];
7272
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
73+
var rows = [];
7374
for (var p = 0; p < prefixes.length; ++p) {
7475
var attr = prefixes[p] + 'repeat';
7576
var repeatElems = using.querySelectorAll('[' + attr + ']');
@@ -80,7 +81,29 @@ clientSideScripts.findBindings = function() {
8081
}
8182
}
8283
}
83-
return [rows[index]];
84+
// multiRows is an array of arrays, where each inner array contains
85+
// one row of elements.
86+
var multiRows = [];
87+
for (var p = 0; p < prefixes.length; ++p) {
88+
var attr = prefixes[p] + 'repeat-start';
89+
var repeatElems = using.querySelectorAll('[' + attr + ']');
90+
attr = attr.replace(/\\/g, '');
91+
for (var i = 0; i < repeatElems.length; ++i) {
92+
if (repeatElems[i].getAttribute(attr).indexOf(repeater) != -1) {
93+
var elem = repeatElems[i];
94+
var row = [];
95+
while (elem.nodeType != 8 ||
96+
elem.nodeValue.indexOf(repeater) == -1) {
97+
if (elem.nodeType == 1) {
98+
row.push(elem);
99+
}
100+
elem = elem.nextSibling;
101+
}
102+
multiRows.push(row);
103+
}
104+
}
105+
}
106+
return [rows[index]].concat(multiRows[index]);
84107
};
85108

86109
/**
@@ -107,6 +130,22 @@ clientSideScripts.findBindings = function() {
107130
}
108131
}
109132
}
133+
for (var p = 0; p < prefixes.length; ++p) {
134+
var attr = prefixes[p] + 'repeat-start';
135+
var repeatElems = using.querySelectorAll('[' + attr + ']');
136+
attr = attr.replace(/\\/g, '');
137+
for (var i = 0; i < repeatElems.length; ++i) {
138+
if (repeatElems[i].getAttribute(attr).indexOf(repeater) != -1) {
139+
var elem = repeatElems[i];
140+
var row = [];
141+
while (elem.nodeType != 8 ||
142+
elem.nodeValue.indexOf(repeater) == -1) {
143+
rows.push(elem);
144+
elem = elem.nextSibling;
145+
}
146+
}
147+
}
148+
}
110149
return rows;
111150
};
112151

@@ -139,14 +178,51 @@ clientSideScripts.findRepeaterElement = function() {
139178
}
140179
}
141180
}
181+
// multiRows is an array of arrays, where each inner array contains
182+
// one row of elements.
183+
var multiRows = [];
184+
for (var p = 0; p < prefixes.length; ++p) {
185+
var attr = prefixes[p] + 'repeat-start';
186+
var repeatElems = using.querySelectorAll('[' + attr + ']');
187+
attr = attr.replace(/\\/g, '');
188+
for (var i = 0; i < repeatElems.length; ++i) {
189+
if (repeatElems[i].getAttribute(attr).indexOf(repeater) != -1) {
190+
var elem = repeatElems[i];
191+
var row = [];
192+
while (elem.nodeType != 8 ||
193+
(elem.nodeValue && elem.nodeValue.indexOf(repeater) == -1)) {
194+
if (elem.nodeType == 1) {
195+
row.push(elem);
196+
}
197+
elem = elem.nextSibling;
198+
}
199+
multiRows.push(row);
200+
}
201+
}
202+
}
142203
var row = rows[index];
204+
var multiRow = multiRows[index];
143205
var bindings = [];
144-
if (row.className.indexOf('ng-binding') != -1) {
145-
bindings.push(row);
206+
if (row) {
207+
if (row.className.indexOf('ng-binding') != -1) {
208+
bindings.push(row);
209+
}
210+
var childBindings = row.getElementsByClassName('ng-binding');
211+
for (var i = 0; i < childBindings.length; ++i) {
212+
bindings.push(childBindings[i]);
213+
}
146214
}
147-
var childBindings = row.getElementsByClassName('ng-binding');
148-
for (var i = 0; i < childBindings.length; ++i) {
149-
bindings.push(childBindings[i]);
215+
if (multiRow) {
216+
for (var i = 0; i < multiRow.length; ++i) {
217+
rowElem = multiRow[i];
218+
if (rowElem.className.indexOf('ng-binding') != -1) {
219+
bindings.push(rowElem);
220+
}
221+
var childBindings = rowElem.getElementsByClassName('ng-binding');
222+
for (var j = 0; j < childBindings.length; ++j) {
223+
bindings.push(childBindings[j]);
224+
}
225+
}
150226
}
151227
for (var i = 0; i < bindings.length; ++i) {
152228
var dataBinding = angular.element(bindings[i]).data('$binding');
@@ -187,22 +263,56 @@ clientSideScripts.findRepeaterColumn = function() {
187263
}
188264
}
189265
}
266+
// multiRows is an array of arrays, where each inner array contains
267+
// one row of elements.
268+
var multiRows = [];
269+
for (var p = 0; p < prefixes.length; ++p) {
270+
var attr = prefixes[p] + 'repeat-start';
271+
var repeatElems = using.querySelectorAll('[' + attr + ']');
272+
attr = attr.replace(/\\/g, '');
273+
for (var i = 0; i < repeatElems.length; ++i) {
274+
if (repeatElems[i].getAttribute(attr).indexOf(repeater) != -1) {
275+
var elem = repeatElems[i];
276+
var row = [];
277+
while (elem.nodeType != 8 ||
278+
(elem.nodeValue && elem.nodeValue.indexOf(repeater) == -1)) {
279+
if (elem.nodeType == 1) {
280+
row.push(elem);
281+
}
282+
elem = elem.nextSibling;
283+
}
284+
multiRows.push(row);
285+
}
286+
}
287+
}
288+
var bindings = [];
190289
for (var i = 0; i < rows.length; ++i) {
191-
var bindings = [];
192290
if (rows[i].className.indexOf('ng-binding') != -1) {
193291
bindings.push(rows[i]);
194292
}
195293
var childBindings = rows[i].getElementsByClassName('ng-binding');
196294
for (var k = 0; k < childBindings.length; ++k) {
197295
bindings.push(childBindings[k]);
198296
}
199-
for (var j = 0; j < bindings.length; ++j) {
200-
var dataBinding = angular.element(bindings[j]).data('$binding');
201-
if(dataBinding) {
202-
var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
203-
if (bindingName.indexOf(binding) != -1) {
204-
matches.push(bindings[j]);
205-
}
297+
}
298+
for (var i = 0; i < multiRows.length; ++i) {
299+
for (var j = 0; j < multiRows[i].length; ++j) {
300+
var elem = multiRows[i][j];
301+
if (elem.className.indexOf('ng-binding') != -1) {
302+
bindings.push(elem);
303+
}
304+
var childBindings = elem.getElementsByClassName('ng-binding');
305+
for (var k = 0; k < childBindings.length; ++k) {
306+
bindings.push(childBindings[k]);
307+
}
308+
}
309+
}
310+
for (var j = 0; j < bindings.length; ++j) {
311+
var dataBinding = angular.element(bindings[j]).data('$binding');
312+
if (dataBinding) {
313+
var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
314+
if (bindingName.indexOf(binding) != -1) {
315+
matches.push(bindings[j]);
206316
}
207317
}
208318
}

spec/basic/findelements_spec.js

+51-6
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,6 @@ describe('locators', function() {
127127
expect(arr[2].getText()).toBe('blue');
128128
});
129129
});
130-
131-
132130
});
133131

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

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

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

175-
var names = browser.findElements(
173+
var names = element.all(
176174
by.repeater('allinfo in days').column('name'));
177175
names.then(function(arr) {
178176
expect(arr.length).toEqual(5);
@@ -253,7 +251,54 @@ describe('locators', function() {
253251
// There are only 5 rows, so the 6th row is not present.
254252
expect(element(by.repeater('allinfo in days').row(5)).isPresent()).
255253
toBe(false);
256-
})
254+
});
255+
256+
describe('repeaters using ng-repeat-start and ng-repeat-end', function() {
257+
it('should return all elements when unmodified', function() {
258+
var all =
259+
element.all(by.repeater('bloop in days'));
260+
261+
all.then(function(arr) {
262+
expect(arr.length).toEqual(3 * 5);
263+
expect(arr[0].getText()).toEqual('M');
264+
expect(arr[1].getText()).toEqual('-');
265+
expect(arr[2].getText()).toEqual('Monday');
266+
expect(arr[3].getText()).toEqual('T');
267+
expect(arr[4].getText()).toEqual('-');
268+
expect(arr[5].getText()).toEqual('Tuesday');
269+
});
270+
});
271+
272+
it('should return a group of elements for a row', function() {
273+
var firstRow = element.all(by.repeater('bloop in days').row(0));
274+
275+
firstRow.then(function(arr) {
276+
expect(arr.length).toEqual(3);
277+
expect(arr[0].getText()).toEqual('M');
278+
expect(arr[1].getText()).toEqual('-');
279+
expect(arr[2].getText()).toEqual('Monday');
280+
});
281+
});
282+
283+
it('should return a group of elements for a column', function() {
284+
var nameColumn = element.all(
285+
by.repeater('bloop in days').column('name'));
286+
287+
nameColumn.then(function(arr) {
288+
expect(arr.length).toEqual(5);
289+
expect(arr[0].getText()).toEqual('Monday');
290+
expect(arr[1].getText()).toEqual('Tuesday');
291+
});
292+
});
293+
294+
it('should find an individual element', function() {
295+
browser.debugger();
296+
var firstInitial = element(
297+
by.repeater('bloop in days').row(0).column('bloop.initial'));
298+
299+
expect(firstInitial.getText()).toEqual('M');
300+
});
301+
});
257302
});
258303

259304
it('should determine if an element is present', function() {

testapp/repeater/repeater.html

+7
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,10 @@
88
<ul><li ng:repeat="bar in days">{{bar.initial}}</li></ul>
99
<ul><li ng_repeat="foo in days">{{foo.initial}}</li></ul>
1010
<ul><li x-ng-repeat="qux in days">{{qux.initial}}</li></ul>
11+
<div ng-repeat-start="bloop in days">
12+
{{bloop.initial}}
13+
</div>
14+
<span>-</span>
15+
<div ng-repeat-end>
16+
{{bloop.name}}
17+
</div>

0 commit comments

Comments
 (0)