Deployed the page to Github Pages.

This commit is contained in:
Batuhan Berk Başoğlu 2024-11-03 21:30:09 -05:00
parent 1d79754e93
commit 2c89899458
Signed by: batuhan-basoglu
SSH key fingerprint: SHA256:kEsnuHX+qbwhxSAXPUQ4ox535wFHu/hIRaa53FzxRpo
62797 changed files with 6551425 additions and 15279 deletions

0
node_modules/protractor/built/cli.d.ts generated vendored Normal file
View file

228
node_modules/protractor/built/cli.js generated vendored Normal file
View file

@ -0,0 +1,228 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const path = require("path");
const yargs = require("yargs");
/**
* The command line interface for interacting with the Protractor runner.
* It takes care of parsing command line options.
*
* Values from command line options override values from the config.
*/
let args = [];
process.argv.slice(2).forEach(function (arg) {
let flag = arg.split('=')[0];
switch (flag) {
case 'debug':
args.push('--nodeDebug');
args.push('true');
break;
case '-d':
case '--debug':
case '--debug-brk':
args.push('--v8Debug');
args.push('true');
break;
default:
args.push(arg);
break;
}
});
// TODO(cnishina): Make cli checks better.
let allowedNames = [
'seleniumServerJar',
'seleniumServerStartTimeout',
'localSeleniumStandaloneOpts',
'chromeDriver',
'seleniumAddress',
'seleniumSessionId',
'webDriverProxy',
'useBlockingProxy',
'blockingProxyUrl',
'sauceUser',
'sauceKey',
'sauceAgent',
'sauceBuild',
'sauceSeleniumUseHttp',
'sauceSeleniumAddress',
'browserstackUser',
'browserstackKey',
'browserstackProxy',
'kobitonUser',
'kobitonKey',
'testobjectUser',
'testobjectKey',
'directConnect',
'firefoxPath',
'noGlobals',
'specs',
'exclude',
'suites',
'suite',
'capabilities',
'multiCapabilities',
'getMultiCapabilities',
'maxSessions',
'verbose',
'verboseMultiSessions',
'baseUrl',
'rootElement',
'allScriptsTimeout',
'getPageTimeout',
'beforeLaunch',
'onPrepare',
'onComplete',
'onCleanUp',
'afterLaunch',
'params',
'resultJsonOutputFile',
'restartBrowserBetweenTests',
'untrackOutstandingTimeouts',
'ignoreUncaughtExceptions',
'framework',
'jasmineNodeOpts',
'mochaOpts',
'plugins',
'skipSourceMapSupport',
'disableEnvironmentOverrides',
'ng12Hybrid',
'seleniumArgs',
'jvmArgs',
'configDir',
'troubleshoot',
'seleniumPort',
'mockSelenium',
'v8Debug',
'nodeDebug',
'debuggerServerPort',
'frameworkPath',
'elementExplorer',
'debug',
'logLevel',
'disableChecks',
'browser',
'name',
'platform',
'platform-version',
'tags',
'build',
'grep',
'invert-grep',
'explorer',
'stackTrace'
];
let yargsOptions = {
describes: {
help: 'Print Protractor help menu',
version: 'Print Protractor version',
browser: 'Browsername, e.g. chrome or firefox',
seleniumAddress: 'A running selenium address to use',
seleniumSessionId: 'Attaching an existing session id',
seleniumServerJar: 'Location of the standalone selenium jar file',
seleniumPort: 'Optional port for the selenium standalone server',
baseUrl: 'URL to prepend to all relative paths',
rootElement: 'Element housing ng-app, if not html or body',
specs: 'Comma-separated list of files to test',
exclude: 'Comma-separated list of files to exclude',
verbose: 'Print full spec names',
stackTrace: 'Print stack trace on error',
params: 'Param object to be passed to the tests',
framework: 'Test framework to use: jasmine, mocha, or custom',
resultJsonOutputFile: 'Path to save JSON test result',
troubleshoot: 'Turn on troubleshooting output',
elementExplorer: 'Interactively test Protractor commands',
debuggerServerPort: 'Start a debugger server at specified port instead of repl',
disableChecks: 'Disable cli checks',
logLevel: 'Define Protractor log level [ERROR, WARN, INFO, DEBUG]'
},
aliases: {
browser: 'capabilities.browserName',
name: 'capabilities.name',
platform: 'capabilities.platform',
'platform-version': 'capabilities.version',
tags: 'capabilities.tags',
build: 'capabilities.build',
grep: 'jasmineNodeOpts.grep',
'invert-grep': 'jasmineNodeOpts.invertGrep',
explorer: 'elementExplorer'
},
strings: { 'capabilities.tunnel-identifier': '' }
};
yargs.usage('Usage: protractor [configFile] [options]\n' +
'configFile defaults to protractor.conf.js\n' +
'The [options] object will override values from the config file.\n' +
'See the reference config for a full list of options.');
for (let key of Object.keys(yargsOptions.describes)) {
yargs.describe(key, yargsOptions.describes[key]);
}
for (let key of Object.keys(yargsOptions.aliases)) {
yargs.alias(key, yargsOptions.aliases[key]);
}
for (let key of Object.keys(yargsOptions.strings)) {
yargs.string(key);
}
yargs.check(function (arg) {
if (arg._.length > 1) {
throw new Error('Error: more than one config file specified');
}
return true;
});
let argv = yargs.parse(args);
if (argv.help) {
yargs.showHelp();
process.exit(0);
}
if (argv.version) {
console.log('Version ' + require(path.resolve(__dirname, '../package.json')).version);
process.exit(0);
}
// Check to see if additional flags were used.
argv.unknownFlags_ = Object.keys(argv).filter((element) => {
return element !== '$0' && element !== '_' && allowedNames.indexOf(element) === -1;
});
/**
* Helper to resolve comma separated lists of file pattern strings relative to
* the cwd.
*
* @private
* @param {Array} list
*/
function processFilePatterns_(list) {
return list.split(',').map(function (spec) {
return path.resolve(process.cwd(), spec);
});
}
;
if (argv.specs) {
argv.specs = processFilePatterns_(argv.specs);
}
if (argv.exclude) {
argv.exclude = processFilePatterns_(argv.exclude);
}
if (argv.capabilities && argv.capabilities.chromeOptions) {
// ensure that single options (which optimist parses as a string)
// are passed in an array in chromeOptions when required:
// https://sites.google.com/a/chromium.org/chromedriver/capabilities#TOC-chromeOptions-object
['args', 'extensions', 'excludeSwitches', 'windowTypes'].forEach((key) => {
if (typeof argv.capabilities.chromeOptions[key] === 'string') {
argv.capabilities.chromeOptions[key] = [argv.capabilities.chromeOptions[key]];
}
});
}
// Use default configuration, if it exists.
let configFile = argv._[0];
if (!configFile) {
if (fs.existsSync('./protractor.conf.js')) {
configFile = './protractor.conf.js';
}
}
if (!configFile && !argv.elementExplorer && args.length < 3) {
console.log('**you must either specify a configuration file ' +
'or at least 3 options. See below for the options:\n');
yargs.showHelp();
process.exit(1);
}
// Run the launcher
const launcher = require("./launcher");
launcher.init(configFile, argv);
//# sourceMappingURL=cli.js.map

939
node_modules/protractor/built/clientsidescripts.js generated vendored Normal file
View file

@ -0,0 +1,939 @@
/**
* All scripts to be run on the client via executeAsyncScript or
* executeScript should be put here.
*
* NOTE: These scripts are transmitted over the wire as JavaScript text
* constructed using their toString representation, and *cannot*
* reference external variables.
*
* Some implementations seem to have issues with // comments, so use star-style
* inside scripts. (TODO: add issue number / example implementations
* that caused the switch to avoid the // comments.)
*/
// jshint browser: true
// jshint shadow: true
/* global angular */
var functions = {};
///////////////////////////////////////////////////////
//// ////
//// HELPERS ////
//// ////
///////////////////////////////////////////////////////
/* Wraps a function up into a string with its helper functions so that it can
* call those helper functions client side
*
* @param {function} fun The function to wrap up with its helpers
* @param {...function} The helper functions. Each function must be named
*
* @return {string} The string which, when executed, will invoke fun in such a
* way that it has access to its helper functions
*/
function wrapWithHelpers(fun) {
var helpers = Array.prototype.slice.call(arguments, 1);
if (!helpers.length) {
return fun;
}
var FunClass = Function; // Get the linter to allow this eval
return new FunClass(
helpers.join(';') + String.fromCharCode(59) +
' return (' + fun.toString() + ').apply(this, arguments);');
}
/* Tests if an ngRepeat matches a repeater
*
* @param {string} ngRepeat The ngRepeat to test
* @param {string} repeater The repeater to test against
* @param {boolean} exact If the ngRepeat expression needs to match the whole
* repeater (not counting any `track by ...` modifier) or if it just needs to
* match a substring
* @return {boolean} If the ngRepeat matched the repeater
*/
function repeaterMatch(ngRepeat, repeater, exact) {
if (exact) {
return ngRepeat.split(' track by ')[0].split(' as ')[0].split('|')[0].
split('=')[0].trim() == repeater;
} else {
return ngRepeat.indexOf(repeater) != -1;
}
}
/* Tries to find $$testability and possibly $injector for an ng1 app
*
* By default, doesn't care about $injector if it finds $$testability. However,
* these priorities can be reversed.
*
* @param {string=} selector The selector for the element with the injector. If
* falsy, tries a variety of methods to find an injector
* @param {boolean=} injectorPlease Prioritize finding an injector
* @return {$$testability?: Testability, $injector?: Injector} Returns whatever
* ng1 app hooks it finds
*/
function getNg1Hooks(selector, injectorPlease) {
function tryEl(el) {
try {
if (!injectorPlease && angular.getTestability) {
var $$testability = angular.getTestability(el);
if ($$testability) {
return {$$testability: $$testability};
}
} else {
var $injector = angular.element(el).injector();
if ($injector) {
return {$injector: $injector};
}
}
} catch(err) {}
}
function trySelector(selector) {
var els = document.querySelectorAll(selector);
for (var i = 0; i < els.length; i++) {
var elHooks = tryEl(els[i]);
if (elHooks) {
return elHooks;
}
}
}
if (selector) {
return trySelector(selector);
} else if (window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__) {
var $injector = window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__;
var $$testability = null;
try {
$$testability = $injector.get('$$testability');
} catch (e) {}
return {$injector: $injector, $$testability: $$testability};
} else {
return tryEl(document.body) ||
trySelector('[ng-app]') || trySelector('[ng\\:app]') ||
trySelector('[ng-controller]') || trySelector('[ng\\:controller]');
}
}
///////////////////////////////////////////////////////
//// ////
//// SCRIPTS ////
//// ////
///////////////////////////////////////////////////////
/**
* Wait until Angular has finished rendering and has
* no outstanding $http calls before continuing. The specific Angular app
* is determined by the rootSelector.
*
* Asynchronous.
*
* @param {string} rootSelector The selector housing an ng-app
* @param {function(string)} callback callback. If a failure occurs, it will
* be passed as a parameter.
*/
functions.waitForAngular = function(rootSelector, callback) {
try {
// Wait for both angular1 testability and angular2 testability.
var testCallback = callback;
// Wait for angular1 testability first and run waitForAngular2 as a callback
var waitForAngular1 = function(callback) {
if (window.angular) {
var hooks = getNg1Hooks(rootSelector);
if (!hooks){
callback(); // not an angular1 app
}
else{
if (hooks.$$testability) {
hooks.$$testability.whenStable(callback);
} else if (hooks.$injector) {
hooks.$injector.get('$browser')
.notifyWhenNoOutstandingRequests(callback);
} else if (!rootSelector) {
throw new Error(
'Could not automatically find injector on page: "' +
window.location.toString() + '". Consider using config.rootEl');
} else {
throw new Error(
'root element (' + rootSelector + ') has no injector.' +
' this may mean it is not inside ng-app.');
}
}
}
else {callback();} // not an angular1 app
};
// Wait for Angular2 testability and then run test callback
var waitForAngular2 = function() {
if (window.getAngularTestability) {
if (rootSelector) {
var testability = null;
var el = document.querySelector(rootSelector);
try{
testability = window.getAngularTestability(el);
}
catch(e){}
if (testability) {
testability.whenStable(testCallback);
return;
}
}
// Didn't specify root element or testability could not be found
// by rootSelector. This may happen in a hybrid app, which could have
// more than one root.
var testabilities = window.getAllAngularTestabilities();
var count = testabilities.length;
// No angular2 testability, this happens when
// going to a hybrid page and going back to a pure angular1 page
if (count === 0) {
testCallback();
return;
}
var decrement = function() {
count--;
if (count === 0) {
testCallback();
}
};
testabilities.forEach(function(testability) {
testability.whenStable(decrement);
});
}
else {testCallback();} // not an angular2 app
};
if (!(window.angular) && !(window.getAngularTestability)) {
// no testability hook
throw new Error(
'both angularJS testability and angular testability are undefined.' +
' This could be either ' +
'because this is a non-angular page or because your test involves ' +
'client-side navigation, which can interfere with Protractor\'s ' +
'bootstrapping. See http://git.io/v4gXM for details');
} else {waitForAngular1(waitForAngular2);} // Wait for angular1 and angular2
// Testability hooks sequentially
} catch (err) {
callback(err.message);
}
};
/**
* Find a list of elements in the page by their angular binding.
*
* @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, rootSelector) {
using = using || document;
if (angular.getTestability) {
return getNg1Hooks(rootSelector).$$testability.
findBindings(using, binding, exactMatch);
}
var bindings = using.getElementsByClassName('ng-binding');
var matches = [];
for (var i = 0; i < bindings.length; ++i) {
var dataBinding = angular.element(bindings[i]).data('$binding');
if (dataBinding) {
var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
if (exactMatch) {
var matcher = new RegExp('({|\\s|^|\\|)' +
/* See http://stackoverflow.com/q/3561711 */
binding.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&') +
'(}|\\s|$|\\|)');
if (matcher.test(bindingName)) {
matches.push(bindings[i]);
}
} else {
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[i]);
}
}
}
}
return matches; /* Return the whole array for webdriver.findElements. */
};
/**
* Find an array of elements matching a row within an ng-repeat.
* Always returns an array of only one element for plain old ng-repeat.
* Returns an array of all the elements in one segment for ng-repeat-start.
*
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
* @param {boolean} exact Whether the repeater needs to be matched exactly
* @param {number} index The row index.
* @param {Element} using The scope of the search.
*
* @return {Array.<Element>} The row of the repeater, or an array of elements
* in the first row in the case of ng-repeat-start.
*/
function findRepeaterRows(repeater, exact, index, using) {
using = using || document;
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
var rows = [];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat';
var repeatElems = using.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
rows.push(repeatElems[i]);
}
}
}
/* multiRows is an array of arrays, where each inner array contains
one row of elements. */
var multiRows = [];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat-start';
var repeatElems = using.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
var elem = repeatElems[i];
var row = [];
while (elem.nodeType != 8 ||
!repeaterMatch(elem.nodeValue, repeater)) {
if (elem.nodeType == 1) {
row.push(elem);
}
elem = elem.nextSibling;
}
multiRows.push(row);
}
}
}
var row = rows[index] || [], multiRow = multiRows[index] || [];
return [].concat(row, multiRow);
}
functions.findRepeaterRows = wrapWithHelpers(findRepeaterRows, repeaterMatch);
/**
* Find all rows of an ng-repeat.
*
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
* @param {boolean} exact Whether the repeater needs to be matched exactly
* @param {Element} using The scope of the search.
*
* @return {Array.<Element>} All rows of the repeater.
*/
function findAllRepeaterRows(repeater, exact, using) {
using = using || document;
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 = using.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
rows.push(repeatElems[i]);
}
}
}
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat-start';
var repeatElems = using.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
var elem = repeatElems[i];
while (elem.nodeType != 8 ||
!repeaterMatch(elem.nodeValue, repeater)) {
if (elem.nodeType == 1) {
rows.push(elem);
}
elem = elem.nextSibling;
}
}
}
}
return rows;
}
functions.findAllRepeaterRows = wrapWithHelpers(findAllRepeaterRows, repeaterMatch);
/**
* Find an element within an ng-repeat by its row and column.
*
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
* @param {boolean} exact Whether the repeater needs to be matched exactly
* @param {number} index The row index.
* @param {string} binding The column binding, e.g. '{{cat.name}}'.
* @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.
*/
function findRepeaterElement(repeater, exact, index, binding, using, rootSelector) {
var matches = [];
using = using || document;
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 = using.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
rows.push(repeatElems[i]);
}
}
}
/* multiRows is an array of arrays, where each inner array contains
one row of elements. */
var multiRows = [];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat-start';
var repeatElems = using.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
var elem = repeatElems[i];
var row = [];
while (elem.nodeType != 8 || (elem.nodeValue &&
!repeaterMatch(elem.nodeValue, repeater))) {
if (elem.nodeType == 1) {
row.push(elem);
}
elem = elem.nextSibling;
}
multiRows.push(row);
}
}
}
var row = rows[index];
var multiRow = multiRows[index];
var bindings = [];
if (row) {
if (angular.getTestability) {
matches.push.apply(
matches,
getNg1Hooks(rootSelector).$$testability.findBindings(row, binding));
} else {
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]);
}
}
}
if (multiRow) {
for (var i = 0; i < multiRow.length; ++i) {
var rowElem = multiRow[i];
if (angular.getTestability) {
matches.push.apply(
matches,
getNg1Hooks(rootSelector).$$testability.findBindings(rowElem,
binding));
} else {
if (rowElem.className.indexOf('ng-binding') != -1) {
bindings.push(rowElem);
}
var childBindings = rowElem.getElementsByClassName('ng-binding');
for (var j = 0; j < childBindings.length; ++j) {
bindings.push(childBindings[j]);
}
}
}
}
for (var i = 0; i < bindings.length; ++i) {
var dataBinding = angular.element(bindings[i]).data('$binding');
if (dataBinding) {
var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[i]);
}
}
}
return matches;
}
functions.findRepeaterElement =
wrapWithHelpers(findRepeaterElement, repeaterMatch, getNg1Hooks);
/**
* Find the elements in a column of an ng-repeat.
*
* @param {string} repeater The text of the repeater, e.g. 'cat in cats'.
* @param {boolean} exact Whether the repeater needs to be matched exactly
* @param {string} binding The column binding, e.g. '{{cat.name}}'.
* @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.
*/
function findRepeaterColumn(repeater, exact, binding, using, rootSelector) {
var matches = [];
using = using || document;
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 = using.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
rows.push(repeatElems[i]);
}
}
}
/* multiRows is an array of arrays, where each inner array contains
one row of elements. */
var multiRows = [];
for (var p = 0; p < prefixes.length; ++p) {
var attr = prefixes[p] + 'repeat-start';
var repeatElems = using.querySelectorAll('[' + attr + ']');
attr = attr.replace(/\\/g, '');
for (var i = 0; i < repeatElems.length; ++i) {
if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
var elem = repeatElems[i];
var row = [];
while (elem.nodeType != 8 || (elem.nodeValue &&
!repeaterMatch(elem.nodeValue, repeater))) {
if (elem.nodeType == 1) {
row.push(elem);
}
elem = elem.nextSibling;
}
multiRows.push(row);
}
}
}
var bindings = [];
for (var i = 0; i < rows.length; ++i) {
if (angular.getTestability) {
matches.push.apply(
matches,
getNg1Hooks(rootSelector).$$testability.findBindings(rows[i],
binding));
} else {
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 i = 0; i < multiRows.length; ++i) {
for (var j = 0; j < multiRows[i].length; ++j) {
if (angular.getTestability) {
matches.push.apply(
matches,
getNg1Hooks(rootSelector).$$testability.findBindings(
multiRows[i][j], binding));
} else {
var elem = multiRows[i][j];
if (elem.className.indexOf('ng-binding') != -1) {
bindings.push(elem);
}
var childBindings = elem.getElementsByClassName('ng-binding');
for (var k = 0; k < childBindings.length; ++k) {
bindings.push(childBindings[k]);
}
}
}
}
for (var j = 0; j < bindings.length; ++j) {
var dataBinding = angular.element(bindings[j]).data('$binding');
if (dataBinding) {
var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
if (bindingName.indexOf(binding) != -1) {
matches.push(bindings[j]);
}
}
}
return matches;
}
functions.findRepeaterColumn =
wrapWithHelpers(findRepeaterColumn, repeaterMatch, getNg1Hooks);
/**
* Find elements by model name.
*
* @param {string} model The model name.
* @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, rootSelector) {
using = using || document;
if (angular.getTestability) {
return getNg1Hooks(rootSelector).$$testability.
findModels(using, model, true);
}
var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
for (var p = 0; p < prefixes.length; ++p) {
var selector = '[' + prefixes[p] + 'model="' + model + '"]';
var elements = using.querySelectorAll(selector);
if (elements.length) {
return elements;
}
}
};
/**
* Find elements by options.
*
* @param {string} optionsDescriptor The descriptor for the option
* (i.e. fruit for fruit in fruits).
* @param {Element} using The scope of the search.
*
* @return {Array.<Element>} The matching elements.
*/
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) {
var selector = '[' + prefixes[p] + 'options="' + optionsDescriptor + '"] option';
var elements = using.querySelectorAll(selector);
if (elements.length) {
return elements;
}
}
};
/**
* Find buttons by textual content.
*
* @param {string} searchText The exact text to match.
* @param {Element} using The scope of the search.
*
* @return {Array.<Element>} The matching elements.
*/
functions.findByButtonText = function(searchText, using) {
using = using || document;
var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
var matches = [];
for (var i = 0; i < elements.length; ++i) {
var element = elements[i];
var elementText;
if (element.tagName.toLowerCase() == 'button') {
elementText = element.textContent || element.innerText || '';
} else {
elementText = element.value;
}
if (elementText.trim() === searchText) {
matches.push(element);
}
}
return matches;
};
/**
* Find buttons by textual content.
*
* @param {string} searchText The exact text to match.
* @param {Element} using The scope of the search.
*
* @return {Array.<Element>} The matching elements.
*/
functions.findByPartialButtonText = function(searchText, using) {
using = using || document;
var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
var matches = [];
for (var i = 0; i < elements.length; ++i) {
var element = elements[i];
var elementText;
if (element.tagName.toLowerCase() == 'button') {
elementText = element.textContent || element.innerText || '';
} else {
elementText = element.value;
}
if (elementText.indexOf(searchText) > -1) {
matches.push(element);
}
}
return matches;
};
/**
* Find elements by css selector and textual content.
*
* @param {string} cssSelector The css selector to match.
* @param {string} searchText The exact text to match or a serialized regex.
* @param {Element} using The scope of the search.
*
* @return {Array.<Element>} An array of matching elements.
*/
functions.findByCssContainingText = function(cssSelector, searchText, using) {
using = using || document;
if (searchText.indexOf('__REGEXP__') === 0) {
var match = searchText.split('__REGEXP__')[1].match(/\/(.*)\/(.*)?/);
searchText = new RegExp(match[1], match[2] || '');
}
var elements = using.querySelectorAll(cssSelector);
var matches = [];
for (var i = 0; i < elements.length; ++i) {
var element = elements[i];
var elementText = element.textContent || element.innerText || '';
var elementMatches = searchText instanceof RegExp ?
searchText.test(elementText) :
elementText.indexOf(searchText) > -1;
if (elementMatches) {
matches.push(element);
}
}
return matches;
};
/**
* Tests whether the angular global variable is present on a page. Retries
* in case the page is just loading slowly.
*
* Asynchronous.
*
* @param {number} attempts Number of times to retry.
* @param {boolean} ng12Hybrid Flag set if app is a hybrid of angular 1 and 2
* @param {function({version: ?number, message: ?string})} asyncCallback callback
*
*/
functions.testForAngular = function(attempts, ng12Hybrid, asyncCallback) {
var callback = function(args) {
setTimeout(function() {
asyncCallback(args);
}, 0);
};
var definitelyNg1 = !!ng12Hybrid;
var definitelyNg2OrNewer = false;
var check = function(n) {
try {
/* Figure out which version of angular we're waiting on */
if (!definitelyNg1 && !definitelyNg2OrNewer) {
if (window.angular && !(window.angular.version && window.angular.version.major > 1)) {
definitelyNg1 = true;
} else if (window.getAllAngularTestabilities) {
definitelyNg2OrNewer = true;
}
}
/* See if our version of angular is ready */
if (definitelyNg1) {
if (window.angular && window.angular.resumeBootstrap) {
return callback({ver: 1});
}
} else if (definitelyNg2OrNewer) {
if (true /* ng2 has no resumeBootstrap() */) {
return callback({ver: 2});
}
}
/* Try again (or fail) */
if (n < 1) {
if (definitelyNg1 && window.angular) {
callback({message: 'angular never provided resumeBootstrap'});
} else if (ng12Hybrid && !window.angular) {
callback({message: 'angular 1 never loaded' +
window.getAllAngularTestabilities ? ' (are you sure this app ' +
'uses ngUpgrade? Try un-setting ng12Hybrid)' : ''});
} else {
callback({message: 'retries looking for angular exceeded'});
}
} else {
window.setTimeout(function() {check(n - 1);}, 1000);
}
} catch (e) {
callback({message: e});
}
};
check(attempts);
};
/**
* Evalute an Angular expression in the context of a given element.
*
* @param {Element} element The element in whose scope to evaluate.
* @param {string} expression The expression to evaluate.
*
* @return {?Object} The result of the evaluation.
*/
functions.evaluate = function(element, expression) {
return angular.element(element).scope().$eval(expression);
};
functions.allowAnimations = function(element, value) {
var ngElement = angular.element(element);
if (ngElement.allowAnimations) {
// AngularDart: $testability API.
return ngElement.allowAnimations(value);
} else {
// AngularJS
var enabledFn = ngElement.injector().get('$animate').enabled;
return (value == null) ? enabledFn() : enabledFn(value);
}
};
/**
* Return the current url using $location.absUrl().
*
* @param {string} selector The selector housing an ng-app
*/
functions.getLocationAbsUrl = function(selector) {
var hooks = getNg1Hooks(selector);
if (angular.getTestability) {
return hooks.$$testability.getLocation();
}
return hooks.$injector.get('$location').absUrl();
};
/**
* Browse to another page using in-page navigation.
*
* @param {string} selector The selector housing an ng-app
* @param {string} url In page URL using the same syntax as $location.url(),
* /path?search=a&b=c#hash
*/
functions.setLocation = function(selector, url) {
var hooks = getNg1Hooks(selector);
if (angular.getTestability) {
return hooks.$$testability.setLocation(url);
}
var $injector = hooks.$injector;
var $location = $injector.get('$location');
var $rootScope = $injector.get('$rootScope');
if (url !== $location.url()) {
$location.url(url);
$rootScope.$digest();
}
};
/**
* Retrieve the pending $http requests.
*
* @param {string} selector The selector housing an ng-app
* @return {!Array<!Object>} An array of pending http requests.
*/
functions.getPendingHttpRequests = function(selector) {
var hooks = getNg1Hooks(selector, true);
var $http = hooks.$injector.get('$http');
return $http.pendingRequests;
};
['waitForAngular', 'findBindings', 'findByModel', 'getLocationAbsUrl',
'setLocation', 'getPendingHttpRequests'].forEach(function(funName) {
functions[funName] = wrapWithHelpers(functions[funName], getNg1Hooks);
});
/* Publish all the functions as strings to pass to WebDriver's
* exec[Async]Script. In addition, also include a script that will
* install all the functions on window (for debugging.)
*
* We also wrap any exceptions thrown by a clientSideScripts function
* that is not an instance of the Error type into an Error type. If we
* don't do so, then the resulting stack trace is completely unhelpful
* and the exception message is just "unknown error." These types of
* exceptions are the common case for dart2js code. This wrapping gives
* us the Dart stack trace and exception message.
*/
var util = require('util');
var scriptsList = [];
var scriptFmt = (
'try { return (%s).apply(this, arguments); }\n' +
'catch(e) { throw (e instanceof Error) ? e : new Error(e); }');
for (var fnName in functions) {
if (functions.hasOwnProperty(fnName)) {
exports[fnName] = util.format(scriptFmt, functions[fnName]);
scriptsList.push(util.format('%s: %s', fnName, functions[fnName]));
}
}
exports.installInBrowser = (util.format(
'window.clientSideScripts = {%s};', scriptsList.join(', ')));
/**
* Automatically installed by Protractor when a page is loaded, this
* default mock module decorates $timeout to keep track of any
* outstanding timeouts.
*
* @param {boolean} trackOutstandingTimeouts
*/
exports.protractorBaseModuleFn = function(trackOutstandingTimeouts) {
var ngMod = angular.module('protractorBaseModule_', []).config([
'$compileProvider',
function($compileProvider) {
if ($compileProvider.debugInfoEnabled) {
$compileProvider.debugInfoEnabled(true);
}
}
]);
if (trackOutstandingTimeouts) {
ngMod.config([
'$provide',
function ($provide) {
$provide.decorator('$timeout', [
'$delegate',
function ($delegate) {
var $timeout = $delegate;
var taskId = 0;
if (!window['NG_PENDING_TIMEOUTS']) {
window['NG_PENDING_TIMEOUTS'] = {};
}
var extendedTimeout= function() {
var args = Array.prototype.slice.call(arguments);
if (typeof(args[0]) !== 'function') {
return $timeout.apply(null, args);
}
taskId++;
var fn = args[0];
window['NG_PENDING_TIMEOUTS'][taskId] =
fn.toString();
var wrappedFn = (function(taskId_) {
return function() {
delete window['NG_PENDING_TIMEOUTS'][taskId_];
return fn.apply(null, arguments);
};
})(taskId);
args[0] = wrappedFn;
var promise = $timeout.apply(null, args);
promise.ptorTaskId_ = taskId;
return promise;
};
extendedTimeout.cancel = function() {
var taskId_ = arguments[0] && arguments[0].ptorTaskId_;
if (taskId_) {
delete window['NG_PENDING_TIMEOUTS'][taskId_];
}
return $timeout.cancel.apply($timeout, arguments);
};
return extendedTimeout;
}
]);
}
]);
}
};

50
node_modules/protractor/built/configParser.d.ts generated vendored Normal file
View file

@ -0,0 +1,50 @@
import { Config } from './config';
export declare class ConfigParser {
private config_;
constructor();
/**
* Resolve a list of file patterns into a list of individual file paths.
*
* @param {Array.<string> | string} patterns
* @param {=boolean} opt_omitWarnings Whether to omit did not match warnings
* @param {=string} opt_relativeTo Path to resolve patterns against
*
* @return {Array} The resolved file paths.
*/
static resolveFilePatterns(patterns: string[] | string, opt_omitWarnings?: boolean, opt_relativeTo?: string): string[];
/**
* Returns only the specs that should run currently based on `config.suite`
*
* @return {Array} An array of globs locating the spec files
*/
static getSpecs(config: Config): string[];
/**
* Add the options in the parameter config to this runner instance.
*
* @private
* @param {Object} additionalConfig
* @param {string} relativeTo the file path to resolve paths against
*/
private addConfig_(additionalConfig, relativeTo);
/**
* Public function specialized towards merging in a file's config
*
* @public
* @param {String} filename
*/
addFileConfig(filename: string): ConfigParser;
/**
* Public function specialized towards merging in config from argv
*
* @public
* @param {Object} argv
*/
addConfig(argv: any): ConfigParser;
/**
* Public getter for the final, computed config object
*
* @public
* @return {Object} config
*/
getConfig(): Config;
}

215
node_modules/protractor/built/configParser.js generated vendored Normal file
View file

@ -0,0 +1,215 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const glob = require("glob");
const path = require("path");
const exitCodes_1 = require("./exitCodes");
const logger_1 = require("./logger");
let logger = new logger_1.Logger('configParser');
// Coffee is required here to enable config files written in coffee-script.
try {
require('coffee-script').register();
}
catch (e) {
// Intentionally blank - ignore if coffee-script is not available.
}
// CoffeeScript lost the hyphen in the module name a long time ago, all new version are named this:
try {
require('coffeescript').register();
}
catch (e) {
// Intentionally blank - ignore if coffeescript is not available.
}
// LiveScript is required here to enable config files written in LiveScript.
try {
require('LiveScript');
}
catch (e) {
// Intentionally blank - ignore if LiveScript is not available.
}
class ConfigParser {
constructor() {
// Default configuration.
this.config_ = {
specs: [],
multiCapabilities: [],
verboseMultiSessions: false,
rootElement: '',
allScriptsTimeout: 11000,
getPageTimeout: 10000,
params: {},
framework: 'jasmine',
jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: (30 * 1000) },
seleniumArgs: [],
mochaOpts: { ui: 'bdd', reporter: 'list' },
configDir: './',
noGlobals: false,
plugins: [],
skipSourceMapSupport: false,
ng12Hybrid: false
};
}
/**
* Resolve a list of file patterns into a list of individual file paths.
*
* @param {Array.<string> | string} patterns
* @param {=boolean} opt_omitWarnings Whether to omit did not match warnings
* @param {=string} opt_relativeTo Path to resolve patterns against
*
* @return {Array} The resolved file paths.
*/
static resolveFilePatterns(patterns, opt_omitWarnings, opt_relativeTo) {
let resolvedFiles = [];
let cwd = opt_relativeTo || process.cwd();
patterns = (typeof patterns === 'string') ? [patterns] : patterns;
if (patterns) {
for (let fileName of patterns) {
let matches = glob.hasMagic(fileName) ? glob.sync(fileName, { cwd }) : [fileName];
if (!matches.length && !opt_omitWarnings) {
logger.warn('pattern ' + fileName + ' did not match any files.');
}
for (let match of matches) {
let resolvedPath = path.resolve(cwd, match);
resolvedFiles.push(resolvedPath);
}
}
}
return resolvedFiles;
}
/**
* Returns only the specs that should run currently based on `config.suite`
*
* @return {Array} An array of globs locating the spec files
*/
static getSpecs(config) {
let specs = [];
if (config.suite) {
config.suite.split(',').forEach((suite) => {
let suiteList = config.suites ? config.suites[suite] : null;
if (suiteList == null) {
throw new exitCodes_1.ConfigError(logger, 'Unknown test suite: ' + suite);
}
union(specs, makeArray(suiteList));
});
return specs;
}
if (config.specs.length > 0) {
return config.specs;
}
Object.keys(config.suites || {}).forEach((suite) => {
union(specs, makeArray(config.suites[suite]));
});
return specs;
}
/**
* Add the options in the parameter config to this runner instance.
*
* @private
* @param {Object} additionalConfig
* @param {string} relativeTo the file path to resolve paths against
*/
addConfig_(additionalConfig, relativeTo) {
// All filepaths should be kept relative to the current config location.
// This will not affect absolute paths.
['seleniumServerJar', 'chromeDriver', 'firefoxPath', 'frameworkPath', 'geckoDriver',
'onPrepare']
.forEach((name) => {
if (additionalConfig[name] && typeof additionalConfig[name] === 'string') {
additionalConfig[name] = path.resolve(relativeTo, additionalConfig[name]);
}
});
merge_(this.config_, additionalConfig);
}
/**
* Public function specialized towards merging in a file's config
*
* @public
* @param {String} filename
*/
addFileConfig(filename) {
if (!filename) {
return this;
}
let filePath = path.resolve(process.cwd(), filename);
let fileConfig;
try {
fileConfig = require(filePath).config;
}
catch (e) {
throw new exitCodes_1.ConfigError(logger, 'failed loading configuration file ' + filename, e);
}
if (!fileConfig) {
throw new exitCodes_1.ConfigError(logger, 'configuration file ' + filename + ' did not export a config object');
}
fileConfig.configDir = path.dirname(filePath);
this.addConfig_(fileConfig, fileConfig.configDir);
return this;
}
/**
* Public function specialized towards merging in config from argv
*
* @public
* @param {Object} argv
*/
addConfig(argv) {
this.addConfig_(argv, process.cwd());
return this;
}
/**
* Public getter for the final, computed config object
*
* @public
* @return {Object} config
*/
getConfig() {
return this.config_;
}
}
exports.ConfigParser = ConfigParser;
/**
* Merge config objects together.
*
* @private
* @param {Object} into
* @param {Object} from
*
* @return {Object} The 'into' config.
*/
let merge_ = function (into, from) {
for (let key in from) {
if (into[key] instanceof Object && !(into[key] instanceof Array) &&
!(into[key] instanceof Function)) {
merge_(into[key], from[key]);
}
else {
into[key] = from[key];
}
}
return into;
};
/**
* Returns the item if it's an array or puts the item in an array
* if it was not one already.
*/
let makeArray = function (item) {
return Array.isArray(item) ? item : [item];
};
/**
* Adds to an array all the elements in another array without adding any
* duplicates
*
* @param {string[]} dest The array to add to
* @param {string[]} src The array to copy from
*/
let union = function (dest, src) {
let elems = {};
for (let key in dest) {
elems[dest[key]] = true;
}
for (let key in src) {
if (!elems[src[key]]) {
dest.push(src[key]);
elems[src[key]] = true;
}
}
};
//# sourceMappingURL=configParser.js.map

View file

@ -0,0 +1,157 @@
var repl = require('repl');
var debuggerCommons = require('../debuggerCommons');
var CommandRepl = require('../modes/commandRepl');
/**
* BETA BETA BETA
* Custom explorer to test protractor commands.
*
* @constructor
*/
var WdRepl = function() {
this.client;
};
/**
* Instantiate a server to handle IO.
* @param {number} port The port to start the server.
* @private
*/
WdRepl.prototype.initServer_ = function(port) {
var net = require('net');
var self = this;
var cmdRepl = new CommandRepl(this.client);
var received = '';
net.createServer(function(sock) {
sock.on('data', function(data) {
received += data.toString();
var eolIndex = received.indexOf('\r\n');
if (eolIndex === 0) {
return;
}
var input = received.substring(0, eolIndex);
received = received.substring(eolIndex + 2);
if (data[0] === 0x1D) {
// '^]': term command
self.client.req({command: 'disconnect'}, function() {
// Intentionally blank.
});
sock.end();
// TODO(juliemr): Investigate why this is necessary. At this point, there
// should be no active listeners so this process should just exit
// by itself.
process.exit(0);
} else if (input[input.length - 1] === '\t') {
// If the last character is the TAB key, this is an autocomplete
// request. We use everything before the TAB as the init data to feed
// into autocomplete.
input = input.substring(0, input.length - 1);
cmdRepl.complete(input, function(err, res) {
if (err) {
sock.write('ERROR: ' + err + '\r\n');
} else {
sock.write(JSON.stringify(res) + '\r\n');
}
});
} else {
// Normal input
input = input.trim();
cmdRepl.stepEval(input, function(err, res) {
if (err) {
sock.write('ERROR: ' + err + '\r\n');
return;
}
if (res === undefined) {
res = '';
}
sock.write(res + '\r\n');
});
}
});
}).listen(port);
console.log('Server listening on 127.0.0.1:' + port);
};
/**
* Instantiate a repl to handle IO.
* @private
*/
WdRepl.prototype.initRepl_ = function() {
var self = this;
var cmdRepl = new CommandRepl(this.client);
// Eval function for processing a single step in repl.
var stepEval = function(cmd, context, filename, callback) {
// The command that eval feeds is of the form '(CMD\n)', so we trim the
// double quotes and new line.
cmd = debuggerCommons.trimReplCmd(cmd);
cmdRepl.stepEval(cmd, function(err, res) {
// Result is a string representation of the evaluation.
if (res !== undefined) {
console.log(res);
}
callback(err, undefined);
});
};
var replServer = repl.start({
prompt: cmdRepl.prompt,
input: process.stdin,
output: process.stdout,
eval: stepEval,
useGlobal: false,
ignoreUndefined: true,
completer: cmdRepl.complete.bind(cmdRepl)
});
replServer.on('exit', function() {
console.log('Element Explorer Exiting...');
self.client.req({command: 'disconnect'}, function() {
// TODO(juliemr): Investigate why this is necessary. At this point, there
// should be no active listeners so this process should just exit
// by itself.
process.exit(0);
});
});
};
/**
* Instantiate a repl or a server.
* @private
*/
WdRepl.prototype.initReplOrServer_ = function() {
// Note instead of starting either repl or server, another approach is to
// feed the server socket into the repl as the input/output streams. The
// advantage is that the process becomes much more realistic because now we're
// using the normal repl. However, it was not possible to test autocomplete
// this way since we cannot immitate the TAB key over the wire.
var debuggerServerPort = process.argv[4];
if (debuggerServerPort) {
this.initServer_(debuggerServerPort);
} else {
this.initRepl_();
}
};
/**
* Initiate the debugger.
* @public
*/
WdRepl.prototype.init = function() {
var self = this;
this.client = debuggerCommons.attachDebugger(process.argv[2], process.argv[3]);
this.client.once('ready', function() {
debuggerCommons.setEvaluateBreakpoint(self.client, function() {
process.send('ready');
self.client.reqContinue(function() {
// Intentionally blank.
});
});
self.initReplOrServer_();
});
};
var wdRepl = new WdRepl();
wdRepl.init();

View file

@ -0,0 +1,83 @@
var repl = require('repl');
var debuggerCommons = require('../debuggerCommons');
var DebuggerRepl = require('../modes/debuggerRepl');
/**
* Custom protractor debugger which steps through one control flow task at a time.
*
* @constructor
*/
var WdDebugger = function() {
this.client;
this.replServer;
this.dbgRepl;
};
/**
* Eval function for processing a single step in repl.
* @private
* @param {string} cmd
* @param {object} context
* @param {string} filename
* @param {function} callback
*/
WdDebugger.prototype.stepEval_ = function(cmd, context, filename, callback) {
// The loop won't come back until 'callback' is called.
// Note - node's debugger gets around this by adding custom objects
// named 'c', 's', etc to the REPL context. They have getters which
// perform the desired function, and the callback is stored for later use.
// Think about whether this is a better pattern.
cmd = debuggerCommons.trimReplCmd(cmd);
this.dbgRepl.stepEval(cmd, callback);
};
/**
* Instantiate all repl objects, and debuggerRepl as current and start repl.
* @private
*/
WdDebugger.prototype.initRepl_ = function() {
var self = this;
this.dbgRepl = new DebuggerRepl(this.client);
// We want the prompt to show up only after the controlflow text prints.
this.dbgRepl.printControlFlow_(function() {
self.replServer = repl.start({
prompt: self.dbgRepl.prompt,
input: process.stdin,
output: process.stdout,
eval: self.stepEval_.bind(self),
useGlobal: false,
ignoreUndefined: true,
completer: self.dbgRepl.complete.bind(self.dbgRepl)
});
self.replServer.on('exit', function() {
console.log('Resuming code execution');
self.client.req({command: 'disconnect'}, function() {
process.exit();
});
});
});
};
/**
* Initiate the debugger.
* @public
*/
WdDebugger.prototype.init = function() {
var self = this;
this.client = debuggerCommons.attachDebugger(process.argv[2], process.argv[3]);
this.client.once('ready', function() {
debuggerCommons.setWebDriverCommandBreakpoint(self.client, function() {
process.send('ready');
self.client.reqContinue(function() {
// Intentionally blank.
});
});
self.initRepl_();
});
};
var wdDebugger = new WdDebugger();
wdDebugger.init();

View file

@ -0,0 +1,113 @@
var baseDebugger;
try {
baseDebugger = require('_debugger');
} catch (e) {
if (e.code == 'MODULE_NOT_FOUND') {
console.log('***********************************************************');
console.log('* WARNING: _debugger module not available on Node.js 8 *');
console.log('* and higher. *');
console.log('* *');
console.log('* Use \'debugger\' keyword instead: *');
console.log('* https://goo.gl/MvWqFh *');
console.log('***********************************************************');
}
throw e;
}
var path = require('path');
/**
* Create a debugger client and attach to a running protractor process.
* @param {number} pid Pid of the process to attach the debugger to.
* @param {number=} opt_port Port to set up the debugger connection over.
* @return {!baseDebugger.Client} The connected debugger client.
*/
exports.attachDebugger = function(pid, opt_port) {
var client = new baseDebugger.Client();
var port = opt_port || process.debugPort;
// Call this private function instead of sending SIGUSR1 because Windows.
process._debugProcess(pid);
// Connect to debugger on port with retry 200ms apart.
var connectWithRetry = function(attempts) {
client.connect(port, 'localhost')
.on('error', function(e) {
if (attempts === 1) {
throw e;
} else {
setTimeout(function() {
connectWithRetry(attempts - 1);
}, 200);
}
});
};
connectWithRetry(10);
return client;
};
/**
* Set a breakpoint for evaluating REPL statements.
* This sets a breakpoint in Protractor's breakpointhook.js, so that we'll
* break after executing a command from the REPL.
*/
exports.setEvaluateBreakpoint = function(client, cb) {
client.setBreakpoint({
type: 'scriptRegExp',
target: prepareDebuggerPath('built', 'breakpointhook.js'),
line: 2
}, function(err, response) {
if (err) {
throw new Error(err);
}
cb(response.breakpoint);
});
};
/**
* Set a breakpoint for moving forward by one webdriver command.
* This sets a breakpoint in selenium-webdriver/lib/http.js, and is
* extremely sensitive to the selenium version. It works for
* selenium-webdriver 3.0.1
* This breaks on the following line in http.js:
* let request = buildRequest(this.customCommands_, this.w3c, command);
* And will need to break at a similar point in future selenium-webdriver
* versions.
*/
exports.setWebDriverCommandBreakpoint = function(client, cb) {
client.setBreakpoint({
type: 'scriptRegExp',
target: prepareDebuggerPath('lib', 'http.js'),
line: 433
}, function(err, response) {
if (err) {
throw new Error(err);
}
cb(response.breakpoint);
});
};
/**
* Create a cross-platform friendly path for setting scriptRegExp breakpoints.
*/
function prepareDebuggerPath(...parts) {
return path.join(...parts)
.replace('\\', '\\\\')
.replace('.', '\\.');
}
/**
* Trim excess symbols from the repl command so that it is consistent with
* the user input.
* @param {string} cmd Cmd provided by the repl server.
* @return {string} The trimmed cmd.
*/
exports.trimReplCmd = function(cmd) {
// Given user input 'foobar', some versions of node provide '(foobar\n)',
// while other versions of node provide 'foobar\n'.
if (cmd.length >= 2 && cmd[0] === '(' && cmd[cmd.length - 1] === ')') {
cmd = cmd.substring(1, cmd.length - 1);
}
return cmd.slice(0, cmd.length - 1);
};

View file

@ -0,0 +1,127 @@
var REPL_INITIAL_SUGGESTIONS = [
'element(by.id(\'\'))',
'element(by.css(\'\'))',
'element(by.name(\'\'))',
'element(by.binding(\'\'))',
'element(by.xpath(\'\'))',
'element(by.tagName(\'\'))',
'element(by.className(\'\'))'
];
/**
* Repl to interactively run commands in the context of the test.
*
* @param {Client} node debugger client.
* @constructor
*/
var CommandRepl = function(client) {
this.client = client;
this.prompt = '> ';
};
/**
* Eval function for processing a single step in repl.
* Call callback with the result when complete.
*
* @public
* @param {string} expression
* @param {function} callback
*/
CommandRepl.prototype.stepEval = function(expression, callback) {
expression = expression.replace(/"/g, '\\\"');
var expr = 'browser.debugHelper.dbgCodeExecutor.execute("' + expression + '")';
this.evaluate_(expr, callback);
};
/**
* Autocomplete user entries.
* Call callback with the suggestions.
*
* @public
* @param {string} line Initial user entry
* @param {function} callback
*/
CommandRepl.prototype.complete = function(line, callback) {
if (line === '') {
callback(null, [REPL_INITIAL_SUGGESTIONS, '']);
} else {
// TODO(juliemr): This is freezing the program!
line = line.replace(/"/g, '\\\"');
var expr = 'browser.debugHelper.dbgCodeExecutor.complete("' + line + '")';
this.evaluate_(expr, function(err, res) {
// Result is a JSON representation of the autocomplete response.
var result = res === undefined ? undefined : JSON.parse(res);
callback(err, result);
});
}
};
/**
* Helper function to evaluate an expression remotely, and callback with
* the result. The expression can be a promise, in which case, the method
* will wait for the result and callback with the resolved value.
*
* @private
* @param {string} expression Expression to evaluate
* @param {function} callback
*/
CommandRepl.prototype.evaluate_ = function(expression, callback) {
var self = this;
var onbreak_ = function() {
self.client.req({
command: 'evaluate',
arguments: {
frame: 0,
maxStringLength: 1000,
expression: 'browser.debugHelper.dbgCodeExecutor.resultReady()'
}
}, function(err, res) {
if (err) {
throw new Error('Error while checking if debugger expression result was ready.' +
'Expression: ' + expression + ' Error: ' + err);
}
// If code finished executing, get result.
if (res.value) {
self.client.req({
command: 'evaluate',
arguments: {
frame: 0,
maxStringLength: -1,
expression: 'browser.debugHelper.dbgCodeExecutor.getResult()'
}
}, function(err, res) {
try {
callback(err, res.value);
} catch (e) {
callback(e, undefined);
}
self.client.removeListener('break', onbreak_);
});
} else {
// If we need more loops for the code to finish executing, continue
// until the next execute step.
self.client.reqContinue(function() {
// Intentionally blank.
});
}
});
};
this.client.on('break', onbreak_);
this.client.req({
command: 'evaluate',
arguments: {
frame: 0,
maxStringLength: 1000,
expression: expression
}
}, function() {
self.client.reqContinue(function() {
// Intentionally blank.
});
});
};
module.exports = CommandRepl;

View file

@ -0,0 +1,143 @@
var util = require('util');
var DBG_INITIAL_SUGGESTIONS =
['repl', 'c', 'frame', 'scopes', 'scripts', 'source', 'backtrace'];
/**
* Repl to step through webdriver test code.
*
* @param {Client} node debugger client.
* @constructor
*/
var DebuggerRepl = function(client) {
this.client = client;
this.prompt = '>>> ';
};
/**
* Eval function for processing a single step in repl.
* Call callback with the result when complete.
*
* @public
* @param {string} cmd
* @param {function} callback
*/
DebuggerRepl.prototype.stepEval = function(cmd, callback) {
switch (cmd) {
case 'c':
this.printNextStep_(callback);
this.client.reqContinue(function() {
// Intentionally blank.
});
break;
case 'repl':
console.log('Error: using repl from browser.pause() has been removed. ' +
'Please use browser.enterRepl instead.');
callback();
break;
case 'schedule':
this.printControlFlow_(callback);
break;
case 'frame':
this.client.req({command: 'frame'}, function(err, res) {
console.log(util.inspect(res, {colors: true}));
callback();
});
break;
case 'scopes':
this.client.req({command: 'scopes'}, function(err, res) {
console.log(util.inspect(res, {depth: 4, colors: true}));
callback();
});
break;
case 'scripts':
this.client.req({command: 'scripts'}, function(err, res) {
console.log(util.inspect(res, {depth: 4, colors: true}));
callback();
});
break;
case 'source':
this.client.req({command: 'source'}, function(err, res) {
console.log(util.inspect(res, {depth: 4, colors: true}));
callback();
});
break;
case 'backtrace':
this.client.req({command: 'backtrace'}, function(err, res) {
console.log(util.inspect(res, {depth: 4, colors: true}));
callback();
});
break;
default:
console.log('Unrecognized command.');
callback();
break;
}
};
/**
* Autocomplete user entries.
* Call callback with the suggestions.
*
* @public
* @param {string} line Initial user entry
* @param {function} callback
*/
DebuggerRepl.prototype.complete = function(line, callback) {
var suggestions = DBG_INITIAL_SUGGESTIONS.filter(function(suggestion) {
return suggestion.indexOf(line) === 0;
});
console.log('suggestions');
callback(null, [suggestions, line]);
};
/**
* Print the next command and setup the next breakpoint.
*
* @private
* @param {function} callback
*/
DebuggerRepl.prototype.printNextStep_ = function(callback) {
var self = this;
var onBreak_ = function() {
self.client.req({
command: 'evaluate',
arguments: {
frame: 0,
maxStringLength: 1000,
expression: 'command.getName()'
}
}, function(err, res) {
// We ignore errors here because we'll get one from the initial break.
if (res.value) {
console.log('-- Next command: ' + res.value);
}
callback();
});
};
this.client.once('break', onBreak_);
};
/**
* Print the controlflow.
*
* @private
* @param {function} callback
*/
DebuggerRepl.prototype.printControlFlow_ = function(callback) {
this.client.req({
command: 'evaluate',
arguments: {
frame: 0,
maxStringLength: 4000,
expression: 'protractor.promise.controlFlow().getSchedule()'
}
}, function(err, controlFlowResponse) {
if (controlFlowResponse.value) {
console.log(controlFlowResponse.value);
}
callback();
});
};
module.exports = DebuggerRepl;

View file

@ -0,0 +1,27 @@
/// <reference types="q" />
import * as q from 'q';
import { promise as wdpromise, WebDriver } from 'selenium-webdriver';
import { Config } from '../config';
import { DriverProvider } from './driverProvider';
export declare class AttachSession extends DriverProvider {
constructor(config: Config);
/**
* Configure and launch (if applicable) the object's environment.
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
protected setupDriverEnv(): q.Promise<any>;
/**
* Getting a new driver by attaching an existing session.
*
* @public
* @return {WebDriver} webdriver instance
*/
getNewDriver(): WebDriver;
/**
* Maintains the existing session and does not quit the driver.
*
* @public
*/
quitDriver(): wdpromise.Promise<void>;
}

View file

@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* This is an implementation of the Attach Session Driver Provider.
* It is responsible for setting up the account object, tearing
* it down, and setting up the driver correctly.
*/
const q = require("q");
const selenium_webdriver_1 = require("selenium-webdriver");
const logger_1 = require("../logger");
const driverProvider_1 = require("./driverProvider");
const http = require('selenium-webdriver/http');
let logger = new logger_1.Logger('attachSession');
class AttachSession extends driverProvider_1.DriverProvider {
constructor(config) {
super(config);
}
/**
* Configure and launch (if applicable) the object's environment.
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
setupDriverEnv() {
logger.info('Using the selenium server at ' + this.config_.seleniumAddress);
logger.info('Using session id - ' + this.config_.seleniumSessionId);
return q(undefined);
}
/**
* Getting a new driver by attaching an existing session.
*
* @public
* @return {WebDriver} webdriver instance
*/
getNewDriver() {
const httpClient = new http.HttpClient(this.config_.seleniumAddress);
const executor = new http.Executor(httpClient);
const newDriver = selenium_webdriver_1.WebDriver.attachToSession(executor, this.config_.seleniumSessionId);
this.drivers_.push(newDriver);
return newDriver;
}
/**
* Maintains the existing session and does not quit the driver.
*
* @public
*/
quitDriver() {
return selenium_webdriver_1.promise.when(undefined);
}
}
exports.AttachSession = AttachSession;
//# sourceMappingURL=attachSession.js.map

View file

@ -0,0 +1,21 @@
/// <reference types="q" />
import * as q from 'q';
import { Config } from '../config';
import { DriverProvider } from './driverProvider';
export declare class BrowserStack extends DriverProvider {
browserstackClient: any;
constructor(config: Config);
/**
* Hook to update the BrowserStack job status.
* @public
* @param {Object} update
* @return {q.promise} A promise that will resolve when the update is complete.
*/
updateJob(update: any): q.Promise<any>;
/**
* Configure and launch (if applicable) the object's environment.
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
protected setupDriverEnv(): q.Promise<any>;
}

View file

@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const q = require("q");
const util = require("util");
const exitCodes_1 = require("../exitCodes");
const logger_1 = require("../logger");
const driverProvider_1 = require("./driverProvider");
const BrowserstackClient = require('browserstack');
let logger = new logger_1.Logger('browserstack');
class BrowserStack extends driverProvider_1.DriverProvider {
constructor(config) {
super(config);
}
/**
* Hook to update the BrowserStack job status.
* @public
* @param {Object} update
* @return {q.promise} A promise that will resolve when the update is complete.
*/
updateJob(update) {
let deferredArray = this.drivers_.map((driver) => {
let deferred = q.defer();
driver.getSession().then((session) => {
// Fetching BrowserStack session details.
this.browserstackClient.getSession(session.getId(), function (error, automate_session) {
if (error) {
logger.info('BrowserStack results available at ' +
'https://www.browserstack.com/automate');
}
else {
if (automate_session && automate_session.browser_url) {
logger.info('BrowserStack results available at ' + automate_session.browser_url);
}
else {
logger.info('BrowserStack results available at ' +
'https://www.browserstack.com/automate');
}
}
});
let jobStatus = update.passed ? 'completed' : 'error';
let statusObj = { status: jobStatus };
// Updating status of BrowserStack session.
this.browserstackClient.updateSession(session.getId(), statusObj, function (error, automate_session) {
if (error) {
throw new exitCodes_1.BrowserError(logger, 'Error updating BrowserStack pass/fail status: ' + util.inspect(error));
}
else {
logger.info(automate_session);
deferred.resolve();
}
});
});
return deferred.promise;
});
return q.all(deferredArray);
}
/**
* Configure and launch (if applicable) the object's environment.
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
setupDriverEnv() {
let deferred = q.defer();
this.config_.capabilities['browserstack.user'] = this.config_.browserstackUser;
this.config_.capabilities['browserstack.key'] = this.config_.browserstackKey;
this.config_.seleniumAddress = 'http://hub.browserstack.com/wd/hub';
this.browserstackClient = BrowserstackClient.createAutomateClient({
username: this.config_.browserstackUser,
password: this.config_.browserstackKey,
proxy: this.config_.browserstackProxy
});
// Append filename to capabilities.name so that it's easier to identify
// tests.
if (this.config_.capabilities.name && this.config_.capabilities.shardTestFiles) {
this.config_.capabilities.name +=
(':' + this.config_.specs.toString().replace(/^.*[\\\/]/, ''));
}
logger.info('Using BrowserStack selenium server at ' + this.config_.seleniumAddress);
deferred.resolve();
return deferred.promise;
}
}
exports.BrowserStack = BrowserStack;
//# sourceMappingURL=browserStack.js.map

View file

@ -0,0 +1,22 @@
/// <reference types="q" />
import * as q from 'q';
import { WebDriver } from 'selenium-webdriver';
import { Config } from '../config';
import { DriverProvider } from './driverProvider';
export declare class Direct extends DriverProvider {
constructor(config: Config);
/**
* Configure and launch (if applicable) the object's environment.
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
protected setupDriverEnv(): q.Promise<any>;
/**
* Create a new driver.
*
* @public
* @override
* @return webdriver instance
*/
getNewDriver(): WebDriver;
}

116
node_modules/protractor/built/driverProviders/direct.js generated vendored Normal file
View file

@ -0,0 +1,116 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* This is an implementation of the Direct Driver Provider.
* It is responsible for setting up the account object, tearing
* it down, and setting up the driver correctly.
*/
const fs = require("fs");
const path = require("path");
const q = require("q");
const selenium_webdriver_1 = require("selenium-webdriver");
const chrome_1 = require("selenium-webdriver/chrome");
const exitCodes_1 = require("../exitCodes");
const logger_1 = require("../logger");
const driverProvider_1 = require("./driverProvider");
const SeleniumConfig = require('webdriver-manager/built/lib/config').Config;
let logger = new logger_1.Logger('direct');
class Direct extends driverProvider_1.DriverProvider {
constructor(config) {
super(config);
}
/**
* Configure and launch (if applicable) the object's environment.
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
setupDriverEnv() {
switch (this.config_.capabilities.browserName) {
case 'chrome':
logger.info('Using ChromeDriver directly...');
break;
case 'firefox':
logger.info('Using FirefoxDriver directly...');
break;
default:
throw new exitCodes_1.BrowserError(logger, 'browserName ' + this.config_.capabilities.browserName +
' is not supported with directConnect.');
}
return q.fcall(function () { });
}
/**
* Create a new driver.
*
* @public
* @override
* @return webdriver instance
*/
getNewDriver() {
let driver;
switch (this.config_.capabilities.browserName) {
case 'chrome':
let chromeDriverFile;
if (this.config_.chromeDriver) {
chromeDriverFile = this.config_.chromeDriver;
}
else {
try {
let updateJson = path.resolve(SeleniumConfig.getSeleniumDir(), 'update-config.json');
let updateConfig = JSON.parse(fs.readFileSync(updateJson).toString());
chromeDriverFile = updateConfig.chrome.last;
}
catch (e) {
throw new exitCodes_1.BrowserError(logger, 'Could not find update-config.json. ' +
'Run \'webdriver-manager update\' to download binaries.');
}
}
if (!fs.existsSync(chromeDriverFile)) {
throw new exitCodes_1.BrowserError(logger, 'Could not find chromedriver at ' + chromeDriverFile +
'. Run \'webdriver-manager update\' to download binaries.');
}
let chromeService = new chrome_1.ServiceBuilder(chromeDriverFile).build();
// driver = ChromeDriver.createSession(new Capabilities(this.config_.capabilities),
// chromeService);
// TODO(ralphj): fix typings
driver =
require('selenium-webdriver/chrome')
.Driver.createSession(new selenium_webdriver_1.Capabilities(this.config_.capabilities), chromeService);
break;
case 'firefox':
let geckoDriverFile;
if (this.config_.geckoDriver) {
geckoDriverFile = this.config_.geckoDriver;
}
else {
try {
let updateJson = path.resolve(SeleniumConfig.getSeleniumDir(), 'update-config.json');
let updateConfig = JSON.parse(fs.readFileSync(updateJson).toString());
geckoDriverFile = updateConfig.gecko.last;
}
catch (e) {
throw new exitCodes_1.BrowserError(logger, 'Could not find update-config.json. ' +
'Run \'webdriver-manager update\' to download binaries.');
}
}
if (!fs.existsSync(geckoDriverFile)) {
throw new exitCodes_1.BrowserError(logger, 'Could not find geckodriver at ' + geckoDriverFile +
'. Run \'webdriver-manager update\' to download binaries.');
}
// TODO (mgiambalvo): Turn this into an import when the selenium typings are updated.
const FirefoxServiceBuilder = require('selenium-webdriver/firefox').ServiceBuilder;
let firefoxService = new FirefoxServiceBuilder(geckoDriverFile).build();
// TODO(mgiambalvo): Fix typings.
driver =
require('selenium-webdriver/firefox')
.Driver.createSession(new selenium_webdriver_1.Capabilities(this.config_.capabilities), firefoxService);
break;
default:
throw new exitCodes_1.BrowserError(logger, 'browserName ' + this.config_.capabilities.browserName +
' is not supported with directConnect.');
}
this.drivers_.push(driver);
return driver;
}
}
exports.Direct = Direct;
//# sourceMappingURL=direct.js.map

View file

@ -0,0 +1,65 @@
/// <reference types="q" />
/**
* This is a base driver provider class.
* It is responsible for setting up the account object, tearing
* it down, and setting up the driver correctly.
*/
import * as q from 'q';
import { promise as wdpromise, WebDriver } from 'selenium-webdriver';
import { Config } from '../config';
export declare abstract class DriverProvider {
drivers_: WebDriver[];
config_: Config;
private bpRunner;
constructor(config: Config);
/**
* Get all existing drivers.
*
* @public
* @return array of webdriver instances
*/
getExistingDrivers(): WebDriver[];
getBPUrl(): string;
/**
* Create a new driver.
*
* @public
* @return webdriver instance
*/
getNewDriver(): WebDriver;
/**
* Quit a driver.
*
* @public
* @param webdriver instance
*/
quitDriver(driver: WebDriver): wdpromise.Promise<void>;
/**
* Quits an array of drivers and returns a q promise instead of a webdriver one
*
* @param drivers {webdriver.WebDriver[]} The webdriver instances
*/
static quitDrivers(provider: DriverProvider, drivers: WebDriver[]): q.Promise<void>;
/**
* Default update job method.
* @return a promise
*/
updateJob(update: any): q.Promise<any>;
/**
* Default setup environment method, common to all driver providers.
*/
setupEnv(): q.Promise<any>;
/**
* Set up environment specific to a particular driver provider. Overridden
* by each driver provider.
*/
protected abstract setupDriverEnv(): q.Promise<any>;
/**
* Teardown and destroy the environment and do any associated cleanup.
* Shuts down the drivers.
*
* @public
* @return {q.Promise<any>} A promise which will resolve when the environment is down.
*/
teardownEnv(): q.Promise<any>;
}

View file

@ -0,0 +1,131 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* This is a base driver provider class.
* It is responsible for setting up the account object, tearing
* it down, and setting up the driver correctly.
*/
const q = require("q");
const selenium_webdriver_1 = require("selenium-webdriver");
const bpRunner_1 = require("../bpRunner");
class DriverProvider {
constructor(config) {
this.config_ = config;
this.drivers_ = [];
this.bpRunner = new bpRunner_1.BlockingProxyRunner(config);
}
/**
* Get all existing drivers.
*
* @public
* @return array of webdriver instances
*/
getExistingDrivers() {
return this.drivers_.slice(); // Create a shallow copy
}
getBPUrl() {
if (this.config_.blockingProxyUrl) {
return this.config_.blockingProxyUrl;
}
return `http://localhost:${this.bpRunner.port}`;
}
/**
* Create a new driver.
*
* @public
* @return webdriver instance
*/
getNewDriver() {
let builder;
if (this.config_.useBlockingProxy) {
builder =
new selenium_webdriver_1.Builder().usingServer(this.getBPUrl()).withCapabilities(this.config_.capabilities);
}
else {
builder = new selenium_webdriver_1.Builder()
.usingServer(this.config_.seleniumAddress)
.usingWebDriverProxy(this.config_.webDriverProxy)
.withCapabilities(this.config_.capabilities);
}
if (this.config_.disableEnvironmentOverrides === true) {
builder.disableEnvironmentOverrides();
}
let newDriver = builder.build();
this.drivers_.push(newDriver);
return newDriver;
}
/**
* Quit a driver.
*
* @public
* @param webdriver instance
*/
quitDriver(driver) {
let driverIndex = this.drivers_.indexOf(driver);
if (driverIndex >= 0) {
this.drivers_.splice(driverIndex, 1);
}
if (driver.getSession() === undefined) {
return selenium_webdriver_1.promise.when(undefined);
}
else {
return driver.getSession()
.then((session_) => {
if (session_) {
return driver.quit();
}
})
.catch(function (err) { });
}
}
/**
* Quits an array of drivers and returns a q promise instead of a webdriver one
*
* @param drivers {webdriver.WebDriver[]} The webdriver instances
*/
static quitDrivers(provider, drivers) {
let deferred = q.defer();
selenium_webdriver_1.promise
.all(drivers.map((driver) => {
return provider.quitDriver(driver);
}))
.then(() => {
deferred.resolve();
}, () => {
deferred.resolve();
});
return deferred.promise;
}
/**
* Default update job method.
* @return a promise
*/
updateJob(update) {
return q.fcall(function () { });
}
;
/**
* Default setup environment method, common to all driver providers.
*/
setupEnv() {
let driverPromise = this.setupDriverEnv();
if (this.config_.useBlockingProxy && !this.config_.blockingProxyUrl) {
// TODO(heathkit): If set, pass the webDriverProxy to BP.
return driverPromise.then(() => this.bpRunner.start());
}
return driverPromise;
}
;
/**
* Teardown and destroy the environment and do any associated cleanup.
* Shuts down the drivers.
*
* @public
* @return {q.Promise<any>} A promise which will resolve when the environment is down.
*/
teardownEnv() {
return DriverProvider.quitDrivers(this, this.drivers_);
}
}
exports.DriverProvider = DriverProvider;
//# sourceMappingURL=driverProvider.js.map

View file

@ -0,0 +1,14 @@
/// <reference types="q" />
import * as q from 'q';
import { Config } from '../config';
import { DriverProvider } from './driverProvider';
export declare class Hosted extends DriverProvider {
constructor(config: Config);
/**
* Configure and launch (if applicable) the object's environment.
* @public
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
protected setupDriverEnv(): q.Promise<any>;
}

View file

@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* This is an implementation of the Hosted Driver Provider.
* It is responsible for setting up the account object, tearing
* it down, and setting up the driver correctly.
*/
const q = require("q");
const logger_1 = require("../logger");
const driverProvider_1 = require("./driverProvider");
let logger = new logger_1.Logger('hosted');
class Hosted extends driverProvider_1.DriverProvider {
constructor(config) {
super(config);
}
/**
* Configure and launch (if applicable) the object's environment.
* @public
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
setupDriverEnv() {
logger.info('Using the selenium server at ' + this.config_.seleniumAddress);
return q.fcall(function () { });
}
}
exports.Hosted = Hosted;
//# sourceMappingURL=hosted.js.map

View file

@ -0,0 +1,15 @@
export * from './attachSession';
export * from './browserStack';
export * from './direct';
export * from './driverProvider';
export * from './hosted';
export * from './local';
export * from './mock';
export * from './sauce';
export * from './testObject';
export * from './kobiton';
export * from './useExistingWebDriver';
import { DriverProvider } from './driverProvider';
import { Config } from '../config';
export declare let buildDriverProvider: (config: Config) => DriverProvider;
export declare let logWarnings: (providerType: string, config: Config) => void;

129
node_modules/protractor/built/driverProviders/index.js generated vendored Normal file
View file

@ -0,0 +1,129 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./attachSession"));
__export(require("./browserStack"));
__export(require("./direct"));
__export(require("./driverProvider"));
__export(require("./hosted"));
__export(require("./local"));
__export(require("./mock"));
__export(require("./sauce"));
__export(require("./testObject"));
__export(require("./kobiton"));
__export(require("./useExistingWebDriver"));
const attachSession_1 = require("./attachSession");
const browserStack_1 = require("./browserStack");
const direct_1 = require("./direct");
const hosted_1 = require("./hosted");
const local_1 = require("./local");
const mock_1 = require("./mock");
const sauce_1 = require("./sauce");
const testObject_1 = require("./testObject");
const kobiton_1 = require("./kobiton");
const useExistingWebDriver_1 = require("./useExistingWebDriver");
const logger_1 = require("../logger");
let logger = new logger_1.Logger('driverProviders');
exports.buildDriverProvider = (config) => {
let driverProvider;
if (config.directConnect) {
driverProvider = new direct_1.Direct(config);
exports.logWarnings('directConnect', config);
}
else if (config.seleniumWebDriver) {
driverProvider = new useExistingWebDriver_1.UseExistingWebDriver(config);
exports.logWarnings('useExistingWebDriver', config);
}
else if (config.seleniumAddress) {
if (config.seleniumSessionId) {
driverProvider = new attachSession_1.AttachSession(config);
exports.logWarnings('attachSession', config);
}
else {
driverProvider = new hosted_1.Hosted(config);
exports.logWarnings('hosted', config);
}
}
else if (config.testobjectUser && config.testobjectKey) {
driverProvider = new testObject_1.TestObject(config);
exports.logWarnings('testObject', config);
}
else if (config.kobitonUser && config.kobitonKey) {
driverProvider = new kobiton_1.Kobiton(config);
exports.logWarnings('kobiton', config);
}
else if (config.browserstackUser && config.browserstackKey) {
driverProvider = new browserStack_1.BrowserStack(config);
exports.logWarnings('browserStack', config);
}
else if (config.sauceUser && config.sauceKey) {
driverProvider = new sauce_1.Sauce(config);
exports.logWarnings('sauce', config);
}
else if (config.seleniumServerJar) {
driverProvider = new local_1.Local(config);
exports.logWarnings('local', config);
}
else if (config.mockSelenium) {
driverProvider = new mock_1.Mock(config);
exports.logWarnings('mock', config);
}
else {
driverProvider = new local_1.Local(config);
exports.logWarnings('local', config);
}
return driverProvider;
};
exports.logWarnings = (providerType, config) => {
let warnInto = 'Using driver provider ' + providerType +
', but also found extra driver provider parameter(s): ';
let warnList = [];
if ('directConnect' !== providerType && config.directConnect) {
warnList.push('directConnect');
}
if ('attachSession' !== providerType && 'hosted' !== providerType && config.seleniumAddress) {
warnList.push('seleniumAddress');
}
if ('attachSession' !== providerType && config.seleniumSessionId) {
warnList.push('seleniumSessionId');
}
if ('testObject' !== providerType && config.testObjectUser) {
warnList.push('testobjectUser');
}
if ('testObject' !== providerType && config.testObjectKey) {
warnList.push('testobjectKey');
}
if ('kobitonUser' !== providerType && config.kobitonUser) {
warnList.push('kobitonUser');
}
if ('kobitonKey' !== providerType && config.kobitonKey) {
warnList.push('kobitonKey');
}
if ('browserStack' !== providerType && config.browserstackUser) {
warnList.push('browserstackUser');
}
if ('browserStack' !== providerType && config.browserstackKey) {
warnList.push('browserstackKey');
}
if ('sauce' !== providerType && config.sauceUser) {
warnList.push('sauceUser');
}
if ('sauce' !== providerType && config.sauceKey) {
warnList.push('sauceKey');
}
if ('local' !== providerType && config.seleniumServerJar) {
warnList.push('seleniumServerJar');
}
if ('mock' !== providerType && config.mockSelenium) {
warnList.push('mockSelenium');
}
if ('useExistingWebDriver' !== providerType && config.seleniumWebDriver) {
warnList.push('seleniumWebDriver');
}
if (warnList.length !== 0) {
logger.warn(warnInto + warnList.join(', '));
}
};
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1,30 @@
/// <reference types="q" />
import * as q from 'q';
import { Config } from '../config';
import { DriverProvider } from './driverProvider';
export declare class Local extends DriverProvider {
server_: any;
constructor(config: Config);
/**
* Helper to locate the default jar path if none is provided by the user.
* @private
*/
addDefaultBinaryLocs_(): void;
/**
* Configure and launch (if applicable) the object's environment.
* @public
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
setupDriverEnv(): q.Promise<any>;
/**
* Teardown and destroy the environment and do any associated cleanup.
* Shuts down the drivers and server.
*
* @public
* @override
* @return {q.promise} A promise which will resolve when the environment
* is down.
*/
teardownEnv(): q.Promise<any>;
}

165
node_modules/protractor/built/driverProviders/local.js generated vendored Normal file
View file

@ -0,0 +1,165 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* This is an implementation of the Local Driver Provider.
* It is responsible for setting up the account object, tearing
* it down, and setting up the driver correctly.
*
* TODO - it would be nice to do this in the launcher phase,
* so that we only start the local selenium once per entire launch.
*/
const fs = require("fs");
const path = require("path");
const q = require("q");
const exitCodes_1 = require("../exitCodes");
const logger_1 = require("../logger");
const driverProvider_1 = require("./driverProvider");
const SeleniumConfig = require('webdriver-manager/built/lib/config').Config;
const remote = require('selenium-webdriver/remote');
let logger = new logger_1.Logger('local');
class Local extends driverProvider_1.DriverProvider {
constructor(config) {
super(config);
this.server_ = null;
}
/**
* Helper to locate the default jar path if none is provided by the user.
* @private
*/
addDefaultBinaryLocs_() {
if (!this.config_.seleniumServerJar) {
logger.debug('Attempting to find the SeleniumServerJar in the default ' +
'location used by webdriver-manager');
try {
let updateJson = path.resolve(SeleniumConfig.getSeleniumDir(), 'update-config.json');
let updateConfig = JSON.parse(fs.readFileSync(updateJson).toString());
this.config_.seleniumServerJar = updateConfig.standalone.last;
}
catch (err) {
throw new exitCodes_1.BrowserError(logger, 'No update-config.json found.' +
' Run \'webdriver-manager update\' to download binaries.');
}
}
if (!fs.existsSync(this.config_.seleniumServerJar)) {
throw new exitCodes_1.BrowserError(logger, 'No selenium server jar found at ' + this.config_.seleniumServerJar +
'. Run \'webdriver-manager update\' to download binaries.');
}
if (this.config_.capabilities.browserName === 'chrome') {
if (!this.config_.chromeDriver) {
logger.debug('Attempting to find the chromedriver binary in the default ' +
'location used by webdriver-manager');
try {
let updateJson = path.resolve(SeleniumConfig.getSeleniumDir(), 'update-config.json');
let updateConfig = JSON.parse(fs.readFileSync(updateJson).toString());
this.config_.chromeDriver = updateConfig.chrome.last;
}
catch (err) {
throw new exitCodes_1.BrowserError(logger, 'No update-config.json found. ' +
'Run \'webdriver-manager update\' to download binaries.');
}
}
// Check if file exists, if not try .exe or fail accordingly
if (!fs.existsSync(this.config_.chromeDriver)) {
if (fs.existsSync(this.config_.chromeDriver + '.exe')) {
this.config_.chromeDriver += '.exe';
}
else {
throw new exitCodes_1.BrowserError(logger, 'Could not find chromedriver at ' + this.config_.chromeDriver +
'. Run \'webdriver-manager update\' to download binaries.');
}
}
}
if (this.config_.capabilities.browserName === 'firefox') {
if (!this.config_.geckoDriver) {
logger.debug('Attempting to find the gecko driver binary in the default ' +
'location used by webdriver-manager');
try {
let updateJson = path.resolve(SeleniumConfig.getSeleniumDir(), 'update-config.json');
let updateConfig = JSON.parse(fs.readFileSync(updateJson).toString());
this.config_.geckoDriver = updateConfig.gecko.last;
}
catch (err) {
throw new exitCodes_1.BrowserError(logger, 'No update-config.json found. ' +
'Run \'webdriver-manager update\' to download binaries.');
}
}
// Check if file exists, if not try .exe or fail accordingly
if (!fs.existsSync(this.config_.geckoDriver)) {
if (fs.existsSync(this.config_.geckoDriver + '.exe')) {
this.config_.geckoDriver += '.exe';
}
else {
throw new exitCodes_1.BrowserError(logger, 'Could not find gecko driver at ' + this.config_.geckoDriver +
'. Run \'webdriver-manager update\' to download binaries.');
}
}
}
}
/**
* Configure and launch (if applicable) the object's environment.
* @public
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
setupDriverEnv() {
this.addDefaultBinaryLocs_();
logger.info('Starting selenium standalone server...');
let serverConf = this.config_.localSeleniumStandaloneOpts || {};
// If args or port is not set use seleniumArgs and seleniumPort
// for backward compatibility
if (serverConf.args === undefined) {
serverConf.args = this.config_.seleniumArgs || [];
}
if (serverConf.jvmArgs === undefined) {
serverConf.jvmArgs = this.config_.jvmArgs || [];
}
else {
if (!Array.isArray(serverConf.jvmArgs)) {
throw new exitCodes_1.ConfigError(logger, 'jvmArgs should be an array.');
}
}
if (serverConf.port === undefined) {
serverConf.port = this.config_.seleniumPort;
}
// configure server
if (this.config_.chromeDriver) {
serverConf.jvmArgs.push('-Dwebdriver.chrome.driver=' + this.config_.chromeDriver);
}
if (this.config_.geckoDriver) {
serverConf.jvmArgs.push('-Dwebdriver.gecko.driver=' + this.config_.geckoDriver);
}
this.server_ = new remote.SeleniumServer(this.config_.seleniumServerJar, serverConf);
let deferred = q.defer();
// start local server, grab hosted address, and resolve promise
this.server_.start(this.config_.seleniumServerStartTimeout)
.then((url) => {
logger.info('Selenium standalone server started at ' + url);
return this.server_.address();
})
.then((address) => {
this.config_.seleniumAddress = address;
deferred.resolve();
})
.catch((err) => {
deferred.reject(err);
});
return deferred.promise;
}
/**
* Teardown and destroy the environment and do any associated cleanup.
* Shuts down the drivers and server.
*
* @public
* @override
* @return {q.promise} A promise which will resolve when the environment
* is down.
*/
teardownEnv() {
return super.teardownEnv().then(() => {
logger.info('Shutting down selenium standalone server.');
return this.server_.stop();
});
}
}
exports.Local = Local;
//# sourceMappingURL=local.js.map

View file

@ -0,0 +1,29 @@
/// <reference types="q" />
import * as q from 'q';
import { WebDriver } from 'selenium-webdriver';
import { Config } from '../config';
import { DriverProvider } from './driverProvider';
export declare class MockExecutor {
execute(command: any): any;
}
export declare class Mock extends DriverProvider {
constructor(config?: Config);
/**
* An execute function that returns a promise with a test value.
*/
execute(): q.Promise<any>;
/**
* Configure and launch (if applicable) the object's environment.
* @public
* @return {q.promise} A promise which will resolve immediately.
*/
protected setupDriverEnv(): q.Promise<any>;
/**
* Create a new driver.
*
* @public
* @override
* @return webdriver instance
*/
getNewDriver(): WebDriver;
}

50
node_modules/protractor/built/driverProviders/mock.js generated vendored Normal file
View file

@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* This is an mock implementation of the Driver Provider.
* It returns a fake webdriver and never actually contacts a selenium
* server.
*/
const q = require("q");
const selenium_webdriver_1 = require("selenium-webdriver");
const driverProvider_1 = require("./driverProvider");
class MockExecutor {
execute(command) { }
}
exports.MockExecutor = MockExecutor;
class Mock extends driverProvider_1.DriverProvider {
constructor(config) {
super(config);
}
/**
* An execute function that returns a promise with a test value.
*/
execute() {
let deferred = q.defer();
deferred.resolve({ value: 'test_response' });
return deferred.promise;
}
/**
* Configure and launch (if applicable) the object's environment.
* @public
* @return {q.promise} A promise which will resolve immediately.
*/
setupDriverEnv() {
return q.fcall(function () { });
}
/**
* Create a new driver.
*
* @public
* @override
* @return webdriver instance
*/
getNewDriver() {
let mockSession = new selenium_webdriver_1.Session('test_session_id', {});
let newDriver = new selenium_webdriver_1.WebDriver(mockSession, new MockExecutor());
this.drivers_.push(newDriver);
return newDriver;
}
}
exports.Mock = Mock;
//# sourceMappingURL=mock.js.map

View file

@ -0,0 +1,29 @@
/// <reference types="q" />
import * as q from 'q';
import { Config } from '../config';
import { DriverProvider } from './driverProvider';
export declare class Sauce extends DriverProvider {
sauceServer_: any;
constructor(config: Config);
/**
* Hook to update the sauce job.
* @public
* @param {Object} update
* @return {q.promise} A promise that will resolve when the update is complete.
*/
updateJob(update: any): q.Promise<any>;
/**
* Configure and launch (if applicable) the object's environment.
* @public
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
protected setupDriverEnv(): q.Promise<any>;
/**
* Get the Sauce Labs endpoint
* @private
* @param {string} region
* @return {string} The endpoint that needs to be used
*/
private getSauceEndpoint(region);
}

93
node_modules/protractor/built/driverProviders/sauce.js generated vendored Normal file
View file

@ -0,0 +1,93 @@
"use strict";
/*
* This is an implementation of the SauceLabs Driver Provider.
* It is responsible for setting up the account object, tearing
* it down, and setting up the driver correctly.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const q = require("q");
const util = require("util");
const logger_1 = require("../logger");
const driverProvider_1 = require("./driverProvider");
const SauceLabs = require('saucelabs');
const SAUCE_REGIONS = {
'us': '',
'eu': 'eu-central-1.'
};
let logger = new logger_1.Logger('sauce');
class Sauce extends driverProvider_1.DriverProvider {
constructor(config) {
super(config);
}
/**
* Hook to update the sauce job.
* @public
* @param {Object} update
* @return {q.promise} A promise that will resolve when the update is complete.
*/
updateJob(update) {
let deferredArray = this.drivers_.map((driver) => {
let deferred = q.defer();
driver.getSession().then((session) => {
logger.info('SauceLabs results available at http://saucelabs.com/jobs/' + session.getId());
this.sauceServer_.updateJob(session.getId(), update, (err) => {
if (err) {
throw new Error('Error updating Sauce pass/fail status: ' + util.inspect(err));
}
deferred.resolve();
});
});
return deferred.promise;
});
return q.all(deferredArray);
}
/**
* Configure and launch (if applicable) the object's environment.
* @public
* @return {q.promise} A promise which will resolve when the environment is
* ready to test.
*/
setupDriverEnv() {
let deferred = q.defer();
this.sauceServer_ = new SauceLabs({
hostname: this.getSauceEndpoint(this.config_.sauceRegion),
username: this.config_.sauceUser,
password: this.config_.sauceKey,
agent: this.config_.sauceAgent,
proxy: this.config_.sauceProxy
});
this.config_.capabilities['username'] = this.config_.sauceUser;
this.config_.capabilities['accessKey'] = this.config_.sauceKey;
this.config_.capabilities['build'] = this.config_.sauceBuild;
let protocol = this.config_.sauceSeleniumUseHttp ? 'http://' : 'https://';
let auth = protocol + this.config_.sauceUser + ':' + this.config_.sauceKey + '@';
this.config_.seleniumAddress = auth +
(this.config_.sauceSeleniumAddress ?
this.config_.sauceSeleniumAddress :
`ondemand.${this.getSauceEndpoint(this.config_.sauceRegion)}:443/wd/hub`);
// Append filename to capabilities.name so that it's easier to identify
// tests.
if (this.config_.capabilities.name && this.config_.capabilities.shardTestFiles) {
this.config_.capabilities.name +=
(':' + this.config_.specs.toString().replace(/^.*[\\\/]/, ''));
}
logger.info('Using SauceLabs selenium server at ' +
this.config_.seleniumAddress.replace(/\/\/.+@/, '//'));
deferred.resolve();
return deferred.promise;
}
/**
* Get the Sauce Labs endpoint
* @private
* @param {string} region
* @return {string} The endpoint that needs to be used
*/
getSauceEndpoint(region) {
const dc = region ?
typeof SAUCE_REGIONS[region] !== 'undefined' ? SAUCE_REGIONS[region] : (region + '.') :
'';
return `${dc}saucelabs.com`;
}
}
exports.Sauce = Sauce;
//# sourceMappingURL=sauce.js.map

871
node_modules/protractor/built/element.d.ts generated vendored Normal file
View file

@ -0,0 +1,871 @@
import { By, promise as wdpromise, WebElement, WebElementPromise } from 'selenium-webdriver';
import { ElementHelper, ProtractorBrowser } from './browser';
import { Locator } from './locators';
export declare class WebdriverWebElement {
}
export interface WebdriverWebElement extends WebElement {
[key: string]: any;
}
/**
* ElementArrayFinder is used for operations on an array of elements (as opposed
* to a single element).
*
* The ElementArrayFinder is used to set up a chain of conditions that identify
* an array of elements. In particular, you can call all(locator) and
* filter(filterFn) to return a new ElementArrayFinder modified by the
* conditions, and you can call get(index) to return a single ElementFinder at
* position 'index'.
*
* Similar to jquery, ElementArrayFinder will search all branches of the DOM
* to find the elements that satisfy the conditions (i.e. all, filter, get).
* However, an ElementArrayFinder will not actually retrieve the elements until
* an action is called, which means it can be set up in helper files (i.e.
* page objects) before the page is available, and reused as the page changes.
*
* You can treat an ElementArrayFinder as an array of WebElements for most
* purposes, in particular, you may perform actions (i.e. click, getText) on
* them as you would an array of WebElements. The action will apply to
* every element identified by the ElementArrayFinder. ElementArrayFinder
* extends Promise, and once an action is performed on an ElementArrayFinder,
* the latest result can be accessed using then, and will be returned as an
* array of the results; the array has length equal to the length of the
* elements found by the ElementArrayFinder and each result represents the
* result of performing the action on the element. Unlike a WebElement, an
* ElementArrayFinder will wait for the angular app to settle before
* performing finds or actions.
*
* @alias element.all(locator)
* @view
* <ul class="items">
* <li>First</li>
* <li>Second</li>
* <li>Third</li>
* </ul>
*
* @example
* element.all(by.css('.items li')).then(function(items) {
* expect(items.length).toBe(3);
* expect(items[0].getText()).toBe('First');
* });
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* $$('.items li').then(function(items) {
* expect(items.length).toBe(3);
* expect(items[0].getText()).toBe('First');
* });
*
* @constructor
* @param {ProtractorBrowser} browser A browser instance.
* @param {function(): Array.<webdriver.WebElement>} getWebElements A function
* that returns a list of the underlying Web Elements.
* @param {webdriver.Locator} locator The most relevant locator. It is only
* used for error reporting and ElementArrayFinder.locator.
* @param {Array.<webdriver.promise.Promise>} opt_actionResults An array
* of promises which will be retrieved with then. Resolves to the latest
* action result, or null if no action has been called.
* @returns {ElementArrayFinder}
*/
export declare class ElementArrayFinder extends WebdriverWebElement {
browser_: ProtractorBrowser;
getWebElements: () => wdpromise.Promise<WebElement[]>;
locator_: any;
actionResults_: wdpromise.Promise<any>;
constructor(browser_: ProtractorBrowser, getWebElements?: () => wdpromise.Promise<WebElement[]>, locator_?: any, actionResults_?: wdpromise.Promise<any>);
/**
* Create a shallow copy of ElementArrayFinder.
*
* @returns {!ElementArrayFinder} A shallow copy of this.
*/
clone(): ElementArrayFinder;
/**
* Calls to ElementArrayFinder may be chained to find an array of elements
* using the current elements in this ElementArrayFinder as the starting
* point. This function returns a new ElementArrayFinder which would contain
* the children elements found (and could also be empty).
*
* @alias element.all(locator).all(locator)
* @view
* <div id='id1' class="parent">
* <ul>
* <li class="foo">1a</li>
* <li class="baz">1b</li>
* </ul>
* </div>
* <div id='id2' class="parent">
* <ul>
* <li class="foo">2a</li>
* <li class="bar">2b</li>
* </ul>
* </div>
*
* @example
* let foo = element.all(by.css('.parent')).all(by.css('.foo'));
* expect(foo.getText()).toEqual(['1a', '2a']);
* let baz = element.all(by.css('.parent')).all(by.css('.baz'));
* expect(baz.getText()).toEqual(['1b']);
* let nonexistent = element.all(by.css('.parent'))
* .all(by.css('.NONEXISTENT'));
* expect(nonexistent.getText()).toEqual(['']);
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* let foo = $$('.parent').$$('.foo');
* expect(foo.getText()).toEqual(['1a', '2a']);
* let baz = $$('.parent').$$('.baz');
* expect(baz.getText()).toEqual(['1b']);
* let nonexistent = $$('.parent').$$('.NONEXISTENT');
* expect(nonexistent.getText()).toEqual(['']);
*
* @param {webdriver.Locator} subLocator
* @returns {ElementArrayFinder}
*/
all(locator: Locator): ElementArrayFinder;
/**
* Apply a filter function to each element within the ElementArrayFinder.
* Returns a new ElementArrayFinder with all elements that pass the filter
* function. The filter function receives the ElementFinder as the first
* argument and the index as a second arg. This does not actually retrieve
* the underlying list of elements, so it can be used in page objects.
*
* @alias element.all(locator).filter(filterFn)
* @view
* <ul class="items">
* <li class="one">First</li>
* <li class="two">Second</li>
* <li class="three">Third</li>
* </ul>
*
* @example
* element.all(by.css('.items li')).filter(function(elem, index) {
* return elem.getText().then(function(text) {
* return text === 'Third';
* });
* }).first().click();
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* $$('.items li').filter(function(elem, index) {
* return elem.getText().then(function(text) {
* return text === 'Third';
* });
* }).first().click();
*
* @param {function(ElementFinder, number): webdriver.WebElement.Promise}
* filterFn
* Filter function that will test if an element should be returned.
* filterFn can either return a boolean or a promise that resolves to a
* boolean
* @returns {!ElementArrayFinder} A ElementArrayFinder that represents an
* array
* of element that satisfy the filter function.
*/
filter(filterFn: (element: ElementFinder, index?: number) => boolean | wdpromise.Promise<boolean>): ElementArrayFinder;
/**
* Get an element within the ElementArrayFinder by index. The index starts at 0.
* Negative indices are wrapped (i.e. -i means ith element from last)
* This does not actually retrieve the underlying element.
*
* @alias element.all(locator).get(index)
* @view
* <ul class="items">
* <li>First</li>
* <li>Second</li>
* <li>Third</li>
* </ul>
*
* @example
* let list = element.all(by.css('.items li'));
* expect(list.get(0).getText()).toBe('First');
* expect(list.get(1).getText()).toBe('Second');
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* let list = $$('.items li');
* expect(list.get(0).getText()).toBe('First');
* expect(list.get(1).getText()).toBe('Second');
*
* @param {number|webdriver.promise.Promise} index Element index.
* @returns {ElementFinder} finder representing element at the given index.
*/
get(index: number | wdpromise.Promise<number>): ElementFinder;
/**
* Get the first matching element for the ElementArrayFinder. This does not
* actually retrieve the underlying element.
*
* @alias element.all(locator).first()
* @view
* <ul class="items">
* <li>First</li>
* <li>Second</li>
* <li>Third</li>
* </ul>
*
* @example
* let first = element.all(by.css('.items li')).first();
* expect(first.getText()).toBe('First');
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* let first = $$('.items li').first();
* expect(first.getText()).toBe('First');
*
* @returns {ElementFinder} finder representing the first matching element
*/
first(): ElementFinder;
/**
* Get the last matching element for the ElementArrayFinder. This does not
* actually retrieve the underlying element.
*
* @alias element.all(locator).last()
* @view
* <ul class="items">
* <li>First</li>
* <li>Second</li>
* <li>Third</li>
* </ul>
*
* @example
* let last = element.all(by.css('.items li')).last();
* expect(last.getText()).toBe('Third');
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* let last = $$('.items li').last();
* expect(last.getText()).toBe('Third');
*
* @returns {ElementFinder} finder representing the last matching element
*/
last(): ElementFinder;
/**
* Shorthand function for finding arrays of elements by css.
* `element.all(by.css('.abc'))` is equivalent to `$$('.abc')`
*
* @alias $$(cssSelector)
* @view
* <div class="count">
* <span class="one">First</span>
* <span class="two">Second</span>
* </div>
*
* @example
* // The following two blocks of code are equivalent.
* let list = element.all(by.css('.count span'));
* expect(list.count()).toBe(2);
* expect(list.get(0).getText()).toBe('First');
* expect(list.get(1).getText()).toBe('Second');
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* let list = $$('.count span');
* expect(list.count()).toBe(2);
* expect(list.get(0).getText()).toBe('First');
* expect(list.get(1).getText()).toBe('Second');
*
* @param {string} selector a css selector
* @returns {ElementArrayFinder} which identifies the
* array of the located {@link webdriver.WebElement}s.
*/
$$(selector: string): ElementArrayFinder;
/**
* Returns an ElementFinder representation of ElementArrayFinder. It ensures
* that the ElementArrayFinder resolves to one and only one underlying
* element.
*
* @returns {ElementFinder} An ElementFinder representation
* @private
*/
toElementFinder_(): ElementFinder;
/**
* Count the number of elements represented by the ElementArrayFinder.
*
* @alias element.all(locator).count()
* @view
* <ul class="items">
* <li>First</li>
* <li>Second</li>
* <li>Third</li>
* </ul>
*
* @example
* let list = element.all(by.css('.items li'));
* expect(list.count()).toBe(3);
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* let list = $$('.items li');
* expect(list.count()).toBe(3);
*
* @returns {!webdriver.promise.Promise} A promise which resolves to the
* number of elements matching the locator.
*/
count(): wdpromise.Promise<number>;
/**
* Returns true if there are any elements present that match the finder.
*
* @alias element.all(locator).isPresent()
*
* @example
* expect($('.item').isPresent()).toBeTruthy();
*
* @returns {Promise<boolean>}
*/
isPresent(): wdpromise.Promise<boolean>;
/**
* Returns the most relevant locator.
*
* @example
* // returns by.css('#ID1')
* $('#ID1').locator();
*
* // returns by.css('#ID2')
* $('#ID1').$('#ID2').locator();
*
* // returns by.css('#ID1')
* $$('#ID1').filter(filterFn).get(0).click().locator();
*
* @returns {webdriver.Locator}
*/
locator(): Locator;
/**
* Apply an action function to every element in the ElementArrayFinder,
* and return a new ElementArrayFinder that contains the results of the
* actions.
*
* @param {function(ElementFinder)} actionFn
*
* @returns {ElementArrayFinder}
* @private
*/
private applyAction_(actionFn);
/**
* Represents the ElementArrayFinder as an array of ElementFinders.
*
* @returns {Array.<ElementFinder>} Return a promise, which resolves to a list
* of ElementFinders specified by the locator.
*/
asElementFinders_(): wdpromise.Promise<ElementFinder[]>;
/**
* Retrieve the elements represented by the ElementArrayFinder. The input
* function is passed to the resulting promise, which resolves to an
* array of ElementFinders.
*
* @alias element.all(locator).then(thenFunction)
* @view
* <ul class="items">
* <li>First</li>
* <li>Second</li>
* <li>Third</li>
* </ul>
*
* @example
* element.all(by.css('.items li')).then(function(arr) {
* expect(arr.length).toEqual(3);
* });
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* $$('.items li').then(function(arr) {
* expect(arr.length).toEqual(3);
* });
*
* @param {function(Array.<ElementFinder>)} fn
* @param {function(Error)} errorFn
*
* @returns {!webdriver.promise.Promise} A promise which will resolve to
* an array of ElementFinders represented by the ElementArrayFinder.
*/
then<T>(fn?: (value: ElementFinder[] | any[]) => T | wdpromise.IThenable<T>, errorFn?: (error: any) => any): wdpromise.Promise<T>;
/**
* Calls the input function on each ElementFinder represented by the
* ElementArrayFinder.
*
* @alias element.all(locator).each(eachFunction)
* @view
* <ul class="items">
* <li>First</li>
* <li>Second</li>
* <li>Third</li>
* </ul>
*
* @example
* element.all(by.css('.items li')).each(function(element, index) {
* // Will print 0 First, 1 Second, 2 Third.
* element.getText().then(function (text) {
* console.log(index, text);
* });
* });
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* $$('.items li').each(function(element, index) {
* // Will print 0 First, 1 Second, 2 Third.
* element.getText().then(function (text) {
* console.log(index, text);
* });
* });
*
* @param {function(ElementFinder)} fn Input function
*
* @returns {!webdriver.promise.Promise} A promise that will resolve when the
* function has been called on all the ElementFinders. The promise will
* resolve to null.
*/
each(fn: (elementFinder?: ElementFinder, index?: number) => any): wdpromise.Promise<any>;
/**
* Apply a map function to each element within the ElementArrayFinder. The
* callback receives the ElementFinder as the first argument and the index as
* a second arg.
*
* @alias element.all(locator).map(mapFunction)
* @view
* <ul class="items">
* <li class="one">First</li>
* <li class="two">Second</li>
* <li class="three">Third</li>
* </ul>
*
* @example
* let items = element.all(by.css('.items li')).map(function(elm, index) {
* return {
* index: index,
* text: elm.getText(),
* class: elm.getAttribute('class')
* };
* });
* expect(items).toEqual([
* {index: 0, text: 'First', class: 'one'},
* {index: 1, text: 'Second', class: 'two'},
* {index: 2, text: 'Third', class: 'three'}
* ]);
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* let items = $$('.items li').map(function(elm, index) {
* return {
* index: index,
* text: elm.getText(),
* class: elm.getAttribute('class')
* };
* });
* expect(items).toEqual([
* {index: 0, text: 'First', class: 'one'},
* {index: 1, text: 'Second', class: 'two'},
* {index: 2, text: 'Third', class: 'three'}
* ]);
*
* @param {function(ElementFinder, number)} mapFn Map function that
* will be applied to each element.
* @returns {!webdriver.promise.Promise} A promise that resolves to an array
* of values returned by the map function.
*/
map<T>(mapFn: (elementFinder?: ElementFinder, index?: number) => T | any): wdpromise.Promise<T[]>;
/**
* Apply a reduce function against an accumulator and every element found
* using the locator (from left-to-right). The reduce function has to reduce
* every element into a single value (the accumulator). Returns promise of
* the accumulator. The reduce function receives the accumulator, current
* ElementFinder, the index, and the entire array of ElementFinders,
* respectively.
*
* @alias element.all(locator).reduce(reduceFn)
* @view
* <ul class="items">
* <li class="one">First</li>
* <li class="two">Second</li>
* <li class="three">Third</li>
* </ul>
*
* @example
* let value = element.all(by.css('.items li')).reduce(function(acc, elem) {
* return elem.getText().then(function(text) {
* return acc + text + ' ';
* });
* }, '');
*
* expect(value).toEqual('First Second Third ');
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* let value = $$('.items li').reduce(function(acc, elem) {
* return elem.getText().then(function(text) {
* return acc + text + ' ';
* });
* }, '');
*
* expect(value).toEqual('First Second Third ');
*
* @param {function(number, ElementFinder, number, Array.<ElementFinder>)}
* reduceFn Reduce function that reduces every element into a single
* value.
* @param {*} initialValue Initial value of the accumulator.
* @returns {!webdriver.promise.Promise} A promise that resolves to the final
* value of the accumulator.
*/
reduce(reduceFn: Function, initialValue: any): wdpromise.Promise<any>;
/**
* Evaluates the input as if it were on the scope of the current underlying
* elements.
*
* @view
* <span class="foo">{{letiableInScope}}</span>
*
* @example
* let value = element.all(by.css('.foo')).evaluate('letiableInScope');
*
* // Or using the shortcut $$() notation instead of element.all(by.css()):
*
* let value = $$('.foo').evaluate('letiableInScope');
*
* @param {string} expression
*
* @returns {ElementArrayFinder} which resolves to the
* evaluated expression for each underlying element.
* The result will be resolved as in
* {@link webdriver.WebDriver.executeScript}. In summary - primitives will
* be resolved as is, functions will be converted to string, and elements
* will be returned as a WebElement.
*/
evaluate(expression: string): ElementArrayFinder;
/**
* Determine if animation is allowed on the current underlying elements.
* @param {string} value
*
* @example
* // Turns off ng-animate animations for all elements in the <body>
* element(by.css('body')).allowAnimations(false);
*
* // Or using the shortcut $() notation instead of element(by.css()):
*
* $('body').allowAnimations(false);
*
* @returns {ElementArrayFinder} which resolves to whether animation is
* allowed.
*/
allowAnimations(value: boolean): ElementArrayFinder;
}
/**
* The ElementFinder simply represents a single element of an
* ElementArrayFinder (and is more like a convenience object). As a result,
* anything that can be done with an ElementFinder, can also be done using
* an ElementArrayFinder.
*
* The ElementFinder can be treated as a WebElement for most purposes, in
* particular, you may perform actions (i.e. click, getText) on them as you
* would a WebElement. Once an action is performed on an ElementFinder, the
* latest result from the chain can be accessed using the then method.
* Unlike a WebElement, an ElementFinder will wait for angular to settle before
* performing finds or actions.
*
* ElementFinder can be used to build a chain of locators that is used to find
* an element. An ElementFinder does not actually attempt to find the element
* until an action is called, which means they can be set up in helper files
* before the page is available.
*
* @alias element(locator)
* @view
* <span>{{person.name}}</span>
* <span ng-bind="person.email"></span>
* <input type="text" ng-model="person.name"/>
*
* @example
* // Find element with {{scopelet}} syntax.
* element(by.binding('person.name')).getText().then(function(name) {
* expect(name).toBe('Foo');
* });
*
* // Find element with ng-bind="scopelet" syntax.
* expect(element(by.binding('person.email')).getText()).toBe('foo@bar.com');
*
* // Find by model.
* let input = element(by.model('person.name'));
* input.sendKeys('123');
* expect(input.getAttribute('value')).toBe('Foo123');
*
* @constructor
* @extends {webdriver.WebElement}
* @param {ProtractorBrowser} browser_ A browser instance.
* @param {ElementArrayFinder} elementArrayFinder The ElementArrayFinder
* that this is branched from.
* @returns {ElementFinder}
*/
export declare class ElementFinder extends WebdriverWebElement {
browser_: ProtractorBrowser;
parentElementArrayFinder: ElementArrayFinder;
elementArrayFinder_: ElementArrayFinder;
then?: (fn: (value: any) => any | wdpromise.IThenable<any>, errorFn?: (error: any) => any) => wdpromise.Promise<any>;
constructor(browser_: ProtractorBrowser, elementArrayFinder: ElementArrayFinder);
static fromWebElement_(browser: ProtractorBrowser, webElem: WebElement, locator?: Locator): ElementFinder;
/**
* Create a shallow copy of ElementFinder.
*
* @returns {!ElementFinder} A shallow copy of this.
*/
clone(): ElementFinder;
/**
* @see ElementArrayFinder.prototype.locator
*
* @returns {webdriver.Locator}
*/
locator(): any;
/**
* Returns the WebElement represented by this ElementFinder.
* Throws the WebDriver error if the element doesn't exist.
*
* @alias element(locator).getWebElement()
* @view
* <div class="parent">
* some text
* </div>
*
* @example
* // The following four expressions are equivalent.
* $('.parent').getWebElement();
* element(by.css('.parent')).getWebElement();
* browser.driver.findElement(by.css('.parent'));
* browser.findElement(by.css('.parent'));
*
* @returns {webdriver.WebElementPromise}
*/
getWebElement(): WebElementPromise;
/**
* Calls to {@code all} may be chained to find an array of elements within a
* parent.
*
* @alias element(locator).all(locator)
* @view
* <div class="parent">
* <ul>
* <li class="one">First</li>
* <li class="two">Second</li>
* <li class="three">Third</li>
* </ul>
* </div>
*
* @example
* let items = element(by.css('.parent')).all(by.tagName('li'));
*
* // Or using the shortcut $() notation instead of element(by.css()):
*
* let items = $('.parent').all(by.tagName('li'));
*
* @param {webdriver.Locator} subLocator
* @returns {ElementArrayFinder}
*/
all(subLocator: Locator): ElementArrayFinder;
/**
* Calls to {@code element} may be chained to find elements within a parent.
*
* @alias element(locator).element(locator)
* @view
* <div class="parent">
* <div class="child">
* Child text
* <div>{{person.phone}}</div>
* </div>
* </div>
*
* @example
* // Chain 2 element calls.
* let child = element(by.css('.parent')).
* element(by.css('.child'));
* expect(child.getText()).toBe('Child text\n555-123-4567');
*
* // Chain 3 element calls.
* let triple = element(by.css('.parent')).
* element(by.css('.child')).
* element(by.binding('person.phone'));
* expect(triple.getText()).toBe('555-123-4567');
*
* // Or using the shortcut $() notation instead of element(by.css()):
*
* // Chain 2 element calls.
* let child = $('.parent').$('.child');
* expect(child.getText()).toBe('Child text\n555-123-4567');
*
* // Chain 3 element calls.
* let triple = $('.parent').$('.child').
* element(by.binding('person.phone'));
* expect(triple.getText()).toBe('555-123-4567');
*
* @param {webdriver.Locator} subLocator
* @returns {ElementFinder}
*/
element(subLocator: Locator): ElementFinder;
/**
* Calls to {@code $$} may be chained to find an array of elements within a
* parent.
*
* @alias element(locator).all(selector)
* @view
* <div class="parent">
* <ul>
* <li class="one">First</li>
* <li class="two">Second</li>
* <li class="three">Third</li>
* </ul>
* </div>
*
* @example
* let items = element(by.css('.parent')).$$('li');
*
* // Or using the shortcut $() notation instead of element(by.css()):
*
* let items = $('.parent').$$('li');
*
* @param {string} selector a css selector
* @returns {ElementArrayFinder}
*/
$$(selector: string): ElementArrayFinder;
/**
* Calls to {@code $} may be chained to find elements within a parent.
*
* @alias element(locator).$(selector)
* @view
* <div class="parent">
* <div class="child">
* Child text
* <div>{{person.phone}}</div>
* </div>
* </div>
*
* @example
* // Chain 2 element calls.
* let child = element(by.css('.parent')).
* $('.child');
* expect(child.getText()).toBe('Child text\n555-123-4567');
*
* // Chain 3 element calls.
* let triple = element(by.css('.parent')).
* $('.child').
* element(by.binding('person.phone'));
* expect(triple.getText()).toBe('555-123-4567');
*
* // Or using the shortcut $() notation instead of element(by.css()):
*
* // Chain 2 element calls.
* let child = $('.parent').$('.child');
* expect(child.getText()).toBe('Child text\n555-123-4567');
*
* // Chain 3 element calls.
* let triple = $('.parent').$('.child').
* element(by.binding('person.phone'));
* expect(triple.getText()).toBe('555-123-4567');
*
* @param {string} selector A css selector
* @returns {ElementFinder}
*/
$(selector: string): ElementFinder;
/**
* Determine whether the element is present on the page.
*
* @view
* <span>{{person.name}}</span>
*
* @example
* // Element exists.
* expect(element(by.binding('person.name')).isPresent()).toBe(true);
*
* // Element not present.
* expect(element(by.binding('notPresent')).isPresent()).toBe(false);
*
* @returns {webdriver.promise.Promise<boolean>} which resolves to whether
* the element is present on the page.
*/
isPresent(): wdpromise.Promise<boolean>;
/**
* Same as ElementFinder.isPresent(), except this checks whether the element
* identified by the subLocator is present, rather than the current element
* finder, i.e.: `element(by.css('#abc')).element(by.css('#def')).isPresent()`
* is identical to `element(by.css('#abc')).isElementPresent(by.css('#def'))`.
*
* // Or using the shortcut $() notation instead of element(by.css()):
*
* `$('#abc').$('#def').isPresent()` is identical to
* `$('#abc').isElementPresent($('#def'))`.
*
* @see ElementFinder.isPresent
*
* @param {webdriver.Locator} subLocator Locator for element to look for.
* @returns {webdriver.promise.Promise<boolean>} which resolves to whether
* the subelement is present on the page.
*/
isElementPresent(subLocator: Locator): wdpromise.Promise<boolean>;
/**
* Evaluates the input as if it were on the scope of the current element.
* @see ElementArrayFinder.prototype.evaluate
*
* @view
* <span id="foo">{{letiableInScope}}</span>
*
* @example
* let value = element(by.id('foo')).evaluate('letiableInScope');
*
* @param {string} expression
*
* @returns {ElementFinder} which resolves to the evaluated expression.
*/
evaluate(expression: string): ElementFinder;
/**
* @see ElementArrayFinder.prototype.allowAnimations.
* @param {string} value
*
* @returns {ElementFinder} which resolves to whether animation is allowed.
*/
allowAnimations(value: boolean): ElementFinder;
/**
* Compares an element to this one for equality.
*
* @param {!ElementFinder|!webdriver.WebElement} The element to compare to.
*
* @returns {!webdriver.promise.Promise.<boolean>} A promise that will be
* resolved to whether the two WebElements are equal.
*/
equals(element: ElementFinder | WebElement): wdpromise.Promise<any>;
}
/**
* Shortcut for querying the document directly with css.
* `element(by.css('.abc'))` is equivalent to `$('.abc')`
*
* @alias $(cssSelector)
* @view
* <div class="count">
* <span class="one">First</span>
* <span class="two">Second</span>
* </div>
*
* @example
* let item = $('.count .two');
* expect(item.getText()).toBe('Second');
*
* @param {string} selector A css selector
* @returns {ElementFinder} which identifies the located
* {@link webdriver.WebElement}
*/
export declare let build$: (element: ElementHelper, by: typeof By) => (selector: string) => ElementFinder;
/**
* Shortcut for querying the document directly with css.
* `element.all(by.css('.abc'))` is equivalent to `$$('.abc')`
*
* @alias $$(cssSelector)
* @view
* <div class="count">
* <span class="one">First</span>
* <span class="two">Second</span>
* </div>
*
* @example
* // The following protractor expressions are equivalent.
* let list = element.all(by.css('.count span'));
* expect(list.count()).toBe(2);
*
* list = $$('.count span');
* expect(list.count()).toBe(2);
* expect(list.get(0).getText()).toBe('First');
* expect(list.get(1).getText()).toBe('Second');
*
* @param {string} selector a css selector
* @returns {ElementArrayFinder} which identifies the
* array of the located {@link webdriver.WebElement}s.
*/
export declare let build$$: (element: ElementHelper, by: typeof By) => (selector: string) => ElementArrayFinder;

1166
node_modules/protractor/built/element.js generated vendored Normal file

File diff suppressed because it is too large Load diff

32
node_modules/protractor/built/exitCodes.d.ts generated vendored Normal file
View file

@ -0,0 +1,32 @@
import { Logger } from './logger';
export declare class IError extends Error {
code?: number;
stack?: string;
}
export declare class ProtractorError extends IError {
static ERR_MSGS: string[];
static CODE: number;
static SUPRESS_EXIT_CODE: boolean;
message: string;
constructor(logger: Logger, message: string, code: number, error?: Error);
static log(logger: Logger, code: number, message: string, stack: string): void;
}
/**
* Configuration file error
*/
export declare class ConfigError extends ProtractorError {
static CODE: number;
constructor(logger: Logger, message: string, error?: Error);
}
/**
* Browser errors including getting a driver session, direct connect, etc.
*/
export declare class BrowserError extends ProtractorError {
static CODE: number;
static ERR_MSGS: string[];
constructor(logger: Logger, message: string);
}
export declare class ErrorHandler {
static isError(errMsgs: string[], e: Error): boolean;
static parseError(e: Error): number;
}

84
node_modules/protractor/built/exitCodes.js generated vendored Normal file
View file

@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const CONFIG_ERROR_CODE = 105;
const BROWSER_CONNECT_ERROR_CODE = 135;
const KITCHEN_SINK_CODE = 199;
class IError extends Error {
}
exports.IError = IError;
class ProtractorError extends IError {
constructor(logger, message, code, error) {
super(message);
this.message = message;
this.code = code;
// replacing the stack trace with the thrown error stack trace.
if (error) {
let protractorError = error;
this.stack = protractorError.stack;
}
ProtractorError.log(logger, this.code, this.message, this.stack);
if (!ProtractorError.SUPRESS_EXIT_CODE) {
process.exit(this.code);
}
}
static log(logger, code, message, stack) {
let messages = message.split('\n');
if (messages.length > 1) {
message = messages[0];
}
logger.error('Error code: ' + code);
logger.error('Error message: ' + message);
logger.error(stack);
}
}
ProtractorError.CODE = KITCHEN_SINK_CODE;
ProtractorError.SUPRESS_EXIT_CODE = false;
exports.ProtractorError = ProtractorError;
/**
* Configuration file error
*/
class ConfigError extends ProtractorError {
constructor(logger, message, error) {
super(logger, message, ConfigError.CODE, error);
}
}
ConfigError.CODE = CONFIG_ERROR_CODE;
exports.ConfigError = ConfigError;
/**
* Browser errors including getting a driver session, direct connect, etc.
*/
class BrowserError extends ProtractorError {
constructor(logger, message) {
super(logger, message, BrowserError.CODE);
}
}
BrowserError.CODE = BROWSER_CONNECT_ERROR_CODE;
BrowserError.ERR_MSGS = [
'ECONNREFUSED connect ECONNREFUSED', 'Sauce Labs Authentication Error',
'Invalid username or password'
];
exports.BrowserError = BrowserError;
class ErrorHandler {
static isError(errMsgs, e) {
if (errMsgs && errMsgs.length > 0) {
for (let errPos in errMsgs) {
let errMsg = errMsgs[errPos];
if (e.message && e.message.indexOf(errMsg) !== -1) {
return true;
}
}
}
return false;
}
static parseError(e) {
if (ErrorHandler.isError(ConfigError.ERR_MSGS, e)) {
return ConfigError.CODE;
}
if (ErrorHandler.isError(BrowserError.ERR_MSGS, e)) {
return BrowserError.CODE;
}
return null;
}
}
exports.ErrorHandler = ErrorHandler;
//# sourceMappingURL=exitCodes.js.map

320
node_modules/protractor/built/expectedConditions.d.ts generated vendored Normal file
View file

@ -0,0 +1,320 @@
import { ProtractorBrowser } from './browser';
import { ElementFinder } from './element';
/**
* Represents a library of canned expected conditions that are useful for
* protractor, especially when dealing with non-angular apps.
*
* Each condition returns a function that evaluates to a promise. You may mix
* multiple conditions using `and`, `or`, and/or `not`. You may also
* mix these conditions with any other conditions that you write.
*
* See ExpectedCondition Class in Selenium WebDriver codebase.
* http://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html
*
*
* @example
* var EC = protractor.ExpectedConditions;
* var button = $('#xyz');
* var isClickable = EC.elementToBeClickable(button);
*
* browser.get(URL);
* browser.wait(isClickable, 5000); //wait for an element to become clickable
* button.click();
*
* // You can define your own expected condition, which is a function that
* // takes no parameter and evaluates to a promise of a boolean.
* var urlChanged = function() {
* return browser.getCurrentUrl().then(function(url) {
* return url === 'http://www.angularjs.org';
* });
* };
*
* // You can customize the conditions with EC.and, EC.or, and EC.not.
* // Here's a condition to wait for url to change, $('abc') element to contain
* // text 'bar', and button becomes clickable.
* var condition = EC.and(urlChanged, EC.textToBePresentInElement($('abc'),
* 'bar'), isClickable);
* browser.get(URL);
* browser.wait(condition, 5000); //wait for condition to be true.
* button.click();
*
* @alias ExpectedConditions
* @constructor
*/
export declare class ProtractorExpectedConditions {
browser: ProtractorBrowser;
constructor(browser: ProtractorBrowser);
/**
* Negates the result of a promise.
*
* @example
* var EC = protractor.ExpectedConditions;
* var titleIsNotFoo = EC.not(EC.titleIs('Foo'));
* // Waits for title to become something besides 'foo'.
* browser.wait(titleIsNotFoo, 5000);
*
* @alias ExpectedConditions.not
* @param {!function} expectedCondition
*
* @returns {!function} An expected condition that returns the negated value.
*/
not(expectedCondition: Function): Function;
/**
* Helper function that is equivalent to the logical_and if defaultRet==true,
* or logical_or if defaultRet==false
*
* @private
* @param {boolean} defaultRet
* @param {Array.<Function>} fns An array of expected conditions to chain.
*
* @returns {!function} An expected condition that returns a promise which
* evaluates to the result of the logical chain.
*/
logicalChain_(defaultRet: boolean, fns: Array<Function>): Function;
/**
* Chain a number of expected conditions using logical_and, short circuiting
* at the first expected condition that evaluates to false.
*
* @example
* var EC = protractor.ExpectedConditions;
* var titleContainsFoo = EC.titleContains('Foo');
* var titleIsNotFooBar = EC.not(EC.titleIs('FooBar'));
* // Waits for title to contain 'Foo', but is not 'FooBar'
* browser.wait(EC.and(titleContainsFoo, titleIsNotFooBar), 5000);
*
* @alias ExpectedConditions.and
* @param {Array.<Function>} fns An array of expected conditions to 'and'
* together.
*
* @returns {!function} An expected condition that returns a promise which
* evaluates to the result of the logical and.
*/
and(...args: Function[]): Function;
/**
* Chain a number of expected conditions using logical_or, short circuiting
* at the first expected condition that evaluates to true.
*
* @alias ExpectedConditions.or
* @example
* var EC = protractor.ExpectedConditions;
* var titleContainsFoo = EC.titleContains('Foo');
* var titleContainsBar = EC.titleContains('Bar');
* // Waits for title to contain either 'Foo' or 'Bar'
* browser.wait(EC.or(titleContainsFoo, titleContainsBar), 5000);
*
* @param {Array.<Function>} fns An array of expected conditions to 'or'
* together.
*
* @returns {!function} An expected condition that returns a promise which
* evaluates to the result of the logical or.
*/
or(...args: Function[]): Function;
/**
* Expect an alert to be present.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for an alert pops up.
* browser.wait(EC.alertIsPresent(), 5000);
*
* @alias ExpectedConditions.alertIsPresent
* @returns {!function} An expected condition that returns a promise
* representing whether an alert is present.
*/
alertIsPresent(): Function;
/**
* An Expectation for checking an element is visible and enabled such that you
* can click it.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to be clickable.
* browser.wait(EC.elementToBeClickable($('#abc')), 5000);
*
* @alias ExpectedConditions.elementToBeClickable
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is clickable.
*/
elementToBeClickable(elementFinder: ElementFinder): Function;
/**
* An expectation for checking if the given text is present in the
* element. Returns false if the elementFinder does not find an element.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to contain the text 'foo'.
* browser.wait(EC.textToBePresentInElement($('#abc'), 'foo'), 5000);
*
* @alias ExpectedConditions.textToBePresentInElement
* @param {!ElementFinder} elementFinder The element to check
* @param {!string} text The text to verify against
*
* @returns {!function} An expected condition that returns a promise
* representing whether the text is present in the element.
*/
textToBePresentInElement(elementFinder: ElementFinder, text: string): Function;
/**
* An expectation for checking if the given text is present in the elements
* value. Returns false if the elementFinder does not find an element.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'myInput' to contain the input 'foo'.
* browser.wait(EC.textToBePresentInElementValue($('#myInput'), 'foo'), 5000);
*
* @alias ExpectedConditions.textToBePresentInElementValue
* @param {!ElementFinder} elementFinder The element to check
* @param {!string} text The text to verify against
*
* @returns {!function} An expected condition that returns a promise
* representing whether the text is present in the element's value.
*/
textToBePresentInElementValue(elementFinder: ElementFinder, text: string): Function;
/**
* An expectation for checking that the title contains a case-sensitive
* substring.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the title to contain 'foo'.
* browser.wait(EC.titleContains('foo'), 5000);
*
* @alias ExpectedConditions.titleContains
* @param {!string} title The fragment of title expected
*
* @returns {!function} An expected condition that returns a promise
* representing whether the title contains the string.
*/
titleContains(title: string): Function;
/**
* An expectation for checking the title of a page.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the title to be 'foo'.
* browser.wait(EC.titleIs('foo'), 5000);
*
* @alias ExpectedConditions.titleIs
* @param {!string} title The expected title, which must be an exact match.
*
* @returns {!function} An expected condition that returns a promise
* representing whether the title equals the string.
*/
titleIs(title: string): Function;
/**
* An expectation for checking that the URL contains a case-sensitive
* substring.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the URL to contain 'foo'.
* browser.wait(EC.urlContains('foo'), 5000);
*
* @alias ExpectedConditions.urlContains
* @param {!string} url The fragment of URL expected
*
* @returns {!function} An expected condition that returns a promise
* representing whether the URL contains the string.
*/
urlContains(url: string): Function;
/**
* An expectation for checking the URL of a page.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the URL to be 'foo'.
* browser.wait(EC.urlIs('foo'), 5000);
*
* @alias ExpectedConditions.urlIs
* @param {!string} url The expected URL, which must be an exact match.
*
* @returns {!function} An expected condition that returns a promise
* representing whether the url equals the string.
*/
urlIs(url: string): Function;
/**
* An expectation for checking that an element is present on the DOM
* of a page. This does not necessarily mean that the element is visible.
* This is the opposite of 'stalenessOf'.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to be present on the dom.
* browser.wait(EC.presenceOf($('#abc')), 5000);
*
* @alias ExpectedConditions.presenceOf
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is present.
*/
presenceOf(elementFinder: ElementFinder): Function;
/**
* An expectation for checking that an element is not attached to the DOM
* of a page. This is the opposite of 'presenceOf'.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to be no longer present on the dom.
* browser.wait(EC.stalenessOf($('#abc')), 5000);
*
* @alias ExpectedConditions.stalenessOf
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is stale.
*/
stalenessOf(elementFinder: ElementFinder): Function;
/**
* An expectation for checking that an element is present on the DOM of a
* page and visible. Visibility means that the element is not only displayed
* but also has a height and width that is greater than 0. This is the
* opposite
* of 'invisibilityOf'.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to be visible on the dom.
* browser.wait(EC.visibilityOf($('#abc')), 5000);
*
* @alias ExpectedConditions.visibilityOf
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is visible.
*/
visibilityOf(elementFinder: ElementFinder): Function;
/**
* An expectation for checking that an element is either invisible or not
* present on the DOM. This is the opposite of 'visibilityOf'.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to be no longer visible on the dom.
* browser.wait(EC.invisibilityOf($('#abc')), 5000);
*
* @alias ExpectedConditions.invisibilityOf
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is invisible.
*/
invisibilityOf(elementFinder: ElementFinder): Function;
/**
* An expectation for checking the selection is selected.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'myCheckbox' to be selected.
* browser.wait(EC.elementToBeSelected($('#myCheckbox')), 5000);
*
* @alias ExpectedConditions.elementToBeSelected
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is selected.
*/
elementToBeSelected(elementFinder: ElementFinder): Function;
}

424
node_modules/protractor/built/expectedConditions.js generated vendored Normal file
View file

@ -0,0 +1,424 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const selenium_webdriver_1 = require("selenium-webdriver");
const util_1 = require("./util");
/**
* Represents a library of canned expected conditions that are useful for
* protractor, especially when dealing with non-angular apps.
*
* Each condition returns a function that evaluates to a promise. You may mix
* multiple conditions using `and`, `or`, and/or `not`. You may also
* mix these conditions with any other conditions that you write.
*
* See ExpectedCondition Class in Selenium WebDriver codebase.
* http://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html
*
*
* @example
* var EC = protractor.ExpectedConditions;
* var button = $('#xyz');
* var isClickable = EC.elementToBeClickable(button);
*
* browser.get(URL);
* browser.wait(isClickable, 5000); //wait for an element to become clickable
* button.click();
*
* // You can define your own expected condition, which is a function that
* // takes no parameter and evaluates to a promise of a boolean.
* var urlChanged = function() {
* return browser.getCurrentUrl().then(function(url) {
* return url === 'http://www.angularjs.org';
* });
* };
*
* // You can customize the conditions with EC.and, EC.or, and EC.not.
* // Here's a condition to wait for url to change, $('abc') element to contain
* // text 'bar', and button becomes clickable.
* var condition = EC.and(urlChanged, EC.textToBePresentInElement($('abc'),
* 'bar'), isClickable);
* browser.get(URL);
* browser.wait(condition, 5000); //wait for condition to be true.
* button.click();
*
* @alias ExpectedConditions
* @constructor
*/
class ProtractorExpectedConditions {
constructor(browser) {
this.browser = browser;
}
;
/**
* Negates the result of a promise.
*
* @example
* var EC = protractor.ExpectedConditions;
* var titleIsNotFoo = EC.not(EC.titleIs('Foo'));
* // Waits for title to become something besides 'foo'.
* browser.wait(titleIsNotFoo, 5000);
*
* @alias ExpectedConditions.not
* @param {!function} expectedCondition
*
* @returns {!function} An expected condition that returns the negated value.
*/
not(expectedCondition) {
return () => {
return expectedCondition().then((bool) => {
return !bool;
});
};
}
/**
* Helper function that is equivalent to the logical_and if defaultRet==true,
* or logical_or if defaultRet==false
*
* @private
* @param {boolean} defaultRet
* @param {Array.<Function>} fns An array of expected conditions to chain.
*
* @returns {!function} An expected condition that returns a promise which
* evaluates to the result of the logical chain.
*/
logicalChain_(defaultRet, fns) {
let self = this;
return () => {
if (fns.length === 0) {
return defaultRet;
}
let fn = fns[0];
return fn().then((bool) => {
if (bool === defaultRet) {
return self.logicalChain_(defaultRet, fns.slice(1))();
}
else {
return !defaultRet;
}
});
};
}
/**
* Chain a number of expected conditions using logical_and, short circuiting
* at the first expected condition that evaluates to false.
*
* @example
* var EC = protractor.ExpectedConditions;
* var titleContainsFoo = EC.titleContains('Foo');
* var titleIsNotFooBar = EC.not(EC.titleIs('FooBar'));
* // Waits for title to contain 'Foo', but is not 'FooBar'
* browser.wait(EC.and(titleContainsFoo, titleIsNotFooBar), 5000);
*
* @alias ExpectedConditions.and
* @param {Array.<Function>} fns An array of expected conditions to 'and'
* together.
*
* @returns {!function} An expected condition that returns a promise which
* evaluates to the result of the logical and.
*/
and(...args) {
return this.logicalChain_(true, args);
}
/**
* Chain a number of expected conditions using logical_or, short circuiting
* at the first expected condition that evaluates to true.
*
* @alias ExpectedConditions.or
* @example
* var EC = protractor.ExpectedConditions;
* var titleContainsFoo = EC.titleContains('Foo');
* var titleContainsBar = EC.titleContains('Bar');
* // Waits for title to contain either 'Foo' or 'Bar'
* browser.wait(EC.or(titleContainsFoo, titleContainsBar), 5000);
*
* @param {Array.<Function>} fns An array of expected conditions to 'or'
* together.
*
* @returns {!function} An expected condition that returns a promise which
* evaluates to the result of the logical or.
*/
or(...args) {
return this.logicalChain_(false, args);
}
/**
* Expect an alert to be present.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for an alert pops up.
* browser.wait(EC.alertIsPresent(), 5000);
*
* @alias ExpectedConditions.alertIsPresent
* @returns {!function} An expected condition that returns a promise
* representing whether an alert is present.
*/
alertIsPresent() {
return () => {
return this.browser.driver.switchTo().alert().then(() => {
return true;
}, (err) => {
if (err instanceof selenium_webdriver_1.error.NoSuchAlertError) {
return false;
}
else {
throw err;
}
});
};
}
/**
* An Expectation for checking an element is visible and enabled such that you
* can click it.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to be clickable.
* browser.wait(EC.elementToBeClickable($('#abc')), 5000);
*
* @alias ExpectedConditions.elementToBeClickable
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is clickable.
*/
elementToBeClickable(elementFinder) {
return this.and(this.visibilityOf(elementFinder), () => {
return elementFinder.isEnabled().then(util_1.passBoolean, util_1.falseIfMissing);
});
}
/**
* An expectation for checking if the given text is present in the
* element. Returns false if the elementFinder does not find an element.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to contain the text 'foo'.
* browser.wait(EC.textToBePresentInElement($('#abc'), 'foo'), 5000);
*
* @alias ExpectedConditions.textToBePresentInElement
* @param {!ElementFinder} elementFinder The element to check
* @param {!string} text The text to verify against
*
* @returns {!function} An expected condition that returns a promise
* representing whether the text is present in the element.
*/
textToBePresentInElement(elementFinder, text) {
let hasText = () => {
return elementFinder.getText().then((actualText) => {
// MSEdge does not properly remove newlines, which causes false
// negatives
return actualText.replace(/\r?\n|\r/g, '').indexOf(text) > -1;
}, util_1.falseIfMissing);
};
return this.and(this.presenceOf(elementFinder), hasText);
}
/**
* An expectation for checking if the given text is present in the elements
* value. Returns false if the elementFinder does not find an element.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'myInput' to contain the input 'foo'.
* browser.wait(EC.textToBePresentInElementValue($('#myInput'), 'foo'), 5000);
*
* @alias ExpectedConditions.textToBePresentInElementValue
* @param {!ElementFinder} elementFinder The element to check
* @param {!string} text The text to verify against
*
* @returns {!function} An expected condition that returns a promise
* representing whether the text is present in the element's value.
*/
textToBePresentInElementValue(elementFinder, text) {
let hasText = () => {
return elementFinder.getAttribute('value').then((actualText) => {
return actualText.indexOf(text) > -1;
}, util_1.falseIfMissing);
};
return this.and(this.presenceOf(elementFinder), hasText);
}
/**
* An expectation for checking that the title contains a case-sensitive
* substring.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the title to contain 'foo'.
* browser.wait(EC.titleContains('foo'), 5000);
*
* @alias ExpectedConditions.titleContains
* @param {!string} title The fragment of title expected
*
* @returns {!function} An expected condition that returns a promise
* representing whether the title contains the string.
*/
titleContains(title) {
return () => {
return this.browser.driver.getTitle().then((actualTitle) => {
return actualTitle.indexOf(title) > -1;
});
};
}
/**
* An expectation for checking the title of a page.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the title to be 'foo'.
* browser.wait(EC.titleIs('foo'), 5000);
*
* @alias ExpectedConditions.titleIs
* @param {!string} title The expected title, which must be an exact match.
*
* @returns {!function} An expected condition that returns a promise
* representing whether the title equals the string.
*/
titleIs(title) {
return () => {
return this.browser.driver.getTitle().then((actualTitle) => {
return actualTitle === title;
});
};
}
/**
* An expectation for checking that the URL contains a case-sensitive
* substring.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the URL to contain 'foo'.
* browser.wait(EC.urlContains('foo'), 5000);
*
* @alias ExpectedConditions.urlContains
* @param {!string} url The fragment of URL expected
*
* @returns {!function} An expected condition that returns a promise
* representing whether the URL contains the string.
*/
urlContains(url) {
return () => {
return this.browser.driver.getCurrentUrl().then((actualUrl) => {
return actualUrl.indexOf(url) > -1;
});
};
}
/**
* An expectation for checking the URL of a page.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the URL to be 'foo'.
* browser.wait(EC.urlIs('foo'), 5000);
*
* @alias ExpectedConditions.urlIs
* @param {!string} url The expected URL, which must be an exact match.
*
* @returns {!function} An expected condition that returns a promise
* representing whether the url equals the string.
*/
urlIs(url) {
return () => {
return this.browser.driver.getCurrentUrl().then((actualUrl) => {
return actualUrl === url;
});
};
}
/**
* An expectation for checking that an element is present on the DOM
* of a page. This does not necessarily mean that the element is visible.
* This is the opposite of 'stalenessOf'.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to be present on the dom.
* browser.wait(EC.presenceOf($('#abc')), 5000);
*
* @alias ExpectedConditions.presenceOf
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is present.
*/
presenceOf(elementFinder) {
return elementFinder.isPresent.bind(elementFinder);
}
;
/**
* An expectation for checking that an element is not attached to the DOM
* of a page. This is the opposite of 'presenceOf'.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to be no longer present on the dom.
* browser.wait(EC.stalenessOf($('#abc')), 5000);
*
* @alias ExpectedConditions.stalenessOf
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is stale.
*/
stalenessOf(elementFinder) {
return this.not(this.presenceOf(elementFinder));
}
/**
* An expectation for checking that an element is present on the DOM of a
* page and visible. Visibility means that the element is not only displayed
* but also has a height and width that is greater than 0. This is the
* opposite
* of 'invisibilityOf'.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to be visible on the dom.
* browser.wait(EC.visibilityOf($('#abc')), 5000);
*
* @alias ExpectedConditions.visibilityOf
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is visible.
*/
visibilityOf(elementFinder) {
return this.and(this.presenceOf(elementFinder), () => {
return elementFinder.isDisplayed().then(util_1.passBoolean, util_1.falseIfMissing);
});
}
/**
* An expectation for checking that an element is either invisible or not
* present on the DOM. This is the opposite of 'visibilityOf'.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'abc' to be no longer visible on the dom.
* browser.wait(EC.invisibilityOf($('#abc')), 5000);
*
* @alias ExpectedConditions.invisibilityOf
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is invisible.
*/
invisibilityOf(elementFinder) {
return this.not(this.visibilityOf(elementFinder));
}
/**
* An expectation for checking the selection is selected.
*
* @example
* var EC = protractor.ExpectedConditions;
* // Waits for the element with id 'myCheckbox' to be selected.
* browser.wait(EC.elementToBeSelected($('#myCheckbox')), 5000);
*
* @alias ExpectedConditions.elementToBeSelected
* @param {!ElementFinder} elementFinder The element to check
*
* @returns {!function} An expected condition that returns a promise
* representing whether the element is selected.
*/
elementToBeSelected(elementFinder) {
return this.and(this.presenceOf(elementFinder), () => {
return elementFinder.isSelected().then(util_1.passBoolean, util_1.falseIfMissing);
});
}
}
exports.ProtractorExpectedConditions = ProtractorExpectedConditions;
//# sourceMappingURL=expectedConditions.js.map

22
node_modules/protractor/built/frameworks/debugprint.js generated vendored Normal file
View file

@ -0,0 +1,22 @@
var util = require('util'),
q = require('q'),
Logger = require('../logger').Logger;
var logger = new Logger('debugger');
/**
* A debug framework which does not actually run any tests, just spits
* out the list that would be run.
*
* @param {Runner} runner The current Protractor Runner.
* @param {Array} specs Array of Directory Path Strings.
* @return {q.Promise} Promise resolved with the test results
*/
exports.run = function(runner, specs) {
return q.promise(function(resolve) {
logger.info('Resolved spec files: ' + util.inspect(specs));
resolve({
failedCount: 0
});
});
};

24
node_modules/protractor/built/frameworks/explorer.js generated vendored Normal file
View file

@ -0,0 +1,24 @@
var q = require('q');
/**
* A framework which does not actually run any tests. It allows users to drop
* into a repl loop to experiment with protractor commands.
*
* @param {Runner} runner The current Protractor Runner.
* @return {q.Promise} Promise resolved with the test results
*/
exports.run = function(runner) {
/* globals browser */
return q.promise(function(resolve) {
if (runner.getConfig().baseUrl) {
browser.get(runner.getConfig().baseUrl);
}
browser.executeScriptWithDescription('var e = 0', 'starting explorer hook');
browser.enterRepl();
browser.executeScriptWithDescription('var e = 1', 'done with explorer hook').then(function() {
resolve({
failedCount: 0
});
});
});
};

135
node_modules/protractor/built/frameworks/jasmine.js generated vendored Normal file
View file

@ -0,0 +1,135 @@
var q = require('q');
var webdriver = require('selenium-webdriver');
var RunnerReporter = function(emitter) {
this.emitter = emitter;
this.testResult = [],
this.failedCount = 0;
};
RunnerReporter.prototype.jasmineStarted = function() {
// Need to initiate startTime here, in case reportSpecStarting is not
// called (e.g. when fit is used)
this.startTime = new Date();
};
RunnerReporter.prototype.specStarted = function() {
this.startTime = new Date();
};
RunnerReporter.prototype.specDone = function(result) {
var specInfo = {
name: result.description,
category: result.fullName.slice(0, -result.description.length).trim()
};
if (result.status == 'passed') {
this.emitter.emit('testPass', specInfo);
} else if (result.status == 'failed') {
this.emitter.emit('testFail', specInfo);
this.failedCount++;
}
var entry = {
description: result.fullName,
assertions: [],
duration: new Date().getTime() - this.startTime.getTime()
};
if (result.failedExpectations.length === 0) {
entry.assertions.push({
passed: true
});
}
result.failedExpectations.forEach(function(item) {
entry.assertions.push({
passed: item.passed,
errorMsg: item.passed ? undefined : item.message,
stackTrace: item.passed ? undefined : item.stack
});
});
this.testResult.push(entry);
};
/**
* Execute the Runner's test cases through Jasmine.
*
* @param {Runner} runner The current Protractor Runner.
* @param {Array} specs Array of Directory Path Strings.
* @return {q.Promise} Promise resolved with the test results
*/
exports.run = function(runner, specs) {
var JasmineRunner = require('jasmine');
var jrunner = new JasmineRunner();
/* global jasmine */
require('jasminewd2').init(webdriver.promise.controlFlow(), webdriver);
var jasmineNodeOpts = runner.getConfig().jasmineNodeOpts;
// On timeout, the flow should be reset. This will prevent webdriver tasks
// from overflowing into the next test and causing it to fail or timeout
// as well. This is done in the reporter instead of an afterEach block
// to ensure that it runs after any afterEach() blocks with webdriver tasks
// get to complete first.
var reporter = new RunnerReporter(runner);
jasmine.getEnv().addReporter(reporter);
// Add hooks for afterEach
require('./setupAfterEach').setup(runner, specs);
// Filter specs to run based on jasmineNodeOpts.grep and jasmineNodeOpts.invert.
jasmine.getEnv().specFilter = function(spec) {
var grepMatch = !jasmineNodeOpts ||
!jasmineNodeOpts.grep ||
spec.getFullName().match(new RegExp(jasmineNodeOpts.grep)) != null;
var invertGrep = !!(jasmineNodeOpts && jasmineNodeOpts.invertGrep);
if (grepMatch == invertGrep) {
spec.disable();
}
return true;
};
// Run specs in semi-random order
if (jasmineNodeOpts.random) {
jasmine.getEnv().randomizeTests(true);
// Sets the randomization seed if randomization is turned on
if (jasmineNodeOpts.seed) {
jasmine.getEnv().seed(jasmineNodeOpts.seed);
}
}
return runner.runTestPreparer().then(function() {
return q.promise(function(resolve, reject) {
if (jasmineNodeOpts && jasmineNodeOpts.defaultTimeoutInterval) {
jasmine.DEFAULT_TIMEOUT_INTERVAL = jasmineNodeOpts.defaultTimeoutInterval;
}
var originalOnComplete = runner.getConfig().onComplete;
jrunner.onComplete(function(passed) {
try {
var completed = q();
if (originalOnComplete) {
completed = q(originalOnComplete(passed));
}
completed.then(function() {
resolve({
failedCount: reporter.failedCount,
specResults: reporter.testResult
});
});
} catch (err) {
reject(err);
}
});
jrunner.configureDefaultReporter(jasmineNodeOpts);
jrunner.projectBaseDir = '';
jrunner.specDir = '';
jrunner.addSpecFiles(specs);
jrunner.execute();
});
});
};

140
node_modules/protractor/built/frameworks/mocha.js generated vendored Normal file
View file

@ -0,0 +1,140 @@
var q = require('q');
/**
* Execute the Runner's test cases through Mocha.
*
* @param {Runner} runner The current Protractor Runner.
* @param {Array} specs Array of Directory Path Strings.
* @return {q.Promise} Promise resolved with the test results
*/
exports.run = function(runner, specs) {
var Mocha = require('mocha'),
mocha = new Mocha(runner.getConfig().mochaOpts);
// Add hooks for afterEach
require('./setupAfterEach').setup(runner, specs);
var deferred = q.defer();
// Mocha doesn't set up the ui until the pre-require event, so
// wait until then to load mocha-webdriver adapters as well.
mocha.suite.on('pre-require', function() {
try {
// We need to re-wrap all of the global functions, which `selenium-webdriver/testing` only
// does when it is required. So first we must remove it from the cache.
delete require.cache[require.resolve('selenium-webdriver/testing')];
var seleniumAdapter = require('selenium-webdriver/testing');
// Save unwrapped version
var unwrappedFns = {};
['after', 'afterEach', 'before', 'beforeEach', 'it', 'xit', 'iit'].forEach(function(fnName) {
unwrappedFns[fnName] = global[fnName] || Mocha[fnName];
});
var wrapFn = function(seleniumWrappedFn, opt_fnName) {
// This does not work on functions that can be nested (e.g. `describe`)
return function() {
// Set globals to unwrapped version to avoid circular reference
var wrappedFns = {};
for (var fnName in unwrappedFns) {
wrappedFns[fnName] = global[fnName];
global[fnName] = unwrappedFns[fnName];
}
var args = arguments;
// Allow before/after hooks to use names
if (opt_fnName && (arguments.length > 1) && (seleniumWrappedFn.length < 2)) {
global[opt_fnName] = global[opt_fnName].bind(this, args[0]);
args = Array.prototype.slice.call(arguments, 1);
}
try {
seleniumWrappedFn.apply(this, args);
} finally {
// Restore wrapped version
for (fnName in wrappedFns) {
global[fnName] = wrappedFns[fnName];
}
}
};
};
// Wrap functions
global.after = wrapFn(seleniumAdapter.after, 'after');
global.afterEach = wrapFn(seleniumAdapter.afterEach, 'afterEach');
global.before = wrapFn(seleniumAdapter.before, 'before');
global.beforeEach = wrapFn(seleniumAdapter.beforeEach, 'beforeEach');
global.it = wrapFn(seleniumAdapter.it);
global.iit = wrapFn(seleniumAdapter.it.only);
global.xit = wrapFn(seleniumAdapter.xit);
global.it.only = wrapFn(seleniumAdapter.it.only);
global.it.skip = wrapFn(seleniumAdapter.it.skip);
} catch (err) {
deferred.reject(err);
}
});
mocha.loadFiles();
runner.runTestPreparer().then(function() {
specs.forEach(function(file) {
mocha.addFile(file);
});
var testResult = [];
var mochaRunner = mocha.run(function(failures) {
try {
var completed = q();
if (runner.getConfig().onComplete) {
completed = q(runner.getConfig().onComplete());
}
completed.then(function() {
deferred.resolve({
failedCount: failures,
specResults: testResult
});
});
} catch (err) {
deferred.reject(err);
}
});
mochaRunner.on('pass', function(test) {
var testInfo = {
name: test.title,
category: test.fullTitle().slice(0, -test.title.length).trim()
};
runner.emit('testPass', testInfo);
testResult.push({
description: test.title,
assertions: [{
passed: true
}],
duration: test.duration
});
});
mochaRunner.on('fail', function(test) {
var testInfo = {
name: test.title,
category: test.fullTitle().slice(0, -test.title.length).trim()
};
runner.emit('testFail', testInfo);
testResult.push({
description: test.title,
assertions: [{
passed: false,
errorMsg: test.err.message,
stackTrace: test.err.stack
}],
duration: test.duration
});
});
}).catch (function(reason) {
deferred.reject(reason);
});
return deferred.promise;
};

2
node_modules/protractor/built/launcher.d.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
import { Config } from './config';
export declare let init: (configFile: string, additionalConfig: Config) => void;

285
node_modules/protractor/built/launcher.js generated vendored Normal file
View file

@ -0,0 +1,285 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* The launcher is responsible for parsing the capabilities from the
* input configuration and launching test runners.
*/
const fs = require("fs");
const q = require("q");
const configParser_1 = require("./configParser");
const exitCodes_1 = require("./exitCodes");
const logger_1 = require("./logger");
const runner_1 = require("./runner");
const taskRunner_1 = require("./taskRunner");
const taskScheduler_1 = require("./taskScheduler");
const helper = require("./util");
let logger = new logger_1.Logger('launcher');
let RUNNERS_FAILED_EXIT_CODE = 100;
/**
* Keeps track of a list of task results. Provides method to add a new
* result, aggregate the results into a summary, count failures,
* and save results into a JSON file.
*/
class TaskResults {
constructor() {
// TODO: set a type for result
this.results_ = [];
}
add(result) {
this.results_.push(result);
}
totalSpecFailures() {
return this.results_.reduce((specFailures, result) => {
return specFailures + result.failedCount;
}, 0);
}
totalProcessFailures() {
return this.results_.reduce((processFailures, result) => {
return !result.failedCount && result.exitCode !== 0 ? processFailures + 1 : processFailures;
}, 0);
}
saveResults(filepath) {
let jsonOutput = this.results_.reduce((jsonOutput, result) => {
return jsonOutput.concat(result.specResults);
}, []);
let json = JSON.stringify(jsonOutput, null, ' ');
fs.writeFileSync(filepath, json);
}
reportSummary() {
let specFailures = this.totalSpecFailures();
let processFailures = this.totalProcessFailures();
this.results_.forEach((result) => {
let capabilities = result.capabilities;
let shortName = (capabilities.browserName) ? capabilities.browserName : '';
shortName = (capabilities.logName) ?
capabilities.logName :
(capabilities.browserName) ? capabilities.browserName : '';
shortName += (capabilities.version) ? capabilities.version : '';
shortName += (capabilities.logName && capabilities.count < 2) ? '' : ' #' + result.taskId;
if (result.failedCount) {
logger.info(shortName + ' failed ' + result.failedCount + ' test(s)');
}
else if (result.exitCode !== 0) {
logger.info(shortName + ' failed with exit code: ' + result.exitCode);
}
else {
logger.info(shortName + ' passed');
}
});
if (specFailures && processFailures) {
logger.info('overall: ' + specFailures + ' failed spec(s) and ' + processFailures +
' process(es) failed to complete');
}
else if (specFailures) {
logger.info('overall: ' + specFailures + ' failed spec(s)');
}
else if (processFailures) {
logger.info('overall: ' + processFailures + ' process(es) failed to complete');
}
}
}
let taskResults_ = new TaskResults();
/**
* Initialize and run the tests.
* Exits with 1 on test failure, and RUNNERS_FAILED_EXIT_CODE on unexpected
* failures.
*
* @param {string=} configFile
* @param {Object=} additionalConfig
*/
let initFn = function (configFile, additionalConfig) {
let configParser = new configParser_1.ConfigParser();
if (configFile) {
configParser.addFileConfig(configFile);
}
if (additionalConfig) {
configParser.addConfig(additionalConfig);
}
let config = configParser.getConfig();
logger_1.Logger.set(config);
logger.debug('Running with --troubleshoot');
logger.debug('Protractor version: ' + require('../package.json').version);
logger.debug('Your base url for tests is ' + config.baseUrl);
// Run beforeLaunch
helper.runFilenameOrFn_(config.configDir, config.beforeLaunch)
.then(() => {
return q
.Promise((resolve, reject) => {
// 1) If getMultiCapabilities is set, resolve that as
// `multiCapabilities`.
if (config.getMultiCapabilities &&
typeof config.getMultiCapabilities === 'function') {
if (config.multiCapabilities.length || config.capabilities) {
logger.warn('getMultiCapabilities() will override both capabilities ' +
'and multiCapabilities');
}
// If getMultiCapabilities is defined and a function, use this.
q(config.getMultiCapabilities())
.then((multiCapabilities) => {
config.multiCapabilities = multiCapabilities;
config.capabilities = null;
})
.then(() => {
resolve();
})
.catch(err => {
reject(err);
});
}
else {
resolve();
}
})
.then(() => {
// 2) Set `multicapabilities` using `capabilities`,
// `multicapabilities`,
// or default
if (config.capabilities) {
if (config.multiCapabilities.length) {
logger.warn('You have specified both capabilities and ' +
'multiCapabilities. This will result in capabilities being ' +
'ignored');
}
else {
// Use capabilities if multiCapabilities is empty.
config.multiCapabilities = [config.capabilities];
}
}
else if (!config.multiCapabilities.length) {
// Default to chrome if no capabilities given
config.multiCapabilities = [{ browserName: 'chrome' }];
}
});
})
.then(() => {
// 3) If we're in `elementExplorer` mode, run only that.
if (config.elementExplorer || config.framework === 'explorer') {
if (config.multiCapabilities.length != 1) {
throw new Error('Must specify only 1 browser while using elementExplorer');
}
else {
config.capabilities = config.multiCapabilities[0];
}
config.framework = 'explorer';
let runner = new runner_1.Runner(config);
return runner.run().then((exitCode) => {
process.exit(exitCode);
}, (err) => {
logger.error(err);
process.exit(1);
});
}
})
.then(() => {
// 4) Run tests.
let scheduler = new taskScheduler_1.TaskScheduler(config);
process.on('uncaughtException', (exc) => {
let e = (exc instanceof Error) ? exc : new Error(exc);
if (config.ignoreUncaughtExceptions) {
// This can be a sign of a bug in the test framework, that it may
// not be handling WebDriver errors properly. However, we don't
// want these errors to prevent running the tests.
logger.warn('Ignoring uncaught error ' + exc);
return;
}
let errorCode = exitCodes_1.ErrorHandler.parseError(e);
if (errorCode) {
let protractorError = e;
exitCodes_1.ProtractorError.log(logger, errorCode, protractorError.message, protractorError.stack);
process.exit(errorCode);
}
else {
logger.error(e.message);
logger.error(e.stack);
process.exit(exitCodes_1.ProtractorError.CODE);
}
});
process.on('exit', (code) => {
if (code) {
logger.error('Process exited with error code ' + code);
}
else if (scheduler.numTasksOutstanding() > 0) {
logger.error('BUG: launcher exited with ' + scheduler.numTasksOutstanding() +
' tasks remaining');
process.exit(RUNNERS_FAILED_EXIT_CODE);
}
});
// Run afterlaunch and exit
let cleanUpAndExit = (exitCode) => {
return helper.runFilenameOrFn_(config.configDir, config.afterLaunch, [exitCode])
.then((returned) => {
if (typeof returned === 'number') {
process.exit(returned);
}
else {
process.exit(exitCode);
}
}, (err) => {
logger.error('Error:', err);
process.exit(1);
});
};
let totalTasks = scheduler.numTasksOutstanding();
let forkProcess = false;
if (totalTasks > 1) {
forkProcess = true;
if (config.debug) {
throw new exitCodes_1.ConfigError(logger, 'Cannot run in debug mode with multiCapabilities, count > 1, or sharding');
}
}
let deferred = q.defer(); // Resolved when all tasks are completed
let createNextTaskRunner = () => {
let task = scheduler.nextTask();
if (task) {
let taskRunner = new taskRunner_1.TaskRunner(configFile, additionalConfig, task, forkProcess);
taskRunner.run()
.then((result) => {
if (result.exitCode && !result.failedCount) {
logger.error('Runner process exited unexpectedly with error code: ' + result.exitCode);
}
taskResults_.add(result);
task.done();
createNextTaskRunner();
// If all tasks are finished
if (scheduler.numTasksOutstanding() === 0) {
deferred.resolve();
}
logger.info(scheduler.countActiveTasks() + ' instance(s) of WebDriver still running');
})
.catch((err) => {
logger.error('Error:', err.stack || err.message || err);
cleanUpAndExit(RUNNERS_FAILED_EXIT_CODE);
});
}
};
// Start `scheduler.maxConcurrentTasks()` workers for handling tasks in
// the beginning. As a worker finishes a task, it will pick up the next
// task
// from the scheduler's queue until all tasks are gone.
for (let i = 0; i < scheduler.maxConcurrentTasks(); ++i) {
createNextTaskRunner();
}
logger.info('Running ' + scheduler.countActiveTasks() + ' instances of WebDriver');
// By now all runners have completed.
deferred.promise
.then(function () {
// Save results if desired
if (config.resultJsonOutputFile) {
taskResults_.saveResults(config.resultJsonOutputFile);
}
taskResults_.reportSummary();
let exitCode = 0;
if (taskResults_.totalProcessFailures() > 0) {
exitCode = RUNNERS_FAILED_EXIT_CODE;
}
else if (taskResults_.totalSpecFailures() > 0) {
exitCode = 1;
}
return cleanUpAndExit(exitCode);
})
.done();
})
.done();
};
exports.init = initFn;
//# sourceMappingURL=launcher.js.map

294
node_modules/protractor/built/locators.d.ts generated vendored Normal file
View file

@ -0,0 +1,294 @@
import { By, ByHash, promise as wdpromise, WebDriver, WebElement } from 'selenium-webdriver';
export declare class WebdriverBy {
className: (className: string) => By;
css: (css: string) => By;
id: (id: string) => By;
linkText: (linkText: string) => By;
js: (js: string | Function, ...var_args: any[]) => By;
name: (name: string) => By;
partialLinkText: (partialText: string) => By;
tagName: (tagName: string) => By;
xpath: (xpath: string) => By;
}
export declare type WebDriverLocator = By | ByHash | Function;
export interface ProtractorLocator {
findElementsOverride: (driver: WebDriver, using: WebElement, rootSelector: string) => wdpromise.Promise<WebElement[]>;
row?: (index: number) => Locator;
column?: (index: string) => Locator;
toString?: () => string;
}
export declare type Locator = ProtractorLocator | WebDriverLocator;
export declare function isProtractorLocator(x: Locator): x is ProtractorLocator;
/**
* The Protractor Locators. These provide ways of finding elements in
* Angular applications by binding, model, etc.
*
* @alias by
* @extends {webdriver.By}
*/
export declare class ProtractorBy extends WebdriverBy {
[key: string]: any;
/**
* Add a locator to this instance of ProtractorBy. This locator can then be
* used with element(by.locatorName(args)).
*
* @view
* <button ng-click="doAddition()">Go!</button>
*
* @example
* // Add the custom locator.
* 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,
* buttons = using.querySelectorAll('button');
*
* // Return an array of buttons with the text.
* return Array.prototype.filter.call(buttons, function(button) {
* return button.textContent === buttonText;
* });
* });
*
* // Use the custom locator.
* element(by.buttonTextSimple('Go!')).click();
*
* @alias by.addLocator(locatorName, functionOrScript)
* @param {string} name The name of the new locator.
* @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 and the css selector for the root angular
* element. It should return an array of elements.
*/
addLocator(name: string, script: Function | string): void;
/**
* Find an element by text binding. Does a partial match, so any elements
* bound to variables containing the input string will be returned.
*
* Note: For AngularJS version 1.2, the interpolation brackets, (usually
* {{}}), are optionally allowed in the binding description string. For
* Angular version 1.3+, they are not allowed, and no elements will be found
* if they are used.
*
* @view
* <span>{{person.name}}</span>
* <span ng-bind="person.email"></span>
*
* @example
* var span1 = element(by.binding('person.name'));
* expect(span1.getText()).toBe('Foo');
*
* var span2 = element(by.binding('person.email'));
* expect(span2.getText()).toBe('foo@bar.com');
*
* // You can also use a substring for a partial match
* var span1alt = element(by.binding('name'));
* expect(span1alt.getText()).toBe('Foo');
*
* // This works for sites using Angular 1.2 but NOT 1.3
* var deprecatedSyntax = element(by.binding('{{person.name}}'));
*
* @param {string} bindingDescriptor
* @returns {ProtractorLocator} location strategy
*/
binding(bindingDescriptor: string): ProtractorLocator;
/**
* Find an element by exact binding.
*
* @view
* <span>{{ person.name }}</span>
* <span ng-bind="person-email"></span>
* <span>{{person_phone|uppercase}}</span>
*
* @example
* expect(element(by.exactBinding('person.name')).isPresent()).toBe(true);
* expect(element(by.exactBinding('person-email')).isPresent()).toBe(true);
* expect(element(by.exactBinding('person')).isPresent()).toBe(false);
* expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true);
* expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true);
* expect(element(by.exactBinding('phone')).isPresent()).toBe(false);
*
* @param {string} bindingDescriptor
* @returns {ProtractorLocator} location strategy
*/
exactBinding(bindingDescriptor: string): ProtractorLocator;
/**
* Find an element by ng-model expression.
*
* @alias by.model(modelName)
* @view
* <input type="text" ng-model="person.name">
*
* @example
* var input = element(by.model('person.name'));
* input.sendKeys('123');
* expect(input.getAttribute('value')).toBe('Foo123');
*
* @param {string} model ng-model expression.
* @returns {ProtractorLocator} location strategy
*/
model(model: string): ProtractorLocator;
/**
* Find a button by text.
*
* @view
* <button>Save</button>
*
* @example
* element(by.buttonText('Save'));
*
* @param {string} searchText
* @returns {ProtractorLocator} location strategy
*/
buttonText(searchText: string): ProtractorLocator;
/**
* Find a button by partial text.
*
* @view
* <button>Save my file</button>
*
* @example
* element(by.partialButtonText('Save'));
*
* @param {string} searchText
* @returns {ProtractorLocator} location strategy
*/
partialButtonText(searchText: string): ProtractorLocator;
private byRepeaterInner(exact, repeatDescriptor);
/**
* Find elements inside an ng-repeat.
*
* @view
* <div ng-repeat="cat in pets">
* <span>{{cat.name}}</span>
* <span>{{cat.age}}</span>
* </div>
*
* <div class="book-img" ng-repeat-start="book in library">
* <span>{{$index}}</span>
* </div>
* <div class="book-info" ng-repeat-end>
* <h4>{{book.name}}</h4>
* <p>{{book.blurb}}</p>
* </div>
*
* @example
* // Returns the DIV for the second cat.
* var secondCat = element(by.repeater('cat in pets').row(1));
*
* // Returns the SPAN for the first cat's name.
* var firstCatName = element(by.repeater('cat in pets').
* row(0).column('cat.name'));
*
* // Returns a promise that resolves to an array of WebElements from a column
* var ages = element.all(
* by.repeater('cat in pets').column('cat.age'));
*
* // Returns a promise that resolves to an array of WebElements containing
* // all top level elements repeated by the repeater. For 2 pets rows
* // resolves to an array of 2 elements.
* var rows = element.all(by.repeater('cat in pets'));
*
* // Returns a promise that resolves to an array of WebElements containing
* // all the elements with a binding to the book's name.
* var divs = element.all(by.repeater('book in library').column('book.name'));
*
* // Returns a promise that resolves to an array of WebElements containing
* // the DIVs for the second book.
* var bookInfo = element.all(by.repeater('book in library').row(1));
*
* // Returns the H4 for the first book's name.
* var firstBookName = element(by.repeater('book in library').
* row(0).column('book.name'));
*
* // Returns a promise that resolves to an array of WebElements containing
* // all top level elements repeated by the repeater. For 2 books divs
* // resolves to an array of 4 elements.
* var divs = element.all(by.repeater('book in library'));
*
* @param {string} repeatDescriptor
* @returns {ProtractorLocator} location strategy
*/
repeater(repeatDescriptor: string): ProtractorLocator;
/**
* Find an element by exact repeater.
*
* @view
* <li ng-repeat="person in peopleWithRedHair"></li>
* <li ng-repeat="car in cars | orderBy:year"></li>
*
* @example
* expect(element(by.exactRepeater('person in
* peopleWithRedHair')).isPresent())
* .toBe(true);
* expect(element(by.exactRepeater('person in
* people')).isPresent()).toBe(false);
* expect(element(by.exactRepeater('car in cars')).isPresent()).toBe(true);
*
* @param {string} repeatDescriptor
* @returns {ProtractorLocator} location strategy
*/
exactRepeater(repeatDescriptor: string): ProtractorLocator;
/**
* Find elements by CSS which contain a certain string.
*
* @view
* <ul>
* <li class="pet">Dog</li>
* <li class="pet">Cat</li>
* </ul>
*
* @example
* // Returns the li for the dog, but not cat.
* var dog = element(by.cssContainingText('.pet', 'Dog'));
*
* @param {string} cssSelector css selector
* @param {string|RegExp} searchString text search
* @returns {ProtractorLocator} location strategy
*/
cssContainingText(cssSelector: string, searchText: string | RegExp): ProtractorLocator;
/**
* Find an element by ng-options expression.
*
* @alias by.options(optionsDescriptor)
* @view
* <select ng-model="color" ng-options="c for c in colors">
* <option value="0" selected="selected">red</option>
* <option value="1">green</option>
* </select>
*
* @example
* var allOptions = element.all(by.options('c for c in colors'));
* expect(allOptions.count()).toEqual(2);
* var firstOption = allOptions.first();
* expect(firstOption.getText()).toEqual('red');
*
* @param {string} optionsDescriptor ng-options expression.
* @returns {ProtractorLocator} location strategy
*/
options(optionsDescriptor: string): ProtractorLocator;
/**
* Find an element by css selector within the Shadow DOM.
*
* @alias by.deepCss(selector)
* @view
* <div>
* <span id="outerspan">
* <"shadow tree">
* <span id="span1"></span>
* <"shadow tree">
* <span id="span2"></span>
* </>
* </>
* </div>
* @example
* var spans = element.all(by.deepCss('span'));
* expect(spans.count()).toEqual(3);
*
* @param {string} selector a css selector within the Shadow DOM.
* @returns {Locator} location strategy
*/
deepCss(selector: string): Locator;
}

451
node_modules/protractor/built/locators.js generated vendored Normal file
View file

@ -0,0 +1,451 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const selenium_webdriver_1 = require("selenium-webdriver");
let clientSideScripts = require('./clientsidescripts');
// Explicitly define webdriver.By.
// We do this because we want to inherit the static methods of webdriver.By, as opposed to
// inheriting from the webdriver.By class itself, which is actually analogous to ProtractorLocator.
class WebdriverBy {
constructor() {
this.className = selenium_webdriver_1.By.className;
this.css = selenium_webdriver_1.By.css;
this.id = selenium_webdriver_1.By.id;
this.linkText = selenium_webdriver_1.By.linkText;
this.js = selenium_webdriver_1.By.js;
this.name = selenium_webdriver_1.By.name;
this.partialLinkText = selenium_webdriver_1.By.partialLinkText;
this.tagName = selenium_webdriver_1.By.tagName;
this.xpath = selenium_webdriver_1.By.xpath;
}
}
exports.WebdriverBy = WebdriverBy;
function isProtractorLocator(x) {
return x && (typeof x.findElementsOverride === 'function');
}
exports.isProtractorLocator = isProtractorLocator;
/**
* The Protractor Locators. These provide ways of finding elements in
* Angular applications by binding, model, etc.
*
* @alias by
* @extends {webdriver.By}
*/
class ProtractorBy extends WebdriverBy {
/**
* Add a locator to this instance of ProtractorBy. This locator can then be
* used with element(by.locatorName(args)).
*
* @view
* <button ng-click="doAddition()">Go!</button>
*
* @example
* // Add the custom locator.
* 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,
* buttons = using.querySelectorAll('button');
*
* // Return an array of buttons with the text.
* return Array.prototype.filter.call(buttons, function(button) {
* return button.textContent === buttonText;
* });
* });
*
* // Use the custom locator.
* element(by.buttonTextSimple('Go!')).click();
*
* @alias by.addLocator(locatorName, functionOrScript)
* @param {string} name The name of the new locator.
* @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 and the css selector for the root angular
* element. It should return an array of elements.
*/
addLocator(name, script) {
this[name] = (...args) => {
let locatorArguments = args;
return {
findElementsOverride: (driver, using, rootSelector) => {
let findElementArguments = [script];
for (let i = 0; i < locatorArguments.length; i++) {
findElementArguments.push(locatorArguments[i]);
}
findElementArguments.push(using);
findElementArguments.push(rootSelector);
return driver.findElements(selenium_webdriver_1.By.js.apply(selenium_webdriver_1.By, findElementArguments));
},
toString: () => {
return 'by.' + name + '("' + Array.prototype.join.call(locatorArguments, '", "') + '")';
}
};
};
}
;
/**
* Find an element by text binding. Does a partial match, so any elements
* bound to variables containing the input string will be returned.
*
* Note: For AngularJS version 1.2, the interpolation brackets, (usually
* {{}}), are optionally allowed in the binding description string. For
* Angular version 1.3+, they are not allowed, and no elements will be found
* if they are used.
*
* @view
* <span>{{person.name}}</span>
* <span ng-bind="person.email"></span>
*
* @example
* var span1 = element(by.binding('person.name'));
* expect(span1.getText()).toBe('Foo');
*
* var span2 = element(by.binding('person.email'));
* expect(span2.getText()).toBe('foo@bar.com');
*
* // You can also use a substring for a partial match
* var span1alt = element(by.binding('name'));
* expect(span1alt.getText()).toBe('Foo');
*
* // This works for sites using Angular 1.2 but NOT 1.3
* var deprecatedSyntax = element(by.binding('{{person.name}}'));
*
* @param {string} bindingDescriptor
* @returns {ProtractorLocator} location strategy
*/
binding(bindingDescriptor) {
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findBindings, bindingDescriptor, false, using, rootSelector));
},
toString: () => {
return 'by.binding("' + bindingDescriptor + '")';
}
};
}
;
/**
* Find an element by exact binding.
*
* @view
* <span>{{ person.name }}</span>
* <span ng-bind="person-email"></span>
* <span>{{person_phone|uppercase}}</span>
*
* @example
* expect(element(by.exactBinding('person.name')).isPresent()).toBe(true);
* expect(element(by.exactBinding('person-email')).isPresent()).toBe(true);
* expect(element(by.exactBinding('person')).isPresent()).toBe(false);
* expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true);
* expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true);
* expect(element(by.exactBinding('phone')).isPresent()).toBe(false);
*
* @param {string} bindingDescriptor
* @returns {ProtractorLocator} location strategy
*/
exactBinding(bindingDescriptor) {
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findBindings, bindingDescriptor, true, using, rootSelector));
},
toString: () => {
return 'by.exactBinding("' + bindingDescriptor + '")';
}
};
}
;
/**
* Find an element by ng-model expression.
*
* @alias by.model(modelName)
* @view
* <input type="text" ng-model="person.name">
*
* @example
* var input = element(by.model('person.name'));
* input.sendKeys('123');
* expect(input.getAttribute('value')).toBe('Foo123');
*
* @param {string} model ng-model expression.
* @returns {ProtractorLocator} location strategy
*/
model(model) {
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findByModel, model, using, rootSelector));
},
toString: () => {
return 'by.model("' + model + '")';
}
};
}
;
/**
* Find a button by text.
*
* @view
* <button>Save</button>
*
* @example
* element(by.buttonText('Save'));
*
* @param {string} searchText
* @returns {ProtractorLocator} location strategy
*/
buttonText(searchText) {
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findByButtonText, searchText, using, rootSelector));
},
toString: () => {
return 'by.buttonText("' + searchText + '")';
}
};
}
;
/**
* Find a button by partial text.
*
* @view
* <button>Save my file</button>
*
* @example
* element(by.partialButtonText('Save'));
*
* @param {string} searchText
* @returns {ProtractorLocator} location strategy
*/
partialButtonText(searchText) {
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findByPartialButtonText, searchText, using, rootSelector));
},
toString: () => {
return 'by.partialButtonText("' + searchText + '")';
}
};
}
;
// Generate either by.repeater or by.exactRepeater
byRepeaterInner(exact, repeatDescriptor) {
let name = 'by.' + (exact ? 'exactR' : 'r') + 'epeater';
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findAllRepeaterRows, repeatDescriptor, exact, using, rootSelector));
},
toString: () => {
return name + '("' + repeatDescriptor + '")';
},
row: (index) => {
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findRepeaterRows, repeatDescriptor, exact, index, using, rootSelector));
},
toString: () => {
return name + '(' + repeatDescriptor + '").row("' + index + '")"';
},
column: (binding) => {
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findRepeaterElement, repeatDescriptor, exact, index, binding, using, rootSelector));
},
toString: () => {
return name + '("' + repeatDescriptor + '").row("' + index + '").column("' +
binding + '")';
}
};
}
};
},
column: (binding) => {
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findRepeaterColumn, repeatDescriptor, exact, binding, using, rootSelector));
},
toString: () => {
return name + '("' + repeatDescriptor + '").column("' + binding + '")';
},
row: (index) => {
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findRepeaterElement, repeatDescriptor, exact, index, binding, using, rootSelector));
},
toString: () => {
return name + '("' + repeatDescriptor + '").column("' + binding + '").row("' +
index + '")';
}
};
}
};
}
};
}
/**
* Find elements inside an ng-repeat.
*
* @view
* <div ng-repeat="cat in pets">
* <span>{{cat.name}}</span>
* <span>{{cat.age}}</span>
* </div>
*
* <div class="book-img" ng-repeat-start="book in library">
* <span>{{$index}}</span>
* </div>
* <div class="book-info" ng-repeat-end>
* <h4>{{book.name}}</h4>
* <p>{{book.blurb}}</p>
* </div>
*
* @example
* // Returns the DIV for the second cat.
* var secondCat = element(by.repeater('cat in pets').row(1));
*
* // Returns the SPAN for the first cat's name.
* var firstCatName = element(by.repeater('cat in pets').
* row(0).column('cat.name'));
*
* // Returns a promise that resolves to an array of WebElements from a column
* var ages = element.all(
* by.repeater('cat in pets').column('cat.age'));
*
* // Returns a promise that resolves to an array of WebElements containing
* // all top level elements repeated by the repeater. For 2 pets rows
* // resolves to an array of 2 elements.
* var rows = element.all(by.repeater('cat in pets'));
*
* // Returns a promise that resolves to an array of WebElements containing
* // all the elements with a binding to the book's name.
* var divs = element.all(by.repeater('book in library').column('book.name'));
*
* // Returns a promise that resolves to an array of WebElements containing
* // the DIVs for the second book.
* var bookInfo = element.all(by.repeater('book in library').row(1));
*
* // Returns the H4 for the first book's name.
* var firstBookName = element(by.repeater('book in library').
* row(0).column('book.name'));
*
* // Returns a promise that resolves to an array of WebElements containing
* // all top level elements repeated by the repeater. For 2 books divs
* // resolves to an array of 4 elements.
* var divs = element.all(by.repeater('book in library'));
*
* @param {string} repeatDescriptor
* @returns {ProtractorLocator} location strategy
*/
repeater(repeatDescriptor) {
return this.byRepeaterInner(false, repeatDescriptor);
}
/**
* Find an element by exact repeater.
*
* @view
* <li ng-repeat="person in peopleWithRedHair"></li>
* <li ng-repeat="car in cars | orderBy:year"></li>
*
* @example
* expect(element(by.exactRepeater('person in
* peopleWithRedHair')).isPresent())
* .toBe(true);
* expect(element(by.exactRepeater('person in
* people')).isPresent()).toBe(false);
* expect(element(by.exactRepeater('car in cars')).isPresent()).toBe(true);
*
* @param {string} repeatDescriptor
* @returns {ProtractorLocator} location strategy
*/
exactRepeater(repeatDescriptor) {
return this.byRepeaterInner(true, repeatDescriptor);
}
/**
* Find elements by CSS which contain a certain string.
*
* @view
* <ul>
* <li class="pet">Dog</li>
* <li class="pet">Cat</li>
* </ul>
*
* @example
* // Returns the li for the dog, but not cat.
* var dog = element(by.cssContainingText('.pet', 'Dog'));
*
* @param {string} cssSelector css selector
* @param {string|RegExp} searchString text search
* @returns {ProtractorLocator} location strategy
*/
cssContainingText(cssSelector, searchText) {
searchText = (searchText instanceof RegExp) ? '__REGEXP__' + searchText.toString() : searchText;
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findByCssContainingText, cssSelector, searchText, using, rootSelector));
},
toString: () => {
return 'by.cssContainingText("' + cssSelector + '", "' + searchText + '")';
}
};
}
;
/**
* Find an element by ng-options expression.
*
* @alias by.options(optionsDescriptor)
* @view
* <select ng-model="color" ng-options="c for c in colors">
* <option value="0" selected="selected">red</option>
* <option value="1">green</option>
* </select>
*
* @example
* var allOptions = element.all(by.options('c for c in colors'));
* expect(allOptions.count()).toEqual(2);
* var firstOption = allOptions.first();
* expect(firstOption.getText()).toEqual('red');
*
* @param {string} optionsDescriptor ng-options expression.
* @returns {ProtractorLocator} location strategy
*/
options(optionsDescriptor) {
return {
findElementsOverride: (driver, using, rootSelector) => {
return driver.findElements(selenium_webdriver_1.By.js(clientSideScripts.findByOptions, optionsDescriptor, using, rootSelector));
},
toString: () => {
return 'by.option("' + optionsDescriptor + '")';
}
};
}
;
/**
* Find an element by css selector within the Shadow DOM.
*
* @alias by.deepCss(selector)
* @view
* <div>
* <span id="outerspan">
* <"shadow tree">
* <span id="span1"></span>
* <"shadow tree">
* <span id="span2"></span>
* </>
* </>
* </div>
* @example
* var spans = element.all(by.deepCss('span'));
* expect(spans.count()).toEqual(3);
*
* @param {string} selector a css selector within the Shadow DOM.
* @returns {Locator} location strategy
*/
deepCss(selector) {
// TODO(julie): syntax will change from /deep/ to >>> at some point.
// When that is supported, switch it here.
return selenium_webdriver_1.By.css('* /deep/ ' + selector);
}
;
}
exports.ProtractorBy = ProtractorBy;
//# sourceMappingURL=locators.js.map

101
node_modules/protractor/built/logger.d.ts generated vendored Normal file
View file

@ -0,0 +1,101 @@
import { Config } from './config';
export declare enum LogLevel {
ERROR = 0,
WARN = 1,
INFO = 2,
DEBUG = 3,
}
export declare enum WriteTo {
CONSOLE = 0,
FILE = 1,
BOTH = 2,
NONE = 3,
}
/**
* Logger class adds timestamp output, log levels, and identifiers to help
* when debugging. Also could write to console, file, both, or none.
*/
export declare class Logger {
private id;
static logLevel: LogLevel;
static showTimestamp: boolean;
static showId: boolean;
static writeTo: WriteTo;
static fd: any;
static firstWrite: boolean;
/**
* Set up the logging configuration from the protractor configuration file.
* @param config The protractor configuration
*/
static set(config: Config): void;
/**
* Set up the write location. If writing to a file, get the file descriptor.
* @param writeTo The enum for where to write the logs.
* @param opt_logFile An optional parameter to override the log file location.
*/
static setWrite(writeTo: WriteTo, opt_logFile?: string): void;
/**
* Creates a logger instance with an ID for the logger.
* @constructor
*/
constructor(id: string);
/**
* Log INFO
* @param ...msgs multiple arguments to be logged.
*/
info(...msgs: any[]): void;
/**
* Log DEBUG
* @param ...msgs multiple arguments to be logged.
*/
debug(...msgs: any[]): void;
/**
* Log WARN
* @param ...msgs multiple arguments to be logged.
*/
warn(...msgs: any[]): void;
/**
* Log ERROR
* @param ...msgs multiple arguments to be logged.
*/
error(...msgs: any[]): void;
/**
* For the log level set, check to see if the messages should be logged.
* @param logLevel The log level of the message.
* @param msgs The messages to be logged
*/
log_(logLevel: LogLevel, msgs: any[]): void;
/**
* Format with timestamp, log level, identifier, and message and log to
* specified medium (console, file, both, none).
* @param logLevel The log level of the message.
* @param msgs The messages to be logged.
*/
print_(logLevel: LogLevel, msgs: any[]): void;
/**
* Get a timestamp formatted with [hh:mm:ss]
* @param writeTo The enum for where to write the logs.
* @return The string of the formatted timestamp
*/
static timestamp_(writeTo: WriteTo): string;
/**
* Get the identifier of the logger as '/<id>'
* @param logLevel The log level of the message.
* @param writeTo The enum for where to write the logs.
* @return The string of the formatted id
*/
static id_(logLevel: LogLevel, id: string, writeTo: WriteTo): string;
/**
* Get the log level formatted with the first letter. For info, it is I.
* @param logLevel The log level of the message.
* @param writeTo The enum for where to write the logs.
* @return The string of the formatted log level
*/
static level_(logLevel: LogLevel, id: string, writeTo: WriteTo): string;
/**
* Convert the list of messages to a single string message.
* @param msgs The list of messages.
* @return The string of the formatted messages
*/
static msgToFile_(msgs: any[]): string;
}

275
node_modules/protractor/built/logger.js generated vendored Normal file
View file

@ -0,0 +1,275 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const path = require("path");
// Will use chalk if chalk is available to add color to console logging
let chalk;
let printRed;
let printYellow;
let printGray;
try {
chalk = require('chalk');
printRed = chalk.red;
printYellow = chalk.yellow;
printGray = chalk.gray;
}
catch (e) {
printRed = printYellow = printGray = (msg) => {
return msg;
};
}
var LogLevel;
(function (LogLevel) {
LogLevel[LogLevel["ERROR"] = 0] = "ERROR";
LogLevel[LogLevel["WARN"] = 1] = "WARN";
LogLevel[LogLevel["INFO"] = 2] = "INFO";
LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG";
})(LogLevel = exports.LogLevel || (exports.LogLevel = {}));
var WriteTo;
(function (WriteTo) {
WriteTo[WriteTo["CONSOLE"] = 0] = "CONSOLE";
WriteTo[WriteTo["FILE"] = 1] = "FILE";
WriteTo[WriteTo["BOTH"] = 2] = "BOTH";
WriteTo[WriteTo["NONE"] = 3] = "NONE";
})(WriteTo = exports.WriteTo || (exports.WriteTo = {}));
let logFile = 'protractor.log'; // the default log file name
/**
* Logger class adds timestamp output, log levels, and identifiers to help
* when debugging. Also could write to console, file, both, or none.
*/
class Logger {
/**
* Creates a logger instance with an ID for the logger.
* @constructor
*/
constructor(id) {
this.id = id;
}
/**
* Set up the logging configuration from the protractor configuration file.
* @param config The protractor configuration
*/
static set(config) {
if (config.troubleshoot) {
Logger.logLevel = LogLevel.DEBUG;
}
else if (config.logLevel) {
Logger.logLevel = LogLevel[config.logLevel];
}
}
/**
* Set up the write location. If writing to a file, get the file descriptor.
* @param writeTo The enum for where to write the logs.
* @param opt_logFile An optional parameter to override the log file location.
*/
static setWrite(writeTo, opt_logFile) {
if (opt_logFile) {
logFile = opt_logFile;
}
Logger.writeTo = writeTo;
if (Logger.writeTo == WriteTo.FILE || Logger.writeTo == WriteTo.BOTH) {
Logger.fd = fs.openSync(path.resolve(logFile), 'a');
Logger.firstWrite = false;
}
}
/**
* Log INFO
* @param ...msgs multiple arguments to be logged.
*/
info(...msgs) {
this.log_(LogLevel.INFO, msgs);
}
/**
* Log DEBUG
* @param ...msgs multiple arguments to be logged.
*/
debug(...msgs) {
this.log_(LogLevel.DEBUG, msgs);
}
/**
* Log WARN
* @param ...msgs multiple arguments to be logged.
*/
warn(...msgs) {
this.log_(LogLevel.WARN, msgs);
}
/**
* Log ERROR
* @param ...msgs multiple arguments to be logged.
*/
error(...msgs) {
this.log_(LogLevel.ERROR, msgs);
}
/**
* For the log level set, check to see if the messages should be logged.
* @param logLevel The log level of the message.
* @param msgs The messages to be logged
*/
log_(logLevel, msgs) {
switch (Logger.logLevel) {
case LogLevel.ERROR:
if (logLevel <= LogLevel.ERROR) {
this.print_(logLevel, msgs);
}
break;
case LogLevel.WARN:
if (logLevel <= LogLevel.WARN) {
this.print_(logLevel, msgs);
}
break;
case LogLevel.INFO:
if (logLevel <= LogLevel.INFO) {
this.print_(logLevel, msgs);
}
break;
case LogLevel.DEBUG:
if (logLevel <= LogLevel.DEBUG) {
this.print_(logLevel, msgs);
}
break;
default:
throw new Error('Invalid log level');
}
}
/**
* Format with timestamp, log level, identifier, and message and log to
* specified medium (console, file, both, none).
* @param logLevel The log level of the message.
* @param msgs The messages to be logged.
*/
print_(logLevel, msgs) {
let consoleLog = '';
let fileLog = '';
if (Logger.showTimestamp) {
consoleLog += Logger.timestamp_(WriteTo.CONSOLE);
fileLog += Logger.timestamp_(WriteTo.FILE);
}
consoleLog += Logger.level_(logLevel, this.id, WriteTo.CONSOLE);
fileLog += Logger.level_(logLevel, this.id, WriteTo.FILE);
if (Logger.showId) {
consoleLog += Logger.id_(logLevel, this.id, WriteTo.CONSOLE);
fileLog += Logger.id_(logLevel, this.id, WriteTo.FILE);
}
consoleLog += ' -';
fileLog += ' - ';
switch (Logger.writeTo) {
case WriteTo.CONSOLE:
msgs.unshift(consoleLog);
console.log.apply(console, msgs);
break;
case WriteTo.FILE:
// for the first line written to the file, add a space
if (!Logger.firstWrite) {
fs.writeSync(Logger.fd, '\n');
Logger.firstWrite = true;
}
fileLog += ' ' + Logger.msgToFile_(msgs);
fs.writeSync(Logger.fd, fileLog + '\n');
break;
case WriteTo.BOTH:
// for the first line written to the file, add a space
if (!Logger.firstWrite) {
fs.writeSync(Logger.fd, '\n');
Logger.firstWrite = true;
}
fileLog += ' ' + Logger.msgToFile_(msgs);
fs.writeSync(Logger.fd, fileLog + '\n');
msgs.unshift(consoleLog);
console.log.apply(console, msgs);
break;
case WriteTo.NONE:
break;
}
}
/**
* Get a timestamp formatted with [hh:mm:ss]
* @param writeTo The enum for where to write the logs.
* @return The string of the formatted timestamp
*/
static timestamp_(writeTo) {
let d = new Date();
let ts = '[';
let hours = d.getHours() < 10 ? '0' + d.getHours() : d.getHours();
let minutes = d.getMinutes() < 10 ? '0' + d.getMinutes() : d.getMinutes();
let seconds = d.getSeconds() < 10 ? '0' + d.getSeconds() : d.getSeconds();
if (writeTo == WriteTo.CONSOLE) {
ts += printGray(hours + ':' + minutes + ':' + seconds) + ']';
}
else {
ts += hours + ':' + minutes + ':' + seconds + ']';
}
ts += ' ';
return ts;
}
/**
* Get the identifier of the logger as '/<id>'
* @param logLevel The log level of the message.
* @param writeTo The enum for where to write the logs.
* @return The string of the formatted id
*/
static id_(logLevel, id, writeTo) {
if (writeTo === WriteTo.FILE) {
return '/' + id;
}
else if (logLevel === LogLevel.ERROR) {
return printRed('/' + id);
}
else if (logLevel === LogLevel.WARN) {
return printYellow('/' + id);
}
else {
return '/' + id;
}
}
/**
* Get the log level formatted with the first letter. For info, it is I.
* @param logLevel The log level of the message.
* @param writeTo The enum for where to write the logs.
* @return The string of the formatted log level
*/
static level_(logLevel, id, writeTo) {
let level = LogLevel[logLevel].toString();
if (writeTo === WriteTo.FILE) {
return level[0];
}
else if (logLevel === LogLevel.ERROR) {
return printRed(level[0]);
}
else if (logLevel === LogLevel.WARN) {
return printYellow(level[0]);
}
else {
return level[0];
}
}
/**
* Convert the list of messages to a single string message.
* @param msgs The list of messages.
* @return The string of the formatted messages
*/
static msgToFile_(msgs) {
let log = '';
for (let pos = 0; pos < msgs.length; pos++) {
let msg = msgs[pos];
let ret;
if (typeof msg === 'object') {
ret = JSON.stringify(msg);
}
else {
ret = msg;
}
if (pos !== msgs.length - 1) {
ret += ' ';
}
log += ret;
}
return log;
}
}
Logger.logLevel = LogLevel.INFO;
Logger.showTimestamp = true;
Logger.showId = true;
Logger.writeTo = WriteTo.CONSOLE;
Logger.firstWrite = false;
exports.Logger = Logger;
//# sourceMappingURL=logger.js.map

348
node_modules/protractor/built/plugins.d.ts generated vendored Normal file
View file

@ -0,0 +1,348 @@
/// <reference types="q" />
import * as q from 'q';
import * as webdriver from 'selenium-webdriver';
import { ProtractorBrowser } from './browser';
import { Config } from './config';
export declare enum PromiseType {
Q = 0,
WEBDRIVER = 1,
}
export interface PluginConfig {
path?: string;
package?: string;
inline?: ProtractorPlugin;
name?: string;
[key: string]: any;
}
export interface ProtractorPlugin {
/**
* Sets up plugins before tests are run. This is called after the WebDriver
* session has been started, but before the test framework has been set up.
*
* @this {Object} bound to module.exports.
*
* @throws {*} If this function throws an error, a failed assertion is added to
* the test results.
*
* @return {Promise=} Can return a promise, in which case protractor will wait
* for the promise to resolve before continuing. If the promise is
* rejected, a failed assertion is added to the test results.
*/
setup?(): void | Promise<void>;
/**
* This is called before the test have been run but after the test framework has
* been set up. Analogous to a config file's `onPrepare`.
*
* Very similar to using `setup`, but allows you to access framework-specific
* variables/functions (e.g. `jasmine.getEnv().addReporter()`).
*
* @this {Object} bound to module.exports.
*
* @throws {*} If this function throws an error, a failed assertion is added to
* the test results.
*
* @return {Promise=} Can return a promise, in which case protractor will wait
* for the promise to resolve before continuing. If the promise is
* rejected, a failed assertion is added to the test results.
*/
onPrepare?(): void | Promise<void>;
/**
* This is called after the tests have been run, but before the WebDriver
* session has been terminated.
*
* @this {Object} bound to module.exports.
*
* @throws {*} If this function throws an error, a failed assertion is added to
* the test results.
*
* @return {Promise=} Can return a promise, in which case protractor will wait
* for the promise to resolve before continuing. If the promise is
* rejected, a failed assertion is added to the test results.
*/
teardown?(): void | Promise<void>;
/**
* Called after the test results have been finalized and any jobs have been
* updated (if applicable).
*
* @this {Object} bound to module.exports.
*
* @throws {*} If this function throws an error, it is outputted to the console.
* It is too late to add a failed assertion to the test results.
*
* @return {Promise=} Can return a promise, in which case protractor will wait
* for the promise to resolve before continuing. If the promise is
* rejected, an error is logged to the console.
*/
postResults?(): void | Promise<void>;
/**
* Called after each test block (in Jasmine, this means an `it` block)
* completes.
*
* @param {boolean} passed True if the test passed.
* @param {Object} testInfo information about the test which just ran.
*
* @this {Object} bound to module.exports.
*
* @throws {*} If this function throws an error, a failed assertion is added to
* the test results.
*
* @return {Promise=} Can return a promise, in which case protractor will wait
* for the promise to resolve before outputting test results. Protractor
* will *not* wait before executing the next test; however, if the promise
* is rejected, a failed assertion is added to the test results.
*/
postTest?(passed: boolean, testInfo: any): void | Promise<void>;
/**
* This is called inside browser.get() directly after the page loads, and before
* angular bootstraps.
*
* @param {ProtractorBrowser} browser The browser instance which is loading a page.
*
* @this {Object} bound to module.exports.
*
* @throws {*} If this function throws an error, a failed assertion is added to
* the test results.
*
* @return {webdriver.promise.Promise=} Can return a promise, in which case
* protractor will wait for the promise to resolve before continuing. If
* the promise is rejected, a failed assertion is added to the test results.
*/
onPageLoad?(browser: ProtractorBrowser): void | webdriver.promise.Promise<void>;
/**
* This is called inside browser.get() directly after angular is done
* bootstrapping/synchronizing. If `browser.ignoreSynchronization` is `true`,
* this will not be called.
*
* @param {ProtractorBrowser} browser The browser instance which is loading a page.
*
* @this {Object} bound to module.exports.
*
* @throws {*} If this function throws an error, a failed assertion is added to
* the test results.
*
* @return {webdriver.promise.Promise=} Can return a promise, in which case
* protractor will wait for the promise to resolve before continuing. If
* the promise is rejected, a failed assertion is added to the test results.
*/
onPageStable?(browser: ProtractorBrowser): void | webdriver.promise.Promise<void>;
/**
* Between every webdriver action, Protractor calls browser.waitForAngular() to
* make sure that Angular has no outstanding $http or $timeout calls.
* You can use waitForPromise() to have Protractor additionally wait for your
* custom promise to be resolved inside of browser.waitForAngular().
*
* @param {ProtractorBrowser} browser The browser instance which needs invoked `waitForAngular`.
*
* @this {Object} bound to module.exports.
*
* @throws {*} If this function throws an error, a failed assertion is added to
* the test results.
*
* @return {webdriver.promise.Promise=} Can return a promise, in which case
* protractor will wait for the promise to resolve before continuing. If the
* promise is rejected, a failed assertion is added to the test results, and
* protractor will continue onto the next command. If nothing is returned or
* something other than a promise is returned, protractor will continue
* onto the next command.
*/
waitForPromise?(browser: ProtractorBrowser): webdriver.promise.Promise<void>;
/**
* Between every webdriver action, Protractor calls browser.waitForAngular() to
* make sure that Angular has no outstanding $http or $timeout calls.
* You can use waitForCondition() to have Protractor additionally wait for your
* custom condition to be truthy. If specified, this function will be called
* repeatedly until truthy.
*
* @param {ProtractorBrowser} browser The browser instance which needs invoked `waitForAngular`.
*
* @this {Object} bound to module.exports.
*
* @throws {*} If this function throws an error, a failed assertion is added to
* the test results.
*
* @return {webdriver.promise.Promise<boolean>|boolean} If truthy, Protractor
* will continue onto the next command. If falsy, webdriver will
* continuously re-run this function until it is truthy. If a rejected promise
* is returned, a failed assertion is added to the test results, and Protractor
* will continue onto the next command.
*/
waitForCondition?(browser: ProtractorBrowser): webdriver.promise.Promise<boolean> | boolean;
/**
* Used to turn off default checks for angular stability
*
* Normally Protractor waits for all $timeout and $http calls to be processed
* before executing the next command. This can be disabled using
* browser.ignoreSynchronization, but that will also disable any
* <Plugin>.waitForPromise or <Plugin>.waitForCondition checks. If you want
* to disable synchronization with angular, but leave intact any custom plugin
* synchronization, this is the option for you.
*
* This is used by plugin authors who want to replace Protractor's
* synchronization code with their own.
*
* @type {boolean}
*/
skipAngularStability?: boolean;
/**
* The name of the plugin. Used when reporting results.
*
* If you do not specify this property, it will be filled in with something
* reasonable (e.g. the plugin's path) by Protractor at runtime.
*
* @type {string}
*/
name?: string;
/**
* The plugin's configuration object.
*
* Note: this property is added by Protractor at runtime. Any pre-existing
* value will be overwritten.
*
* Note: that this is not the entire Protractor config object, just the entry
* in the `plugins` array for this plugin.
*
* @type {Object}
*/
config?: PluginConfig;
/**
* Adds a failed assertion to the test's results.
*
* Note: this property is added by Protractor at runtime. Any pre-existing
* value will be overwritten.
*
* @param {string} message The error message for the failed assertion
* @param {specName: string, stackTrace: string} options Some optional extra
* information about the assertion:
* - specName The name of the spec which this assertion belongs to.
* Defaults to `PLUGIN_NAME + ' Plugin Tests'`.
* - stackTrace The stack trace for the failure. Defaults to undefined.
* Defaults to `{}`.
*
* @throws {Error} Throws an error if called after results have been reported
*/
addFailure?(message?: string, info?: {
specName?: string;
stackTrace?: string;
}): void;
/**
* Adds a passed assertion to the test's results.
*
* Note: this property is added by Protractor at runtime. Any pre-existing
* value will be overwritten.
*
* @param {specName: string} options Extra information about the assertion:
* - specName The name of the spec which this assertion belongs to.
* Defaults to `PLUGIN_NAME + ' Plugin Tests'`.
* Defaults to `{}`.
*
* @throws {Error} Throws an error if called after results have been reported
*/
addSuccess?(info?: {
specName?: string;
}): void;
/**
* Warns the user that something is problematic.
*
* Note: this property is added by Protractor at runtime. Any pre-existing
* value will be overwritten.
*
* @param {string} message The message to warn the user about
* @param {specName: string} options Extra information about the assertion:
* - specName The name of the spec which this assertion belongs to.
* Defaults to `PLUGIN_NAME + ' Plugin Tests'`.
* Defaults to `{}`.
*/
addWarning?(message?: string, info?: {
specName?: string;
}): void;
}
/**
* The plugin API for Protractor. Note that this API is unstable. See
* plugins/README.md for more information.
*
* @constructor
* @param {Object} config parsed from the config file
*/
export declare class Plugins {
pluginObjs: ProtractorPlugin[];
assertions: {
[key: string]: AssertionResult[];
};
resultsReported: boolean;
constructor(config: Config);
/**
* Adds properties to a plugin's object
*
* @see docs/plugins.md#provided-properties-and-functions
*/
private annotatePluginObj(obj, conf, i);
private printPluginResults(specResults);
/**
* Gets the tests results generated by any plugins
*
* @see lib/frameworks/README.md#requirements for a complete description of what
* the results object must look like
*
* @return {Object} The results object
*/
getResults(): {
failedCount: number;
specResults: SpecResult[];
};
/**
* Returns true if any loaded plugin has skipAngularStability enabled.
*
* @return {boolean}
*/
skipAngularStability(): boolean;
/**
* @see docs/plugins.md#writing-plugins for information on these functions
*/
setup: (...args: any[]) => q.Promise<any[]>;
onPrepare: (...args: any[]) => q.Promise<any[]>;
teardown: (...args: any[]) => q.Promise<any[]>;
postResults: (...args: any[]) => q.Promise<any[]>;
postTest: (...args: any[]) => q.Promise<any[]>;
onPageLoad: (...args: any[]) => webdriver.promise.Promise<any[]>;
onPageStable: (...args: any[]) => webdriver.promise.Promise<any[]>;
waitForPromise: (...args: any[]) => webdriver.promise.Promise<any[]>;
waitForCondition: (...args: any[]) => webdriver.promise.Promise<any[]>;
/**
* Calls a function from a plugin safely. If the plugin's function throws an
* exception or returns a rejected promise, that failure will be logged as a
* failed test result instead of crashing protractor. If the tests results have
* already been reported, the failure will be logged to the console.
*
* @param {Object} pluginObj The plugin object containing the function to be run
* @param {string} funName The name of the function we want to run
* @param {*[]} args The arguments we want to invoke the function with
* @param {PromiseType} promiseType The type of promise (WebDriver or Q) that
* should be used
* @param {boolean} resultsReported If the results have already been reported
* @param {*} failReturnVal The value to return if the function fails
*
* @return {webdriver.promise.Promise|Q.Promise} A promise which resolves to the
* function's return value
*/
private safeCallPluginFun(pluginObj, funName, args, promiseType, failReturnVal);
/**
* Generates the handler for a plugin function (e.g. the setup() function)
*
* @param {string} funName The name of the function to make a handler for
* @param {PromiseType} promiseType The type of promise (WebDriver or Q) that should be used
* @param {boolean=} failReturnVal The value that the function should return if the plugin crashes
*
* @return The handler
*/
private pluginFunFactory(funName, promiseType, failReturnVal?);
private pluginFunFactory(funName, promiseType, failReturnVal?);
}
export interface SpecResult {
description: string;
assertions: AssertionResult[];
}
export interface AssertionResult {
passed: boolean;
errorMsg?: string;
stackTrace?: string;
}

225
node_modules/protractor/built/plugins.js generated vendored Normal file
View file

@ -0,0 +1,225 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const q = require("q");
const webdriver = require("selenium-webdriver");
const configParser_1 = require("./configParser");
const logger_1 = require("./logger");
const ptor_1 = require("./ptor");
let logger = new logger_1.Logger('plugins');
var PromiseType;
(function (PromiseType) {
PromiseType[PromiseType["Q"] = 0] = "Q";
PromiseType[PromiseType["WEBDRIVER"] = 1] = "WEBDRIVER";
})(PromiseType = exports.PromiseType || (exports.PromiseType = {}));
/**
* The plugin API for Protractor. Note that this API is unstable. See
* plugins/README.md for more information.
*
* @constructor
* @param {Object} config parsed from the config file
*/
class Plugins {
constructor(config) {
/**
* @see docs/plugins.md#writing-plugins for information on these functions
*/
this.setup = this.pluginFunFactory('setup', PromiseType.Q);
this.onPrepare = this.pluginFunFactory('onPrepare', PromiseType.Q);
this.teardown = this.pluginFunFactory('teardown', PromiseType.Q);
this.postResults = this.pluginFunFactory('postResults', PromiseType.Q);
this.postTest = this.pluginFunFactory('postTest', PromiseType.Q);
this.onPageLoad = this.pluginFunFactory('onPageLoad', PromiseType.WEBDRIVER);
this.onPageStable = this.pluginFunFactory('onPageStable', PromiseType.WEBDRIVER);
this.waitForPromise = this.pluginFunFactory('waitForPromise', PromiseType.WEBDRIVER);
this.waitForCondition = this.pluginFunFactory('waitForCondition', PromiseType.WEBDRIVER, true);
this.pluginObjs = [];
this.assertions = {};
this.resultsReported = false;
if (config.plugins) {
config.plugins.forEach((pluginConf, i) => {
let path;
if (pluginConf.path) {
path = configParser_1.ConfigParser.resolveFilePatterns(pluginConf.path, true, config.configDir)[0];
if (!path) {
throw new Error('Invalid path to plugin: ' + pluginConf.path);
}
}
else {
path = pluginConf.package;
}
let pluginObj;
if (path) {
pluginObj = require(path);
}
else if (pluginConf.inline) {
pluginObj = pluginConf.inline;
}
else {
throw new Error('Plugin configuration did not contain a valid path or ' +
'inline definition.');
}
this.annotatePluginObj(pluginObj, pluginConf, i);
logger.debug('Plugin "' + pluginObj.name + '" loaded.');
this.pluginObjs.push(pluginObj);
});
}
}
;
/**
* Adds properties to a plugin's object
*
* @see docs/plugins.md#provided-properties-and-functions
*/
annotatePluginObj(obj, conf, i) {
let addAssertion = (info, passed, message) => {
if (this.resultsReported) {
throw new Error('Cannot add new tests results, since they were already ' +
'reported.');
}
info = info || {};
const specName = info.specName || (obj.name + ' Plugin Tests');
const assertion = { passed: passed };
if (!passed) {
assertion.errorMsg = message;
if (info.stackTrace) {
assertion.stackTrace = info.stackTrace;
}
}
this.assertions[specName] = this.assertions[specName] || [];
this.assertions[specName].push(assertion);
};
obj.name = obj.name || conf.name || conf.path || conf.package || ('Plugin #' + i);
obj.config = conf;
obj.addFailure = (message, info) => {
addAssertion(info, false, message);
};
obj.addSuccess = (options) => {
addAssertion(options, true);
};
obj.addWarning = (message, options) => {
options = options || {};
logger.warn('Warning ' +
(options.specName ? 'in ' + options.specName : 'from "' + obj.name + '" plugin') + ': ' +
message);
};
}
printPluginResults(specResults) {
const green = '\x1b[32m';
const red = '\x1b[31m';
const normalColor = '\x1b[39m';
const printResult = (message, pass) => {
logger.info(pass ? green : red, '\t', pass ? 'Pass: ' : 'Fail: ', message, normalColor);
};
for (const specResult of specResults) {
const passed = specResult.assertions.map(x => x.passed).reduce((x, y) => (x && y), true);
printResult(specResult.description, passed);
if (!passed) {
for (const assertion of specResult.assertions) {
if (!assertion.passed) {
logger.error('\t\t' + assertion.errorMsg);
if (assertion.stackTrace) {
logger.error('\t\t' + assertion.stackTrace.replace(/\n/g, '\n\t\t'));
}
}
}
}
}
}
/**
* Gets the tests results generated by any plugins
*
* @see lib/frameworks/README.md#requirements for a complete description of what
* the results object must look like
*
* @return {Object} The results object
*/
getResults() {
const results = { failedCount: 0, specResults: [] };
for (const specName in this.assertions) {
results.specResults.push({ description: specName, assertions: this.assertions[specName] });
results.failedCount +=
this.assertions[specName].filter(assertion => !assertion.passed).length;
}
this.printPluginResults(results.specResults);
this.resultsReported = true;
return results;
}
;
/**
* Returns true if any loaded plugin has skipAngularStability enabled.
*
* @return {boolean}
*/
skipAngularStability() {
const result = this.pluginObjs.some(pluginObj => pluginObj.skipAngularStability);
return result;
}
;
/**
* Calls a function from a plugin safely. If the plugin's function throws an
* exception or returns a rejected promise, that failure will be logged as a
* failed test result instead of crashing protractor. If the tests results have
* already been reported, the failure will be logged to the console.
*
* @param {Object} pluginObj The plugin object containing the function to be run
* @param {string} funName The name of the function we want to run
* @param {*[]} args The arguments we want to invoke the function with
* @param {PromiseType} promiseType The type of promise (WebDriver or Q) that
* should be used
* @param {boolean} resultsReported If the results have already been reported
* @param {*} failReturnVal The value to return if the function fails
*
* @return {webdriver.promise.Promise|Q.Promise} A promise which resolves to the
* function's return value
*/
safeCallPluginFun(pluginObj, funName, args, promiseType, failReturnVal) {
const resolver = (done) => {
const logError = (e) => {
if (this.resultsReported) {
this.printPluginResults([{
description: pluginObj.name + ' Runtime',
assertions: [{
passed: false,
errorMsg: 'Failure during ' + funName + ': ' + (e.message || e),
stackTrace: e.stack
}]
}]);
}
else {
pluginObj.addFailure('Failure during ' + funName + ': ' + e.message || e, { stackTrace: e.stack });
}
done(failReturnVal);
};
try {
const result = pluginObj[funName].apply(pluginObj, args);
if (webdriver.promise.isPromise(result)) {
result.then(done, logError);
}
else {
done(result);
}
}
catch (e) {
logError(e);
}
};
if (promiseType == PromiseType.Q) {
return q.Promise(resolver);
}
else if (ptor_1.protractor.browser.controlFlowIsEnabled()) {
return new webdriver.promise.Promise(resolver);
}
else {
return new Promise(resolver);
}
}
pluginFunFactory(funName, promiseType, failReturnVal) {
return (...args) => {
const promises = this.pluginObjs.filter(pluginObj => typeof pluginObj[funName] === 'function')
.map(pluginObj => this.safeCallPluginFun(pluginObj, funName, args, promiseType, failReturnVal));
return promiseType == PromiseType.Q ? q.all(promises) : webdriver.promise.all(promises);
};
}
}
exports.Plugins = Plugins;
//# sourceMappingURL=plugins.js.map

104
node_modules/protractor/built/runner.d.ts generated vendored Normal file
View file

@ -0,0 +1,104 @@
/// <reference types="node" />
/// <reference types="q" />
import { EventEmitter } from 'events';
import * as q from 'q';
import { promise as wdpromise } from 'selenium-webdriver';
import { ProtractorBrowser } from './browser';
import { Config } from './config';
import { DriverProvider } from './driverProviders';
import { Plugins } from './plugins';
export declare class Runner extends EventEmitter {
config_: Config;
preparer_: any;
driverprovider_: DriverProvider;
o: any;
plugins_: Plugins;
restartPromise: q.Promise<any>;
frameworkUsesAfterEach: boolean;
ready_?: wdpromise.Promise<void>;
constructor(config: Config);
/**
* Registrar for testPreparers - executed right before tests run.
* @public
* @param {string/Fn} filenameOrFn
*/
setTestPreparer(filenameOrFn: string | Function): void;
/**
* Executor of testPreparer
* @public
* @param {string[]=} An optional list of command line arguments the framework will accept.
* @return {q.Promise} A promise that will resolve when the test preparers
* are finished.
*/
runTestPreparer(extraFlags?: string[]): q.Promise<any>;
/**
* Called after each test finishes.
*
* Responsible for `restartBrowserBetweenTests`
*
* @public
* @return {q.Promise} A promise that will resolve when the work here is done
*/
afterEach(): q.Promise<void>;
/**
* Grab driver provider based on type
* @private
*
* Priority
* 1) if directConnect is true, use that
* 2) if seleniumAddress is given, use that
* 3) if a Sauce Labs account is given, use that
* 4) if a seleniumServerJar is specified, use that
* 5) try to find the seleniumServerJar in protractor/selenium
*/
loadDriverProvider_(config: Config): void;
/**
* Responsible for cleaning up test run and exiting the process.
* @private
* @param {int} Standard unix exit code
*/
exit_: (exitCode: number) => any;
/**
* Getter for the Runner config object
* @public
* @return {Object} config
*/
getConfig(): Config;
/**
* Get the control flow used by this runner.
* @return {Object} WebDriver control flow.
*/
controlFlow(): any;
/**
* Sets up convenience globals for test specs
* @private
*/
setupGlobals_(browser_: ProtractorBrowser): void;
/**
* Create a new driver from a driverProvider. Then set up a
* new protractor instance using this driver.
* This is used to set up the initial protractor instances and any
* future ones.
*
* @param {Plugin} plugins The plugin functions
* @param {ProtractorBrowser=} parentBrowser The browser which spawned this one
*
* @return {Protractor} a protractor instance.
* @public
*/
createBrowser(plugins: any, parentBrowser?: ProtractorBrowser): any;
/**
* Final cleanup on exiting the runner.
*
* @return {q.Promise} A promise which resolves on finish.
* @private
*/
shutdown_(): q.Promise<void>;
/**
* The primary workhorse interface. Kicks off the test running process.
*
* @return {q.Promise} A promise which resolves to the exit code of the tests.
* @public
*/
run(): q.Promise<any>;
}

445
node_modules/protractor/built/runner.js generated vendored Normal file
View file

@ -0,0 +1,445 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const q = require("q");
const selenium_webdriver_1 = require("selenium-webdriver");
const util = require("util");
const browser_1 = require("./browser");
const driverProviders_1 = require("./driverProviders");
const logger_1 = require("./logger");
const plugins_1 = require("./plugins");
const ptor_1 = require("./ptor");
const helper = require("./util");
let logger = new logger_1.Logger('runner');
/*
* Runner is responsible for starting the execution of a test run and triggering
* setup, teardown, managing config, etc through its various dependencies.
*
* The Protractor Runner is a node EventEmitter with the following events:
* - testPass
* - testFail
* - testsDone
*
* @param {Object} config
* @constructor
*/
class Runner extends events_1.EventEmitter {
constructor(config) {
super();
/**
* Responsible for cleaning up test run and exiting the process.
* @private
* @param {int} Standard unix exit code
*/
this.exit_ = function (exitCode) {
return helper.runFilenameOrFn_(this.config_.configDir, this.config_.onCleanUp, [exitCode])
.then((returned) => {
if (typeof returned === 'number') {
return returned;
}
else {
return exitCode;
}
});
};
this.config_ = config;
if (config.v8Debug) {
// Call this private function instead of sending SIGUSR1 because Windows.
process['_debugProcess'](process.pid);
}
if (config.nodeDebug) {
process['_debugProcess'](process.pid);
let flow = selenium_webdriver_1.promise.controlFlow();
this.ready_ = flow.execute(() => {
let nodedebug = require('child_process').fork('debug', ['localhost:5858']);
process.on('exit', function () {
nodedebug.kill('SIGTERM');
});
nodedebug.on('exit', function () {
process.exit(1);
});
}, 'start the node debugger').then(() => {
return flow.timeout(1000, 'waiting for debugger to attach');
});
}
if (config.capabilities && config.capabilities.seleniumAddress) {
config.seleniumAddress = config.capabilities.seleniumAddress;
}
this.loadDriverProvider_(config);
this.setTestPreparer(config.onPrepare);
}
/**
* Registrar for testPreparers - executed right before tests run.
* @public
* @param {string/Fn} filenameOrFn
*/
setTestPreparer(filenameOrFn) {
this.preparer_ = filenameOrFn;
}
/**
* Executor of testPreparer
* @public
* @param {string[]=} An optional list of command line arguments the framework will accept.
* @return {q.Promise} A promise that will resolve when the test preparers
* are finished.
*/
runTestPreparer(extraFlags) {
let unknownFlags = this.config_.unknownFlags_ || [];
if (extraFlags) {
unknownFlags = unknownFlags.filter((f) => extraFlags.indexOf(f) === -1);
}
if (unknownFlags.length > 0 && !this.config_.disableChecks) {
// TODO: Make this throw a ConfigError in Protractor 6.
logger.warn('Ignoring unknown extra flags: ' + unknownFlags.join(', ') + '. This will be' +
' an error in future versions, please use --disableChecks flag to disable the ' +
' Protractor CLI flag checks. ');
}
return this.plugins_.onPrepare().then(() => {
return helper.runFilenameOrFn_(this.config_.configDir, this.preparer_);
});
}
/**
* Called after each test finishes.
*
* Responsible for `restartBrowserBetweenTests`
*
* @public
* @return {q.Promise} A promise that will resolve when the work here is done
*/
afterEach() {
let ret;
this.frameworkUsesAfterEach = true;
if (this.config_.restartBrowserBetweenTests) {
this.restartPromise = this.restartPromise || q(ptor_1.protractor.browser.restart());
ret = this.restartPromise;
this.restartPromise = undefined;
}
return ret || q();
}
/**
* Grab driver provider based on type
* @private
*
* Priority
* 1) if directConnect is true, use that
* 2) if seleniumAddress is given, use that
* 3) if a Sauce Labs account is given, use that
* 4) if a seleniumServerJar is specified, use that
* 5) try to find the seleniumServerJar in protractor/selenium
*/
loadDriverProvider_(config) {
this.config_ = config;
this.driverprovider_ = driverProviders_1.buildDriverProvider(this.config_);
}
/**
* Getter for the Runner config object
* @public
* @return {Object} config
*/
getConfig() {
return this.config_;
}
/**
* Get the control flow used by this runner.
* @return {Object} WebDriver control flow.
*/
controlFlow() {
return selenium_webdriver_1.promise.controlFlow();
}
/**
* Sets up convenience globals for test specs
* @private
*/
setupGlobals_(browser_) {
// Keep $, $$, element, and by/By under the global protractor namespace
ptor_1.protractor.browser = browser_;
ptor_1.protractor.$ = browser_.$;
ptor_1.protractor.$$ = browser_.$$;
ptor_1.protractor.element = browser_.element;
ptor_1.protractor.by = ptor_1.protractor.By = browser_1.ProtractorBrowser.By;
ptor_1.protractor.ExpectedConditions = browser_.ExpectedConditions;
if (!this.config_.noGlobals) {
// Export protractor to the global namespace to be used in tests.
global.browser = browser_;
global.$ = browser_.$;
global.$$ = browser_.$$;
global.element = browser_.element;
global.by = global.By = ptor_1.protractor.By;
global.ExpectedConditions = ptor_1.protractor.ExpectedConditions;
}
global.protractor = ptor_1.protractor;
if (!this.config_.skipSourceMapSupport) {
// Enable sourcemap support for stack traces.
require('source-map-support').install();
}
// Required by dart2js machinery.
// https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/sdk/lib/js/dart2js/js_dart2js.dart?spec=svn32943&r=32943#487
global.DartObject = function (o) {
this.o = o;
};
}
/**
* Create a new driver from a driverProvider. Then set up a
* new protractor instance using this driver.
* This is used to set up the initial protractor instances and any
* future ones.
*
* @param {Plugin} plugins The plugin functions
* @param {ProtractorBrowser=} parentBrowser The browser which spawned this one
*
* @return {Protractor} a protractor instance.
* @public
*/
createBrowser(plugins, parentBrowser) {
let config = this.config_;
let driver = this.driverprovider_.getNewDriver();
let blockingProxyUrl;
if (config.useBlockingProxy) {
blockingProxyUrl = this.driverprovider_.getBPUrl();
}
let initProperties = {
baseUrl: config.baseUrl,
rootElement: config.rootElement,
untrackOutstandingTimeouts: config.untrackOutstandingTimeouts,
params: config.params,
getPageTimeout: config.getPageTimeout,
allScriptsTimeout: config.allScriptsTimeout,
debuggerServerPort: config.debuggerServerPort,
ng12Hybrid: config.ng12Hybrid,
waitForAngularEnabled: true
};
if (parentBrowser) {
initProperties.baseUrl = parentBrowser.baseUrl;
initProperties.rootElement = parentBrowser.angularAppRoot();
initProperties.untrackOutstandingTimeouts = !parentBrowser.trackOutstandingTimeouts_;
initProperties.params = parentBrowser.params;
initProperties.getPageTimeout = parentBrowser.getPageTimeout;
initProperties.allScriptsTimeout = parentBrowser.allScriptsTimeout;
initProperties.debuggerServerPort = parentBrowser.debuggerServerPort;
initProperties.ng12Hybrid = parentBrowser.ng12Hybrid;
initProperties.waitForAngularEnabled = parentBrowser.waitForAngularEnabled();
}
let browser_ = new browser_1.ProtractorBrowser(driver, initProperties.baseUrl, initProperties.rootElement, initProperties.untrackOutstandingTimeouts, blockingProxyUrl);
browser_.params = initProperties.params;
browser_.plugins_ = plugins || new plugins_1.Plugins({});
if (initProperties.getPageTimeout) {
browser_.getPageTimeout = initProperties.getPageTimeout;
}
if (initProperties.allScriptsTimeout) {
browser_.allScriptsTimeout = initProperties.allScriptsTimeout;
}
if (initProperties.debuggerServerPort) {
browser_.debuggerServerPort = initProperties.debuggerServerPort;
}
if (initProperties.ng12Hybrid) {
browser_.ng12Hybrid = initProperties.ng12Hybrid;
}
browser_.ready =
browser_.ready
.then(() => {
return browser_.waitForAngularEnabled(initProperties.waitForAngularEnabled);
})
.then(() => {
return driver.manage().timeouts().setScriptTimeout(initProperties.allScriptsTimeout || 0);
})
.then(() => {
return browser_;
});
browser_.getProcessedConfig = () => {
return selenium_webdriver_1.promise.when(config);
};
browser_.forkNewDriverInstance =
(useSameUrl, copyMockModules, copyConfigUpdates = true) => {
let newBrowser = this.createBrowser(plugins);
if (copyMockModules) {
newBrowser.mockModules_ = browser_.mockModules_;
}
if (useSameUrl) {
newBrowser.ready = newBrowser.ready
.then(() => {
return browser_.driver.getCurrentUrl();
})
.then((url) => {
return newBrowser.get(url);
})
.then(() => {
return newBrowser;
});
}
return newBrowser;
};
let replaceBrowser = () => {
let newBrowser = browser_.forkNewDriverInstance(false, true);
if (browser_ === ptor_1.protractor.browser) {
this.setupGlobals_(newBrowser);
}
return newBrowser;
};
browser_.restart = () => {
// Note: because tests are not paused at this point, any async
// calls here are not guaranteed to complete before the tests resume.
// Seperate solutions depending on if the control flow is enabled (see lib/browser.ts)
if (browser_.controlFlowIsEnabled()) {
return browser_.restartSync().ready;
}
else {
return this.driverprovider_.quitDriver(browser_.driver)
.then(replaceBrowser)
.then(newBrowser => newBrowser.ready);
}
};
browser_.restartSync = () => {
if (!browser_.controlFlowIsEnabled()) {
throw TypeError('Unable to use `browser.restartSync()` when the control flow is disabled');
}
this.driverprovider_.quitDriver(browser_.driver);
return replaceBrowser();
};
return browser_;
}
/**
* Final cleanup on exiting the runner.
*
* @return {q.Promise} A promise which resolves on finish.
* @private
*/
shutdown_() {
return driverProviders_1.DriverProvider.quitDrivers(this.driverprovider_, this.driverprovider_.getExistingDrivers());
}
/**
* The primary workhorse interface. Kicks off the test running process.
*
* @return {q.Promise} A promise which resolves to the exit code of the tests.
* @public
*/
run() {
let testPassed;
let plugins = this.plugins_ = new plugins_1.Plugins(this.config_);
let pluginPostTestPromises;
let browser_;
let results;
if (this.config_.framework !== 'explorer' && !this.config_.specs.length) {
throw new Error('Spec patterns did not match any files.');
}
if (this.config_.SELENIUM_PROMISE_MANAGER != null) {
selenium_webdriver_1.promise.USE_PROMISE_MANAGER = this.config_.SELENIUM_PROMISE_MANAGER;
}
if (this.config_.webDriverLogDir || this.config_.highlightDelay) {
this.config_.useBlockingProxy = true;
}
// 0) Wait for debugger
return q(this.ready_)
.then(() => {
// 1) Setup environment
// noinspection JSValidateTypes
return this.driverprovider_.setupEnv();
})
.then(() => {
// 2) Create a browser and setup globals
browser_ = this.createBrowser(plugins);
this.setupGlobals_(browser_);
return browser_.ready.then(browser_.getSession)
.then((session) => {
logger.debug('WebDriver session successfully started with capabilities ' +
util.inspect(session.getCapabilities()));
}, (err) => {
logger.error('Unable to start a WebDriver session.');
throw err;
});
// 3) Setup plugins
})
.then(() => {
return plugins.setup();
// 4) Execute test cases
})
.then(() => {
// Do the framework setup here so that jasmine and mocha globals are
// available to the onPrepare function.
let frameworkPath = '';
if (this.config_.framework === 'jasmine' || this.config_.framework === 'jasmine2') {
frameworkPath = './frameworks/jasmine.js';
}
else if (this.config_.framework === 'mocha') {
frameworkPath = './frameworks/mocha.js';
}
else if (this.config_.framework === 'debugprint') {
// Private framework. Do not use.
frameworkPath = './frameworks/debugprint.js';
}
else if (this.config_.framework === 'explorer') {
// Private framework. Do not use.
frameworkPath = './frameworks/explorer.js';
}
else if (this.config_.framework === 'custom') {
if (!this.config_.frameworkPath) {
throw new Error('When config.framework is custom, ' +
'config.frameworkPath is required.');
}
frameworkPath = this.config_.frameworkPath;
}
else {
throw new Error('config.framework (' + this.config_.framework + ') is not a valid framework.');
}
if (this.config_.restartBrowserBetweenTests) {
// TODO(sjelin): replace with warnings once `afterEach` support is required
let restartDriver = () => {
if (!this.frameworkUsesAfterEach) {
this.restartPromise = q(browser_.restart());
}
};
this.on('testPass', restartDriver);
this.on('testFail', restartDriver);
}
// We need to save these promises to make sure they're run, but we
// don't
// want to delay starting the next test (because we can't, it's just
// an event emitter).
pluginPostTestPromises = [];
this.on('testPass', (testInfo) => {
pluginPostTestPromises.push(plugins.postTest(true, testInfo));
});
this.on('testFail', (testInfo) => {
pluginPostTestPromises.push(plugins.postTest(false, testInfo));
});
logger.debug('Running with spec files ' + this.config_.specs);
return require(frameworkPath).run(this, this.config_.specs);
// 5) Wait for postTest plugins to finish
})
.then((testResults) => {
results = testResults;
return q.all(pluginPostTestPromises);
// 6) Teardown plugins
})
.then(() => {
return plugins.teardown();
// 7) Teardown
})
.then(() => {
results = helper.joinTestLogs(results, plugins.getResults());
this.emit('testsDone', results);
testPassed = results.failedCount === 0;
if (this.driverprovider_.updateJob) {
return this.driverprovider_.updateJob({ 'passed': testPassed }).then(() => {
return this.driverprovider_.teardownEnv();
});
}
else {
return this.driverprovider_.teardownEnv();
}
// 8) Let plugins do final cleanup
})
.then(() => {
return plugins.postResults();
// 9) Exit process
})
.then(() => {
let exitCode = testPassed ? 0 : 1;
return this.exit_(exitCode);
})
.fin(() => {
return this.shutdown_();
});
}
}
exports.Runner = Runner;
//# sourceMappingURL=runner.js.map

0
node_modules/protractor/built/runnerCli.d.ts generated vendored Normal file
View file

56
node_modules/protractor/built/runnerCli.js generated vendored Normal file
View file

@ -0,0 +1,56 @@
"use strict";
/**
* This serves as the main function for starting a test run that has been
* requested by the launcher.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const configParser_1 = require("./configParser");
const logger_1 = require("./logger");
const runner_1 = require("./runner");
let logger = new logger_1.Logger('runnerCli');
process.on('message', (m) => {
switch (m.command) {
case 'run':
if (!m.capabilities) {
throw new Error('Run message missing capabilities');
}
// Merge in config file options.
let configParser = new configParser_1.ConfigParser();
if (m.configFile) {
configParser.addFileConfig(m.configFile);
}
if (m.additionalConfig) {
configParser.addConfig(m.additionalConfig);
}
let config = configParser.getConfig();
logger_1.Logger.set(config);
// Grab capabilities to run from launcher.
config.capabilities = m.capabilities;
// Get specs to be executed by this runner
config.specs = m.specs;
// Launch test run.
let runner = new runner_1.Runner(config);
// Pipe events back to the launcher.
runner.on('testPass', () => {
process.send({ event: 'testPass' });
});
runner.on('testFail', () => {
process.send({ event: 'testFail' });
});
runner.on('testsDone', (results) => {
process.send({ event: 'testsDone', results: results });
});
runner.run()
.then((exitCode) => {
process.exit(exitCode);
})
.catch((err) => {
logger.info(err.message);
process.exit(1);
});
break;
default:
throw new Error('command ' + m.command + ' is invalid');
}
});
//# sourceMappingURL=runnerCli.js.map

View file

@ -0,0 +1,216 @@
// Used to provide better protractor documentation for webdriver. These files
// are not used to provide code for protractor and are only used for the website.
/**
* @fileoverview Factory methods for the supported locator strategies.
*/
goog.provide('webdriver');
/**
* A collection of factory functions for creating {@link webdriver.Locator}
* instances.
*/
webdriver.By = {};
/**
* Locates elements that have a specific class name. The returned locator
* is equivalent to searching for elements with the CSS selector ".clazz".
*
* @view
* <ul class="pet">
* <li class="dog">Dog</li>
* <li class="cat">Cat</li>
* </ul>
*
* @example
* // Returns the web element for dog
* var dog = element(by.className('dog'));
* expect(dog.getText()).toBe('Dog');
*
* @param {string} className The class name to search for.
* @returns {!webdriver.Locator} The new locator.
* @see http://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes
* @see http://www.w3.org/TR/CSS2/selector.html#class-html
*/
webdriver.By.className = webdriver.Locator.factory_('class name');
/**
* Locates elements using a CSS selector. For browsers that do not support
* CSS selectors, WebDriver implementations may return an
* {@linkplain bot.Error.State.INVALID_SELECTOR invalid selector} error. An
* implementation may, however, emulate the CSS selector API.
*
* @view
* <ul class="pet">
* <li class="dog">Dog</li>
* <li class="cat">Cat</li>
* </ul>
*
* @example
* // Returns the web element for cat
* var cat = element(by.css('.pet .cat'));
* expect(cat.getText()).toBe('Cat');
*
* @param {string} selector The CSS selector to use.
* @returns {!webdriver.Locator} The new locator.
* @see http://www.w3.org/TR/CSS2/selector.html
*/
webdriver.By.css = webdriver.Locator.factory_('css selector');
/**
* Locates an element by its ID.
*
* @view
* <ul id="pet_id">
* <li id="dog_id">Dog</li>
* <li id="cat_id">Cat</li>
* </ul>
*
* @example
* // Returns the web element for dog
* var dog = element(by.id('dog_id'));
* expect(dog.getText()).toBe('Dog');
*
* @param {string} id The ID to search for.
* @returns {!webdriver.Locator} The new locator.
*/
webdriver.By.id = webdriver.Locator.factory_('id');
/**
* Locates link elements whose {@linkplain webdriver.WebElement#getText visible
* text} matches the given string.
*
* @view
* <a href="http://www.google.com">Google</a>
*
* @example
* expect(element(by.linkText('Google')).getTagName()).toBe('a');
*
* @param {string} text The link text to search for.
* @returns {!webdriver.Locator} The new locator.
*/
webdriver.By.linkText = webdriver.Locator.factory_('link text');
/**
* Locates an elements by evaluating a JavaScript expression, which may
* be either a function or a string. Like
* {@link webdriver.WebDriver.executeScript}, the expression is evaluated
* in the context of the page and cannot access variables from
* the test file.
*
* The result of this expression must be an element or list of elements.
*
* @alias by.js(expression)
* @view
* <span class="small">One</span>
* <span class="medium">Two</span>
* <span class="large">Three</span>
*
* @example
* var wideElement = element(by.js(function() {
* var spans = document.querySelectorAll('span');
* for (var i = 0; i < spans.length; ++i) {
* if (spans[i].offsetWidth > 100) {
* return spans[i];
* }
* }
* }));
* expect(wideElement.getText()).toEqual('Three');
*
* @param {!(string|Function)} script The script to execute.
* @param {...*} var_args The arguments to pass to the script.
* @returns {!webdriver.Locator}
*/
webdriver.By.js = function(script, var_args) {};
/**
* Locates elements whose {@code name} attribute has the given value.
*
* @view
* <ul>
* <li name="dog_name">Dog</li>
* <li name="cat_name">Cat</li>
* </ul>
*
* @example
* // Returns the web element for dog
* var dog = element(by.name('dog_name'));
* expect(dog.getText()).toBe('Dog');
*
* @param {string} name The name attribute to search for.
* @returns {!webdriver.Locator} The new locator.
*/
webdriver.By.name = webdriver.Locator.factory_('name');
/**
* Locates link elements whose {@linkplain webdriver.WebElement#getText visible
* text} contains the given substring.
*
* @view
* <ul>
* <li><a href="https://en.wikipedia.org/wiki/Doge_(meme)">Doge meme</a></li>
* <li>Cat</li>
* </ul>
*
* @example
* // Returns the 'a' web element for doge meme and navigate to that link
* var doge = element(by.partialLinkText('Doge'));
* doge.click();
*
* @param {string} text The substring to check for in a link's visible text.
* @returns {!webdriver.Locator} The new locator.
*/
webdriver.By.partialLinkText = webdriver.Locator.factory_(
'partial link text');
/**
* Locates elements with a given tag name. The returned locator is
* equivalent to using the
* [getElementsByTagName](https://developer.mozilla.org/en-US/docs/Web/API/Element.getElementsByTagName)
* DOM function.
*
* @view
* <a href="http://www.google.com">Google</a>
*
* @example
* expect(element(by.tagName('a')).getText()).toBe('Google');
*
* @param {string} text The substring to check for in a link's visible text.
* @returns {!webdriver.Locator} The new locator.
* @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html
*/
webdriver.By.tagName = webdriver.Locator.factory_('tag name');
/**
* Locates elements matching a XPath selector. Care should be taken when
* using an XPath selector with a {@link webdriver.WebElement} as WebDriver
* will respect the context in the specified in the selector. For example,
* given the selector {@code "//div"}, WebDriver will search from the
* document root regardless of whether the locator was used with a
* WebElement.
*
* @view
* <ul>
* <li><a href="https://en.wikipedia.org/wiki/Doge_(meme)">Doge meme</a></li>
* <li>Cat</li>
* </ul>
*
* @example
* // Returns the 'a' element for doge meme
* var li = element(by.xpath('//ul/li/a'));
* expect(li.getText()).toBe('Doge meme');
*
* @param {string} xpath The XPath selector to use.
* @returns {!webdriver.Locator} The new locator.
* @see http://www.w3.org/TR/xpath/
*/
webdriver.By.xpath = webdriver.Locator.factory_('xpath');

View file

@ -0,0 +1,765 @@
// Used to provide better protractor documentation for webdriver. These files
// are not used to provide code for protractor and are only used for the website.
/**
* @fileoverview The heart of the WebDriver JavaScript API.
*/
goog.provide('webdriver');
/**
* Class for defining sequences of complex user interactions.
* @external webdriver.ActionSequence
* @see http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/actions_exports_ActionSequence.html
*/
webdriver.ActionSequence = function() {};
/**
* Class for defining sequences of user touch interactions.
* @external webdriver.TouchSequence
* @see http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_TouchSequence.html
*/
webdriver.TouchSequence = function() {};
// //////////////////////////////////////////////////////////////////////////////
// //
// // webdriver.WebDriver
// //
// /////////////////////////////////////////////////////////////////////////////
/**
* Protractor's `browser` object is a wrapper for `selenium-webdriver` WebDriver.
* It inherits call of WebDriver's methods, but only the methods most useful to
* Protractor users are documented here.
*
* A full list of all functions available on WebDriver can be found
* in the selenium-webdriver
* <a href="http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/webdriver_exports_WebDriver.html">documentation</a>
* @constructor
*/
webdriver.WebDriver = function() {};
/**
* Creates a sequence of user actions using this driver. The sequence will not be
* scheduled for execution until {@link webdriver.ActionSequence#perform} is
* called.
*
* See the selenium webdriver docs <a href="http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/actions_exports_ActionSequence.html">
* for more details on action sequences</a>.
*
* Mouse actions do not work on Chrome with the HTML5 Drag and Drop API due to a known <a href="https://bugs.chromium.org/p/chromedriver/issues/detail?id=841">
* Chromedriver issue</a>
*
* @example
* // Dragging one element to another.
* browser.actions().
* mouseDown(element1).
* mouseMove(element2).
* mouseUp().
* perform();
*
* // You can also use the `dragAndDrop` convenience action.
* browser.actions().
* dragAndDrop(element1, element2).
* perform();
*
* // Instead of specifying an element as the target, you can specify an offset
* // in pixels. This example double-clicks slightly to the right of an element.
* browser.actions().
* mouseMove(element).
* mouseMove({x: 50, y: 0}).
* doubleClick().
* perform();
*
* @returns {!webdriver.ActionSequence} A new action sequence for this instance.
*/
webdriver.WebDriver.prototype.actions = function() {};
/**
* Creates a new touch sequence using this driver. The sequence will not be
* scheduled for execution until {@link actions.TouchSequence#perform} is
* called.
*
* See the selenium webdriver docs <a href="http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_TouchSequence.html">
* for more details on touch sequences</a>.
*
* @example
* browser.touchActions().
* tap(element1).
* doubleTap(element2).
* perform();
*
* @return {!webdriver.TouchSequence} A new touch sequence for this instance.
*/
webdriver.WebDriver.prototype.touchActions = function() {};
/**
* Schedules a command to execute JavaScript in the context of the currently
* selected frame or window. The script fragment will be executed as the body
* of an anonymous function. If the script is provided as a function object,
* that function will be converted to a string for injection into the target
* window.
*
* Any arguments provided in addition to the script will be included as script
* arguments and may be referenced using the {@code arguments} object.
* Arguments may be a boolean, number, string, or {@linkplain WebElement}.
* Arrays and objects may also be used as script arguments as long as each item
* adheres to the types previously mentioned.
*
* The script may refer to any variables accessible from the current window.
* Furthermore, the script will execute in the window's context, thus
* {@code document} may be used to refer to the current document. Any local
* variables will not be available once the script has finished executing,
* though global variables will persist.
*
* If the script has a return value (i.e. if the script contains a return
* statement), then the following steps will be taken for resolving this
* functions return value:
*
* - For a HTML element, the value will resolve to a {@linkplain WebElement}
* - Null and undefined return values will resolve to null</li>
* - Booleans, numbers, and strings will resolve as is</li>
* - Functions will resolve to their string representation</li>
* - For arrays and objects, each member item will be converted according to
* the rules above
*
* @example
* var el = element(by.module('header'));
* var tag = browser.executeScript('return arguments[0].tagName', el);
* expect(tag).toEqual('h1');
*
* @param {!(string|Function)} script The script to execute.
* @param {...*} var_args The arguments to pass to the script.
* @return {!promise.Promise<T>} A promise that will resolve to the
* scripts return value.
* @template T
*/
webdriver.WebDriver.prototype.executeScript = function(script, var_args) {};
/**
* Schedules a command to execute asynchronous JavaScript in the context of the
* currently selected frame or window. The script fragment will be executed as
* the body of an anonymous function. If the script is provided as a function
* object, that function will be converted to a string for injection into the
* target window.
*
* Any arguments provided in addition to the script will be included as script
* arguments and may be referenced using the {@code arguments} object.
* Arguments may be a boolean, number, string, or {@code WebElement}.
* Arrays and objects may also be used as script arguments as long as each item
* adheres to the types previously mentioned.
*
* Unlike executing synchronous JavaScript with {@link #executeScript},
* scripts executed with this function must explicitly signal they are finished
* by invoking the provided callback. This callback will always be injected
* into the executed function as the last argument, and thus may be referenced
* with {@code arguments[arguments.length - 1]}. The following steps will be
* taken for resolving this functions return value against the first argument
* to the script's callback function:
*
* - For a HTML element, the value will resolve to a
* {@link WebElement}
* - Null and undefined return values will resolve to null
* - Booleans, numbers, and strings will resolve as is
* - Functions will resolve to their string representation
* - For arrays and objects, each member item will be converted according to
* the rules above
*
* @example
* // Example 1
* // Performing a sleep that is synchronized with the currently selected window
* var start = new Date().getTime();
* browser.executeAsyncScript(
* 'window.setTimeout(arguments[arguments.length - 1], 500);').
* then(function() {
* console.log(
* 'Elapsed time: ' + (new Date().getTime() - start) + ' ms');
* });
*
* // Example 2
* // Synchronizing a test with an AJAX application:
* var button = element(by.id('compose-button'));
* button.click();
* browser.executeAsyncScript(
* 'var callback = arguments[arguments.length - 1];' +
* 'mailClient.getComposeWindowWidget().onload(callback);');
* browser.switchTo().frame('composeWidget');
* element(by.id('to')).sendKeys('dog@example.com');
*
* // Example 3
* // Injecting a XMLHttpRequest and waiting for the result. In this example,
* // the inject script is specified with a function literal. When using this
* // format, the function is converted to a string for injection, so it should
* // not reference any symbols not defined in the scope of the page under test.
* browser.executeAsyncScript(function() {
* var callback = arguments[arguments.length - 1];
* var xhr = new XMLHttpRequest();
* xhr.open("GET", "/resource/data.json", true);
* xhr.onreadystatechange = function() {
* if (xhr.readyState == 4) {
* callback(xhr.responseText);
* }
* };
* xhr.send('');
* }).then(function(str) {
* console.log(JSON.parse(str)['food']);
* });
*
* @param {!(string|Function)} script The script to execute.
* @param {...*} var_args The arguments to pass to the script.
* @return {!promise.Promise<T>} A promise that will resolve to the
* scripts return value.
* @template T
*/
webdriver.WebDriver.prototype.executeAsyncScript = (script, var_args) => {};
/**
* Schedules a command to execute a custom function within the context of
* webdriver's control flow.
*
* Most webdriver actions are asynchronous, but the control flow makes sure that
* commands are executed in the order they were received. By running your
* function in the control flow, you can ensure that it is executed before/after
* other webdriver actions. Additionally, Protractor will wait until the
* control flow is empty before deeming a test finished.
*
* @example
* var logText = function(el) {
* return el.getText().then((text) => {
* console.log(text);
* });
* };
* var counter = element(by.id('counter'));
* var button = element(by.id('button'));
* // Use `browser.call()` to make sure `logText` is run before and after
* // `button.click()`
* browser.call(logText, counter);
* button.click();
* browser.call(logText, counter);
*
* @param {function(...): (T|promise.Promise<T>)} fn The function to
* execute.
* @param {Object=} opt_scope The object in whose scope to execute the function
* (i.e. the `this` object for the function).
* @param {...*} var_args Any arguments to pass to the function. If any of the
* arguments are promised, webdriver will wait for these promised to resolve
* and pass the resulting value onto the function.
* @return {!promise.Promise<T>} A promise that will be resolved
* with the function's result.
* @template T
*/
webdriver.WebDriver.prototype.call = function(fn, opt_scope, var_args) {};
/**
* Schedules a command to wait for a condition to hold or {@link
* webdriver.promise.Promise promise} to be resolved.
*
* This function blocks WebDriver's control flow, not the javascript runtime.
* It will only delay future webdriver commands from being executed (e.g. it
* will cause Protractor to wait before sending future commands to the selenium
* server), and only when the webdriver control flow is enabled.
*
* This function returnes a promise, which can be used if you need to block
* javascript execution and not just the control flow.
*
* See also {@link ExpectedConditions}
*
* *Example:* Suppose you have a function, `startTestServer`, that returns a
* promise for when a server is ready for requests. You can block a `WebDriver`
* client on this promise with:
*
* @example
* var started = startTestServer();
* browser.wait(started, 5 * 1000, 'Server should start within 5 seconds');
* browser.get(getServerUrl());
*
* @param {!(webdriver.promise.Promise<T>|
* webdriver.until.Condition<T>|
* function(!webdriver.WebDriver): T)} condition The condition to
* wait on, defined as a promise, condition object, or a function to
* evaluate as a condition.
* @param {number=} opt_timeout How long to wait for the condition to be true. Will default 30 seconds, or to the jasmineNodeOpts.defaultTimeoutInterval in your protractor.conf.js file.
* @param {string=} opt_message An optional message to use if the wait times
* out.
* @returns {!webdriver.promise.Promise<T>} A promise that will be fulfilled
* with the first truthy value returned by the condition function, or
* rejected if the condition times out.
*/
webdriver.WebDriver.prototype.wait = function() {};
/**
* Schedules a command to make the driver sleep for the given amount of time.
* @param {number} ms The amount of time, in milliseconds, to sleep.
* @returns {!webdriver.promise.Promise.<void>} A promise that will be resolved
* when the sleep has finished.
*/
webdriver.WebDriver.prototype.sleep = function() {};
/**
* Schedules a command to retrieve the current page's source. The page source
* returned is a representation of the underlying DOM: do not expect it to be
* formatted or escaped in the same way as the response sent from the web
* server.
* @return {!promise.Promise<string>} A promise that will be
* resolved with the current page source.
*/
webdriver.WebDriver.prototype.getPageSource = function() {};
/**
* Schedules a command to close the current window.
* @return {!promise.Promise<void>} A promise that will be resolved
* when this command has completed.
*/
webdriver.WebDriver.prototype.close = function() {};
/**
* Schedules a command to retrieve the URL of the current page.
* @returns {!webdriver.promise.Promise.<string>} A promise that will be
* resolved with the current URL.
*/
webdriver.WebDriver.prototype.getCurrentUrl = function() {};
/**
* Schedules a command to retrieve the current page's title.
* @returns {!webdriver.promise.Promise.<string>} A promise that will be
* resolved with the current page's title.
*/
webdriver.WebDriver.prototype.getTitle = function() {};
/**
* Schedule a command to take a screenshot. The driver makes a best effort to
* return a screenshot of the following, in order of preference:
* <ol>
* <li>Entire page
* <li>Current window
* <li>Visible portion of the current frame
* <li>The screenshot of the entire display containing the browser
* </ol>
*
* @returns {!webdriver.promise.Promise.<string>} A promise that will be
* resolved to the screenshot as a base-64 encoded PNG.
*/
webdriver.WebDriver.prototype.takeScreenshot = function() {};
/**
* Used to switch WebDriver's focus to a frame or window (e.g. an alert, an
* iframe, another window).
*
* See [WebDriver's TargetLocator Docs](http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/webdriver_exports_TargetLocator.html)
* for more information.
*
* @example
* browser.switchTo().frame(element(by.tagName('iframe')).getWebElement());
*
* @return {!TargetLocator} The target locator interface for this
* instance.
*/
webdriver.WebDriver.prototype.switchTo = function() {}
// /////////////////////////////////////////////////////////////////////////////
// //
// // webdriver.WebElement
// //
// /////////////////////////////////////////////////////////////////////////////
//
//
//
/**
* Protractor's ElementFinders are wrappers for selenium-webdriver WebElement.
* A full list of all functions available on WebElement can be found
* in the selenium-webdriver
* <a href="http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/webdriver_exports_WebElement.html">documentation</a>.
*
* @param {!webdriver.WebDriver} driver The webdriver driver or the parent WebDriver instance for this
* element.
* @param {!(webdriver.promise.Promise.<webdriver.WebElement.Id>|
* webdriver.WebElement.Id)} id The server-assigned opaque ID for the
* underlying DOM element.
* @constructor
*/
webdriver.WebElement = function(driver, id) {};
/**
* Gets the parent web element of this web element.
*
* @view
* <ul class="pet">
* <li class="dog">Dog</li>
* <li class="cat">Cat</li>
* </ul>
*
* @example
* // Using getDriver to find the parent web element to find the cat li
* var liDog = element(by.css('.dog')).getWebElement();
* var liCat = liDog.getDriver().findElement(by.css('.cat'));
*
* @returns {!webdriver.WebDriver} The parent driver for this instance.
*/
webdriver.WebElement.prototype.getDriver = function() {};
/**
* Gets the WebDriver ID string representation for this web element.
*
* @view
* <ul class="pet">
* <li class="dog">Dog</li>
* <li class="cat">Cat</li>
* </ul>
*
* @example
* // returns the dog web element
* var dog = element(by.css('.dog')).getWebElement();
* expect(dog.getId()).not.toBe(undefined);
*
* @returns {!webdriver.promise.Promise.<webdriver.WebElement.Id>} A promise
* that resolves to this element's JSON representation as defined by the
* WebDriver wire protocol.
* @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
*/
webdriver.WebElement.prototype.getId = function() {};
/**
* Use {@link ElementFinder.prototype.element} instead
*
* @see ElementFinder.prototype.element
*
* @param {webdriver.Locator} subLocator
*
* @returns {!webdriver.WebElement}
*/
webdriver.WebElement.prototype.findElement = function(subLocator) {};
/**
* Schedules a command to click on this element.
*
* @view
* <ul>
* <li><a href="https://en.wikipedia.org/wiki/Doge_(meme)">Doge meme</a></li>
* <li>Cat</li>
* </ul>
*
* @example
* // Clicks on the web link
* element(by.partialLinkText('Doge')).click();
*
* @returns {!webdriver.promise.Promise.<void>} A promise that will be resolved
* when the click command has completed.
*/
webdriver.WebElement.prototype.click = function() {};
/**
* Schedules a command to type a sequence on the DOM element represented by this
* instance.
*
* Modifier keys (SHIFT, CONTROL, ALT, META) are stateful; once a modifier is
* processed in the keysequence, that key state is toggled until one of the
* following occurs:
*
* - The modifier key is encountered again in the sequence. At this point the
* state of the key is toggled (along with the appropriate keyup/down events).
* - The {@link webdriver.Key.NULL} key is encountered in the sequence. When
* this key is encountered, all modifier keys current in the down state are
* released (with accompanying keyup events). The NULL key can be used to
* simulate common keyboard shortcuts:
*
* element.sendKeys("text was",
* protractor.Key.CONTROL, "a", protractor.Key.NULL,
* "now text is");
* // Alternatively:
* element.sendKeys("text was",
* protractor.Key.chord(protractor.Key.CONTROL, "a"),
* "now text is");
*
* - The end of the keysequence is encountered. When there are no more keys
* to type, all depressed modifier keys are released (with accompanying keyup
* events).
*
* If this element is a file input ({@code <input type="file">}), the
* specified key sequence should specify the path to the file to attach to
* the element. This is analgous to the user clicking "Browse..." and entering
* the path into the file select dialog.
*
* var form = driver.findElement(By.css('form'));
* var element = form.findElement(By.css('input[type=file]'));
* element.sendKeys('/path/to/file.txt');
* form.submit();
*
* For uploads to function correctly, the entered path must reference a file
* on the _browser's_ machine, not the local machine running this script. When
* running against a remote Selenium server, a {@link webdriver.FileDetector}
* may be used to transparently copy files to the remote machine before
* attempting to upload them in the browser.
*
* __Note:__ On browsers where native keyboard events are not supported
* (e.g. Firefox on OS X), key events will be synthesized. Special
* punctionation keys will be synthesized according to a standard QWERTY en-us
* keyboard layout.
*
* @param {...(string|!webdriver.promise.Promise<string>)} var_args The sequence
* of keys to type. All arguments will be joined into a single sequence.
* @returns {!webdriver.promise.Promise.<void>} A promise that will be resolved
* when all keys have been typed.
*/
webdriver.WebElement.prototype.sendKeys = function(var_args) {};
/**
* Gets the tag/node name of this element.
*
* @view
* <span>{{person.name}}</span>
*
* @example
* expect(element(by.binding('person.name')).getTagName()).toBe('span');
*
* @returns {!webdriver.promise.Promise.<string>} A promise that will be
* resolved with the element's tag name.
*/
webdriver.WebElement.prototype.getTagName = function() {};
/**
* Gets the computed style of an element. If the element inherits the named
* style from its parent, the parent will be queried for its value. Where
* possible, color values will be converted to their hex representation (e.g.
* #00ff00 instead of rgb(0, 255, 0)).
*
* _Warning:_ the value returned will be as the browser interprets it, so
* it may be tricky to form a proper assertion.
*
* @view
* <span style='color: #000000'>{{person.name}}</span>
*
* @example
* expect(element(by.binding('person.name')).getCssValue('color')).toBe('#000000');
*
* @param {string} cssStyleProperty The name of the CSS style property to look
* up.
* @returns {!webdriver.promise.Promise.<string>} A promise that will be
* resolved with the requested CSS value.
*/
webdriver.WebElement.prototype.getCssValue = function(cssStyleProperty) {};
/**
* Schedules a command to query for the value of the given attribute of the
* element. Will return the current value, even if it has been modified after
* the page has been loaded. More exactly, this method will return the value of
* the given attribute, unless that attribute is not present, in which case the
* value of the property with the same name is returned. If neither value is
* set, null is returned (for example, the "value" property of a textarea
* element). The "style" attribute is converted as best can be to a
* text representation with a trailing semi-colon. The following are deemed to
* be "boolean" attributes and will return either "true" or null:
*
* async, autofocus, autoplay, checked, compact, complete, controls, declare,
* defaultchecked, defaultselected, defer, disabled, draggable, ended,
* formnovalidate, hidden, indeterminate, iscontenteditable, ismap, itemscope,
* loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open,
* paused, pubdate, readonly, required, reversed, scoped, seamless, seeking,
* selected, spellcheck, truespeed, willvalidate
*
* Finally, the following commonly mis-capitalized attribute/property names
* are evaluated as expected:
*
* - "class"
* - "readonly"
*
* @view
* <div id="foo" class="bar"></div>
*
* @example
* var foo = element(by.id('foo'));
* expect(foo.getAttribute('class')).toEqual('bar');
*
* @param {string} attributeName The name of the attribute to query.
* @returns {!webdriver.promise.Promise.<?string>} A promise that will be
* resolved with the attribute's value. The returned value will always be
* either a string or null.
*/
webdriver.WebElement.prototype.getAttribute = function(attributeName) {};
/**
* Get the visible innerText of this element, including sub-elements, without
* any leading or trailing whitespace. Visible elements are not hidden by CSS.
*
* @view
* <div id="foo" class="bar">Inner text</div>
*
* @example
* var foo = element(by.id('foo'));
* expect(foo.getText()).toEqual('Inner text');
*
* @returns {!webdriver.promise.Promise.<string>} A promise that will be
* resolved with the element's visible text.
*/
webdriver.WebElement.prototype.getText = function() {};
/**
* Schedules a command to compute the size of this element's bounding box, in
* pixels.
*
* @view
* <div id="foo" style="width:50px; height: 20px">
* Inner text
* </div>
*
* @example
* var foo = element(by.id('foo'));
* expect(foo.getSize()).toEqual(jasmine.objectContaining({
* width: 50,
* height: 20
* });
*
* @returns {!webdriver.promise.Promise.<{width: number, height: number}>} A
* promise that will be resolved with the element's size as a
* {@code {width:number, height:number}} object.
*/
webdriver.WebElement.prototype.getSize = function() {};
/**
* Schedules a command to compute the location of this element in page space.
*
* @view
* <div id="foo" style="position: absolute; top:20px; left: 15px">
* Inner text
* </div>
*
* @example
* var foo = element(by.id('foo'));
* expect(foo.getLocation()).toEqual(jasmine.objectContaining({
* x: 15,
* y: 20
* });
*
* @returns {!webdriver.promise.Promise.<{x: number, y: number}>} A promise that
* will be resolved to the element's location as a
* {@code {x:number, y:number}} object.
*/
webdriver.WebElement.prototype.getLocation = function() {};
/**
* Schedules a command to query whether the DOM element represented by this
* instance is enabled, as dicted by the {@code disabled} attribute.
*
* @view
* <input id="foo" disabled=true>
*
* @example
* var foo = element(by.id('foo'));
* expect(foo.isEnabled()).toBe(false);
*
* @returns {!webdriver.promise.Promise.<boolean>} A promise that will be
* resolved with whether this element is currently enabled.
*/
webdriver.WebElement.prototype.isEnabled = function() {};
/**
* Schedules a command to query whether this element is selected.
*
* @view
* <input id="foo" type="checkbox">
*
* @example
* var foo = element(by.id('foo'));
* expect(foo.isSelected()).toBe(false);
* foo.click();
* expect(foo.isSelected()).toBe(true);
*
* @returns {!webdriver.promise.Promise.<boolean>} A promise that will be
* resolved with whether this element is currently selected.
*/
webdriver.WebElement.prototype.isSelected = function() {};
/**
* Schedules a command to submit the form containing this element (or this
* element if it is a FORM element). This command is a no-op if the element is
* not contained in a form.
*
* @view
* <form id="login">
* <input name="user">
* </form>
*
* @example
* var login_form = element(by.id('login'));
* login_form.submit();
*
* @returns {!webdriver.promise.Promise.<void>} A promise that will be resolved
* when the form has been submitted.
*/
webdriver.WebElement.prototype.submit = function() {};
/**
* Schedules a command to clear the {@code value} of this element. This command
* has no effect if the underlying DOM element is neither a text INPUT element
* nor a TEXTAREA element.
*
* @view
* <input id="foo" value="Default Text">
*
* @example
* var foo = element(by.id('foo'));
* expect(foo.getAttribute('value')).toEqual('Default Text');
* foo.clear();
* expect(foo.getAttribute('value')).toEqual('');
*
* @returns {!webdriver.promise.Promise.<void>} A promise that will be resolved
* when the element has been cleared.
*/
webdriver.WebElement.prototype.clear = function() {};
/**
* Schedules a command to test whether this element is currently displayed.
*
* @view
* <div id="foo" style="visibility:hidden">
*
* @example
* var foo = element(by.id('foo'));
* expect(foo.isDisplayed()).toBe(false);
*
* @returns {!webdriver.promise.Promise.<boolean>} A promise that will be
* resolved with whether this element is currently visible on the page.
*/
webdriver.WebElement.prototype.isDisplayed = function() {};
/**
* Take a screenshot of the visible region encompassed by this element's
* bounding rectangle.
*
* @view
* <div id="foo">Inner Text</div>
*
* @example
* function writeScreenShot(data, filename) {
* var stream = fs.createWriteStream(filename);
* stream.write(new Buffer(data, 'base64'));
* stream.end();
* }
* var foo = element(by.id('foo'));
* foo.takeScreenshot().then((png) => {
* writeScreenShot(png, 'foo.png');
* });
*
* Note that this is a new feature in WebDriver and may not be supported by
* your browser's driver. It isn't yet supported in Chromedriver as of 2.21.
*
* @param {boolean=} opt_scroll Optional argument that indicates whether the
* element should be scrolled into view before taking a screenshot. Defaults
* to false.
* @returns {!webdriver.promise.Promise.<string>} A promise that will be
* resolved to the screenshot as a base-64 encoded PNG.
*/
webdriver.WebElement.prototype.takeScreenshot = function(opt_scroll) {};

37
node_modules/protractor/built/taskLogger.d.ts generated vendored Normal file
View file

@ -0,0 +1,37 @@
export declare class TaskLogger {
private task;
private pid;
private buffer;
private insertTag;
/**
* Log output such that metadata are appended.
* Calling log(data) will not flush to console until you call flush()
*
* @constructor
* @param {object} task Task that is being reported.
* @param {number} pid PID of process running the task.
*/
constructor(task: any, pid: number);
/**
* Log the header for the current task including information such as
* PID, browser name/version, task Id, specs being run.
*
* @private
*/
private logHeader_();
/**
* Prints the contents of the buffer without clearing it.
*/
peek(): void;
/**
* Flushes the buffer to stdout.
*/
flush(): void;
/**
* Log the data in the argument such that metadata are appended.
* The data will be saved to a buffer until flush() is called.
*
* @param {string} data
*/
log(data: string): void;
}

92
node_modules/protractor/built/taskLogger.js generated vendored Normal file
View file

@ -0,0 +1,92 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const os = require("os");
const logger_1 = require("./logger");
let logger = new logger_1.Logger('testLogger');
class TaskLogger {
/**
* Log output such that metadata are appended.
* Calling log(data) will not flush to console until you call flush()
*
* @constructor
* @param {object} task Task that is being reported.
* @param {number} pid PID of process running the task.
*/
constructor(task, pid) {
this.task = task;
this.pid = pid;
this.buffer = '';
this.insertTag = true;
this.logHeader_();
}
/**
* Log the header for the current task including information such as
* PID, browser name/version, task Id, specs being run.
*
* @private
*/
logHeader_() {
let output = 'PID: ' + this.pid + os.EOL;
if (this.task.specs.length === 1) {
output += 'Specs: ' + this.task.specs.toString() + os.EOL + os.EOL;
}
this.log(output);
}
/**
* Prints the contents of the buffer without clearing it.
*/
peek() {
if (this.buffer) {
// Flush buffer if nonempty
logger.info(os.EOL + '------------------------------------' + os.EOL);
logger.info(this.buffer);
logger.info(os.EOL);
}
}
/**
* Flushes the buffer to stdout.
*/
flush() {
if (this.buffer) {
this.peek();
this.buffer = '';
}
}
/**
* Log the data in the argument such that metadata are appended.
* The data will be saved to a buffer until flush() is called.
*
* @param {string} data
*/
log(data) {
let tag = '[';
let capabilities = this.task.capabilities;
tag += (capabilities.logName) ? capabilities.logName :
(capabilities.browserName) ? capabilities.browserName : '';
tag += (capabilities.version) ? (' ' + capabilities.version) : '';
tag += (capabilities.platform) ? (' ' + capabilities.platform) : '';
tag += (capabilities.logName && capabilities.count < 2) ? '' : ' #' + this.task.taskId;
tag += '] ';
data = data.toString();
for (let i = 0; i < data.length; i++) {
if (this.insertTag) {
this.insertTag = false;
// This ensures that the '\x1B[0m' appears before the tag, so that
// data remains correct when color is not processed.
// See https://github.com/angular/protractor/pull/1216
if (data[i] === '\x1B' && data.substring(i, i + 4) === '\x1B[0m') {
this.buffer += ('\x1B[0m' + tag);
i += 3;
continue;
}
this.buffer += tag;
}
if (data[i] === '\n') {
this.insertTag = true;
}
this.buffer += data[i];
}
}
}
exports.TaskLogger = TaskLogger;
//# sourceMappingURL=taskLogger.js.map

40
node_modules/protractor/built/taskRunner.d.ts generated vendored Normal file
View file

@ -0,0 +1,40 @@
/// <reference types="node" />
/// <reference types="q" />
import { EventEmitter } from 'events';
import * as q from 'q';
import { Config } from './config';
export interface RunResults {
taskId: number;
specs: Array<string>;
capabilities: any;
failedCount: number;
exitCode: number;
specResults: Array<any>;
}
/**
* A runner for running a specified task (capabilities + specs).
* The TaskRunner can either run the task from the current process (via
* './runner.js') or from a new process (via './runnerCli.js').
*
* @constructor
* @param {string} configFile Path of test configuration.
* @param {object} additionalConfig Additional configuration.
* @param {object} task Task to run.
* @param {boolean} runInFork Whether to run test in a forked process.
* @constructor
*/
export declare class TaskRunner extends EventEmitter {
private configFile;
private additionalConfig;
private task;
private runInFork;
constructor(configFile: string, additionalConfig: Config, task: any, runInFork: boolean);
/**
* Sends the run command.
* @return {q.Promise} A promise that will resolve when the task finishes
* running. The promise contains the following parameters representing the
* result of the run:
* taskId, specs, capabilities, failedCount, exitCode, specResults
*/
run(): q.Promise<any>;
}

118
node_modules/protractor/built/taskRunner.js generated vendored Normal file
View file

@ -0,0 +1,118 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const child_process = require("child_process");
const events_1 = require("events");
const q = require("q");
const configParser_1 = require("./configParser");
const runner_1 = require("./runner");
const taskLogger_1 = require("./taskLogger");
/**
* A runner for running a specified task (capabilities + specs).
* The TaskRunner can either run the task from the current process (via
* './runner.js') or from a new process (via './runnerCli.js').
*
* @constructor
* @param {string} configFile Path of test configuration.
* @param {object} additionalConfig Additional configuration.
* @param {object} task Task to run.
* @param {boolean} runInFork Whether to run test in a forked process.
* @constructor
*/
class TaskRunner extends events_1.EventEmitter {
constructor(configFile, additionalConfig, task, runInFork) {
super();
this.configFile = configFile;
this.additionalConfig = additionalConfig;
this.task = task;
this.runInFork = runInFork;
}
/**
* Sends the run command.
* @return {q.Promise} A promise that will resolve when the task finishes
* running. The promise contains the following parameters representing the
* result of the run:
* taskId, specs, capabilities, failedCount, exitCode, specResults
*/
run() {
let runResults = {
taskId: this.task.taskId,
specs: this.task.specs,
capabilities: this.task.capabilities,
// The following are populated while running the test:
failedCount: 0,
exitCode: -1,
specResults: []
};
let configParser = new configParser_1.ConfigParser();
if (this.configFile) {
configParser.addFileConfig(this.configFile);
}
if (this.additionalConfig) {
configParser.addConfig(this.additionalConfig);
}
let config = configParser.getConfig();
config.capabilities = this.task.capabilities;
config.specs = this.task.specs;
if (this.runInFork) {
let deferred = q.defer();
let childProcess = child_process.fork(__dirname + '/runnerCli.js', process.argv.slice(2), { cwd: process.cwd(), silent: true });
let taskLogger = new taskLogger_1.TaskLogger(this.task, childProcess.pid);
// stdout pipe
childProcess.stdout.on('data', (data) => {
taskLogger.log(data);
});
// stderr pipe
childProcess.stderr.on('data', (data) => {
taskLogger.log(data);
});
childProcess
.on('message', (m) => {
if (config.verboseMultiSessions) {
taskLogger.peek();
}
switch (m.event) {
case 'testPass':
process.stdout.write('.');
break;
case 'testFail':
process.stdout.write('F');
break;
case 'testsDone':
runResults.failedCount = m.results.failedCount;
runResults.specResults = m.results.specResults;
break;
}
})
.on('error', (err) => {
taskLogger.flush();
deferred.reject(err);
})
.on('exit', (code) => {
taskLogger.flush();
runResults.exitCode = code;
deferred.resolve(runResults);
});
childProcess.send({
command: 'run',
configFile: this.configFile,
additionalConfig: this.additionalConfig,
capabilities: this.task.capabilities,
specs: this.task.specs
});
return deferred.promise;
}
else {
let runner = new runner_1.Runner(config);
runner.on('testsDone', (results) => {
runResults.failedCount = results.failedCount;
runResults.specResults = results.specResults;
});
return runner.run().then((exitCode) => {
runResults.exitCode = exitCode;
return runResults;
});
}
}
}
exports.TaskRunner = TaskRunner;
//# sourceMappingURL=taskRunner.js.map

61
node_modules/protractor/built/taskScheduler.d.ts generated vendored Normal file
View file

@ -0,0 +1,61 @@
import { Config } from './config';
export interface Task {
capabilities: any;
specs: Array<string>;
taskId: string;
done: any;
}
/**
* The taskScheduler keeps track of the spec files that needs to run next
* and which task is running what.
*/
export declare class TaskQueue {
capabilities: any;
specLists: any;
numRunningInstances: number;
maxInstance: number;
specsIndex: number;
constructor(capabilities: any, specLists: any);
}
export declare class TaskScheduler {
private config;
taskQueues: Array<TaskQueue>;
rotationIndex: number;
/**
* A scheduler to keep track of specs that need running and their associated
* capabilities. It will suggest a task (combination of capabilities and spec)
* to run while observing the following config rules:
* multiCapabilities, shardTestFiles, and maxInstance.
* Precondition: multiCapabilities is a non-empty array
* (capabilities and getCapabilities will both be ignored)
*
* @constructor
* @param {Object} config parsed from the config file
*/
constructor(config: Config);
/**
* Get the next task that is allowed to run without going over maxInstance.
*
* @return {{capabilities: Object, specs: Array.<string>, taskId: string,
* done: function()}}
*/
nextTask(): Task;
/**
* Get the number of tasks left to run or are currently running.
*
* @return {number}
*/
numTasksOutstanding(): number;
/**
* Get maximum number of concurrent tasks required/permitted.
*
* @return {number}
*/
maxConcurrentTasks(): number;
/**
* Returns number of tasks currently running.
*
* @return {number}
*/
countActiveTasks(): number;
}

146
node_modules/protractor/built/taskScheduler.js generated vendored Normal file
View file

@ -0,0 +1,146 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const configParser_1 = require("./configParser");
/**
* The taskScheduler keeps track of the spec files that needs to run next
* and which task is running what.
*/
class TaskQueue {
// A queue of specs for a particular capacity
constructor(capabilities, specLists) {
this.capabilities = capabilities;
this.specLists = specLists;
this.numRunningInstances = 0;
this.specsIndex = 0;
this.maxInstance = capabilities.maxInstances || 1;
}
}
exports.TaskQueue = TaskQueue;
class TaskScheduler {
/**
* A scheduler to keep track of specs that need running and their associated
* capabilities. It will suggest a task (combination of capabilities and spec)
* to run while observing the following config rules:
* multiCapabilities, shardTestFiles, and maxInstance.
* Precondition: multiCapabilities is a non-empty array
* (capabilities and getCapabilities will both be ignored)
*
* @constructor
* @param {Object} config parsed from the config file
*/
constructor(config) {
this.config = config;
let excludes = configParser_1.ConfigParser.resolveFilePatterns(config.exclude, true, config.configDir);
let allSpecs = configParser_1.ConfigParser.resolveFilePatterns(configParser_1.ConfigParser.getSpecs(config), false, config.configDir)
.filter((path) => {
return excludes.indexOf(path) < 0;
});
let taskQueues = [];
config.multiCapabilities.forEach((capabilities) => {
let capabilitiesSpecs = allSpecs;
if (capabilities.specs) {
let capabilitiesSpecificSpecs = configParser_1.ConfigParser.resolveFilePatterns(capabilities.specs, false, config.configDir);
capabilitiesSpecs = capabilitiesSpecs.concat(capabilitiesSpecificSpecs);
}
if (capabilities.exclude) {
let capabilitiesSpecExcludes = configParser_1.ConfigParser.resolveFilePatterns(capabilities.exclude, true, config.configDir);
capabilitiesSpecs = capabilitiesSpecs.filter((path) => {
return capabilitiesSpecExcludes.indexOf(path) < 0;
});
}
let specLists = [];
// If we shard, we return an array of one element arrays, each containing
// the spec file. If we don't shard, we return an one element array
// containing an array of all the spec files
if (capabilities.shardTestFiles) {
capabilitiesSpecs.forEach((spec) => {
specLists.push([spec]);
});
}
else {
specLists.push(capabilitiesSpecs);
}
capabilities.count = capabilities.count || 1;
for (let i = 0; i < capabilities.count; ++i) {
taskQueues.push(new TaskQueue(capabilities, specLists));
}
});
this.taskQueues = taskQueues;
this.rotationIndex = 0; // Helps suggestions to rotate amongst capabilities
}
/**
* Get the next task that is allowed to run without going over maxInstance.
*
* @return {{capabilities: Object, specs: Array.<string>, taskId: string,
* done: function()}}
*/
nextTask() {
for (let i = 0; i < this.taskQueues.length; ++i) {
let rotatedIndex = ((i + this.rotationIndex) % this.taskQueues.length);
let queue = this.taskQueues[rotatedIndex];
if (queue.numRunningInstances < queue.maxInstance &&
queue.specsIndex < queue.specLists.length) {
this.rotationIndex = rotatedIndex + 1;
++queue.numRunningInstances;
let taskId = '' + rotatedIndex + 1;
if (queue.specLists.length > 1) {
taskId += '-' + queue.specsIndex;
}
let specs = queue.specLists[queue.specsIndex];
++queue.specsIndex;
return {
capabilities: queue.capabilities,
specs: specs,
taskId: taskId,
done: function () {
--queue.numRunningInstances;
}
};
}
}
return null;
}
/**
* Get the number of tasks left to run or are currently running.
*
* @return {number}
*/
numTasksOutstanding() {
let count = 0;
this.taskQueues.forEach((queue) => {
count += queue.numRunningInstances + (queue.specLists.length - queue.specsIndex);
});
return count;
}
/**
* Get maximum number of concurrent tasks required/permitted.
*
* @return {number}
*/
maxConcurrentTasks() {
if (this.config.maxSessions && this.config.maxSessions > 0) {
return this.config.maxSessions;
}
else {
let count = 0;
this.taskQueues.forEach((queue) => {
count += Math.min(queue.maxInstance, queue.specLists.length);
});
return count;
}
}
/**
* Returns number of tasks currently running.
*
* @return {number}
*/
countActiveTasks() {
let count = 0;
this.taskQueues.forEach((queue) => {
count += queue.numRunningInstances;
});
return count;
}
}
exports.TaskScheduler = TaskScheduler;
//# sourceMappingURL=taskScheduler.js.map

40
node_modules/protractor/built/util.d.ts generated vendored Normal file
View file

@ -0,0 +1,40 @@
/// <reference types="q" />
import { Promise } from 'q';
/**
* Utility function that filters a stack trace to be more readable. It removes
* Jasmine test frames and webdriver promise resolution.
* @param {string} text Original stack trace.
* @return {string}
*/
export declare function filterStackTrace(text: string): string;
/**
* Internal helper for abstraction of polymorphic filenameOrFn properties.
* @param {object} filenameOrFn The filename or function that we will execute.
* @param {Array.<object>}} args The args to pass into filenameOrFn.
* @return {q.Promise} A promise that will resolve when filenameOrFn completes.
*/
export declare function runFilenameOrFn_(configDir: string, filenameOrFn: any, args?: any[]): Promise<any>;
/**
* Joins two logs of test results, each following the format of <framework>.run
* @param {object} log1
* @param {object} log2
* @return {object} The joined log
*/
export declare function joinTestLogs(log1: any, log2: any): any;
/**
* Returns false if an error indicates a missing or stale element, re-throws
* the error otherwise
*
* @param {*} The error to check
* @throws {*} The error it was passed if it doesn't indicate a missing or stale
* element
* @return {boolean} false, if it doesn't re-throw the error
*/
export declare function falseIfMissing(error: any): boolean;
/**
* Return a boolean given boolean value.
*
* @param {boolean} value
* @returns {boolean} given value
*/
export declare function passBoolean(value: boolean): boolean;

109
node_modules/protractor/built/util.js generated vendored Normal file
View file

@ -0,0 +1,109 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const q_1 = require("q");
const selenium_webdriver_1 = require("selenium-webdriver");
let STACK_SUBSTRINGS_TO_FILTER = [
'node_modules/jasmine/', 'node_modules/selenium-webdriver', 'at Module.', 'at Object.Module.',
'at Function.Module', '(timers.js:', 'jasminewd2/index.js', 'protractor/lib/'
];
/**
* Utility function that filters a stack trace to be more readable. It removes
* Jasmine test frames and webdriver promise resolution.
* @param {string} text Original stack trace.
* @return {string}
*/
function filterStackTrace(text) {
if (!text) {
return text;
}
let lines = text.split(/\n/).filter((line) => {
for (let filter of STACK_SUBSTRINGS_TO_FILTER) {
if (line.indexOf(filter) !== -1) {
return false;
}
}
return true;
});
return lines.join('\n');
}
exports.filterStackTrace = filterStackTrace;
/**
* Internal helper for abstraction of polymorphic filenameOrFn properties.
* @param {object} filenameOrFn The filename or function that we will execute.
* @param {Array.<object>}} args The args to pass into filenameOrFn.
* @return {q.Promise} A promise that will resolve when filenameOrFn completes.
*/
function runFilenameOrFn_(configDir, filenameOrFn, args) {
return q_1.Promise((resolvePromise) => {
if (filenameOrFn && !(typeof filenameOrFn === 'string' || typeof filenameOrFn === 'function')) {
throw new Error('filenameOrFn must be a string or function');
}
if (typeof filenameOrFn === 'string') {
filenameOrFn = require(path_1.resolve(configDir, filenameOrFn));
}
if (typeof filenameOrFn === 'function') {
let results = q_1.when(filenameOrFn.apply(null, args), null, (err) => {
if (typeof err === 'string') {
err = new Error(err);
}
else {
err = err;
if (!err.stack) {
err.stack = new Error().stack;
}
}
err.stack = exports.filterStackTrace(err.stack);
throw err;
});
resolvePromise(results);
}
else {
resolvePromise(undefined);
}
});
}
exports.runFilenameOrFn_ = runFilenameOrFn_;
/**
* Joins two logs of test results, each following the format of <framework>.run
* @param {object} log1
* @param {object} log2
* @return {object} The joined log
*/
function joinTestLogs(log1, log2) {
return {
failedCount: log1.failedCount + log2.failedCount,
specResults: (log1.specResults || []).concat(log2.specResults || [])
};
}
exports.joinTestLogs = joinTestLogs;
/**
* Returns false if an error indicates a missing or stale element, re-throws
* the error otherwise
*
* @param {*} The error to check
* @throws {*} The error it was passed if it doesn't indicate a missing or stale
* element
* @return {boolean} false, if it doesn't re-throw the error
*/
function falseIfMissing(error) {
if ((error instanceof selenium_webdriver_1.error.NoSuchElementError) ||
(error instanceof selenium_webdriver_1.error.StaleElementReferenceError)) {
return false;
}
else {
throw error;
}
}
exports.falseIfMissing = falseIfMissing;
/**
* Return a boolean given boolean value.
*
* @param {boolean} value
* @returns {boolean} given value
*/
function passBoolean(value) {
return value;
}
exports.passBoolean = passBoolean;
//# sourceMappingURL=util.js.map