Socket
Socket
Sign inDemoInstall

protractor

Package Overview
Dependencies
Maintainers
1
Versions
103
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

protractor - npm Package Compare versions

Comparing version 0.1.3 to 0.2.0

7

package.json

@@ -10,2 +10,7 @@ {

},
"devDependencies" : {
"jasmine-node" : "~1.8.0",
"expect.js" : "~0.2.0",
"mocha" : "~1.10.0"
},
"repository" : {

@@ -16,3 +21,3 @@ "type" : "git",

"main" : "protractor.js",
"version" : "0.1.3"
"version" : "0.2.0"
}

@@ -5,3 +5,272 @@ var util = require('util');

var DEFER_LABEL = 'NG_DEFER_BOOTSTRAP!';
/**
* All scripts to be run on the client via executeAsyncScript or
* executeScript should be put here. These scripts are transmitted over
* the wire using their toString representation, and cannot reference
* external variables. They can, however use the array passed in to
* arguments. Instead of params, all functions on clientSideScripts
* should list the arguments array they expect.
*/
var clientSideScripts = {};
/**
* Wait until Angular has finished rendering and has
* no outstanding $http calls before continuing.
*
* arguments none
*/
clientSideScripts.waitForAngular = function() {
var callback = arguments[arguments.length - 1];
angular.element(document.body).injector().get('$browser').
notifyWhenNoOutstandingRequests(callback);
};
/**
* Find an element in the page by their angular binding.
*
* arguments[0] {string} The binding, e.g. {{cat.name}}
*
* @return {WebElement} The element containing the binding
*/
clientSideScripts.findBinding = function() {
var bindings = document.getElementsByClassName('ng-binding');
var matches = [];
var binding = arguments[0];
for (var i = 0; i < bindings.length; ++i) {
var bindingName = angular.element(bindings[i]).data().$binding[0].exp ||
angular.element(bindings[i]).data().$binding;
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[i]);
}
}
return matches[0]; // We can only return one with webdriver.findElement.
};
/**
* Find a list of elements in the page by their angular binding.
*
* arguments[0] {string} The binding, e.g. {{cat.name}}
*
* @return {Array.<WebElement>} The elements containing the binding
*/
clientSideScripts.findBindings = function() {
var bindings = document.getElementsByClassName('ng-binding');
var matches = [];
var binding = arguments[0];
for (var i = 0; i < bindings.length; ++i) {
var bindingName = angular.element(bindings[i]).data().$binding[0].exp ||
angular.element(bindings[i]).data().$binding;
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[i]);
}
}
return matches; // Return the whole array for webdriver.findElements.
};
/**
* Find a row within an ng-repeat.
*
* arguments[0] {string} The text of the repeater, e.g. 'cat in cats'
* arguments[1] {number} The row index
*
* @return {Element} The row element
*/
clientSideScripts.findRepeaterRow = function() {
var repeater = arguments[0];
var index = arguments[1];
var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat';
var repeatElems = document.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeatElems[i].getAttribute(attr).indexOf(repeater) != -1) {
rows.push(repeatElems[i]);
}
}
}
return rows[index - 1];
};
/**
* Find an element within an ng-repeat by its row and column.
*
* arguments[0] {string} The text of the repeater, e.g. 'cat in cats'
* arguments[1] {number} The row index
* arguments[2] {string} The column binding, e.g. '{{cat.name}}'
*
* @return {Element} The element
*/
clientSideScripts.findRepeaterElement = function() {
var matches = [];
var repeater = arguments[0];
var index = arguments[1];
var binding = arguments[2];
var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat';
var repeatElems = document.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeatElems[i].getAttribute(attr).indexOf(repeater) != -1) {
rows.push(repeatElems[i]);
}
}
}
var row = rows[index - 1];
var bindings = [];
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]);
}
for (var i = 0; i < bindings.length; ++i) {
var bindingName = angular.element(bindings[i]).data().$binding[0].exp ||
angular.element(bindings[i]).data().$binding;
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[i]);
}
}
// We can only return one with webdriver.findElement.
return matches[0];
};
/**
* Find the elements in a column of an ng-repeat.
*
* arguments[0] {string} The text of the repeater, e.g. 'cat in cats'
* arguments[1] {string} The column binding, e.g. '{{cat.name}}'
*
* @return {Array.<Element>} The elements in the column
*/
clientSideScripts.findRepeaterColumn = function() {
var matches = [];
var repeater = arguments[0];
var binding = arguments[1];
var rows = [];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat';
var repeatElems = document.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeatElems[i].getAttribute(attr).indexOf(repeater) != -1) {
rows.push(repeatElems[i]);
}
}
}
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 bindingName = angular.element(bindings[j]).data().$binding[0].exp ||
angular.element(bindings[j]).data().$binding;
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[j]);
}
}
}
return matches;
};
/**
* Find an input element by model name.
*
* arguments[0] {string} The model name
*
* @return {Element} The first matching input element.
*/
clientSideScripts.findInput = function() {
var model = arguments[0];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
for (var p = 0; p < prefixes.length; ++p) {
var selector = 'input[' + prefixes[p] + 'model=' + model + ']';
var inputs = document.querySelectorAll(selector);
if (inputs.length) {
return inputs[0];
}
}
};
/**
* Find an select element by model name.
*
* arguments[0] {string} The model name
*
* @return {Element} The first matching select element.
*/
clientSideScripts.findSelect = function() {
var model = arguments[0];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
for (var p = 0; p < prefixes.length; ++p) {
var selector = 'select[' + prefixes[p] + 'model=' + model + ']';
var inputs = document.querySelectorAll(selector);
if (inputs.length) {
return inputs[0];
}
}
};
/**
* Find an selected option element by model name.
*
* arguments[0] {string} The model name
*
* @return {Element} The first matching input element.
*/
clientSideScripts.findSelectedOption = function() {
var model = arguments[0];
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
for (var p = 0; p < prefixes.length; ++p) {
var selector =
'select[' + prefixes[p] + 'model=' + model + '] option:checked';
var inputs = document.querySelectorAll(selector);
if (inputs.length) {
return inputs[0];
}
}
};
/**
* Tests whether the angular global variable is present on a page. Retries
* twice in case the page is just loading slowly.
*
* arguments none
*
* @return {boolean} true if angular was found.
*/
clientSideScripts.testForAngular = function() {
var callback = arguments[arguments.length - 1];
var retry = function(n) {
if (window.angular && window.angular.resumeBootstrap) {
callback(true);
} else if (n < 1) {
callback(false)
} else {
window.setTimeout(function() {retry(n - 1)}, 1000);
}
}
if (window.angular && window.angular.resumeBootstrap) {
callback(true);
} else {
retry(3);
}
}
/**
* @param {webdriver.WebDriver} webdriver

@@ -26,7 +295,3 @@ * @constructor

Protractor.prototype.waitForAngular = function() {
return this.driver.executeAsyncScript(function() {
var callback = arguments[arguments.length - 1];
angular.element(document.body).injector().get('$browser').
notifyWhenNoOutstandingRequests(callback);
});
return this.driver.executeAsyncScript(clientSideScripts.waitForAngular);
};

@@ -48,2 +313,15 @@

/**
* See webdriver.WebDriver.findElements
*
* Waits for Angular to finish rendering before searching for elements.
*/
Protractor.prototype.findElements = function(locator, varArgs) {
this.waitForAngular();
if (locator.findArrayOverride) {
return locator.findArrayOverride(this.driver);
}
return this.driver.findElements(locator, varArgs);
};
/**
* Add a module to load before Angular whenever Protractor.get is called.

@@ -80,5 +358,14 @@ * Modules will be registered after existing modules already on the page,

'window.location.href = "' + destination + '"');
// Make sure the page is an Angular page.
this.driver.executeAsyncScript(clientSideScripts.testForAngular).
then(function(hasAngular) {
if (!hasAngular) {
throw new Error("Angular could not be found on the page " +
destination);
}
});
// At this point, Angular will pause for us, until angular.resumeBootstrap
// is called.
for (var i = 0; i < this.moduleScripts_.length; ++i) {

@@ -130,14 +417,9 @@ this.driver.executeScript(this.moduleScripts_[i]);

findOverride: function(driver) {
return driver.findElement(webdriver.By.js(function() {
var bindings = document.getElementsByClassName('ng-binding');
var matches = [];
var binding = arguments[0];
for (var i = 0; i < bindings.length; ++i) {
if (angular.element(bindings[i]).data().$binding[0].exp == binding) {
matches.push(bindings[i]);
}
}
return matches[0]; // We can only return one with webdriver.findElement.
}), bindingDescriptor);
return driver.findElement(webdriver.By.js(clientSideScripts.findBinding),
bindingDescriptor);
},
findArrayOverride: function(driver) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findBindings),
bindingDescriptor);
}

@@ -154,4 +436,6 @@ };

return {
using: 'css selector',
value: 'select[ng-model=' + model + ']'
findOverride: function(driver) {
return driver.findElement(
webdriver.By.js(clientSideScripts.findSelect), model);
}
};

@@ -162,4 +446,6 @@ };

return {
using: 'css selector',
value: 'select[ng-model=' + model + '] option:checked'
findOverride: function(driver) {
return driver.findElement(
webdriver.By.js(clientSideScripts.findSelectedOption), model);
}
};

@@ -170,4 +456,6 @@ };

return {
using: 'css selector',
value: 'input[ng-model=' + model + ']'
findOverride: function(driver) {
return driver.findElement(
webdriver.By.js(clientSideScripts.findInput), model);
}
};

@@ -189,2 +477,5 @@ };

* protractor.By.repeater("cat in pets").row(1).column("{{cat.name}}"));
* // Returns an array of WebElements from a column
* var ages = ptor.findElements(
* protractor.By.repeater("cat in pets").column("{{cat.age}}"));
*/

@@ -195,26 +486,13 @@ ProtractorBy.prototype.repeater = function(repeatDescriptor) {

return {
using: 'css selector',
value: '[ng-repeat="' + repeatDescriptor
+ '"]:nth-of-type(' + index + ')',
findOverride: function(driver) {
return driver.findElement(
webdriver.By.js(clientSideScripts.findRepeaterRow),
repeatDescriptor, index);
},
column: function(binding) {
return {
findOverride: function(driver) {
return driver.findElement(webdriver.By.js(function() {
var matches = [];
var repeater = arguments[0];
var index = arguments[1];
var binding = arguments[2];
var rows = document.querySelectorAll('[ng-repeat="'
+ repeater + '"]');
var row = rows[index - 1];
var bindings = row.getElementsByClassName('ng-binding');
for (var i = 0; i < bindings.length; ++i) {
if (angular.element(bindings[i]).data().$binding[0].exp == binding) {
matches.push(bindings[i]);
}
}
// We can only return one with webdriver.findElement.
return matches[0];
}), repeatDescriptor, index, binding);
return driver.findElement(
webdriver.By.js(clientSideScripts.findRepeaterElement),
repeatDescriptor, index, binding);
}

@@ -224,2 +502,11 @@ };

};
},
column: function(binding) {
return {
findArrayOverride: function(driver) {
return driver.findElements(
webdriver.By.js(clientSideScripts.findRepeaterColumn),
repeatDescriptor, binding);
}
}
}

@@ -226,0 +513,0 @@ };

9

README.md
Protractor
==========
Protractor is an end to end test framework for Angular applications built on top of [webdriverJS](https://code.google.com/p/selenium/wiki/WebDriverJs). It is still quite in progress.
Protractor is an end to end test framework for Angular applications built on top of [webdriverJS](https://code.google.com/p/selenium/wiki/WebDriverJs).

@@ -25,3 +25,4 @@ To run the sample tests

node httpspec.js
jasmine-node spec
mocha test

@@ -40,7 +41,7 @@ To just use Protractor

var webdriver = require('selenium-webdriver');
var protractor = require('./protractor.js');
var protractor = require('protractor');
// Configure and build your webdriver instance.
var ptor = protractor.wrapDriver(driver);
See httpspec.js for examples of use.
See spec/testAppSpec.js for examples of use.

@@ -47,0 +48,0 @@ Appendix A: Setting up a standalone selenium server

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc