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

Changes for upcoming Angular refactoring #1233

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 54 additions & 30 deletions lib/clientsidescripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ functions.waitForAngular = function(selector, callback) {
* @param {string} binding The binding, e.g. {{cat.name}}.
* @param {boolean} exactMatch Whether the binding needs to be matched exactly
* @param {Element} using The scope of the search.
* @param {string} rootSelector The selector to use for the root app element.
*
* @return {Array.<Element>} The elements containing the binding.
*/
functions.findBindings = function(binding, exactMatch, using) {
using = using || document;
functions.findBindings = function(binding, exactMatch, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);
if (angular.getTestability) {
return angular.getTestability(using).
findBindings(using, binding, exactMatch);
Expand Down Expand Up @@ -83,13 +85,15 @@ functions.findBindings = function(binding, exactMatch, using) {
*
* @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. Defaults to 'document'.
* @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) {
using = using || document;
functions.findRepeaterRows = function(repeater, index, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);

var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
var rows = [];
Expand Down Expand Up @@ -132,12 +136,14 @@ functions.findBindings = function(binding, exactMatch, using) {
* Find all rows of an ng-repeat.
*
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
* @param {Element} using The scope of the search. Defaults to 'document'.
* @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) {
using = using || document;
functions.findAllRepeaterRows = function(repeater, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);

var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
Expand Down Expand Up @@ -177,13 +183,15 @@ functions.findBindings = function(binding, exactMatch, using) {
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
* @param {number} index The row index.
* @param {string} binding The column binding, e.g. '{{cat.name}}'.
* @param {Element} using The scope of the search. Defaults to 'document'.
* @param {Element} using The scope of the search.
* @param {string} rootSelector The selector to use for the root app element.
*
* @return {Array.<Element>} The element in an array.
*/
functions.findRepeaterElement = function(repeater, index, binding, using) {
functions.findRepeaterElement = function(repeater, index, binding, using, rootSelector) {
var matches = [];
using = using || document;
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);

var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
Expand Down Expand Up @@ -272,13 +280,15 @@ functions.findRepeaterElement = function(repeater, index, binding, using) {
*
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
* @param {string} binding The column binding, e.g. '{{cat.name}}'.
* @param {Element} using The scope of the search. Defaults to 'document'.
* @param {Element} using The scope of the search.
* @param {string} rootSelector The selector to use for the root app element.
*
* @return {Array.<Element>} The elements in the column.
*/
functions.findRepeaterColumn = function(repeater, binding, using) {
functions.findRepeaterColumn = function(repeater, binding, using, rootSelector) {
var matches = [];
using = using || document;
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);

var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
Expand Down Expand Up @@ -364,12 +374,15 @@ functions.findRepeaterColumn = function(repeater, binding, using) {
* Find elements by model name.
*
* @param {string} model The model name.
* @param {Element} using The scope of the search. Defaults to 'document'.
* @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.findByModel = function(model, using) {
using = using || document;
functions.findByModel = function(model, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);

if (angular.getTestability) {
return angular.getTestability(using).
findModels(using, model);
Expand All @@ -389,12 +402,15 @@ functions.findByModel = function(model, using) {
*
* @param {string} optionsDescriptor The descriptor for the option
* (i.e. fruit for fruit in fruits).
* @param {Element} using The scope of the search. Defaults to 'document'.
* @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) {
using = using || document;
functions.findByOptions = function(optionsDescriptor, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);

var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
for (var p = 0; p < prefixes.length; ++p) {
var selector = '[' + prefixes[p] + 'options="' + optionsDescriptor + '"] option';
Expand All @@ -409,12 +425,15 @@ functions.findByOptions = function(optionsDescriptor, using) {
* Find buttons by textual content.
*
* @param {string} searchText The exact text to match.
* @param {Element} using The scope of the search. Defaults to 'document'.
* @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) {
using = using || document;
functions.findByButtonText = function(searchText, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);

var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
var matches = [];
for (var i = 0; i < elements.length; ++i) {
Expand All @@ -437,12 +456,15 @@ functions.findByButtonText = function(searchText, using) {
* Find buttons by textual content.
*
* @param {string} searchText The exact text to match.
* @param {Element} using The scope of the search. Defaults to 'document'.
* @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) {
using = using || document;
functions.findByPartialButtonText = function(searchText, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);

var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
var matches = [];
for (var i = 0; i < elements.length; ++i) {
Expand All @@ -466,12 +488,15 @@ functions.findByPartialButtonText = function(searchText, using) {
*
* @param {string} cssSelector The css selector to match.
* @param {string} searchText The exact text to match.
* @param {Element} using The scope of the search. Defaults to 'document'.
* @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) {
var using = using || document;
functions.findByCssContainingText = function(cssSelector, searchText, using, rootSelector) {
rootSelector = rootSelector || 'body';
using = using || document.querySelector(rootSelector);

var elements = using.querySelectorAll(cssSelector);
var matches = [];
for (var i = 0; i < elements.length; ++i) {
Expand Down Expand Up @@ -528,7 +553,6 @@ functions.testForAngular = function(attempts, asyncCallback) {
* @return {?Object} The result of the evaluation.
*/
functions.evaluate = function(element, expression) {

return angular.element(element).scope().$eval(expression);
};

Expand Down
61 changes: 33 additions & 28 deletions lib/locators.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ util.inherits(ProtractorBy, WebdriverBy);
*
* @example
* // Add the custom locator.
* by.addLocator('buttonTextSimple', function(buttonText, opt_parentElement) {
* by.addLocator('buttonTextSimple',
* function(buttonText, opt_parentElement, opt_rootSelector) {
* // 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,
* var using = opt_parentElement || document.querySelector(opt_rootSelector),
* buttons = using.querySelectorAll('button');
*
* // Return an array of buttons with the text.
Expand All @@ -49,18 +50,20 @@ util.inherits(ProtractorBy, WebdriverBy);
* @param {Function|string} script A script to be run in the context of
* the browser. This script will be passed an array of arguments
* that contains any args passed into the locator followed by the
* element scoping the search. It should return an array of elements.
* element scoping the search and the css selector for the root angular
* element. It should return an array of elements.
*/
ProtractorBy.prototype.addLocator = function(name, script) {
this[name] = function() {
var locatorArguments = arguments;
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
var findElementArguments = [script];
for (var i = 0; i < locatorArguments.length; i++) {
findElementArguments.push(locatorArguments[i]);
}
findElementArguments.push(using);
findElementArguments.push(rootSelector);

return driver.findElements(
webdriver.By.js.apply(webdriver.By, findElementArguments));
Expand Down Expand Up @@ -93,10 +96,10 @@ ProtractorBy.prototype.addLocator = function(name, script) {
*/
ProtractorBy.prototype.binding = function(bindingDescriptor) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findBindings,
bindingDescriptor, false, using));
bindingDescriptor, false, using, rootSelector));
},
toString: function toString() {
return 'by.binding("' + bindingDescriptor + '")';
Expand Down Expand Up @@ -126,10 +129,10 @@ ProtractorBy.prototype.binding = function(bindingDescriptor) {
*/
ProtractorBy.prototype.exactBinding = function(bindingDescriptor) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findBindings,
bindingDescriptor, true, using));
bindingDescriptor, true, using, rootSelector));
},
toString: function toString() {
return 'by.exactBinding("' + bindingDescriptor + '")';
Expand All @@ -153,9 +156,10 @@ ProtractorBy.prototype.exactBinding = function(bindingDescriptor) {
*/
ProtractorBy.prototype.model = function(model) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findByModel, model, using));
webdriver.By.js(
clientSideScripts.findByModel, model, using, rootSelector));
},
toString: function toString() {
return 'by.model("' + model + '")';
Expand All @@ -177,10 +181,10 @@ ProtractorBy.prototype.model = function(model) {
*/
ProtractorBy.prototype.buttonText = function(searchText) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findByButtonText,
searchText, using));
searchText, using, rootSelector));
},
toString: function toString() {
return 'by.buttonText("' + searchText + '")';
Expand All @@ -202,10 +206,10 @@ ProtractorBy.prototype.buttonText = function(searchText) {
*/
ProtractorBy.prototype.partialButtonText = function(searchText) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findByPartialButtonText,
searchText, using));
searchText, using, rootSelector));
},
toString: function toString() {
return 'by.partialButtonText("' + searchText + '")';
Expand Down Expand Up @@ -267,30 +271,30 @@ ProtractorBy.prototype.partialButtonText = function(searchText) {
*/
ProtractorBy.prototype.repeater = function(repeatDescriptor) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findAllRepeaterRows,
repeatDescriptor, using));
repeatDescriptor, using, rootSelector));
},
toString: function toString() {
return 'by.repeater("' + repeatDescriptor + '")';
},
row: function(index) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findRepeaterRows,
repeatDescriptor, index, using));
repeatDescriptor, index, using, rootSelector));
},
toString: function toString() {
return 'by.repeater(' + repeatDescriptor + '").row("' + index + '")"';
},
column: function(binding) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findRepeaterElement,
repeatDescriptor, index, binding, using));
repeatDescriptor, index, binding, using, rootSelector));
},
toString: function toString() {
return 'by.repeater("' + repeatDescriptor + '").row("' + index +
Expand All @@ -302,21 +306,21 @@ ProtractorBy.prototype.repeater = function(repeatDescriptor) {
},
column: function(binding) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findRepeaterColumn,
repeatDescriptor, binding, using));
repeatDescriptor, binding, using, rootSelector));
},
toString: function toString() {
return 'by.repeater("' + repeatDescriptor + '").column("' +
binding + '")';
},
row: function(index) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findRepeaterElement,
repeatDescriptor, index, binding, using));
repeatDescriptor, index, binding, using, rootSelector));
},
toString: function toString() {
return 'by.repeater("' + repeatDescriptor + '").column("' +
Expand Down Expand Up @@ -344,10 +348,10 @@ ProtractorBy.prototype.repeater = function(repeatDescriptor) {
*/
ProtractorBy.prototype.cssContainingText = function(cssSelector, searchText) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findByCssContainingText,
cssSelector, searchText, using));
cssSelector, searchText, using, rootSelector));
},
toString: function toString() {
return 'by.cssContainingText("' + cssSelector + '", "' + searchText + '")';
Expand Down Expand Up @@ -375,9 +379,10 @@ ProtractorBy.prototype.cssContainingText = function(cssSelector, searchText) {
*/
ProtractorBy.prototype.options = function(optionsDescriptor) {
return {
findElementsOverride: function(driver, using) {
findElementsOverride: function(driver, using, rootSelector) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findByOptions, optionsDescriptor, using));
webdriver.By.js(clientSideScripts.findByOptions, optionsDescriptor,
using, rootSelector));
},
toString: function toString() {
return 'by.option("' + optionsDescriptor + '")';
Expand Down
Loading