Deployed the page to Github Pages.
This commit is contained in:
parent
1d79754e93
commit
2c89899458
62797 changed files with 6551425 additions and 15279 deletions
0
node_modules/protractor/built/cli.d.ts
generated
vendored
Normal file
0
node_modules/protractor/built/cli.d.ts
generated
vendored
Normal file
228
node_modules/protractor/built/cli.js
generated
vendored
Normal file
228
node_modules/protractor/built/cli.js
generated
vendored
Normal 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
939
node_modules/protractor/built/clientsidescripts.js
generated
vendored
Normal 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
50
node_modules/protractor/built/configParser.d.ts
generated
vendored
Normal 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
215
node_modules/protractor/built/configParser.js
generated
vendored
Normal 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
|
157
node_modules/protractor/built/debugger/clients/explorer.js
generated
vendored
Normal file
157
node_modules/protractor/built/debugger/clients/explorer.js
generated
vendored
Normal 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();
|
83
node_modules/protractor/built/debugger/clients/wddebugger.js
generated
vendored
Normal file
83
node_modules/protractor/built/debugger/clients/wddebugger.js
generated
vendored
Normal 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();
|
113
node_modules/protractor/built/debugger/debuggerCommons.js
generated
vendored
Normal file
113
node_modules/protractor/built/debugger/debuggerCommons.js
generated
vendored
Normal 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);
|
||||
};
|
127
node_modules/protractor/built/debugger/modes/commandRepl.js
generated
vendored
Normal file
127
node_modules/protractor/built/debugger/modes/commandRepl.js
generated
vendored
Normal 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;
|
143
node_modules/protractor/built/debugger/modes/debuggerRepl.js
generated
vendored
Normal file
143
node_modules/protractor/built/debugger/modes/debuggerRepl.js
generated
vendored
Normal 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;
|
27
node_modules/protractor/built/driverProviders/attachSession.d.ts
generated
vendored
Normal file
27
node_modules/protractor/built/driverProviders/attachSession.d.ts
generated
vendored
Normal 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>;
|
||||
}
|
51
node_modules/protractor/built/driverProviders/attachSession.js
generated
vendored
Normal file
51
node_modules/protractor/built/driverProviders/attachSession.js
generated
vendored
Normal 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
|
21
node_modules/protractor/built/driverProviders/browserStack.d.ts
generated
vendored
Normal file
21
node_modules/protractor/built/driverProviders/browserStack.d.ts
generated
vendored
Normal 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>;
|
||||
}
|
84
node_modules/protractor/built/driverProviders/browserStack.js
generated
vendored
Normal file
84
node_modules/protractor/built/driverProviders/browserStack.js
generated
vendored
Normal 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
|
22
node_modules/protractor/built/driverProviders/direct.d.ts
generated
vendored
Normal file
22
node_modules/protractor/built/driverProviders/direct.d.ts
generated
vendored
Normal 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
116
node_modules/protractor/built/driverProviders/direct.js
generated
vendored
Normal 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
|
65
node_modules/protractor/built/driverProviders/driverProvider.d.ts
generated
vendored
Normal file
65
node_modules/protractor/built/driverProviders/driverProvider.d.ts
generated
vendored
Normal 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>;
|
||||
}
|
131
node_modules/protractor/built/driverProviders/driverProvider.js
generated
vendored
Normal file
131
node_modules/protractor/built/driverProviders/driverProvider.js
generated
vendored
Normal 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
|
14
node_modules/protractor/built/driverProviders/hosted.d.ts
generated
vendored
Normal file
14
node_modules/protractor/built/driverProviders/hosted.d.ts
generated
vendored
Normal 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>;
|
||||
}
|
28
node_modules/protractor/built/driverProviders/hosted.js
generated
vendored
Normal file
28
node_modules/protractor/built/driverProviders/hosted.js
generated
vendored
Normal 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
|
15
node_modules/protractor/built/driverProviders/index.d.ts
generated
vendored
Normal file
15
node_modules/protractor/built/driverProviders/index.d.ts
generated
vendored
Normal 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
129
node_modules/protractor/built/driverProviders/index.js
generated
vendored
Normal 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
|
30
node_modules/protractor/built/driverProviders/local.d.ts
generated
vendored
Normal file
30
node_modules/protractor/built/driverProviders/local.d.ts
generated
vendored
Normal 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
165
node_modules/protractor/built/driverProviders/local.js
generated
vendored
Normal 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
|
29
node_modules/protractor/built/driverProviders/mock.d.ts
generated
vendored
Normal file
29
node_modules/protractor/built/driverProviders/mock.d.ts
generated
vendored
Normal 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
50
node_modules/protractor/built/driverProviders/mock.js
generated
vendored
Normal 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
|
29
node_modules/protractor/built/driverProviders/sauce.d.ts
generated
vendored
Normal file
29
node_modules/protractor/built/driverProviders/sauce.d.ts
generated
vendored
Normal 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
93
node_modules/protractor/built/driverProviders/sauce.js
generated
vendored
Normal 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
871
node_modules/protractor/built/element.d.ts
generated
vendored
Normal 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
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
32
node_modules/protractor/built/exitCodes.d.ts
generated
vendored
Normal 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
84
node_modules/protractor/built/exitCodes.js
generated
vendored
Normal 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
320
node_modules/protractor/built/expectedConditions.d.ts
generated
vendored
Normal 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 element’s
|
||||
* 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
424
node_modules/protractor/built/expectedConditions.js
generated
vendored
Normal 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 element’s
|
||||
* 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
22
node_modules/protractor/built/frameworks/debugprint.js
generated
vendored
Normal 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
24
node_modules/protractor/built/frameworks/explorer.js
generated
vendored
Normal 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
135
node_modules/protractor/built/frameworks/jasmine.js
generated
vendored
Normal 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
140
node_modules/protractor/built/frameworks/mocha.js
generated
vendored
Normal 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
2
node_modules/protractor/built/launcher.d.ts
generated
vendored
Normal 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
285
node_modules/protractor/built/launcher.js
generated
vendored
Normal 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
294
node_modules/protractor/built/locators.d.ts
generated
vendored
Normal 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
451
node_modules/protractor/built/locators.js
generated
vendored
Normal 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
101
node_modules/protractor/built/logger.d.ts
generated
vendored
Normal 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
275
node_modules/protractor/built/logger.js
generated
vendored
Normal 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
348
node_modules/protractor/built/plugins.d.ts
generated
vendored
Normal 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
225
node_modules/protractor/built/plugins.js
generated
vendored
Normal 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
104
node_modules/protractor/built/runner.d.ts
generated
vendored
Normal 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
445
node_modules/protractor/built/runner.js
generated
vendored
Normal 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
0
node_modules/protractor/built/runnerCli.d.ts
generated
vendored
Normal file
56
node_modules/protractor/built/runnerCli.js
generated
vendored
Normal file
56
node_modules/protractor/built/runnerCli.js
generated
vendored
Normal 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
|
216
node_modules/protractor/built/selenium-webdriver/locators.js
generated
vendored
Normal file
216
node_modules/protractor/built/selenium-webdriver/locators.js
generated
vendored
Normal 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');
|
765
node_modules/protractor/built/selenium-webdriver/webdriver.js
generated
vendored
Normal file
765
node_modules/protractor/built/selenium-webdriver/webdriver.js
generated
vendored
Normal 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
37
node_modules/protractor/built/taskLogger.d.ts
generated
vendored
Normal 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
92
node_modules/protractor/built/taskLogger.js
generated
vendored
Normal 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
40
node_modules/protractor/built/taskRunner.d.ts
generated
vendored
Normal 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
118
node_modules/protractor/built/taskRunner.js
generated
vendored
Normal 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
61
node_modules/protractor/built/taskScheduler.d.ts
generated
vendored
Normal 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
146
node_modules/protractor/built/taskScheduler.js
generated
vendored
Normal 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
40
node_modules/protractor/built/util.d.ts
generated
vendored
Normal 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
109
node_modules/protractor/built/util.js
generated
vendored
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue