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

Commit

Permalink
use the root element only to find the testability API, not scope sear…
Browse files Browse the repository at this point in the history
…ches

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.
  • Loading branch information
juliemr committed Oct 1, 2014
1 parent f4e6b40 commit 2fbaf52
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 44 deletions.
72 changes: 30 additions & 42 deletions lib/clientsidescripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ var functions = {};
*
* Asynchronous.
*
* @param {string} selector The selector housing an ng-app
* @param {string} rootSelector The selector housing an ng-app
* @param {function} callback callback
*/
functions.waitForAngular = function(selector, callback) {
var el = document.querySelector(selector);
functions.waitForAngular = function(rootSelector, callback) {
var el = document.querySelector(rootSelector);
try {
if (angular.getTestability) {
angular.getTestability(el).whenStable(callback);
Expand All @@ -50,10 +50,10 @@ functions.waitForAngular = function(selector, callback) {
* @return {Array.<Element>} The elements containing the binding.
*/
functions.findBindings = function(binding, exactMatch, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);
var root = document.querySelector(rootSelector || 'body');
using = using || document;
if (angular.getTestability) {
return angular.getTestability(using).
return angular.getTestability(root).
findBindings(using, binding, exactMatch);
}
var bindings = using.getElementsByClassName('ng-binding');
Expand Down Expand Up @@ -86,14 +86,12 @@ functions.findBindings = function(binding, exactMatch, using, rootSelector) {
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
* @param {number} index The row index.
* @param {Element} using The scope of the search.
* @param {string} rootSelector The selector to use for the root app element.
*
* @return {Array.<Element>} The row of the repeater, or an array of elements
* in the first row in the case of ng-repeat-start.
*/
functions.findRepeaterRows = function(repeater, index, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);
functions.findRepeaterRows = function(repeater, index, using) {
using = using || document;

var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
var rows = [];
Expand Down Expand Up @@ -137,13 +135,11 @@ functions.findBindings = function(binding, exactMatch, using, rootSelector) {
*
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
* @param {Element} using The scope of the search.
* @param {string} rootSelector The selector to use for the root app element.
*
* @return {Array.<Element>} All rows of the repeater.
*/
functions.findAllRepeaterRows = function(repeater, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);
functions.findAllRepeaterRows = function(repeater, using) {
using = using || document;

var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
Expand Down Expand Up @@ -190,8 +186,8 @@ functions.findBindings = function(binding, exactMatch, using, rootSelector) {
*/
functions.findRepeaterElement = function(repeater, index, binding, using, rootSelector) {
var matches = [];
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);
var root = document.querySelector(rootSelector || 'body');
using = using || document;

var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
Expand Down Expand Up @@ -234,7 +230,7 @@ functions.findRepeaterElement = function(repeater, index, binding, using, rootSe
if (angular.getTestability) {
matches.push.apply(
matches,
angular.getTestability(using).findBindings(row, binding));
angular.getTestability(root).findBindings(row, binding));
} else {
if (row.className.indexOf('ng-binding') != -1) {
bindings.push(row);
Expand All @@ -251,7 +247,7 @@ functions.findRepeaterElement = function(repeater, index, binding, using, rootSe
if (angular.getTestability) {
matches.push.apply(
matches,
angular.getTestability(using).findBindings(rowElem, binding));
angular.getTestability(root).findBindings(rowElem, binding));
} else {
if (rowElem.className.indexOf('ng-binding') != -1) {
bindings.push(rowElem);
Expand Down Expand Up @@ -287,8 +283,8 @@ functions.findRepeaterElement = function(repeater, index, binding, using, rootSe
*/
functions.findRepeaterColumn = function(repeater, binding, using, rootSelector) {
var matches = [];
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);
var root = document.querySelector(rootSelector || 'body');
using = using || document;

var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
Expand Down Expand Up @@ -329,7 +325,7 @@ functions.findRepeaterColumn = function(repeater, binding, using, rootSelector)
if (angular.getTestability) {
matches.push.apply(
matches,
angular.getTestability(using).findBindings(rows[i], binding));
angular.getTestability(root).findBindings(rows[i], binding));
} else {
if (rows[i].className.indexOf('ng-binding') != -1) {
bindings.push(rows[i]);
Expand All @@ -345,7 +341,7 @@ functions.findRepeaterColumn = function(repeater, binding, using, rootSelector)
if (angular.getTestability) {
matches.push.apply(
matches,
angular.getTestability(using).findBindings(multiRows[i][j], binding));
angular.getTestability(root).findBindings(multiRows[i][j], binding));
} else {
var elem = multiRows[i][j];
if (elem.className.indexOf('ng-binding') != -1) {
Expand Down Expand Up @@ -380,11 +376,11 @@ functions.findRepeaterColumn = function(repeater, binding, using, rootSelector)
* @return {Array.<Element>} The matching elements.
*/
functions.findByModel = function(model, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);
var root = document.querySelector(rootSelector || 'body');
using = using || document;

if (angular.getTestability) {
return angular.getTestability(using).
return angular.getTestability(root).
findModels(using, model, true);
}
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
Expand All @@ -403,13 +399,11 @@ functions.findByModel = function(model, using, rootSelector) {
* @param {string} optionsDescriptor The descriptor for the option
* (i.e. fruit for fruit in fruits).
* @param {Element} using The scope of the search.
* @param {string} rootSelector The selector to use for the root app element.
*
* @return {Array.<Element>} The matching elements.
*/
functions.findByOptions = function(optionsDescriptor, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);
functions.findByOptions = function(optionsDescriptor, using) {
using = using || document;

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

var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
var matches = [];
Expand All @@ -457,13 +449,11 @@ functions.findByButtonText = function(searchText, using, rootSelector) {
*
* @param {string} searchText The exact text to match.
* @param {Element} using The scope of the search.
* @param {string} rootSelector The selector to use for the root app element.
*
* @return {Array.<Element>} The matching elements.
*/
functions.findByPartialButtonText = function(searchText, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);
functions.findByPartialButtonText = function(searchText, using) {
using = using || document;

var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
var matches = [];
Expand All @@ -489,13 +479,11 @@ functions.findByPartialButtonText = function(searchText, using, rootSelector) {
* @param {string} cssSelector The css selector to match.
* @param {string} searchText The exact text to match.
* @param {Element} using The scope of the search.
* @param {string} rootSelector The selector to use for the root app element.
*
* @return {Array.<Element>} An array of matching elements.
*/
functions.findByCssContainingText = function(cssSelector, searchText, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);
functions.findByCssContainingText = function(cssSelector, searchText, using) {
using = using || document;

var elements = using.querySelectorAll(cssSelector);
var matches = [];
Expand Down Expand Up @@ -629,4 +617,4 @@ for (var fnName in functions) {
}

exports.installInBrowser = (util.format(
'window.clientSideScripts = {%s};', scriptsList.join(', ')));
'window.clientSideScripts = {%s};', scriptsList.join(', ')));
4 changes: 2 additions & 2 deletions lib/locators.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ util.inherits(ProtractorBy, WebdriverBy);
* // This function will be serialized as a string and will execute in the
* // browser. The first argument is the text for the button. The second
* // argument is the parent element, if any.
* var using = opt_parentElement || document.querySelector(opt_rootSelector),
* buttons = using.querySelectorAll('button');
* var using = opt_parentElement,
* buttons = using.querySelectorAll('button');
*
* // Return an array of buttons with the text.
* return Array.prototype.filter.call(buttons, function(button) {
Expand Down

0 comments on commit 2fbaf52

Please sign in to comment.