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

Commit 2fbaf52

Browse files
committed
use the root element only to find the testability API, not scope searches
n 9a8f45a a change was introduced which made Protractor's custom locators (by.binding, by.model, etc) use config.rootElement as the root for all their searches. This meant that config.rootElement was used both to specify how to get hold of Angular's injector as well as where to begin searching for elements. This does not work for all cases, for example if a dialog should be searched for elements but is a sibling, not a child, of ng-app. This reverts that change, and uses document as the parent for all searches. This is consistent with the behavior of the native locators by.id, by.css, and friends, which do not scope their search based on config.rootElement.
1 parent f4e6b40 commit 2fbaf52

File tree

2 files changed

+32
-44
lines changed

2 files changed

+32
-44
lines changed

Diff for: lib/clientsidescripts.js

+30-42
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ var functions = {};
2222
*
2323
* Asynchronous.
2424
*
25-
* @param {string} selector The selector housing an ng-app
25+
* @param {string} rootSelector The selector housing an ng-app
2626
* @param {function} callback callback
2727
*/
28-
functions.waitForAngular = function(selector, callback) {
29-
var el = document.querySelector(selector);
28+
functions.waitForAngular = function(rootSelector, callback) {
29+
var el = document.querySelector(rootSelector);
3030
try {
3131
if (angular.getTestability) {
3232
angular.getTestability(el).whenStable(callback);
@@ -50,10 +50,10 @@ functions.waitForAngular = function(selector, callback) {
5050
* @return {Array.<Element>} The elements containing the binding.
5151
*/
5252
functions.findBindings = function(binding, exactMatch, using, rootSelector) {
53-
rootSelector = rootSelector || 'body';
54-
using = using || document.querySelector(rootSelector);
53+
var root = document.querySelector(rootSelector || 'body');
54+
using = using || document;
5555
if (angular.getTestability) {
56-
return angular.getTestability(using).
56+
return angular.getTestability(root).
5757
findBindings(using, binding, exactMatch);
5858
}
5959
var bindings = using.getElementsByClassName('ng-binding');
@@ -86,14 +86,12 @@ functions.findBindings = function(binding, exactMatch, using, rootSelector) {
8686
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
8787
* @param {number} index The row index.
8888
* @param {Element} using The scope of the search.
89-
* @param {string} rootSelector The selector to use for the root app element.
9089
*
9190
* @return {Array.<Element>} The row of the repeater, or an array of elements
9291
* in the first row in the case of ng-repeat-start.
9392
*/
94-
functions.findRepeaterRows = function(repeater, index, using, rootSelector) {
95-
rootSelector = rootSelector || 'body';
96-
using = using || document.querySelector(rootSelector);
93+
functions.findRepeaterRows = function(repeater, index, using) {
94+
using = using || document;
9795

9896
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
9997
var rows = [];
@@ -137,13 +135,11 @@ functions.findBindings = function(binding, exactMatch, using, rootSelector) {
137135
*
138136
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
139137
* @param {Element} using The scope of the search.
140-
* @param {string} rootSelector The selector to use for the root app element.
141138
*
142139
* @return {Array.<Element>} All rows of the repeater.
143140
*/
144-
functions.findAllRepeaterRows = function(repeater, using, rootSelector) {
145-
rootSelector = rootSelector || 'body';
146-
using = using || document.querySelector(rootSelector);
141+
functions.findAllRepeaterRows = function(repeater, using) {
142+
using = using || document;
147143

148144
var rows = [];
149145
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
@@ -190,8 +186,8 @@ functions.findBindings = function(binding, exactMatch, using, rootSelector) {
190186
*/
191187
functions.findRepeaterElement = function(repeater, index, binding, using, rootSelector) {
192188
var matches = [];
193-
rootSelector = rootSelector || 'body';
194-
using = using || document.querySelector(rootSelector);
189+
var root = document.querySelector(rootSelector || 'body');
190+
using = using || document;
195191

196192
var rows = [];
197193
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
@@ -234,7 +230,7 @@ functions.findRepeaterElement = function(repeater, index, binding, using, rootSe
234230
if (angular.getTestability) {
235231
matches.push.apply(
236232
matches,
237-
angular.getTestability(using).findBindings(row, binding));
233+
angular.getTestability(root).findBindings(row, binding));
238234
} else {
239235
if (row.className.indexOf('ng-binding') != -1) {
240236
bindings.push(row);
@@ -251,7 +247,7 @@ functions.findRepeaterElement = function(repeater, index, binding, using, rootSe
251247
if (angular.getTestability) {
252248
matches.push.apply(
253249
matches,
254-
angular.getTestability(using).findBindings(rowElem, binding));
250+
angular.getTestability(root).findBindings(rowElem, binding));
255251
} else {
256252
if (rowElem.className.indexOf('ng-binding') != -1) {
257253
bindings.push(rowElem);
@@ -287,8 +283,8 @@ functions.findRepeaterElement = function(repeater, index, binding, using, rootSe
287283
*/
288284
functions.findRepeaterColumn = function(repeater, binding, using, rootSelector) {
289285
var matches = [];
290-
rootSelector = rootSelector || 'body';
291-
using = using || document.querySelector(rootSelector);
286+
var root = document.querySelector(rootSelector || 'body');
287+
using = using || document;
292288

293289
var rows = [];
294290
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
@@ -329,7 +325,7 @@ functions.findRepeaterColumn = function(repeater, binding, using, rootSelector)
329325
if (angular.getTestability) {
330326
matches.push.apply(
331327
matches,
332-
angular.getTestability(using).findBindings(rows[i], binding));
328+
angular.getTestability(root).findBindings(rows[i], binding));
333329
} else {
334330
if (rows[i].className.indexOf('ng-binding') != -1) {
335331
bindings.push(rows[i]);
@@ -345,7 +341,7 @@ functions.findRepeaterColumn = function(repeater, binding, using, rootSelector)
345341
if (angular.getTestability) {
346342
matches.push.apply(
347343
matches,
348-
angular.getTestability(using).findBindings(multiRows[i][j], binding));
344+
angular.getTestability(root).findBindings(multiRows[i][j], binding));
349345
} else {
350346
var elem = multiRows[i][j];
351347
if (elem.className.indexOf('ng-binding') != -1) {
@@ -380,11 +376,11 @@ functions.findRepeaterColumn = function(repeater, binding, using, rootSelector)
380376
* @return {Array.<Element>} The matching elements.
381377
*/
382378
functions.findByModel = function(model, using, rootSelector) {
383-
rootSelector = rootSelector || 'body';
384-
using = using || document.querySelector(rootSelector);
379+
var root = document.querySelector(rootSelector || 'body');
380+
using = using || document;
385381

386382
if (angular.getTestability) {
387-
return angular.getTestability(using).
383+
return angular.getTestability(root).
388384
findModels(using, model, true);
389385
}
390386
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
@@ -403,13 +399,11 @@ functions.findByModel = function(model, using, rootSelector) {
403399
* @param {string} optionsDescriptor The descriptor for the option
404400
* (i.e. fruit for fruit in fruits).
405401
* @param {Element} using The scope of the search.
406-
* @param {string} rootSelector The selector to use for the root app element.
407402
*
408403
* @return {Array.<Element>} The matching elements.
409404
*/
410-
functions.findByOptions = function(optionsDescriptor, using, rootSelector) {
411-
rootSelector = rootSelector || 'body';
412-
using = using || document.querySelector(rootSelector);
405+
functions.findByOptions = function(optionsDescriptor, using) {
406+
using = using || document;
413407

414408
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
415409
for (var p = 0; p < prefixes.length; ++p) {
@@ -426,13 +420,11 @@ functions.findByOptions = function(optionsDescriptor, using, rootSelector) {
426420
*
427421
* @param {string} searchText The exact text to match.
428422
* @param {Element} using The scope of the search.
429-
* @param {string} rootSelector The selector to use for the root app element.
430423
*
431424
* @return {Array.<Element>} The matching elements.
432425
*/
433-
functions.findByButtonText = function(searchText, using, rootSelector) {
434-
rootSelector = rootSelector || 'body';
435-
using = using || document.querySelector(rootSelector);
426+
functions.findByButtonText = function(searchText, using) {
427+
using = using || document;
436428

437429
var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
438430
var matches = [];
@@ -457,13 +449,11 @@ functions.findByButtonText = function(searchText, using, rootSelector) {
457449
*
458450
* @param {string} searchText The exact text to match.
459451
* @param {Element} using The scope of the search.
460-
* @param {string} rootSelector The selector to use for the root app element.
461452
*
462453
* @return {Array.<Element>} The matching elements.
463454
*/
464-
functions.findByPartialButtonText = function(searchText, using, rootSelector) {
465-
rootSelector = rootSelector || 'body';
466-
using = using || document.querySelector(rootSelector);
455+
functions.findByPartialButtonText = function(searchText, using) {
456+
using = using || document;
467457

468458
var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
469459
var matches = [];
@@ -489,13 +479,11 @@ functions.findByPartialButtonText = function(searchText, using, rootSelector) {
489479
* @param {string} cssSelector The css selector to match.
490480
* @param {string} searchText The exact text to match.
491481
* @param {Element} using The scope of the search.
492-
* @param {string} rootSelector The selector to use for the root app element.
493482
*
494483
* @return {Array.<Element>} An array of matching elements.
495484
*/
496-
functions.findByCssContainingText = function(cssSelector, searchText, using, rootSelector) {
497-
rootSelector = rootSelector || 'body';
498-
using = using || document.querySelector(rootSelector);
485+
functions.findByCssContainingText = function(cssSelector, searchText, using) {
486+
using = using || document;
499487

500488
var elements = using.querySelectorAll(cssSelector);
501489
var matches = [];
@@ -629,4 +617,4 @@ for (var fnName in functions) {
629617
}
630618

631619
exports.installInBrowser = (util.format(
632-
'window.clientSideScripts = {%s};', scriptsList.join(', ')));
620+
'window.clientSideScripts = {%s};', scriptsList.join(', ')));

Diff for: lib/locators.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ util.inherits(ProtractorBy, WebdriverBy);
3434
* // This function will be serialized as a string and will execute in the
3535
* // browser. The first argument is the text for the button. The second
3636
* // argument is the parent element, if any.
37-
* var using = opt_parentElement || document.querySelector(opt_rootSelector),
38-
* buttons = using.querySelectorAll('button');
37+
* var using = opt_parentElement,
38+
* buttons = using.querySelectorAll('button');
3939
*
4040
* // Return an array of buttons with the text.
4141
* return Array.prototype.filter.call(buttons, function(button) {

0 commit comments

Comments
 (0)