Deployed the page to Github Pages.
This commit is contained in:
parent
1d79754e93
commit
2c89899458
62797 changed files with 6551425 additions and 15279 deletions
4288
node_modules/protractor/CHANGELOG.md
generated
vendored
Normal file
4288
node_modules/protractor/CHANGELOG.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
74
node_modules/protractor/CONTRIBUTING.md
generated
vendored
Normal file
74
node_modules/protractor/CONTRIBUTING.md
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
Contributing
|
||||
============
|
||||
|
||||
Questions
|
||||
---------
|
||||
|
||||
Please first read through the [FAQ](https://github.com/angular/protractor/blob/master/docs/faq.md).
|
||||
|
||||
Please ask questions on [StackOverflow](http://stackoverflow.com/questions/tagged/protractor), [Google Group discussion list](https://groups.google.com/forum/?fromgroups#!forum/angular), or [Gitter](https://gitter.im/angular/protractor).
|
||||
|
||||
Any questions posted to Protractor's Github Issues will be closed with this note:
|
||||
|
||||
Please direct general support questions like this one to an appropriate support channel, see https://github.com/angular/protractor/blob/master/CONTRIBUTING.md#questions
|
||||
|
||||
Thank you!
|
||||
|
||||
|
||||
Issues
|
||||
======
|
||||
|
||||
If you have a bug or feature request, please file an issue.
|
||||
Before submitting an issue, please search the issue archive to help reduce duplicates, and read the
|
||||
[FAQ](https://github.com/angular/protractor/blob/master/docs/faq.md).
|
||||
|
||||
Try running with troubleshooting messages (`protractor --troubleshoot`) against your configuration to make sure that there is not an error with your setup.
|
||||
|
||||
When submitting an issue, please include a reproducible case that we can actually run. Protractor has a test Angular application available at `http://www.protractortest.org/testapp` which you can use for the reproducible test case. If there's an error, please include the error text.
|
||||
|
||||
Please format code and markup in your issue using [github markdown](https://help.github.com/articles/github-flavored-markdown).
|
||||
|
||||
|
||||
Contributing to Source Code (Pull Requests)
|
||||
===========================================
|
||||
|
||||
Loosely, follow the [Angular contribution rules](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
|
||||
|
||||
* If your PR changes any behavior or fixes an issue, it should have an associated test.
|
||||
* New features should be general and as simple as possible.
|
||||
* Breaking changes should be avoided if possible.
|
||||
* All pull requests require review. No PR will be merged without a comment from a team member stating LGTM (Looks good to me).
|
||||
|
||||
Protractor specific rules
|
||||
-------------------------
|
||||
|
||||
* JavaScript style should generally follow the [Google JS style guide](https://google.github.io/styleguide/javascriptguide.xml).
|
||||
* Wrap code at 80 chars.
|
||||
* Document public methods with jsdoc.
|
||||
* Be consistent with the code around you!
|
||||
|
||||
Commit Messages
|
||||
---------------
|
||||
|
||||
Please write meaningful commit messages - they are used to generate the changelog, so the commit message should tell a user everything they need to know about a commit. Protractor follows AngularJS's [commit message format](https://docs.google.com/a/google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#heading=h.z8a3t6ehl060).
|
||||
|
||||
In summary, this style is
|
||||
|
||||
<type>(<scope>): <subject>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
|
||||
Where `<type>` is one of [feat, fix, docs, refactor, test, chore, deps] and
|
||||
`<scope>` is a quick descriptor of the location of the change, such as cli, clientSideScripts, element.
|
||||
|
||||
Testing your changes
|
||||
--------------------
|
||||
|
||||
Test your changes on your machine by running `npm start` to start up the test application,
|
||||
then `npm test` to run the test suite. This assumes you have a Selenium Server running
|
||||
at localhost:4444.
|
||||
|
||||
When you submit a PR, tests will also be run on the Continuous Integration environment
|
||||
through Travis. If your tests fail on Travis, take a look at the logs - if the failures
|
||||
are known flakes in Internet Explorer or Safari you can ignore them, but otherwise
|
||||
Travis should pass.
|
21
node_modules/protractor/LICENSE
generated
vendored
Normal file
21
node_modules/protractor/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2017 Google, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
37
node_modules/protractor/README.md
generated
vendored
Normal file
37
node_modules/protractor/README.md
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
Protractor [](https://travis-ci.org/angular/protractor) [](https://circleci.com/gh/angular/protractor) [](https://gitter.im/angular/protractor)
|
||||
==========
|
||||
|
||||
[Protractor](http://angular.github.io/protractor) is an end-to-end test framework for [Angular](http://angular.io/) and [AngularJS](http://angularjs.org) applications. Protractor is a [Node.js](http://nodejs.org/) program built on top of [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs). Protractor runs tests against your application running in a real browser, interacting with it as a user would.
|
||||
|
||||
Compatibility
|
||||
-------------
|
||||
|
||||
Protractor 5 is compatible with nodejs v6 and newer.
|
||||
|
||||
Protractor works with AngularJS versions greater than 1.0.6/1.1.4, and is compatible with Angular applications. Note that for Angular apps, the `binding` and `model` locators are not supported. We recommend using `by.css`.
|
||||
|
||||
|
||||
Getting Started
|
||||
---------------
|
||||
See the [Protractor Website](http://www.protractortest.org) for most documentation.
|
||||
|
||||
To get set up and running quickly:
|
||||
- Work through the [Tutorial](http://www.protractortest.org/#/tutorial)
|
||||
- See the [API](http://www.protractortest.org/#/api)
|
||||
|
||||
Once you are familiar with the tutorial, you’re ready to move on. To modify your environment, see the Protractor Setup docs. To start writing tests, see the Protractor Tests docs.
|
||||
|
||||
To better understand how Protractor works with the Selenium WebDriver and Selenium Server see the reference materials.
|
||||
|
||||
|
||||
Getting Help
|
||||
------------
|
||||
|
||||
Check the [Protractor FAQ](https://github.com/angular/protractor/blob/master/docs/faq.md) and read through the [Top 20 questions on StackOverflow](http://stackoverflow.com/questions/tagged/protractor?sort=votes&pageSize=20).
|
||||
|
||||
Please ask usage and debugging questions on [StackOverflow](http://stackoverflow.com/questions/tagged/protractor) (use the ["protractor"](http://stackoverflow.com/questions/ask?tags=protractor) tag), the [Gitter](https://gitter.im/angular/protractor) chat room, or in the [Angular discussion group](https://groups.google.com/forum/?fromgroups#!forum/angular). (Please do not ask support questions here on Github.)
|
||||
|
||||
|
||||
For Contributors
|
||||
----------------
|
||||
See [DEVELOPER.md](https://github.com/angular/protractor/blob/master/DEVELOPER.md)
|
46
node_modules/protractor/bin/elementexplorer.js
generated
vendored
Executable file
46
node_modules/protractor/bin/elementexplorer.js
generated
vendored
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* This is an explorer to help get the right element locators, and test out what
|
||||
* Protractor commands will do on your site without running a full test suite.
|
||||
*
|
||||
* This beta version only uses the Chrome browser.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* Expects a selenium standalone server to be running at http://localhost:4444
|
||||
* from protractor directory, run with:
|
||||
*
|
||||
* ./bin/elementexplorer.js <urL>
|
||||
*
|
||||
* This will load up the URL on webdriver and put the terminal into a REPL loop.
|
||||
* You will see a > prompt. The `browser`, `element` and `protractor` variables
|
||||
* will be available. Enter a command such as:
|
||||
*
|
||||
* > element(by.id('foobar')).getText()
|
||||
*
|
||||
* or
|
||||
*
|
||||
* > browser.get('http://www.angularjs.org')
|
||||
*
|
||||
* try just
|
||||
*
|
||||
* > browser
|
||||
*
|
||||
* to get a list of functions you can call.
|
||||
*
|
||||
* Typing tab at a blank prompt will fill in a suggestion for finding
|
||||
* elements.
|
||||
*/
|
||||
console.log('Please use "protractor [configFile] [options] --elementExplorer"' +
|
||||
' for full functionality\n');
|
||||
|
||||
if (process.argv.length > 3) {
|
||||
console.log('usage: elementexplorer.js [url]');
|
||||
process.exit(1);
|
||||
} else if (process.argv.length === 3) {
|
||||
process.argv[2] = ('--baseUrl=' + process.argv[2]);
|
||||
}
|
||||
|
||||
process.argv.push('--elementExplorer');
|
||||
require('../built/cli.js');
|
5
node_modules/protractor/bin/protractor
generated
vendored
Executable file
5
node_modules/protractor/bin/protractor
generated
vendored
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || 'test';
|
||||
|
||||
require('../built/cli.js');
|
3
node_modules/protractor/bin/webdriver-manager
generated
vendored
Executable file
3
node_modules/protractor/bin/webdriver-manager
generated
vendored
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
require('webdriver-manager');
|
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
|
21
node_modules/protractor/example/conf.js
generated
vendored
Normal file
21
node_modules/protractor/example/conf.js
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
// An example configuration file.
|
||||
exports.config = {
|
||||
directConnect: true,
|
||||
|
||||
// Capabilities to be passed to the webdriver instance.
|
||||
capabilities: {
|
||||
'browserName': 'chrome'
|
||||
},
|
||||
|
||||
// Framework to use. Jasmine is recommended.
|
||||
framework: 'jasmine',
|
||||
|
||||
// Spec patterns are relative to the current working directory when
|
||||
// protractor is called.
|
||||
specs: ['example_spec.js'],
|
||||
|
||||
// Options to be passed to Jasmine.
|
||||
jasmineNodeOpts: {
|
||||
defaultTimeoutInterval: 30000
|
||||
}
|
||||
};
|
37
node_modules/protractor/example/example_spec.js
generated
vendored
Normal file
37
node_modules/protractor/example/example_spec.js
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
describe('angularjs homepage', function() {
|
||||
it('should greet the named user', function() {
|
||||
browser.get('http://www.angularjs.org');
|
||||
|
||||
element(by.model('yourName')).sendKeys('Julie');
|
||||
|
||||
var greeting = element(by.binding('yourName'));
|
||||
|
||||
expect(greeting.getText()).toEqual('Hello Julie!');
|
||||
});
|
||||
|
||||
describe('todo list', function() {
|
||||
var todoList;
|
||||
|
||||
beforeEach(function() {
|
||||
browser.get('http://www.angularjs.org');
|
||||
|
||||
todoList = element.all(by.repeater('todo in todoList.todos'));
|
||||
});
|
||||
|
||||
it('should list todos', function() {
|
||||
expect(todoList.count()).toEqual(2);
|
||||
expect(todoList.get(1).getText()).toEqual('build an AngularJS app');
|
||||
});
|
||||
|
||||
it('should add a todo', function() {
|
||||
var addTodo = element(by.model('todoList.todoText'));
|
||||
var addButton = element(by.css('[value="add"]'));
|
||||
|
||||
addTodo.sendKeys('write a protractor test');
|
||||
addButton.click();
|
||||
|
||||
expect(todoList.count()).toEqual(3);
|
||||
expect(todoList.get(2).getText()).toEqual('write a protractor test');
|
||||
});
|
||||
});
|
||||
});
|
100
node_modules/protractor/gulpfile.js
generated
vendored
Normal file
100
node_modules/protractor/gulpfile.js
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
'use strict';
|
||||
|
||||
const gulp = require('gulp');
|
||||
const format = require('gulp-clang-format');
|
||||
const clangFormat = require('clang-format');
|
||||
const spawn = require('child_process').spawn;
|
||||
const tslint = require('gulp-tslint');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const semver = require('semver');
|
||||
|
||||
const runSpawn = (done, task, opt_arg, opt_io) => {
|
||||
opt_arg = typeof opt_arg !== 'undefined' ? opt_arg : [];
|
||||
const stdio = 'inherit';
|
||||
if (opt_io === 'ignore') {
|
||||
stdio = 'ignore';
|
||||
}
|
||||
const child = spawn(task, opt_arg, {stdio: stdio});
|
||||
let running = false;
|
||||
child.on('close', () => {
|
||||
if (!running) {
|
||||
running = true;
|
||||
done();
|
||||
}
|
||||
});
|
||||
child.on('error', () => {
|
||||
if (!running) {
|
||||
console.error('gulp encountered a child error');
|
||||
running = true;
|
||||
done();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
gulp.task('tslint', () => {
|
||||
return gulp.src(['lib/**/*.ts', 'spec/**/*.ts', '!spec/install/**/*.ts'])
|
||||
.pipe(tslint())
|
||||
.pipe(tslint.report());
|
||||
});
|
||||
|
||||
gulp.task('format:enforce', () => {
|
||||
return gulp.src(['lib/**/*.ts'])
|
||||
.pipe(format.checkFormat('file', clangFormat,
|
||||
{verbose: true, fail: true}));
|
||||
});
|
||||
|
||||
gulp.task('lint', gulp.series('tslint', 'format:enforce'));
|
||||
|
||||
// prevent contributors from using the wrong version of node
|
||||
gulp.task('checkVersion', (done) => {
|
||||
// read minimum node on package.json
|
||||
const packageJson = JSON.parse(fs.readFileSync(path.resolve('package.json')));
|
||||
const protractorVersion = packageJson.version;
|
||||
const nodeVersion = packageJson.engines.node;
|
||||
|
||||
if (semver.satisfies(process.version, nodeVersion)) {
|
||||
done();
|
||||
} else {
|
||||
throw new Error('minimum node version for Protractor ' +
|
||||
protractorVersion + ' is node ' + nodeVersion);
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task('built:copy', () => {
|
||||
return gulp.src(['lib/**/*.js'])
|
||||
.pipe(gulp.dest('built/'));
|
||||
});
|
||||
|
||||
gulp.task('built:copy:typings', () => {
|
||||
return gulp.src(['lib/selenium-webdriver/**/*.d.ts'])
|
||||
.pipe(gulp.dest('built/selenium-webdriver/'));
|
||||
});
|
||||
|
||||
gulp.task('webdriver:update', (done) => {
|
||||
runSpawn(done, 'node', ['bin/webdriver-manager', 'update',
|
||||
'--versions.chrome=2.44']);
|
||||
});
|
||||
|
||||
gulp.task('format', () => {
|
||||
return gulp.src(['lib/**/*.ts'], { base: '.' })
|
||||
.pipe(format.format('file', clangFormat))
|
||||
.pipe(gulp.dest('.'));
|
||||
});
|
||||
|
||||
gulp.task('tsc', (done) => {
|
||||
runSpawn(done, 'node', ['node_modules/typescript/bin/tsc']);
|
||||
});
|
||||
|
||||
gulp.task('tsc:spec', (done) => {
|
||||
runSpawn(done, 'node', ['node_modules/typescript/bin/tsc', '-p', 'ts_spec_config.json']);
|
||||
});
|
||||
|
||||
gulp.task('prepublish', gulp.series('checkVersion', 'tsc', 'built:copy'));
|
||||
|
||||
gulp.task('pretest', gulp.series(
|
||||
'checkVersion',
|
||||
gulp.parallel('webdriver:update', 'tslint', 'format'),
|
||||
'tsc', 'built:copy', 'built:copy:typings', 'tsc:spec'));
|
||||
|
||||
gulp.task('default', gulp.series('prepublish'));
|
4
node_modules/protractor/node_modules/ansi-regex/index.js
generated
vendored
Normal file
4
node_modules/protractor/node_modules/ansi-regex/index.js
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
'use strict';
|
||||
module.exports = function () {
|
||||
return /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]/g;
|
||||
};
|
21
node_modules/protractor/node_modules/ansi-regex/license
generated
vendored
Normal file
21
node_modules/protractor/node_modules/ansi-regex/license
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
64
node_modules/protractor/node_modules/ansi-regex/package.json
generated
vendored
Normal file
64
node_modules/protractor/node_modules/ansi-regex/package.json
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"name": "ansi-regex",
|
||||
"version": "2.1.1",
|
||||
"description": "Regular expression for matching ANSI escape codes",
|
||||
"license": "MIT",
|
||||
"repository": "chalk/ansi-regex",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"maintainers": [
|
||||
"Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)",
|
||||
"Joshua Appelman <jappelman@xebia.com> (jbnicolai.com)",
|
||||
"JD Ballard <i.am.qix@gmail.com> (github.com/qix-)"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava --verbose",
|
||||
"view-supported": "node fixtures/view-codes.js"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"ansi",
|
||||
"styles",
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"tty",
|
||||
"escape",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"command-line",
|
||||
"text",
|
||||
"regex",
|
||||
"regexp",
|
||||
"re",
|
||||
"match",
|
||||
"test",
|
||||
"find",
|
||||
"pattern"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "0.17.0",
|
||||
"xo": "0.16.0"
|
||||
},
|
||||
"xo": {
|
||||
"rules": {
|
||||
"guard-for-in": 0,
|
||||
"no-loop-func": 0
|
||||
}
|
||||
}
|
||||
}
|
39
node_modules/protractor/node_modules/ansi-regex/readme.md
generated
vendored
Normal file
39
node_modules/protractor/node_modules/ansi-regex/readme.md
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
# ansi-regex [](https://travis-ci.org/chalk/ansi-regex)
|
||||
|
||||
> Regular expression for matching [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save ansi-regex
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const ansiRegex = require('ansi-regex');
|
||||
|
||||
ansiRegex().test('\u001b[4mcake\u001b[0m');
|
||||
//=> true
|
||||
|
||||
ansiRegex().test('cake');
|
||||
//=> false
|
||||
|
||||
'\u001b[4mcake\u001b[0m'.match(ansiRegex());
|
||||
//=> ['\u001b[4m', '\u001b[0m']
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### Why do you test for codes not in the ECMA 48 standard?
|
||||
|
||||
Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. If I recall correctly, we test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them.
|
||||
|
||||
On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
65
node_modules/protractor/node_modules/ansi-styles/index.js
generated
vendored
Normal file
65
node_modules/protractor/node_modules/ansi-styles/index.js
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
'use strict';
|
||||
|
||||
function assembleStyles () {
|
||||
var styles = {
|
||||
modifiers: {
|
||||
reset: [0, 0],
|
||||
bold: [1, 22], // 21 isn't widely supported and 22 does the same thing
|
||||
dim: [2, 22],
|
||||
italic: [3, 23],
|
||||
underline: [4, 24],
|
||||
inverse: [7, 27],
|
||||
hidden: [8, 28],
|
||||
strikethrough: [9, 29]
|
||||
},
|
||||
colors: {
|
||||
black: [30, 39],
|
||||
red: [31, 39],
|
||||
green: [32, 39],
|
||||
yellow: [33, 39],
|
||||
blue: [34, 39],
|
||||
magenta: [35, 39],
|
||||
cyan: [36, 39],
|
||||
white: [37, 39],
|
||||
gray: [90, 39]
|
||||
},
|
||||
bgColors: {
|
||||
bgBlack: [40, 49],
|
||||
bgRed: [41, 49],
|
||||
bgGreen: [42, 49],
|
||||
bgYellow: [43, 49],
|
||||
bgBlue: [44, 49],
|
||||
bgMagenta: [45, 49],
|
||||
bgCyan: [46, 49],
|
||||
bgWhite: [47, 49]
|
||||
}
|
||||
};
|
||||
|
||||
// fix humans
|
||||
styles.colors.grey = styles.colors.gray;
|
||||
|
||||
Object.keys(styles).forEach(function (groupName) {
|
||||
var group = styles[groupName];
|
||||
|
||||
Object.keys(group).forEach(function (styleName) {
|
||||
var style = group[styleName];
|
||||
|
||||
styles[styleName] = group[styleName] = {
|
||||
open: '\u001b[' + style[0] + 'm',
|
||||
close: '\u001b[' + style[1] + 'm'
|
||||
};
|
||||
});
|
||||
|
||||
Object.defineProperty(styles, groupName, {
|
||||
value: group,
|
||||
enumerable: false
|
||||
});
|
||||
});
|
||||
|
||||
return styles;
|
||||
}
|
||||
|
||||
Object.defineProperty(module, 'exports', {
|
||||
enumerable: true,
|
||||
get: assembleStyles
|
||||
});
|
21
node_modules/protractor/node_modules/ansi-styles/license
generated
vendored
Normal file
21
node_modules/protractor/node_modules/ansi-styles/license
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
50
node_modules/protractor/node_modules/ansi-styles/package.json
generated
vendored
Normal file
50
node_modules/protractor/node_modules/ansi-styles/package.json
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"name": "ansi-styles",
|
||||
"version": "2.2.1",
|
||||
"description": "ANSI escape codes for styling strings in the terminal",
|
||||
"license": "MIT",
|
||||
"repository": "chalk/ansi-styles",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"maintainers": [
|
||||
"Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)",
|
||||
"Joshua Appelman <jappelman@xebia.com> (jbnicolai.com)"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"ansi",
|
||||
"styles",
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"tty",
|
||||
"escape",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"log",
|
||||
"logging",
|
||||
"command-line",
|
||||
"text"
|
||||
],
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
}
|
||||
}
|
86
node_modules/protractor/node_modules/ansi-styles/readme.md
generated
vendored
Normal file
86
node_modules/protractor/node_modules/ansi-styles/readme.md
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
# ansi-styles [](https://travis-ci.org/chalk/ansi-styles)
|
||||
|
||||
> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal
|
||||
|
||||
You probably want the higher-level [chalk](https://github.com/chalk/chalk) module for styling your strings.
|
||||
|
||||

|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save ansi-styles
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var ansi = require('ansi-styles');
|
||||
|
||||
console.log(ansi.green.open + 'Hello world!' + ansi.green.close);
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
Each style has an `open` and `close` property.
|
||||
|
||||
|
||||
## Styles
|
||||
|
||||
### Modifiers
|
||||
|
||||
- `reset`
|
||||
- `bold`
|
||||
- `dim`
|
||||
- `italic` *(not widely supported)*
|
||||
- `underline`
|
||||
- `inverse`
|
||||
- `hidden`
|
||||
- `strikethrough` *(not widely supported)*
|
||||
|
||||
### Colors
|
||||
|
||||
- `black`
|
||||
- `red`
|
||||
- `green`
|
||||
- `yellow`
|
||||
- `blue`
|
||||
- `magenta`
|
||||
- `cyan`
|
||||
- `white`
|
||||
- `gray`
|
||||
|
||||
### Background colors
|
||||
|
||||
- `bgBlack`
|
||||
- `bgRed`
|
||||
- `bgGreen`
|
||||
- `bgYellow`
|
||||
- `bgBlue`
|
||||
- `bgMagenta`
|
||||
- `bgCyan`
|
||||
- `bgWhite`
|
||||
|
||||
|
||||
## Advanced usage
|
||||
|
||||
By default you get a map of styles, but the styles are also available as groups. They are non-enumerable so they don't show up unless you access them explicitly. This makes it easier to expose only a subset in a higher-level module.
|
||||
|
||||
- `ansi.modifiers`
|
||||
- `ansi.colors`
|
||||
- `ansi.bgColors`
|
||||
|
||||
|
||||
###### Example
|
||||
|
||||
```js
|
||||
console.log(ansi.colors.green.open);
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
116
node_modules/protractor/node_modules/chalk/index.js
generated
vendored
Normal file
116
node_modules/protractor/node_modules/chalk/index.js
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
'use strict';
|
||||
var escapeStringRegexp = require('escape-string-regexp');
|
||||
var ansiStyles = require('ansi-styles');
|
||||
var stripAnsi = require('strip-ansi');
|
||||
var hasAnsi = require('has-ansi');
|
||||
var supportsColor = require('supports-color');
|
||||
var defineProps = Object.defineProperties;
|
||||
var isSimpleWindowsTerm = process.platform === 'win32' && !/^xterm/i.test(process.env.TERM);
|
||||
|
||||
function Chalk(options) {
|
||||
// detect mode if not set manually
|
||||
this.enabled = !options || options.enabled === undefined ? supportsColor : options.enabled;
|
||||
}
|
||||
|
||||
// use bright blue on Windows as the normal blue color is illegible
|
||||
if (isSimpleWindowsTerm) {
|
||||
ansiStyles.blue.open = '\u001b[94m';
|
||||
}
|
||||
|
||||
var styles = (function () {
|
||||
var ret = {};
|
||||
|
||||
Object.keys(ansiStyles).forEach(function (key) {
|
||||
ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
|
||||
|
||||
ret[key] = {
|
||||
get: function () {
|
||||
return build.call(this, this._styles.concat(key));
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return ret;
|
||||
})();
|
||||
|
||||
var proto = defineProps(function chalk() {}, styles);
|
||||
|
||||
function build(_styles) {
|
||||
var builder = function () {
|
||||
return applyStyle.apply(builder, arguments);
|
||||
};
|
||||
|
||||
builder._styles = _styles;
|
||||
builder.enabled = this.enabled;
|
||||
// __proto__ is used because we must return a function, but there is
|
||||
// no way to create a function with a different prototype.
|
||||
/* eslint-disable no-proto */
|
||||
builder.__proto__ = proto;
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
function applyStyle() {
|
||||
// support varags, but simply cast to string in case there's only one arg
|
||||
var args = arguments;
|
||||
var argsLen = args.length;
|
||||
var str = argsLen !== 0 && String(arguments[0]);
|
||||
|
||||
if (argsLen > 1) {
|
||||
// don't slice `arguments`, it prevents v8 optimizations
|
||||
for (var a = 1; a < argsLen; a++) {
|
||||
str += ' ' + args[a];
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.enabled || !str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
var nestedStyles = this._styles;
|
||||
var i = nestedStyles.length;
|
||||
|
||||
// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
|
||||
// see https://github.com/chalk/chalk/issues/58
|
||||
// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop.
|
||||
var originalDim = ansiStyles.dim.open;
|
||||
if (isSimpleWindowsTerm && (nestedStyles.indexOf('gray') !== -1 || nestedStyles.indexOf('grey') !== -1)) {
|
||||
ansiStyles.dim.open = '';
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
var code = ansiStyles[nestedStyles[i]];
|
||||
|
||||
// Replace any instances already present with a re-opening code
|
||||
// otherwise only the part of the string until said closing code
|
||||
// will be colored, and the rest will simply be 'plain'.
|
||||
str = code.open + str.replace(code.closeRe, code.open) + code.close;
|
||||
}
|
||||
|
||||
// Reset the original 'dim' if we changed it to work around the Windows dimmed gray issue.
|
||||
ansiStyles.dim.open = originalDim;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function init() {
|
||||
var ret = {};
|
||||
|
||||
Object.keys(styles).forEach(function (name) {
|
||||
ret[name] = {
|
||||
get: function () {
|
||||
return build.call(this, [name]);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
defineProps(Chalk.prototype, init());
|
||||
|
||||
module.exports = new Chalk();
|
||||
module.exports.styles = ansiStyles;
|
||||
module.exports.hasColor = hasAnsi;
|
||||
module.exports.stripColor = stripAnsi;
|
||||
module.exports.supportsColor = supportsColor;
|
21
node_modules/protractor/node_modules/chalk/license
generated
vendored
Normal file
21
node_modules/protractor/node_modules/chalk/license
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
70
node_modules/protractor/node_modules/chalk/package.json
generated
vendored
Normal file
70
node_modules/protractor/node_modules/chalk/package.json
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"name": "chalk",
|
||||
"version": "1.1.3",
|
||||
"description": "Terminal string styling done right. Much color.",
|
||||
"license": "MIT",
|
||||
"repository": "chalk/chalk",
|
||||
"maintainers": [
|
||||
"Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)",
|
||||
"Joshua Appelman <jappelman@xebia.com> (jbnicolai.com)",
|
||||
"JD Ballard <i.am.qix@gmail.com> (github.com/qix-)"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && mocha",
|
||||
"bench": "matcha benchmark.js",
|
||||
"coverage": "nyc npm test && nyc report",
|
||||
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"str",
|
||||
"ansi",
|
||||
"style",
|
||||
"styles",
|
||||
"tty",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"log",
|
||||
"logging",
|
||||
"command-line",
|
||||
"text"
|
||||
],
|
||||
"dependencies": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.11.2",
|
||||
"matcha": "^0.6.0",
|
||||
"mocha": "*",
|
||||
"nyc": "^3.0.0",
|
||||
"require-uncached": "^1.0.2",
|
||||
"resolve-from": "^1.0.0",
|
||||
"semver": "^4.3.3",
|
||||
"xo": "*"
|
||||
},
|
||||
"xo": {
|
||||
"envs": [
|
||||
"node",
|
||||
"mocha"
|
||||
]
|
||||
}
|
||||
}
|
213
node_modules/protractor/node_modules/chalk/readme.md
generated
vendored
Normal file
213
node_modules/protractor/node_modules/chalk/readme.md
generated
vendored
Normal file
|
@ -0,0 +1,213 @@
|
|||
<h1 align="center">
|
||||
<br>
|
||||
<br>
|
||||
<img width="360" src="https://cdn.rawgit.com/chalk/chalk/19935d6484811c5e468817f846b7b3d417d7bf4a/logo.svg" alt="chalk">
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
> Terminal string styling done right
|
||||
|
||||
[](https://travis-ci.org/chalk/chalk)
|
||||
[](https://coveralls.io/r/chalk/chalk?branch=master)
|
||||
[](https://www.youtube.com/watch?v=9auOCbH5Ns4)
|
||||
|
||||
|
||||
[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68). Although there are other ones, they either do too much or not enough.
|
||||
|
||||
**Chalk is a clean and focused alternative.**
|
||||
|
||||

|
||||
|
||||
|
||||
## Why
|
||||
|
||||
- Highly performant
|
||||
- Doesn't extend `String.prototype`
|
||||
- Expressive API
|
||||
- Ability to nest styles
|
||||
- Clean and focused
|
||||
- Auto-detects color support
|
||||
- Actively maintained
|
||||
- [Used by ~4500 modules](https://www.npmjs.com/browse/depended/chalk) as of July 15, 2015
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save chalk
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
|
||||
|
||||
```js
|
||||
var chalk = require('chalk');
|
||||
|
||||
// style a string
|
||||
chalk.blue('Hello world!');
|
||||
|
||||
// combine styled and normal strings
|
||||
chalk.blue('Hello') + 'World' + chalk.red('!');
|
||||
|
||||
// compose multiple styles using the chainable API
|
||||
chalk.blue.bgRed.bold('Hello world!');
|
||||
|
||||
// pass in multiple arguments
|
||||
chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz');
|
||||
|
||||
// nest styles
|
||||
chalk.red('Hello', chalk.underline.bgBlue('world') + '!');
|
||||
|
||||
// nest styles of the same type even (color, underline, background)
|
||||
chalk.green(
|
||||
'I am a green line ' +
|
||||
chalk.blue.underline.bold('with a blue substring') +
|
||||
' that becomes green again!'
|
||||
);
|
||||
```
|
||||
|
||||
Easily define your own themes.
|
||||
|
||||
```js
|
||||
var chalk = require('chalk');
|
||||
var error = chalk.bold.red;
|
||||
console.log(error('Error!'));
|
||||
```
|
||||
|
||||
Take advantage of console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data).
|
||||
|
||||
```js
|
||||
var name = 'Sindre';
|
||||
console.log(chalk.green('Hello %s'), name);
|
||||
//=> Hello Sindre
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### chalk.`<style>[.<style>...](string, [string...])`
|
||||
|
||||
Example: `chalk.red.bold.underline('Hello', 'world');`
|
||||
|
||||
Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter, and later styles take precedent in case of a conflict. This simply means that `Chalk.red.yellow.green` is equivalent to `Chalk.green`.
|
||||
|
||||
Multiple arguments will be separated by space.
|
||||
|
||||
### chalk.enabled
|
||||
|
||||
Color support is automatically detected, but you can override it by setting the `enabled` property. You should however only do this in your own code as it applies globally to all chalk consumers.
|
||||
|
||||
If you need to change this in a reusable module create a new instance:
|
||||
|
||||
```js
|
||||
var ctx = new chalk.constructor({enabled: false});
|
||||
```
|
||||
|
||||
### chalk.supportsColor
|
||||
|
||||
Detect whether the terminal [supports color](https://github.com/chalk/supports-color). Used internally and handled for you, but exposed for convenience.
|
||||
|
||||
Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, add an environment variable `FORCE_COLOR` with any value to force color. Trumps `--no-color`.
|
||||
|
||||
### chalk.styles
|
||||
|
||||
Exposes the styles as [ANSI escape codes](https://github.com/chalk/ansi-styles).
|
||||
|
||||
Generally not useful, but you might need just the `.open` or `.close` escape code if you're mixing externally styled strings with your own.
|
||||
|
||||
```js
|
||||
var chalk = require('chalk');
|
||||
|
||||
console.log(chalk.styles.red);
|
||||
//=> {open: '\u001b[31m', close: '\u001b[39m'}
|
||||
|
||||
console.log(chalk.styles.red.open + 'Hello' + chalk.styles.red.close);
|
||||
```
|
||||
|
||||
### chalk.hasColor(string)
|
||||
|
||||
Check whether a string [has color](https://github.com/chalk/has-ansi).
|
||||
|
||||
### chalk.stripColor(string)
|
||||
|
||||
[Strip color](https://github.com/chalk/strip-ansi) from a string.
|
||||
|
||||
Can be useful in combination with `.supportsColor` to strip color on externally styled text when it's not supported.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
var chalk = require('chalk');
|
||||
var styledString = getText();
|
||||
|
||||
if (!chalk.supportsColor) {
|
||||
styledString = chalk.stripColor(styledString);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Styles
|
||||
|
||||
### Modifiers
|
||||
|
||||
- `reset`
|
||||
- `bold`
|
||||
- `dim`
|
||||
- `italic` *(not widely supported)*
|
||||
- `underline`
|
||||
- `inverse`
|
||||
- `hidden`
|
||||
- `strikethrough` *(not widely supported)*
|
||||
|
||||
### Colors
|
||||
|
||||
- `black`
|
||||
- `red`
|
||||
- `green`
|
||||
- `yellow`
|
||||
- `blue` *(on Windows the bright version is used as normal blue is illegible)*
|
||||
- `magenta`
|
||||
- `cyan`
|
||||
- `white`
|
||||
- `gray`
|
||||
|
||||
### Background colors
|
||||
|
||||
- `bgBlack`
|
||||
- `bgRed`
|
||||
- `bgGreen`
|
||||
- `bgYellow`
|
||||
- `bgBlue`
|
||||
- `bgMagenta`
|
||||
- `bgCyan`
|
||||
- `bgWhite`
|
||||
|
||||
|
||||
## 256-colors
|
||||
|
||||
Chalk does not support anything other than the base eight colors, which guarantees it will work on all terminals and systems. Some terminals, specifically `xterm` compliant ones, will support the full range of 8-bit colors. For this the lower level [ansi-256-colors](https://github.com/jbnicolai/ansi-256-colors) package can be used.
|
||||
|
||||
|
||||
## Windows
|
||||
|
||||
If you're on Windows, do yourself a favor and use [`cmder`](http://bliker.github.io/cmder/) instead of `cmd.exe`.
|
||||
|
||||
|
||||
## Related
|
||||
|
||||
- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module
|
||||
- [ansi-styles](https://github.com/chalk/ansi-styles/) - ANSI escape codes for styling strings in the terminal
|
||||
- [supports-color](https://github.com/chalk/supports-color/) - Detect whether a terminal supports color
|
||||
- [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes
|
||||
- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes
|
||||
- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes
|
||||
- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
21
node_modules/protractor/node_modules/source-map-support/LICENSE.md
generated
vendored
Normal file
21
node_modules/protractor/node_modules/source-map-support/LICENSE.md
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Evan Wallace
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
251
node_modules/protractor/node_modules/source-map-support/README.md
generated
vendored
Normal file
251
node_modules/protractor/node_modules/source-map-support/README.md
generated
vendored
Normal file
|
@ -0,0 +1,251 @@
|
|||
# Source Map Support
|
||||
[](https://travis-ci.org/evanw/node-source-map-support)
|
||||
|
||||
This module provides source map support for stack traces in node via the [V8 stack trace API](https://github.com/v8/v8/wiki/Stack-Trace-API). It uses the [source-map](https://github.com/mozilla/source-map) module to replace the paths and line numbers of source-mapped files with their original paths and line numbers. The output mimics node's stack trace format with the goal of making every compile-to-JS language more of a first-class citizen. Source maps are completely general (not specific to any one language) so you can use source maps with multiple compile-to-JS languages in the same node process.
|
||||
|
||||
## Installation and Usage
|
||||
|
||||
#### Node support
|
||||
|
||||
```
|
||||
$ npm install source-map-support
|
||||
```
|
||||
|
||||
Source maps can be generated using libraries such as [source-map-index-generator](https://github.com/twolfson/source-map-index-generator). Once you have a valid source map, insert the following line at the top of your compiled code:
|
||||
|
||||
```js
|
||||
require('source-map-support').install();
|
||||
```
|
||||
|
||||
And place a source mapping comment somewhere in the file (usually done automatically or with an option by your transpiler):
|
||||
|
||||
```
|
||||
//# sourceMappingURL=path/to/source.map
|
||||
```
|
||||
|
||||
If multiple sourceMappingURL comments exist in one file, the last sourceMappingURL comment will be
|
||||
respected (e.g. if a file mentions the comment in code, or went through multiple transpilers).
|
||||
The path should either be absolute or relative to the compiled file.
|
||||
|
||||
It is also possible to to install the source map support directly by
|
||||
requiring the `register` module which can be handy with ES6:
|
||||
|
||||
```js
|
||||
import 'source-map-support/register'
|
||||
|
||||
// Instead of:
|
||||
import sourceMapSupport from 'source-map-support'
|
||||
sourceMapSupport.install()
|
||||
```
|
||||
Note: if you're using babel-register, it includes source-map-support already.
|
||||
|
||||
It is also very useful with Mocha:
|
||||
|
||||
```
|
||||
$ mocha --require source-map-support/register tests/
|
||||
```
|
||||
|
||||
#### Browser support
|
||||
|
||||
This library also works in Chrome. While the DevTools console already supports source maps, the V8 engine doesn't and `Error.prototype.stack` will be incorrect without this library. Everything will just work if you deploy your source files using [browserify](http://browserify.org/). Just make sure to pass the `--debug` flag to the browserify command so your source maps are included in the bundled code.
|
||||
|
||||
This library also works if you use another build process or just include the source files directly. In this case, include the file `browser-source-map-support.js` in your page and call `sourceMapSupport.install()`. It contains the whole library already bundled for the browser using browserify.
|
||||
|
||||
```html
|
||||
<script src="browser-source-map-support.js"></script>
|
||||
<script>sourceMapSupport.install();</script>
|
||||
```
|
||||
|
||||
This library also works if you use AMD (Asynchronous Module Definition), which is used in tools like [RequireJS](http://requirejs.org/). Just list `browser-source-map-support` as a dependency:
|
||||
|
||||
```html
|
||||
<script>
|
||||
define(['browser-source-map-support'], function(sourceMapSupport) {
|
||||
sourceMapSupport.install();
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
This module installs two things: a change to the `stack` property on `Error` objects and a handler for uncaught exceptions that mimics node's default exception handler (the handler can be seen in the demos below). You may want to disable the handler if you have your own uncaught exception handler. This can be done by passing an argument to the installer:
|
||||
|
||||
```js
|
||||
require('source-map-support').install({
|
||||
handleUncaughtExceptions: false
|
||||
});
|
||||
```
|
||||
|
||||
This module loads source maps from the filesystem by default. You can provide alternate loading behavior through a callback as shown below. For example, [Meteor](https://github.com/meteor) keeps all source maps cached in memory to avoid disk access.
|
||||
|
||||
```js
|
||||
require('source-map-support').install({
|
||||
retrieveSourceMap: function(source) {
|
||||
if (source === 'compiled.js') {
|
||||
return {
|
||||
url: 'original.js',
|
||||
map: fs.readFileSync('compiled.js.map', 'utf8')
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The module will by default assume a browser environment if XMLHttpRequest and window are defined. If either of these do not exist it will instead assume a node environment.
|
||||
In some rare cases, e.g. when running a browser emulation and where both variables are also set, you can explictly specify the environment to be either 'browser' or 'node'.
|
||||
|
||||
```js
|
||||
require('source-map-support').install({
|
||||
environment: 'node'
|
||||
});
|
||||
```
|
||||
|
||||
To support files with inline source maps, the `hookRequire` options can be specified, which will monitor all source files for inline source maps.
|
||||
|
||||
|
||||
```js
|
||||
require('source-map-support').install({
|
||||
hookRequire: true
|
||||
});
|
||||
```
|
||||
|
||||
This monkey patches the `require` module loading chain, so is not enabled by default and is not recommended for any sort of production usage.
|
||||
|
||||
## Demos
|
||||
|
||||
#### Basic Demo
|
||||
|
||||
original.js:
|
||||
|
||||
```js
|
||||
throw new Error('test'); // This is the original code
|
||||
```
|
||||
|
||||
compiled.js:
|
||||
|
||||
```js
|
||||
require('source-map-support').install();
|
||||
|
||||
throw new Error('test'); // This is the compiled code
|
||||
// The next line defines the sourceMapping.
|
||||
//# sourceMappingURL=compiled.js.map
|
||||
```
|
||||
|
||||
compiled.js.map:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 3,
|
||||
"file": "compiled.js",
|
||||
"sources": ["original.js"],
|
||||
"names": [],
|
||||
"mappings": ";;AAAA,MAAM,IAAI"
|
||||
}
|
||||
```
|
||||
|
||||
Run compiled.js using node (notice how the stack trace uses original.js instead of compiled.js):
|
||||
|
||||
```
|
||||
$ node compiled.js
|
||||
|
||||
original.js:1
|
||||
throw new Error('test'); // This is the original code
|
||||
^
|
||||
Error: test
|
||||
at Object.<anonymous> (original.js:1:7)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
at node.js:901:3
|
||||
```
|
||||
|
||||
#### TypeScript Demo
|
||||
|
||||
demo.ts:
|
||||
|
||||
```typescript
|
||||
declare function require(name: string);
|
||||
require('source-map-support').install();
|
||||
class Foo {
|
||||
constructor() { this.bar(); }
|
||||
bar() { throw new Error('this is a demo'); }
|
||||
}
|
||||
new Foo();
|
||||
```
|
||||
|
||||
Compile and run the file using the TypeScript compiler from the terminal:
|
||||
|
||||
```
|
||||
$ npm install source-map-support typescript
|
||||
$ node_modules/typescript/bin/tsc -sourcemap demo.ts
|
||||
$ node demo.js
|
||||
|
||||
demo.ts:5
|
||||
bar() { throw new Error('this is a demo'); }
|
||||
^
|
||||
Error: this is a demo
|
||||
at Foo.bar (demo.ts:5:17)
|
||||
at new Foo (demo.ts:4:24)
|
||||
at Object.<anonymous> (demo.ts:7:1)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
at node.js:901:3
|
||||
```
|
||||
|
||||
#### CoffeeScript Demo
|
||||
|
||||
demo.coffee:
|
||||
|
||||
```coffee
|
||||
require('source-map-support').install()
|
||||
foo = ->
|
||||
bar = -> throw new Error 'this is a demo'
|
||||
bar()
|
||||
foo()
|
||||
```
|
||||
|
||||
Compile and run the file using the CoffeeScript compiler from the terminal:
|
||||
|
||||
```sh
|
||||
$ npm install source-map-support coffee-script
|
||||
$ node_modules/coffee-script/bin/coffee --map --compile demo.coffee
|
||||
$ node demo.js
|
||||
|
||||
demo.coffee:3
|
||||
bar = -> throw new Error 'this is a demo'
|
||||
^
|
||||
Error: this is a demo
|
||||
at bar (demo.coffee:3:22)
|
||||
at foo (demo.coffee:4:3)
|
||||
at Object.<anonymous> (demo.coffee:5:1)
|
||||
at Object.<anonymous> (demo.coffee:1:1)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
This repo contains both automated tests for node and manual tests for the browser. The automated tests can be run using mocha (type `mocha` in the root directory). To run the manual tests:
|
||||
|
||||
* Build the tests using `build.js`
|
||||
* Launch the HTTP server (`npm run serve-tests`) and visit
|
||||
* http://127.0.0.1:1336/amd-test
|
||||
* http://127.0.0.1:1336/browser-test
|
||||
* http://127.0.0.1:1336/browserify-test - **Currently not working** due to a bug with browserify (see [pull request #66](https://github.com/evanw/node-source-map-support/pull/66) for details).
|
||||
* For `header-test`, run `server.js` inside that directory and visit http://127.0.0.1:1337/
|
||||
|
||||
## License
|
||||
|
||||
This code is available under the [MIT license](http://opensource.org/licenses/MIT).
|
110
node_modules/protractor/node_modules/source-map-support/browser-source-map-support.js
generated
vendored
Normal file
110
node_modules/protractor/node_modules/source-map-support/browser-source-map-support.js
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Support for source maps in V8 stack traces
|
||||
* https://github.com/evanw/node-source-map-support
|
||||
*/
|
||||
/*
|
||||
The buffer module from node.js, for the browser.
|
||||
|
||||
@author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
|
||||
license MIT
|
||||
*/
|
||||
(this.define||function(N,O){this.sourceMapSupport=O()})("browser-source-map-support",function(N){(function n(v,m,c){function d(e,a){if(!m[e]){if(!v[e]){var h="function"==typeof require&&require;if(!a&&h)return h(e,!0);if(k)return k(e,!0);throw Error("Cannot find module '"+e+"'");}h=m[e]={exports:{}};v[e][0].call(h.exports,function(a){var c=v[e][1][a];return d(c?c:a)},h,h.exports,n,v,m,c)}return m[e].exports}for(var k="function"==typeof require&&require,q=0;q<c.length;q++)d(c[q]);return d})({1:[function(n,
|
||||
v,m){N=n("./source-map-support")},{"./source-map-support":19}],2:[function(n,v,m){(function(c){function d(c){c=c.charCodeAt(0);if(43===c||45===c)return 62;if(47===c||95===c)return 63;if(48>c)return-1;if(58>c)return c-48+52;if(91>c)return c-65;if(123>c)return c-97+26}var k="undefined"!==typeof Uint8Array?Uint8Array:Array;c.toByteArray=function(c){function e(a){u[b++]=a}if(0<c.length%4)throw Error("Invalid string. Length must be a multiple of 4");var a=c.length;var h="="===c.charAt(a-2)?2:"="===c.charAt(a-
|
||||
1)?1:0;var u=new k(3*c.length/4-h);var r=0<h?c.length-4:c.length;var b=0;for(a=0;a<r;a+=4){var f=d(c.charAt(a))<<18|d(c.charAt(a+1))<<12|d(c.charAt(a+2))<<6|d(c.charAt(a+3));e((f&16711680)>>16);e((f&65280)>>8);e(f&255)}2===h?(f=d(c.charAt(a))<<2|d(c.charAt(a+1))>>4,e(f&255)):1===h&&(f=d(c.charAt(a))<<10|d(c.charAt(a+1))<<4|d(c.charAt(a+2))>>2,e(f>>8&255),e(f&255));return u};c.fromByteArray=function(c){var e=c.length%3,a="",h;var d=0;for(h=c.length-e;d<h;d+=3){var r=(c[d]<<16)+(c[d+1]<<8)+c[d+2];r=
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>18&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>12&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>6&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r&63);a+=r}switch(e){case 1:r=c[c.length-1];a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>2);a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<
|
||||
4&63);a+="==";break;case 2:r=(c[c.length-2]<<8)+c[c.length-1],a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>10),a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>4&63),a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<2&63),a+="="}return a}})("undefined"===typeof m?this.base64js={}:m)},{}],3:[function(n,v,m){},{}],4:[function(n,v,m){function c(g,l,b){if(!(this instanceof c))return new c(g,l,b);var x=typeof g;
|
||||
if("base64"===l&&"string"===x)for(g=g.trim?g.trim():g.replace(/^\s+|\s+$/g,"");0!==g.length%4;)g+="=";if("number"===x)var a=B(g);else if("string"===x)a=c.byteLength(g,l);else if("object"===x)a=B(g.length);else throw Error("First argument needs to be a number, array or string.");if(c._useTypedArrays)var f=c._augment(new Uint8Array(a));else f=this,f.length=a,f._isBuffer=!0;if(c._useTypedArrays&&"number"===typeof g.byteLength)f._set(g);else{var e=g;if(L(e)||c.isBuffer(e)||e&&"object"===typeof e&&"number"===
|
||||
typeof e.length)for(l=0;l<a;l++)c.isBuffer(g)?f[l]=g.readUInt8(l):f[l]=g[l];else if("string"===x)f.write(g,0,l);else if("number"===x&&!c._useTypedArrays&&!b)for(l=0;l<a;l++)f[l]=0}return f}function d(g,l,b){var x="";for(b=Math.min(g.length,b);l<b;l++)x+=String.fromCharCode(g[l]);return x}function k(g,l,b,a){a||(p("boolean"===typeof b,"missing or invalid endian"),p(void 0!==l&&null!==l,"missing offset"),p(l+1<g.length,"Trying to read beyond buffer length"));a=g.length;if(!(l>=a))return b?(b=g[l],l+
|
||||
1<a&&(b|=g[l+1]<<8)):(b=g[l]<<8,l+1<a&&(b|=g[l+1])),b}function q(g,l,b,a){a||(p("boolean"===typeof b,"missing or invalid endian"),p(void 0!==l&&null!==l,"missing offset"),p(l+3<g.length,"Trying to read beyond buffer length"));a=g.length;if(!(l>=a)){var x;b?(l+2<a&&(x=g[l+2]<<16),l+1<a&&(x|=g[l+1]<<8),x|=g[l],l+3<a&&(x+=g[l+3]<<24>>>0)):(l+1<a&&(x=g[l+1]<<16),l+2<a&&(x|=g[l+2]<<8),l+3<a&&(x|=g[l+3]),x+=g[l]<<24>>>0);return x}}function e(g,l,b,a){a||(p("boolean"===typeof b,"missing or invalid endian"),
|
||||
p(void 0!==l&&null!==l,"missing offset"),p(l+1<g.length,"Trying to read beyond buffer length"));if(!(l>=g.length))return g=k(g,l,b,!0),g&32768?-1*(65535-g+1):g}function a(g,l,b,a){a||(p("boolean"===typeof b,"missing or invalid endian"),p(void 0!==l&&null!==l,"missing offset"),p(l+3<g.length,"Trying to read beyond buffer length"));if(!(l>=g.length))return g=q(g,l,b,!0),g&2147483648?-1*(4294967295-g+1):g}function h(g,l,b,a){a||(p("boolean"===typeof b,"missing or invalid endian"),p(l+3<g.length,"Trying to read beyond buffer length"));
|
||||
return J.read(g,l,b,23,4)}function u(g,l,b,a){a||(p("boolean"===typeof b,"missing or invalid endian"),p(l+7<g.length,"Trying to read beyond buffer length"));return J.read(g,l,b,52,8)}function r(g,l,b,a,c){c||(p(void 0!==l&&null!==l,"missing value"),p("boolean"===typeof a,"missing or invalid endian"),p(void 0!==b&&null!==b,"missing offset"),p(b+1<g.length,"trying to write beyond buffer length"),H(l,65535));var x=g.length;if(!(b>=x))for(c=0,x=Math.min(x-b,2);c<x;c++)g[b+c]=(l&255<<8*(a?c:1-c))>>>8*
|
||||
(a?c:1-c)}function b(g,l,b,a,c){c||(p(void 0!==l&&null!==l,"missing value"),p("boolean"===typeof a,"missing or invalid endian"),p(void 0!==b&&null!==b,"missing offset"),p(b+3<g.length,"trying to write beyond buffer length"),H(l,4294967295));var x=g.length;if(!(b>=x))for(c=0,x=Math.min(x-b,4);c<x;c++)g[b+c]=l>>>8*(a?c:3-c)&255}function f(g,l,b,a,c){c||(p(void 0!==l&&null!==l,"missing value"),p("boolean"===typeof a,"missing or invalid endian"),p(void 0!==b&&null!==b,"missing offset"),p(b+1<g.length,
|
||||
"Trying to write beyond buffer length"),z(l,32767,-32768));b>=g.length||(0<=l?r(g,l,b,a,c):r(g,65535+l+1,b,a,c))}function G(g,l,a,c,f){f||(p(void 0!==l&&null!==l,"missing value"),p("boolean"===typeof c,"missing or invalid endian"),p(void 0!==a&&null!==a,"missing offset"),p(a+3<g.length,"Trying to write beyond buffer length"),z(l,2147483647,-2147483648));a>=g.length||(0<=l?b(g,l,a,c,f):b(g,4294967295+l+1,a,c,f))}function t(g,b,a,c,f){f||(p(void 0!==b&&null!==b,"missing value"),p("boolean"===typeof c,
|
||||
"missing or invalid endian"),p(void 0!==a&&null!==a,"missing offset"),p(a+3<g.length,"Trying to write beyond buffer length"),E(b,3.4028234663852886E38,-3.4028234663852886E38));a>=g.length||J.write(g,b,a,c,23,4)}function M(g,b,a,c,f){f||(p(void 0!==b&&null!==b,"missing value"),p("boolean"===typeof c,"missing or invalid endian"),p(void 0!==a&&null!==a,"missing offset"),p(a+7<g.length,"Trying to write beyond buffer length"),E(b,1.7976931348623157E308,-1.7976931348623157E308));a>=g.length||J.write(g,
|
||||
b,a,c,52,8)}function I(g,b,a){if("number"!==typeof g)return a;g=~~g;if(g>=b)return b;if(0<=g)return g;g+=b;return 0<=g?g:0}function B(g){g=~~Math.ceil(+g);return 0>g?0:g}function L(g){return(Array.isArray||function(g){return"[object Array]"===Object.prototype.toString.call(g)})(g)}function C(g){return 16>g?"0"+g.toString(16):g.toString(16)}function y(g){for(var b=[],a=0;a<g.length;a++){var c=g.charCodeAt(a);if(127>=c)b.push(g.charCodeAt(a));else{var f=a;55296<=c&&57343>=c&&a++;c=encodeURIComponent(g.slice(f,
|
||||
a+1)).substr(1).split("%");for(f=0;f<c.length;f++)b.push(parseInt(c[f],16))}}return b}function K(g){for(var b=[],a=0;a<g.length;a++)b.push(g.charCodeAt(a)&255);return b}function A(g,b,a,c){for(var l=0;l<c&&!(l+a>=b.length||l>=g.length);l++)b[l+a]=g[l];return l}function F(g){try{return decodeURIComponent(g)}catch(l){return String.fromCharCode(65533)}}function H(g,b){p("number"===typeof g,"cannot write a non-number as a number");p(0<=g,"specified a negative value for writing an unsigned value");p(g<=
|
||||
b,"value is larger than maximum value for type");p(Math.floor(g)===g,"value has a fractional component")}function z(g,b,a){p("number"===typeof g,"cannot write a non-number as a number");p(g<=b,"value larger than maximum allowed value");p(g>=a,"value smaller than minimum allowed value");p(Math.floor(g)===g,"value has a fractional component")}function E(g,b,a){p("number"===typeof g,"cannot write a non-number as a number");p(g<=b,"value larger than maximum allowed value");p(g>=a,"value smaller than minimum allowed value")}
|
||||
function p(g,b){if(!g)throw Error(b||"Failed assertion");}var D=n("base64-js"),J=n("ieee754");m.Buffer=c;m.SlowBuffer=c;m.INSPECT_MAX_BYTES=50;c.poolSize=8192;c._useTypedArrays=function(){try{var g=new ArrayBuffer(0),b=new Uint8Array(g);b.foo=function(){return 42};return 42===b.foo()&&"function"===typeof b.subarray}catch(x){return!1}}();c.isEncoding=function(g){switch(String(g).toLowerCase()){case "hex":case "utf8":case "utf-8":case "ascii":case "binary":case "base64":case "raw":case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return!0;
|
||||
default:return!1}};c.isBuffer=function(g){return!(null===g||void 0===g||!g._isBuffer)};c.byteLength=function(g,b){g+="";switch(b||"utf8"){case "hex":var a=g.length/2;break;case "utf8":case "utf-8":a=y(g).length;break;case "ascii":case "binary":case "raw":a=g.length;break;case "base64":a=D.toByteArray(g).length;break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":a=2*g.length;break;default:throw Error("Unknown encoding");}return a};c.concat=function(g,b){p(L(g),"Usage: Buffer.concat(list, [totalLength])\nlist should be an Array.");
|
||||
if(0===g.length)return new c(0);if(1===g.length)return g[0];var a;if("number"!==typeof b)for(a=b=0;a<g.length;a++)b+=g[a].length;var l=new c(b),f=0;for(a=0;a<g.length;a++){var e=g[a];e.copy(l,f);f+=e.length}return l};c.prototype.write=function(g,b,a,f){if(isFinite(b))isFinite(a)||(f=a,a=void 0);else{var l=f;f=b;b=a;a=l}b=Number(b)||0;l=this.length-b;a?(a=Number(a),a>l&&(a=l)):a=l;f=String(f||"utf8").toLowerCase();switch(f){case "hex":b=Number(b)||0;f=this.length-b;a?(a=Number(a),a>f&&(a=f)):a=f;f=
|
||||
g.length;p(0===f%2,"Invalid hex string");a>f/2&&(a=f/2);for(f=0;f<a;f++)l=parseInt(g.substr(2*f,2),16),p(!isNaN(l),"Invalid hex string"),this[b+f]=l;c._charsWritten=2*f;g=f;break;case "utf8":case "utf-8":g=c._charsWritten=A(y(g),this,b,a);break;case "ascii":g=c._charsWritten=A(K(g),this,b,a);break;case "binary":g=c._charsWritten=A(K(g),this,b,a);break;case "base64":g=c._charsWritten=A(D.toByteArray(g),this,b,a);break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":l=[];for(var e=0;e<g.length;e++){var h=
|
||||
g.charCodeAt(e);f=h>>8;h%=256;l.push(h);l.push(f)}g=c._charsWritten=A(l,this,b,a);break;default:throw Error("Unknown encoding");}return g};c.prototype.toString=function(g,b,a){g=String(g||"utf8").toLowerCase();b=Number(b)||0;a=void 0!==a?Number(a):a=this.length;if(a===b)return"";switch(g){case "hex":g=this.length;if(!b||0>b)b=0;if(!a||0>a||a>g)a=g;for(g="";b<a;b++)g+=C(this[b]);a=g;break;case "utf8":case "utf-8":var c=g="";for(a=Math.min(this.length,a);b<a;b++)127>=this[b]?(g+=F(c)+String.fromCharCode(this[b]),
|
||||
c=""):c+="%"+this[b].toString(16);a=g+F(c);break;case "ascii":a=d(this,b,a);break;case "binary":a=d(this,b,a);break;case "base64":a=0===b&&a===this.length?D.fromByteArray(this):D.fromByteArray(this.slice(b,a));break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":a=this.slice(b,a);b="";for(g=0;g<a.length;g+=2)b+=String.fromCharCode(a[g]+256*a[g+1]);a=b;break;default:throw Error("Unknown encoding");}return a};c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||
|
||||
this,0)}};c.prototype.copy=function(g,b,a,f){a||(a=0);f||0===f||(f=this.length);b||(b=0);if(f!==a&&0!==g.length&&0!==this.length)if(p(f>=a,"sourceEnd < sourceStart"),p(0<=b&&b<g.length,"targetStart out of bounds"),p(0<=a&&a<this.length,"sourceStart out of bounds"),p(0<=f&&f<=this.length,"sourceEnd out of bounds"),f>this.length&&(f=this.length),g.length-b<f-a&&(f=g.length-b+a),f-=a,100>f||!c._useTypedArrays)for(var l=0;l<f;l++)g[l+b]=this[l+a];else g._set(this.subarray(a,a+f),b)};c.prototype.slice=
|
||||
function(b,a){var g=this.length;b=I(b,g,0);a=I(a,g,g);if(c._useTypedArrays)return c._augment(this.subarray(b,a));g=a-b;for(var f=new c(g,void 0,!0),l=0;l<g;l++)f[l]=this[l+b];return f};c.prototype.get=function(b){console.log(".get() is deprecated. Access using array indexes instead.");return this.readUInt8(b)};c.prototype.set=function(b,a){console.log(".set() is deprecated. Access using array indexes instead.");return this.writeUInt8(b,a)};c.prototype.readUInt8=function(b,a){a||(p(void 0!==b&&null!==
|
||||
b,"missing offset"),p(b<this.length,"Trying to read beyond buffer length"));if(!(b>=this.length))return this[b]};c.prototype.readUInt16LE=function(b,a){return k(this,b,!0,a)};c.prototype.readUInt16BE=function(b,a){return k(this,b,!1,a)};c.prototype.readUInt32LE=function(b,a){return q(this,b,!0,a)};c.prototype.readUInt32BE=function(b,a){return q(this,b,!1,a)};c.prototype.readInt8=function(b,a){a||(p(void 0!==b&&null!==b,"missing offset"),p(b<this.length,"Trying to read beyond buffer length"));if(!(b>=
|
||||
this.length))return this[b]&128?-1*(255-this[b]+1):this[b]};c.prototype.readInt16LE=function(b,a){return e(this,b,!0,a)};c.prototype.readInt16BE=function(b,a){return e(this,b,!1,a)};c.prototype.readInt32LE=function(b,f){return a(this,b,!0,f)};c.prototype.readInt32BE=function(b,f){return a(this,b,!1,f)};c.prototype.readFloatLE=function(b,a){return h(this,b,!0,a)};c.prototype.readFloatBE=function(b,a){return h(this,b,!1,a)};c.prototype.readDoubleLE=function(b,a){return u(this,b,!0,a)};c.prototype.readDoubleBE=
|
||||
function(b,a){return u(this,b,!1,a)};c.prototype.writeUInt8=function(b,a,f){f||(p(void 0!==b&&null!==b,"missing value"),p(void 0!==a&&null!==a,"missing offset"),p(a<this.length,"trying to write beyond buffer length"),H(b,255));a>=this.length||(this[a]=b)};c.prototype.writeUInt16LE=function(b,a,f){r(this,b,a,!0,f)};c.prototype.writeUInt16BE=function(b,a,f){r(this,b,a,!1,f)};c.prototype.writeUInt32LE=function(a,f,c){b(this,a,f,!0,c)};c.prototype.writeUInt32BE=function(a,f,c){b(this,a,f,!1,c)};c.prototype.writeInt8=
|
||||
function(b,a,f){f||(p(void 0!==b&&null!==b,"missing value"),p(void 0!==a&&null!==a,"missing offset"),p(a<this.length,"Trying to write beyond buffer length"),z(b,127,-128));a>=this.length||(0<=b?this.writeUInt8(b,a,f):this.writeUInt8(255+b+1,a,f))};c.prototype.writeInt16LE=function(b,a,c){f(this,b,a,!0,c)};c.prototype.writeInt16BE=function(b,a,c){f(this,b,a,!1,c)};c.prototype.writeInt32LE=function(b,a,f){G(this,b,a,!0,f)};c.prototype.writeInt32BE=function(b,a,f){G(this,b,a,!1,f)};c.prototype.writeFloatLE=
|
||||
function(b,a,f){t(this,b,a,!0,f)};c.prototype.writeFloatBE=function(b,a,f){t(this,b,a,!1,f)};c.prototype.writeDoubleLE=function(b,a,f){M(this,b,a,!0,f)};c.prototype.writeDoubleBE=function(b,a,f){M(this,b,a,!1,f)};c.prototype.fill=function(b,a,f){b||(b=0);a||(a=0);f||(f=this.length);"string"===typeof b&&(b=b.charCodeAt(0));p("number"===typeof b&&!isNaN(b),"value is not a number");p(f>=a,"end < start");if(f!==a&&0!==this.length)for(p(0<=a&&a<this.length,"start out of bounds"),p(0<=f&&f<=this.length,
|
||||
"end out of bounds");a<f;a++)this[a]=b};c.prototype.inspect=function(){for(var b=[],a=this.length,f=0;f<a;f++)if(b[f]=C(this[f]),f===m.INSPECT_MAX_BYTES){b[f+1]="...";break}return"<Buffer "+b.join(" ")+">"};c.prototype.toArrayBuffer=function(){if("undefined"!==typeof Uint8Array){if(c._useTypedArrays)return(new c(this)).buffer;for(var b=new Uint8Array(this.length),a=0,f=b.length;a<f;a+=1)b[a]=this[a];return b.buffer}throw Error("Buffer.toArrayBuffer not supported in this browser");};var w=c.prototype;
|
||||
c._augment=function(b){b._isBuffer=!0;b._get=b.get;b._set=b.set;b.get=w.get;b.set=w.set;b.write=w.write;b.toString=w.toString;b.toLocaleString=w.toString;b.toJSON=w.toJSON;b.copy=w.copy;b.slice=w.slice;b.readUInt8=w.readUInt8;b.readUInt16LE=w.readUInt16LE;b.readUInt16BE=w.readUInt16BE;b.readUInt32LE=w.readUInt32LE;b.readUInt32BE=w.readUInt32BE;b.readInt8=w.readInt8;b.readInt16LE=w.readInt16LE;b.readInt16BE=w.readInt16BE;b.readInt32LE=w.readInt32LE;b.readInt32BE=w.readInt32BE;b.readFloatLE=w.readFloatLE;
|
||||
b.readFloatBE=w.readFloatBE;b.readDoubleLE=w.readDoubleLE;b.readDoubleBE=w.readDoubleBE;b.writeUInt8=w.writeUInt8;b.writeUInt16LE=w.writeUInt16LE;b.writeUInt16BE=w.writeUInt16BE;b.writeUInt32LE=w.writeUInt32LE;b.writeUInt32BE=w.writeUInt32BE;b.writeInt8=w.writeInt8;b.writeInt16LE=w.writeInt16LE;b.writeInt16BE=w.writeInt16BE;b.writeInt32LE=w.writeInt32LE;b.writeInt32BE=w.writeInt32BE;b.writeFloatLE=w.writeFloatLE;b.writeFloatBE=w.writeFloatBE;b.writeDoubleLE=w.writeDoubleLE;b.writeDoubleBE=w.writeDoubleBE;
|
||||
b.fill=w.fill;b.inspect=w.inspect;b.toArrayBuffer=w.toArrayBuffer;return b}},{"base64-js":2,ieee754:5}],5:[function(n,v,m){m.read=function(c,d,k,q,e){var a=8*e-q-1;var h=(1<<a)-1,u=h>>1,r=-7;e=k?e-1:0;var b=k?-1:1,f=c[d+e];e+=b;k=f&(1<<-r)-1;f>>=-r;for(r+=a;0<r;k=256*k+c[d+e],e+=b,r-=8);a=k&(1<<-r)-1;k>>=-r;for(r+=q;0<r;a=256*a+c[d+e],e+=b,r-=8);if(0===k)k=1-u;else{if(k===h)return a?NaN:Infinity*(f?-1:1);a+=Math.pow(2,q);k-=u}return(f?-1:1)*a*Math.pow(2,k-q)};m.write=function(c,d,k,q,e,a){var h,u=
|
||||
8*a-e-1,r=(1<<u)-1,b=r>>1,f=23===e?Math.pow(2,-24)-Math.pow(2,-77):0;a=q?0:a-1;var G=q?1:-1,t=0>d||0===d&&0>1/d?1:0;d=Math.abs(d);isNaN(d)||Infinity===d?(d=isNaN(d)?1:0,q=r):(q=Math.floor(Math.log(d)/Math.LN2),1>d*(h=Math.pow(2,-q))&&(q--,h*=2),d=1<=q+b?d+f/h:d+f*Math.pow(2,1-b),2<=d*h&&(q++,h/=2),q+b>=r?(d=0,q=r):1<=q+b?(d=(d*h-1)*Math.pow(2,e),q+=b):(d=d*Math.pow(2,b-1)*Math.pow(2,e),q=0));for(;8<=e;c[k+a]=d&255,a+=G,d/=256,e-=8);q=q<<e|d;for(u+=e;0<u;c[k+a]=q&255,a+=G,q/=256,u-=8);c[k+a-G]|=128*
|
||||
t}},{}],6:[function(n,v,m){(function(c){function d(a,c){for(var e=0,h=a.length-1;0<=h;h--){var b=a[h];"."===b?a.splice(h,1):".."===b?(a.splice(h,1),e++):e&&(a.splice(h,1),e--)}if(c)for(;e--;e)a.unshift("..");return a}function k(a,c){if(a.filter)return a.filter(c);for(var e=[],h=0;h<a.length;h++)c(a[h],h,a)&&e.push(a[h]);return e}var q=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;m.resolve=function(){for(var a="",e=!1,u=arguments.length-1;-1<=u&&!e;u--){var r=0<=u?arguments[u]:c.cwd();
|
||||
if("string"!==typeof r)throw new TypeError("Arguments to path.resolve must be strings");r&&(a=r+"/"+a,e="/"===r.charAt(0))}a=d(k(a.split("/"),function(b){return!!b}),!e).join("/");return(e?"/":"")+a||"."};m.normalize=function(a){var c=m.isAbsolute(a),u="/"===e(a,-1);(a=d(k(a.split("/"),function(a){return!!a}),!c).join("/"))||c||(a=".");a&&u&&(a+="/");return(c?"/":"")+a};m.isAbsolute=function(a){return"/"===a.charAt(0)};m.join=function(){var a=Array.prototype.slice.call(arguments,0);return m.normalize(k(a,
|
||||
function(a,c){if("string"!==typeof a)throw new TypeError("Arguments to path.join must be strings");return a}).join("/"))};m.relative=function(a,c){function e(b){for(var a=0;a<b.length&&""===b[a];a++);for(var f=b.length-1;0<=f&&""===b[f];f--);return a>f?[]:b.slice(a,f-a+1)}a=m.resolve(a).substr(1);c=m.resolve(c).substr(1);for(var h=e(a.split("/")),b=e(c.split("/")),f=Math.min(h.length,b.length),G=f,t=0;t<f;t++)if(h[t]!==b[t]){G=t;break}f=[];for(t=G;t<h.length;t++)f.push("..");f=f.concat(b.slice(G));
|
||||
return f.join("/")};m.sep="/";m.delimiter=":";m.dirname=function(a){var c=q.exec(a).slice(1);a=c[0];c=c[1];if(!a&&!c)return".";c&&(c=c.substr(0,c.length-1));return a+c};m.basename=function(a,c){var e=q.exec(a).slice(1)[2];c&&e.substr(-1*c.length)===c&&(e=e.substr(0,e.length-c.length));return e};m.extname=function(a){return q.exec(a).slice(1)[3]};var e="b"==="ab".substr(-1)?function(a,c,e){return a.substr(c,e)}:function(a,c,e){0>c&&(c=a.length+c);return a.substr(c,e)}}).call(this,n("node_modules/process/browser.js"))},
|
||||
{"node_modules/process/browser.js":7}],7:[function(n,v,m){function c(){}n=v.exports={};n.nextTick=function(){if("undefined"!==typeof window&&window.setImmediate)return function(c){return window.setImmediate(c)};if("undefined"!==typeof window&&window.postMessage&&window.addEventListener){var c=[];window.addEventListener("message",function(d){var k=d.source;k!==window&&null!==k||"process-tick"!==d.data||(d.stopPropagation(),0<c.length&&c.shift()())},!0);return function(d){c.push(d);window.postMessage("process-tick",
|
||||
"*")}}return function(c){setTimeout(c,0)}}();n.title="browser";n.browser=!0;n.env={};n.argv=[];n.on=c;n.once=c;n.off=c;n.emit=c;n.binding=function(c){throw Error("process.binding is not supported");};n.cwd=function(){return"/"};n.chdir=function(c){throw Error("process.chdir is not supported");}},{}],8:[function(n,v,m){function c(){this._array=[];this._set=Object.create(null)}var d=n("./util"),k=Object.prototype.hasOwnProperty;c.fromArray=function(d,e){for(var a=new c,h=0,k=d.length;h<k;h++)a.add(d[h],
|
||||
e);return a};c.prototype.size=function(){return Object.getOwnPropertyNames(this._set).length};c.prototype.add=function(c,e){var a=d.toSetString(c),h=k.call(this._set,a),u=this._array.length;h&&!e||this._array.push(c);h||(this._set[a]=u)};c.prototype.has=function(c){c=d.toSetString(c);return k.call(this._set,c)};c.prototype.indexOf=function(c){var e=d.toSetString(c);if(k.call(this._set,e))return this._set[e];throw Error('"'+c+'" is not in the set.');};c.prototype.at=function(c){if(0<=c&&c<this._array.length)return this._array[c];
|
||||
throw Error("No element indexed by "+c);};c.prototype.toArray=function(){return this._array.slice()};m.ArraySet=c},{"./util":17}],9:[function(n,v,m){var c=n("./base64");m.encode=function(d){var k="",q=0>d?(-d<<1)+1:(d<<1)+0;do d=q&31,q>>>=5,0<q&&(d|=32),k+=c.encode(d);while(0<q);return k};m.decode=function(d,k,q){var e=d.length,a=0,h=0;do{if(k>=e)throw Error("Expected more digits in base 64 VLQ value.");var u=c.decode(d.charCodeAt(k++));if(-1===u)throw Error("Invalid base64 digit: "+d.charAt(k-1));
|
||||
var r=!!(u&32);u&=31;a+=u<<h;h+=5}while(r);d=a>>1;q.value=1===(a&1)?-d:d;q.rest=k}},{"./base64":10}],10:[function(n,v,m){var c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");m.encode=function(d){if(0<=d&&d<c.length)return c[d];throw new TypeError("Must be between 0 and 63: "+d);};m.decode=function(c){return 65<=c&&90>=c?c-65:97<=c&&122>=c?c-97+26:48<=c&&57>=c?c-48+52:43==c?62:47==c?63:-1}},{}],11:[function(n,v,m){function c(d,k,q,e,a,h){var u=Math.floor((k-d)/2)+d,r=
|
||||
a(q,e[u],!0);return 0===r?u:0<r?1<k-u?c(u,k,q,e,a,h):h==m.LEAST_UPPER_BOUND?k<e.length?k:-1:u:1<u-d?c(d,u,q,e,a,h):h==m.LEAST_UPPER_BOUND?u:0>d?-1:d}m.GREATEST_LOWER_BOUND=1;m.LEAST_UPPER_BOUND=2;m.search=function(d,k,q,e){if(0===k.length)return-1;d=c(-1,k.length,d,k,q,e||m.GREATEST_LOWER_BOUND);if(0>d)return-1;for(;0<=d-1&&0===q(k[d],k[d-1],!0);)--d;return d}},{}],12:[function(n,v,m){function c(){this._array=[];this._sorted=!0;this._last={generatedLine:-1,generatedColumn:0}}var d=n("./util");c.prototype.unsortedForEach=
|
||||
function(c,d){this._array.forEach(c,d)};c.prototype.add=function(c){var k=this._last,e=k.generatedLine,a=c.generatedLine,h=k.generatedColumn,u=c.generatedColumn;a>e||a==e&&u>=h||0>=d.compareByGeneratedPositionsInflated(k,c)?this._last=c:this._sorted=!1;this._array.push(c)};c.prototype.toArray=function(){this._sorted||(this._array.sort(d.compareByGeneratedPositionsInflated),this._sorted=!0);return this._array};m.MappingList=c},{"./util":17}],13:[function(n,v,m){function c(c,d,e){var a=c[d];c[d]=c[e];
|
||||
c[e]=a}function d(k,m,e,a){if(e<a){var h=e-1;c(k,Math.round(e+Math.random()*(a-e)),a);for(var u=k[a],r=e;r<a;r++)0>=m(k[r],u)&&(h+=1,c(k,h,r));c(k,h+1,r);h+=1;d(k,m,e,h-1);d(k,m,h+1,a)}}m.quickSort=function(c,m){d(c,m,0,c.length-1)}},{}],14:[function(n,v,m){function c(b){var a=b;"string"===typeof b&&(a=JSON.parse(b.replace(/^\)\]\}'/,"")));return null!=a.sections?new q(a):new d(a)}function d(b){var a=b;"string"===typeof b&&(a=JSON.parse(b.replace(/^\)\]\}'/,"")));b=e.getArg(a,"version");var c=e.getArg(a,
|
||||
"sources"),t=e.getArg(a,"names",[]),d=e.getArg(a,"sourceRoot",null),r=e.getArg(a,"sourcesContent",null),k=e.getArg(a,"mappings");a=e.getArg(a,"file",null);if(b!=this._version)throw Error("Unsupported version: "+b);c=c.map(String).map(e.normalize).map(function(b){return d&&e.isAbsolute(d)&&e.isAbsolute(b)?e.relative(d,b):b});this._names=h.fromArray(t.map(String),!0);this._sources=h.fromArray(c,!0);this.sourceRoot=d;this.sourcesContent=r;this._mappings=k;this.file=a}function k(){this.generatedColumn=
|
||||
this.generatedLine=0;this.name=this.originalColumn=this.originalLine=this.source=null}function q(b){var a=b;"string"===typeof b&&(a=JSON.parse(b.replace(/^\)\]\}'/,"")));b=e.getArg(a,"version");a=e.getArg(a,"sections");if(b!=this._version)throw Error("Unsupported version: "+b);this._sources=new h;this._names=new h;var d={line:-1,column:0};this._sections=a.map(function(b){if(b.url)throw Error("Support for url field in sections not implemented.");var a=e.getArg(b,"offset"),f=e.getArg(a,"line"),t=e.getArg(a,
|
||||
"column");if(f<d.line||f===d.line&&t<d.column)throw Error("Section offsets must be ordered and non-overlapping.");d=a;return{generatedOffset:{generatedLine:f+1,generatedColumn:t+1},consumer:new c(e.getArg(b,"map"))}})}var e=n("./util"),a=n("./binary-search"),h=n("./array-set").ArraySet,u=n("./base64-vlq"),r=n("./quick-sort").quickSort;c.fromSourceMap=function(b){return d.fromSourceMap(b)};c.prototype._version=3;c.prototype.__generatedMappings=null;Object.defineProperty(c.prototype,"_generatedMappings",
|
||||
{get:function(){this.__generatedMappings||this._parseMappings(this._mappings,this.sourceRoot);return this.__generatedMappings}});c.prototype.__originalMappings=null;Object.defineProperty(c.prototype,"_originalMappings",{get:function(){this.__originalMappings||this._parseMappings(this._mappings,this.sourceRoot);return this.__originalMappings}});c.prototype._charIsMappingSeparator=function(b,a){var c=b.charAt(a);return";"===c||","===c};c.prototype._parseMappings=function(b,a){throw Error("Subclasses must implement _parseMappings");
|
||||
};c.GENERATED_ORDER=1;c.ORIGINAL_ORDER=2;c.GREATEST_LOWER_BOUND=1;c.LEAST_UPPER_BOUND=2;c.prototype.eachMapping=function(b,a,d){a=a||null;switch(d||c.GENERATED_ORDER){case c.GENERATED_ORDER:d=this._generatedMappings;break;case c.ORIGINAL_ORDER:d=this._originalMappings;break;default:throw Error("Unknown order of iteration.");}var f=this.sourceRoot;d.map(function(b){var a=null===b.source?null:this._sources.at(b.source);null!=a&&null!=f&&(a=e.join(f,a));return{source:a,generatedLine:b.generatedLine,
|
||||
generatedColumn:b.generatedColumn,originalLine:b.originalLine,originalColumn:b.originalColumn,name:null===b.name?null:this._names.at(b.name)}},this).forEach(b,a)};c.prototype.allGeneratedPositionsFor=function(b){var c=e.getArg(b,"line"),d={source:e.getArg(b,"source"),originalLine:c,originalColumn:e.getArg(b,"column",0)};null!=this.sourceRoot&&(d.source=e.relative(this.sourceRoot,d.source));if(!this._sources.has(d.source))return[];d.source=this._sources.indexOf(d.source);var t=[];d=this._findMapping(d,
|
||||
this._originalMappings,"originalLine","originalColumn",e.compareByOriginalPositions,a.LEAST_UPPER_BOUND);if(0<=d){var h=this._originalMappings[d];if(void 0===b.column)for(c=h.originalLine;h&&h.originalLine===c;)t.push({line:e.getArg(h,"generatedLine",null),column:e.getArg(h,"generatedColumn",null),lastColumn:e.getArg(h,"lastGeneratedColumn",null)}),h=this._originalMappings[++d];else for(b=h.originalColumn;h&&h.originalLine===c&&h.originalColumn==b;)t.push({line:e.getArg(h,"generatedLine",null),column:e.getArg(h,
|
||||
"generatedColumn",null),lastColumn:e.getArg(h,"lastGeneratedColumn",null)}),h=this._originalMappings[++d]}return t};m.SourceMapConsumer=c;d.prototype=Object.create(c.prototype);d.prototype.consumer=c;d.fromSourceMap=function(b){var a=Object.create(d.prototype),c=a._names=h.fromArray(b._names.toArray(),!0),t=a._sources=h.fromArray(b._sources.toArray(),!0);a.sourceRoot=b._sourceRoot;a.sourcesContent=b._generateSourcesContent(a._sources.toArray(),a.sourceRoot);a.file=b._file;b=b._mappings.toArray().slice();
|
||||
for(var u=a.__generatedMappings=[],m=a.__originalMappings=[],q=0,n=b.length;q<n;q++){var C=b[q],y=new k;y.generatedLine=C.generatedLine;y.generatedColumn=C.generatedColumn;C.source&&(y.source=t.indexOf(C.source),y.originalLine=C.originalLine,y.originalColumn=C.originalColumn,C.name&&(y.name=c.indexOf(C.name)),m.push(y));u.push(y)}r(a.__originalMappings,e.compareByOriginalPositions);return a};d.prototype._version=3;Object.defineProperty(d.prototype,"sources",{get:function(){return this._sources.toArray().map(function(b){return null!=
|
||||
this.sourceRoot?e.join(this.sourceRoot,b):b},this)}});d.prototype._parseMappings=function(b,a){for(var c=1,f=0,d=0,h=0,m=0,q=0,n=b.length,y=0,v={},A={},F=[],H=[],z,E,p,D,J;y<n;)if(";"===b.charAt(y))c++,y++,f=0;else if(","===b.charAt(y))y++;else{z=new k;z.generatedLine=c;for(D=y;D<n&&!this._charIsMappingSeparator(b,D);D++);E=b.slice(y,D);if(p=v[E])y+=E.length;else{for(p=[];y<D;)u.decode(b,y,A),J=A.value,y=A.rest,p.push(J);if(2===p.length)throw Error("Found a source, but no line and column");if(3===
|
||||
p.length)throw Error("Found a source and line, but no column");v[E]=p}z.generatedColumn=f+p[0];f=z.generatedColumn;1<p.length&&(z.source=m+p[1],m+=p[1],z.originalLine=d+p[2],d=z.originalLine,z.originalLine+=1,z.originalColumn=h+p[3],h=z.originalColumn,4<p.length&&(z.name=q+p[4],q+=p[4]));H.push(z);"number"===typeof z.originalLine&&F.push(z)}r(H,e.compareByGeneratedPositionsDeflated);this.__generatedMappings=H;r(F,e.compareByOriginalPositions);this.__originalMappings=F};d.prototype._findMapping=function(b,
|
||||
c,e,d,h,r){if(0>=b[e])throw new TypeError("Line must be greater than or equal to 1, got "+b[e]);if(0>b[d])throw new TypeError("Column must be greater than or equal to 0, got "+b[d]);return a.search(b,c,h,r)};d.prototype.computeColumnSpans=function(){for(var b=0;b<this._generatedMappings.length;++b){var a=this._generatedMappings[b];if(b+1<this._generatedMappings.length){var c=this._generatedMappings[b+1];if(a.generatedLine===c.generatedLine){a.lastGeneratedColumn=c.generatedColumn-1;continue}}a.lastGeneratedColumn=
|
||||
Infinity}};d.prototype.originalPositionFor=function(b){var a={generatedLine:e.getArg(b,"line"),generatedColumn:e.getArg(b,"column")};b=this._findMapping(a,this._generatedMappings,"generatedLine","generatedColumn",e.compareByGeneratedPositionsDeflated,e.getArg(b,"bias",c.GREATEST_LOWER_BOUND));if(0<=b&&(b=this._generatedMappings[b],b.generatedLine===a.generatedLine)){a=e.getArg(b,"source",null);null!==a&&(a=this._sources.at(a),null!=this.sourceRoot&&(a=e.join(this.sourceRoot,a)));var d=e.getArg(b,
|
||||
"name",null);null!==d&&(d=this._names.at(d));return{source:a,line:e.getArg(b,"originalLine",null),column:e.getArg(b,"originalColumn",null),name:d}}return{source:null,line:null,column:null,name:null}};d.prototype.hasContentsOfAllSources=function(){return this.sourcesContent?this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some(function(b){return null==b}):!1};d.prototype.sourceContentFor=function(b,a){if(!this.sourcesContent)return null;null!=this.sourceRoot&&(b=e.relative(this.sourceRoot,
|
||||
b));if(this._sources.has(b))return this.sourcesContent[this._sources.indexOf(b)];var c;if(null!=this.sourceRoot&&(c=e.urlParse(this.sourceRoot))){var f=b.replace(/^file:\/\//,"");if("file"==c.scheme&&this._sources.has(f))return this.sourcesContent[this._sources.indexOf(f)];if((!c.path||"/"==c.path)&&this._sources.has("/"+b))return this.sourcesContent[this._sources.indexOf("/"+b)]}if(a)return null;throw Error('"'+b+'" is not in the SourceMap.');};d.prototype.generatedPositionFor=function(b){var a=
|
||||
e.getArg(b,"source");null!=this.sourceRoot&&(a=e.relative(this.sourceRoot,a));if(!this._sources.has(a))return{line:null,column:null,lastColumn:null};a=this._sources.indexOf(a);a={source:a,originalLine:e.getArg(b,"line"),originalColumn:e.getArg(b,"column")};b=this._findMapping(a,this._originalMappings,"originalLine","originalColumn",e.compareByOriginalPositions,e.getArg(b,"bias",c.GREATEST_LOWER_BOUND));return 0<=b&&(b=this._originalMappings[b],b.source===a.source)?{line:e.getArg(b,"generatedLine",
|
||||
null),column:e.getArg(b,"generatedColumn",null),lastColumn:e.getArg(b,"lastGeneratedColumn",null)}:{line:null,column:null,lastColumn:null}};m.BasicSourceMapConsumer=d;q.prototype=Object.create(c.prototype);q.prototype.constructor=c;q.prototype._version=3;Object.defineProperty(q.prototype,"sources",{get:function(){for(var a=[],c=0;c<this._sections.length;c++)for(var e=0;e<this._sections[c].consumer.sources.length;e++)a.push(this._sections[c].consumer.sources[e]);return a}});q.prototype.originalPositionFor=
|
||||
function(b){var c={generatedLine:e.getArg(b,"line"),generatedColumn:e.getArg(b,"column")},d=a.search(c,this._sections,function(a,b){var c=a.generatedLine-b.generatedOffset.generatedLine;return c?c:a.generatedColumn-b.generatedOffset.generatedColumn});return(d=this._sections[d])?d.consumer.originalPositionFor({line:c.generatedLine-(d.generatedOffset.generatedLine-1),column:c.generatedColumn-(d.generatedOffset.generatedLine===c.generatedLine?d.generatedOffset.generatedColumn-1:0),bias:b.bias}):{source:null,
|
||||
line:null,column:null,name:null}};q.prototype.hasContentsOfAllSources=function(){return this._sections.every(function(a){return a.consumer.hasContentsOfAllSources()})};q.prototype.sourceContentFor=function(a,c){for(var b=0;b<this._sections.length;b++){var f=this._sections[b].consumer.sourceContentFor(a,!0);if(f)return f}if(c)return null;throw Error('"'+a+'" is not in the SourceMap.');};q.prototype.generatedPositionFor=function(a){for(var b=0;b<this._sections.length;b++){var c=this._sections[b];if(-1!==
|
||||
c.consumer.sources.indexOf(e.getArg(a,"source"))){var d=c.consumer.generatedPositionFor(a);if(d)return{line:d.line+(c.generatedOffset.generatedLine-1),column:d.column+(c.generatedOffset.generatedLine===d.line?c.generatedOffset.generatedColumn-1:0)}}}return{line:null,column:null}};q.prototype._parseMappings=function(a,c){this.__generatedMappings=[];this.__originalMappings=[];for(var b=0;b<this._sections.length;b++)for(var f=this._sections[b],d=f.consumer._generatedMappings,h=0;h<d.length;h++){var k=
|
||||
d[h],u=f.consumer._sources.at(k.source);null!==f.consumer.sourceRoot&&(u=e.join(f.consumer.sourceRoot,u));this._sources.add(u);u=this._sources.indexOf(u);var m=f.consumer._names.at(k.name);this._names.add(m);m=this._names.indexOf(m);k={source:u,generatedLine:k.generatedLine+(f.generatedOffset.generatedLine-1),generatedColumn:k.generatedColumn+(f.generatedOffset.generatedLine===k.generatedLine?f.generatedOffset.generatedColumn-1:0),originalLine:k.originalLine,originalColumn:k.originalColumn,name:m};
|
||||
this.__generatedMappings.push(k);"number"===typeof k.originalLine&&this.__originalMappings.push(k)}r(this.__generatedMappings,e.compareByGeneratedPositionsDeflated);r(this.__originalMappings,e.compareByOriginalPositions)};m.IndexedSourceMapConsumer=q},{"./array-set":8,"./base64-vlq":9,"./binary-search":11,"./quick-sort":13,"./util":17}],15:[function(n,v,m){function c(a){a||(a={});this._file=k.getArg(a,"file",null);this._sourceRoot=k.getArg(a,"sourceRoot",null);this._skipValidation=k.getArg(a,"skipValidation",
|
||||
!1);this._sources=new q;this._names=new q;this._mappings=new e;this._sourcesContents=null}var d=n("./base64-vlq"),k=n("./util"),q=n("./array-set").ArraySet,e=n("./mapping-list").MappingList;c.prototype._version=3;c.fromSourceMap=function(a){var e=a.sourceRoot,d=new c({file:a.file,sourceRoot:e});a.eachMapping(function(a){var b={generated:{line:a.generatedLine,column:a.generatedColumn}};null!=a.source&&(b.source=a.source,null!=e&&(b.source=k.relative(e,b.source)),b.original={line:a.originalLine,column:a.originalColumn},
|
||||
null!=a.name&&(b.name=a.name));d.addMapping(b)});a.sources.forEach(function(c){var b=a.sourceContentFor(c);null!=b&&d.setSourceContent(c,b)});return d};c.prototype.addMapping=function(a){var c=k.getArg(a,"generated"),e=k.getArg(a,"original",null),d=k.getArg(a,"source",null);a=k.getArg(a,"name",null);this._skipValidation||this._validateMapping(c,e,d,a);null!=d&&(d=String(d),this._sources.has(d)||this._sources.add(d));null!=a&&(a=String(a),this._names.has(a)||this._names.add(a));this._mappings.add({generatedLine:c.line,
|
||||
generatedColumn:c.column,originalLine:null!=e&&e.line,originalColumn:null!=e&&e.column,source:d,name:a})};c.prototype.setSourceContent=function(a,c){var e=a;null!=this._sourceRoot&&(e=k.relative(this._sourceRoot,e));null!=c?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[k.toSetString(e)]=c):this._sourcesContents&&(delete this._sourcesContents[k.toSetString(e)],0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))};c.prototype.applySourceMap=
|
||||
function(a,c,e){var d=c;if(null==c){if(null==a.file)throw Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');d=a.file}var b=this._sourceRoot;null!=b&&(d=k.relative(b,d));var f=new q,h=new q;this._mappings.unsortedForEach(function(c){if(c.source===d&&null!=c.originalLine){var t=a.originalPositionFor({line:c.originalLine,column:c.originalColumn});null!=t.source&&(c.source=t.source,null!=e&&(c.source=
|
||||
k.join(e,c.source)),null!=b&&(c.source=k.relative(b,c.source)),c.originalLine=t.line,c.originalColumn=t.column,null!=t.name&&(c.name=t.name))}t=c.source;null==t||f.has(t)||f.add(t);c=c.name;null==c||h.has(c)||h.add(c)},this);this._sources=f;this._names=h;a.sources.forEach(function(c){var f=a.sourceContentFor(c);null!=f&&(null!=e&&(c=k.join(e,c)),null!=b&&(c=k.relative(b,c)),this.setSourceContent(c,f))},this)};c.prototype._validateMapping=function(a,c,e,d){if(!(a&&"line"in a&&"column"in a&&0<a.line&&
|
||||
0<=a.column&&!c&&!e&&!d||a&&"line"in a&&"column"in a&&c&&"line"in c&&"column"in c&&0<a.line&&0<=a.column&&0<c.line&&0<=c.column&&e))throw Error("Invalid mapping: "+JSON.stringify({generated:a,source:e,original:c,name:d}));};c.prototype._serializeMappings=function(){for(var a=0,c=1,e=0,m=0,b=0,f=0,q="",t,n,I,B=this._mappings.toArray(),v=0,C=B.length;v<C;v++){n=B[v];t="";if(n.generatedLine!==c)for(a=0;n.generatedLine!==c;)t+=";",c++;else if(0<v){if(!k.compareByGeneratedPositionsInflated(n,B[v-1]))continue;
|
||||
t+=","}t+=d.encode(n.generatedColumn-a);a=n.generatedColumn;null!=n.source&&(I=this._sources.indexOf(n.source),t+=d.encode(I-f),f=I,t+=d.encode(n.originalLine-1-m),m=n.originalLine-1,t+=d.encode(n.originalColumn-e),e=n.originalColumn,null!=n.name&&(n=this._names.indexOf(n.name),t+=d.encode(n-b),b=n));q+=t}return q};c.prototype._generateSourcesContent=function(a,c){return a.map(function(a){if(!this._sourcesContents)return null;null!=c&&(a=k.relative(c,a));a=k.toSetString(a);return Object.prototype.hasOwnProperty.call(this._sourcesContents,
|
||||
a)?this._sourcesContents[a]:null},this)};c.prototype.toJSON=function(){var a={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};null!=this._file&&(a.file=this._file);null!=this._sourceRoot&&(a.sourceRoot=this._sourceRoot);this._sourcesContents&&(a.sourcesContent=this._generateSourcesContent(a.sources,a.sourceRoot));return a};c.prototype.toString=function(){return JSON.stringify(this.toJSON())};m.SourceMapGenerator=c},{"./array-set":8,
|
||||
"./base64-vlq":9,"./mapping-list":12,"./util":17}],16:[function(n,v,m){function c(c,a,d,k,m){this.children=[];this.sourceContents={};this.line=null==c?null:c;this.column=null==a?null:a;this.source=null==d?null:d;this.name=null==m?null:m;this.$$$isSourceNode$$$=!0;null!=k&&this.add(k)}var d=n("./source-map-generator").SourceMapGenerator,k=n("./util"),q=/(\r?\n)/;c.fromStringWithSourceMap=function(e,a,d){function h(a,b){if(null===a||void 0===a.source)m.add(b);else{var f=d?k.join(d,a.source):a.source;
|
||||
m.add(new c(a.originalLine,a.originalColumn,f,b,a.name))}}var m=new c,b=e.split(q),f=function(){var a=b.shift(),c=b.shift()||"";return a+c},n=1,t=0,v=null;a.eachMapping(function(a){if(null!==v)if(n<a.generatedLine)h(v,f()),n++,t=0;else{var c=b[0];var e=c.substr(0,a.generatedColumn-t);b[0]=c.substr(a.generatedColumn-t);t=a.generatedColumn;h(v,e);v=a;return}for(;n<a.generatedLine;)m.add(f()),n++;t<a.generatedColumn&&(c=b[0],m.add(c.substr(0,a.generatedColumn)),b[0]=c.substr(a.generatedColumn),t=a.generatedColumn);
|
||||
v=a},this);0<b.length&&(v&&h(v,f()),m.add(b.join("")));a.sources.forEach(function(b){var c=a.sourceContentFor(b);null!=c&&(null!=d&&(b=k.join(d,b)),m.setSourceContent(b,c))});return m};c.prototype.add=function(c){if(Array.isArray(c))c.forEach(function(a){this.add(a)},this);else if(c.$$$isSourceNode$$$||"string"===typeof c)c&&this.children.push(c);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+c);return this};c.prototype.prepend=function(c){if(Array.isArray(c))for(var a=
|
||||
c.length-1;0<=a;a--)this.prepend(c[a]);else if(c.$$$isSourceNode$$$||"string"===typeof c)this.children.unshift(c);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+c);return this};c.prototype.walk=function(c){for(var a,e=0,d=this.children.length;e<d;e++)a=this.children[e],a.$$$isSourceNode$$$?a.walk(c):""!==a&&c(a,{source:this.source,line:this.line,column:this.column,name:this.name})};c.prototype.join=function(c){var a,e=this.children.length;if(0<
|
||||
e){var d=[];for(a=0;a<e-1;a++)d.push(this.children[a]),d.push(c);d.push(this.children[a]);this.children=d}return this};c.prototype.replaceRight=function(c,a){var e=this.children[this.children.length-1];e.$$$isSourceNode$$$?e.replaceRight(c,a):"string"===typeof e?this.children[this.children.length-1]=e.replace(c,a):this.children.push("".replace(c,a));return this};c.prototype.setSourceContent=function(c,a){this.sourceContents[k.toSetString(c)]=a};c.prototype.walkSourceContents=function(c){for(var a=
|
||||
0,e=this.children.length;a<e;a++)this.children[a].$$$isSourceNode$$$&&this.children[a].walkSourceContents(c);var d=Object.keys(this.sourceContents);a=0;for(e=d.length;a<e;a++)c(k.fromSetString(d[a]),this.sourceContents[d[a]])};c.prototype.toString=function(){var c="";this.walk(function(a){c+=a});return c};c.prototype.toStringWithSourceMap=function(c){var a="",e=1,k=0,m=new d(c),b=!1,f=null,n=null,t=null,q=null;this.walk(function(c,d){a+=c;null!==d.source&&null!==d.line&&null!==d.column?(f===d.source&&
|
||||
n===d.line&&t===d.column&&q===d.name||m.addMapping({source:d.source,original:{line:d.line,column:d.column},generated:{line:e,column:k},name:d.name}),f=d.source,n=d.line,t=d.column,q=d.name,b=!0):b&&(m.addMapping({generated:{line:e,column:k}}),f=null,b=!1);for(var h=0,r=c.length;h<r;h++)10===c.charCodeAt(h)?(e++,k=0,h+1===r?(f=null,b=!1):b&&m.addMapping({source:d.source,original:{line:d.line,column:d.column},generated:{line:e,column:k},name:d.name})):k++});this.walkSourceContents(function(a,b){m.setSourceContent(a,
|
||||
b)});return{code:a,map:m}};m.SourceNode=c},{"./source-map-generator":15,"./util":17}],17:[function(n,v,m){function c(a){return(a=a.match(u))?{scheme:a[1],auth:a[2],host:a[3],port:a[4],path:a[5]}:null}function d(a){var b="";a.scheme&&(b+=a.scheme+":");b+="//";a.auth&&(b+=a.auth+"@");a.host&&(b+=a.host);a.port&&(b+=":"+a.port);a.path&&(b+=a.path);return b}function k(a){var b=a,e=c(a);if(e){if(!e.path)return a;b=e.path}a=m.isAbsolute(b);b=b.split(/\/+/);for(var k,h=0,n=b.length-1;0<=n;n--)k=b[n],"."===
|
||||
k?b.splice(n,1):".."===k?h++:0<h&&(""===k?(b.splice(n+1,h),h=0):(b.splice(n,2),h--));b=b.join("/");""===b&&(b=a?"/":".");return e?(e.path=b,d(e)):b}function q(a){return a}function e(a){return h(a)?"$"+a:a}function a(a){return h(a)?a.slice(1):a}function h(a){if(!a)return!1;var b=a.length;if(9>b||95!==a.charCodeAt(b-1)||95!==a.charCodeAt(b-2)||111!==a.charCodeAt(b-3)||116!==a.charCodeAt(b-4)||111!==a.charCodeAt(b-5)||114!==a.charCodeAt(b-6)||112!==a.charCodeAt(b-7)||95!==a.charCodeAt(b-8)||95!==a.charCodeAt(b-
|
||||
9))return!1;for(b-=10;0<=b;b--)if(36!==a.charCodeAt(b))return!1;return!0}m.getArg=function(a,c,d){if(c in a)return a[c];if(3===arguments.length)return d;throw Error('"'+c+'" is a required argument.');};var u=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/,r=/^data:.+\,.+$/;m.urlParse=c;m.urlGenerate=d;m.normalize=k;m.join=function(a,e){""===a&&(a=".");""===e&&(e=".");var b=c(e),f=c(a);f&&(a=f.path||"/");if(b&&!b.scheme)return f&&(b.scheme=f.scheme),d(b);if(b||e.match(r))return e;
|
||||
if(f&&!f.host&&!f.path)return f.host=e,d(f);b="/"===e.charAt(0)?e:k(a.replace(/\/+$/,"")+"/"+e);return f?(f.path=b,d(f)):b};m.isAbsolute=function(a){return"/"===a.charAt(0)||!!a.match(u)};m.relative=function(a,c){""===a&&(a=".");a=a.replace(/\/$/,"");for(var b=0;0!==c.indexOf(a+"/");){var d=a.lastIndexOf("/");if(0>d)return c;a=a.slice(0,d);if(a.match(/^([^\/]+:\/)?\/*$/))return c;++b}return Array(b+1).join("../")+c.substr(a.length+1)};n=!("__proto__"in Object.create(null));m.toSetString=n?q:e;m.fromSetString=
|
||||
n?q:a;m.compareByOriginalPositions=function(a,c,d){var b=a.source-c.source;if(0!==b)return b;b=a.originalLine-c.originalLine;if(0!==b)return b;b=a.originalColumn-c.originalColumn;if(0!==b||d)return b;b=a.generatedColumn-c.generatedColumn;if(0!==b)return b;b=a.generatedLine-c.generatedLine;return 0!==b?b:a.name-c.name};m.compareByGeneratedPositionsDeflated=function(a,c,d){var b=a.generatedLine-c.generatedLine;if(0!==b)return b;b=a.generatedColumn-c.generatedColumn;if(0!==b||d)return b;b=a.source-c.source;
|
||||
if(0!==b)return b;b=a.originalLine-c.originalLine;if(0!==b)return b;b=a.originalColumn-c.originalColumn;return 0!==b?b:a.name-c.name};m.compareByGeneratedPositionsInflated=function(a,c){var b=a.generatedLine-c.generatedLine;if(0!==b)return b;b=a.generatedColumn-c.generatedColumn;if(0!==b)return b;b=a.source;var d=c.source;b=b===d?0:b>d?1:-1;if(0!==b)return b;b=a.originalLine-c.originalLine;if(0!==b)return b;b=a.originalColumn-c.originalColumn;0===b&&(b=a.name,d=c.name,b=b===d?0:b>d?1:-1);return b}},
|
||||
{}],18:[function(n,v,m){m.SourceMapGenerator=n("./lib/source-map-generator").SourceMapGenerator;m.SourceMapConsumer=n("./lib/source-map-consumer").SourceMapConsumer;m.SourceNode=n("./lib/source-node").SourceNode},{"./lib/source-map-consumer":14,"./lib/source-map-generator":15,"./lib/source-node":16}],19:[function(n,v,m){(function(c,d){function k(){return"browser"===K?!0:"node"===K?!1:"undefined"!==typeof window&&"function"===typeof XMLHttpRequest&&!(window.require&&window.module&&window.process&&
|
||||
"renderer"===window.process.type)}function q(a){return function(b){for(var c=0;c<a.length;c++){var d=a[c](b);if(d)return d}return null}}function e(a,b){if(!a)return b;var c=I.dirname(a),d=/^\w+:\/\/[^\/]*/.exec(c);d=d?d[0]:"";return d+I.resolve(c.slice(d.length),b)}function a(a){var b=F[a.source];if(!b){var c=D(a.source);c?(b=F[a.source]={url:c.url,map:new M(c.map)},b.map.sourcesContent&&b.map.sources.forEach(function(a,c){var d=b.map.sourcesContent[c];if(d){var g=e(b.url,a);A[g]=d}})):b=F[a.source]=
|
||||
{url:null,map:null}}return b&&b.map&&(c=b.map.originalPositionFor(a),null!==c.source)?(c.source=e(b.url,c.source),c):a}function h(b){var c=/^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(b);return c?(b=a({source:c[2],line:+c[3],column:c[4]-1}),"eval at "+c[1]+" ("+b.source+":"+b.line+":"+(b.column+1)+")"):(c=/^eval at ([^(]+) \((.+)\)$/.exec(b))?"eval at "+c[1]+" ("+h(c[2])+")":b}function u(){var a="";if(this.isNative())a="native";else{var b=this.getScriptNameOrSourceURL();!b&&this.isEval()&&(a=this.getEvalOrigin(),
|
||||
a+=", ");a=b?a+b:a+"<anonymous>";b=this.getLineNumber();null!=b&&(a+=":"+b,(b=this.getColumnNumber())&&(a+=":"+b))}b="";var c=this.getFunctionName(),d=!0,e=this.isConstructor();if(this.isToplevel()||e)e?b+="new "+(c||"<anonymous>"):c?b+=c:(b+=a,d=!1);else{e=this.getTypeName();"[object Object]"===e&&(e="null");var f=this.getMethodName();c?(e&&0!=c.indexOf(e)&&(b+=e+"."),b+=c,f&&c.indexOf("."+f)!=c.length-f.length-1&&(b+=" [as "+f+"]")):b+=e+"."+(f||"<anonymous>")}d&&(b+=" ("+a+")");return b}function r(a){var b=
|
||||
{};Object.getOwnPropertyNames(Object.getPrototypeOf(a)).forEach(function(c){b[c]=/^(?:is|get)/.test(c)?function(){return a[c].call(a)}:a[c]});b.toString=u;return b}function b(b){if(b.isNative())return b;var c=b.getFileName()||b.getScriptNameOrSourceURL();if(c){var d=b.getLineNumber(),e=b.getColumnNumber()-1;1===d&&62<e&&!k()&&!b.isEval()&&(e-=62);var f=a({source:c,line:d,column:e});b=r(b);b.getFileName=function(){return f.source};b.getLineNumber=function(){return f.line};b.getColumnNumber=function(){return f.column+
|
||||
1};b.getScriptNameOrSourceURL=function(){return f.source};return b}var m=b.isEval()&&b.getEvalOrigin();m&&(m=h(m),b=r(b),b.getEvalOrigin=function(){return m});return b}function f(a,c){y&&(A={},F={});return a+c.map(function(a){return"\n at "+b(a)}).join("")}function v(a){var b=/\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(a.stack);if(b){a=b[1];var c=+b[2];b=+b[3];var d=A[a];if(!d&&B&&B.existsSync(a))try{d=B.readFileSync(a,"utf8")}catch(x){d=""}if(d&&(d=d.split(/(?:\r\n|\r|\n)/)[c-1]))return a+":"+
|
||||
c+"\n"+d+"\n"+Array(b).join(" ")+"^"}return null}function t(){var a=c.emit;c.emit=function(b){if("uncaughtException"===b){var d=arguments[1]&&arguments[1].stack,e=0<this.listeners(b).length;if(d&&!e){d=arguments[1];if(e=v(d))console.error(),console.error(e);console.error(d.stack);c.exit(1);return}}return a.apply(this,arguments)}}var M=n("source-map").SourceMapConsumer,I=n("path");try{var B=n("fs");B.existsSync&&B.readFileSync||(B=null)}catch(J){}var L=!1,C=!1,y=!1,K="auto",A={},F={},H=/^data:application\/json[^,]+base64,/,
|
||||
z=[],E=[],p=q(z);z.push(function(a){a=a.trim();if(a in A)return A[a];var b=null;if(!B){var c=new XMLHttpRequest;c.open("GET",a,!1);c.send(null);b=null;4===c.readyState&&200===c.status&&(b=c.responseText)}else if(B.existsSync(a))try{b=B.readFileSync(a,"utf8")}catch(l){b=""}return A[a]=b});var D=q(E);E.push(function(a){a:{if(k())try{var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);var c=b.getResponseHeader("SourceMap")||b.getResponseHeader("X-SourceMap");if(c){var f=c;break a}}catch(P){}f=p(a);
|
||||
b=/(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^\*]+?)[ \t]*(?:\*\/)[ \t]*$)/mg;for(var h;c=b.exec(f);)h=c;f=h?h[1]:null}if(!f)return null;H.test(f)?(h=f.slice(f.indexOf(",")+1),h=(new d(h,"base64")).toString(),f=a):(f=e(a,f),h=p(f));return h?{url:f,map:h}:null});m.wrapCallSite=b;m.getErrorSource=v;m.mapSourcePosition=a;m.retrieveSourceMap=D;m.install=function(a){a=a||{};if(a.environment&&(K=a.environment,-1===["node","browser","auto"].indexOf(K)))throw Error("environment "+
|
||||
K+" was unknown. Available options are {auto, browser, node}");a.retrieveFile&&(a.overrideRetrieveFile&&(z.length=0),z.unshift(a.retrieveFile));a.retrieveSourceMap&&(a.overrideRetrieveSourceMap&&(E.length=0),E.unshift(a.retrieveSourceMap));if(a.hookRequire&&!k()){try{var b=n("module")}catch(l){}var d=b.prototype._compile;d.__sourceMapSupport||(b.prototype._compile=function(a,b){A[b]=a;F[b]=void 0;return d.call(this,a,b)},b.prototype._compile.__sourceMapSupport=!0)}y||(y="emptyCacheBetweenOperations"in
|
||||
a?a.emptyCacheBetweenOperations:!1);L||(L=!0,Error.prepareStackTrace=f);!C&&("handleUncaughtExceptions"in a?a.handleUncaughtExceptions:1)&&"object"===typeof c&&null!==c&&"function"===typeof c.on&&(C=!0,t())}}).call(this,n("node_modules/process/browser.js"),n("buffer").Buffer)},{"node_modules/process/browser.js":7,buffer:4,fs:3,module:3,path:6,"source-map":18}]},{},[1]);return N});
|
30
node_modules/protractor/node_modules/source-map-support/package.json
generated
vendored
Normal file
30
node_modules/protractor/node_modules/source-map-support/package.json
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "source-map-support",
|
||||
"description": "Fixes stack traces for files with source maps",
|
||||
"version": "0.4.18",
|
||||
"main": "./source-map-support.js",
|
||||
"scripts": {
|
||||
"build": "node build.js",
|
||||
"serve-tests": "http-server -p 1336",
|
||||
"prepublish": "npm run build",
|
||||
"test": "mocha"
|
||||
},
|
||||
"dependencies": {
|
||||
"source-map": "^0.5.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browserify": "3.44.2",
|
||||
"coffee-script": "1.7.1",
|
||||
"http-server": "^0.8.5",
|
||||
"mocha": "1.18.2",
|
||||
"webpack": "^1.13.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/evanw/node-source-map-support"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/evanw/node-source-map-support/issues"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
1
node_modules/protractor/node_modules/source-map-support/register.js
generated
vendored
Normal file
1
node_modules/protractor/node_modules/source-map-support/register.js
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
require('./').install();
|
527
node_modules/protractor/node_modules/source-map-support/source-map-support.js
generated
vendored
Normal file
527
node_modules/protractor/node_modules/source-map-support/source-map-support.js
generated
vendored
Normal file
|
@ -0,0 +1,527 @@
|
|||
var SourceMapConsumer = require('source-map').SourceMapConsumer;
|
||||
var path = require('path');
|
||||
|
||||
var fs;
|
||||
try {
|
||||
fs = require('fs');
|
||||
if (!fs.existsSync || !fs.readFileSync) {
|
||||
// fs doesn't have all methods we need
|
||||
fs = null;
|
||||
}
|
||||
} catch (err) {
|
||||
/* nop */
|
||||
}
|
||||
|
||||
// Only install once if called multiple times
|
||||
var errorFormatterInstalled = false;
|
||||
var uncaughtShimInstalled = false;
|
||||
|
||||
// If true, the caches are reset before a stack trace formatting operation
|
||||
var emptyCacheBetweenOperations = false;
|
||||
|
||||
// Supports {browser, node, auto}
|
||||
var environment = "auto";
|
||||
|
||||
// Maps a file path to a string containing the file contents
|
||||
var fileContentsCache = {};
|
||||
|
||||
// Maps a file path to a source map for that file
|
||||
var sourceMapCache = {};
|
||||
|
||||
// Regex for detecting source maps
|
||||
var reSourceMap = /^data:application\/json[^,]+base64,/;
|
||||
|
||||
// Priority list of retrieve handlers
|
||||
var retrieveFileHandlers = [];
|
||||
var retrieveMapHandlers = [];
|
||||
|
||||
function isInBrowser() {
|
||||
if (environment === "browser")
|
||||
return true;
|
||||
if (environment === "node")
|
||||
return false;
|
||||
return ((typeof window !== 'undefined') && (typeof XMLHttpRequest === 'function') && !(window.require && window.module && window.process && window.process.type === "renderer"));
|
||||
}
|
||||
|
||||
function hasGlobalProcessEventEmitter() {
|
||||
return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
|
||||
}
|
||||
|
||||
function handlerExec(list) {
|
||||
return function(arg) {
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var ret = list[i](arg);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
var retrieveFile = handlerExec(retrieveFileHandlers);
|
||||
|
||||
retrieveFileHandlers.push(function(path) {
|
||||
// Trim the path to make sure there is no extra whitespace.
|
||||
path = path.trim();
|
||||
if (path in fileContentsCache) {
|
||||
return fileContentsCache[path];
|
||||
}
|
||||
|
||||
var contents = null;
|
||||
if (!fs) {
|
||||
// Use SJAX if we are in the browser
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', path, false);
|
||||
xhr.send(null);
|
||||
var contents = null
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
contents = xhr.responseText
|
||||
}
|
||||
} else if (fs.existsSync(path)) {
|
||||
// Otherwise, use the filesystem
|
||||
try {
|
||||
contents = fs.readFileSync(path, 'utf8');
|
||||
} catch (er) {
|
||||
contents = '';
|
||||
}
|
||||
}
|
||||
|
||||
return fileContentsCache[path] = contents;
|
||||
});
|
||||
|
||||
// Support URLs relative to a directory, but be careful about a protocol prefix
|
||||
// in case we are in the browser (i.e. directories may start with "http://")
|
||||
function supportRelativeURL(file, url) {
|
||||
if (!file) return url;
|
||||
var dir = path.dirname(file);
|
||||
var match = /^\w+:\/\/[^\/]*/.exec(dir);
|
||||
var protocol = match ? match[0] : '';
|
||||
return protocol + path.resolve(dir.slice(protocol.length), url);
|
||||
}
|
||||
|
||||
function retrieveSourceMapURL(source) {
|
||||
var fileData;
|
||||
|
||||
if (isInBrowser()) {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', source, false);
|
||||
xhr.send(null);
|
||||
fileData = xhr.readyState === 4 ? xhr.responseText : null;
|
||||
|
||||
// Support providing a sourceMappingURL via the SourceMap header
|
||||
var sourceMapHeader = xhr.getResponseHeader("SourceMap") ||
|
||||
xhr.getResponseHeader("X-SourceMap");
|
||||
if (sourceMapHeader) {
|
||||
return sourceMapHeader;
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Get the URL of the source map
|
||||
fileData = retrieveFile(source);
|
||||
var re = /(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^\*]+?)[ \t]*(?:\*\/)[ \t]*$)/mg;
|
||||
// Keep executing the search to find the *last* sourceMappingURL to avoid
|
||||
// picking up sourceMappingURLs from comments, strings, etc.
|
||||
var lastMatch, match;
|
||||
while (match = re.exec(fileData)) lastMatch = match;
|
||||
if (!lastMatch) return null;
|
||||
return lastMatch[1];
|
||||
};
|
||||
|
||||
// Can be overridden by the retrieveSourceMap option to install. Takes a
|
||||
// generated source filename; returns a {map, optional url} object, or null if
|
||||
// there is no source map. The map field may be either a string or the parsed
|
||||
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
|
||||
// constructor).
|
||||
var retrieveSourceMap = handlerExec(retrieveMapHandlers);
|
||||
retrieveMapHandlers.push(function(source) {
|
||||
var sourceMappingURL = retrieveSourceMapURL(source);
|
||||
if (!sourceMappingURL) return null;
|
||||
|
||||
// Read the contents of the source map
|
||||
var sourceMapData;
|
||||
if (reSourceMap.test(sourceMappingURL)) {
|
||||
// Support source map URL as a data url
|
||||
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1);
|
||||
sourceMapData = new Buffer(rawData, "base64").toString();
|
||||
sourceMappingURL = source;
|
||||
} else {
|
||||
// Support source map URLs relative to the source URL
|
||||
sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
|
||||
sourceMapData = retrieveFile(sourceMappingURL);
|
||||
}
|
||||
|
||||
if (!sourceMapData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
url: sourceMappingURL,
|
||||
map: sourceMapData
|
||||
};
|
||||
});
|
||||
|
||||
function mapSourcePosition(position) {
|
||||
var sourceMap = sourceMapCache[position.source];
|
||||
if (!sourceMap) {
|
||||
// Call the (overrideable) retrieveSourceMap function to get the source map.
|
||||
var urlAndMap = retrieveSourceMap(position.source);
|
||||
if (urlAndMap) {
|
||||
sourceMap = sourceMapCache[position.source] = {
|
||||
url: urlAndMap.url,
|
||||
map: new SourceMapConsumer(urlAndMap.map)
|
||||
};
|
||||
|
||||
// Load all sources stored inline with the source map into the file cache
|
||||
// to pretend like they are already loaded. They may not exist on disk.
|
||||
if (sourceMap.map.sourcesContent) {
|
||||
sourceMap.map.sources.forEach(function(source, i) {
|
||||
var contents = sourceMap.map.sourcesContent[i];
|
||||
if (contents) {
|
||||
var url = supportRelativeURL(sourceMap.url, source);
|
||||
fileContentsCache[url] = contents;
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
sourceMap = sourceMapCache[position.source] = {
|
||||
url: null,
|
||||
map: null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the source URL relative to the URL of the source map
|
||||
if (sourceMap && sourceMap.map) {
|
||||
var originalPosition = sourceMap.map.originalPositionFor(position);
|
||||
|
||||
// Only return the original position if a matching line was found. If no
|
||||
// matching line is found then we return position instead, which will cause
|
||||
// the stack trace to print the path and line for the compiled file. It is
|
||||
// better to give a precise location in the compiled file than a vague
|
||||
// location in the original file.
|
||||
if (originalPosition.source !== null) {
|
||||
originalPosition.source = supportRelativeURL(
|
||||
sourceMap.url, originalPosition.source);
|
||||
return originalPosition;
|
||||
}
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
// Parses code generated by FormatEvalOrigin(), a function inside V8:
|
||||
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
|
||||
function mapEvalOrigin(origin) {
|
||||
// Most eval() calls are in this format
|
||||
var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
|
||||
if (match) {
|
||||
var position = mapSourcePosition({
|
||||
source: match[2],
|
||||
line: +match[3],
|
||||
column: match[4] - 1
|
||||
});
|
||||
return 'eval at ' + match[1] + ' (' + position.source + ':' +
|
||||
position.line + ':' + (position.column + 1) + ')';
|
||||
}
|
||||
|
||||
// Parse nested eval() calls using recursion
|
||||
match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
|
||||
if (match) {
|
||||
return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')';
|
||||
}
|
||||
|
||||
// Make sure we still return useful information if we didn't find anything
|
||||
return origin;
|
||||
}
|
||||
|
||||
// This is copied almost verbatim from the V8 source code at
|
||||
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js. The
|
||||
// implementation of wrapCallSite() used to just forward to the actual source
|
||||
// code of CallSite.prototype.toString but unfortunately a new release of V8
|
||||
// did something to the prototype chain and broke the shim. The only fix I
|
||||
// could find was copy/paste.
|
||||
function CallSiteToString() {
|
||||
var fileName;
|
||||
var fileLocation = "";
|
||||
if (this.isNative()) {
|
||||
fileLocation = "native";
|
||||
} else {
|
||||
fileName = this.getScriptNameOrSourceURL();
|
||||
if (!fileName && this.isEval()) {
|
||||
fileLocation = this.getEvalOrigin();
|
||||
fileLocation += ", "; // Expecting source position to follow.
|
||||
}
|
||||
|
||||
if (fileName) {
|
||||
fileLocation += fileName;
|
||||
} else {
|
||||
// Source code does not originate from a file and is not native, but we
|
||||
// can still get the source position inside the source string, e.g. in
|
||||
// an eval string.
|
||||
fileLocation += "<anonymous>";
|
||||
}
|
||||
var lineNumber = this.getLineNumber();
|
||||
if (lineNumber != null) {
|
||||
fileLocation += ":" + lineNumber;
|
||||
var columnNumber = this.getColumnNumber();
|
||||
if (columnNumber) {
|
||||
fileLocation += ":" + columnNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var line = "";
|
||||
var functionName = this.getFunctionName();
|
||||
var addSuffix = true;
|
||||
var isConstructor = this.isConstructor();
|
||||
var isMethodCall = !(this.isToplevel() || isConstructor);
|
||||
if (isMethodCall) {
|
||||
var typeName = this.getTypeName();
|
||||
// Fixes shim to be backward compatable with Node v0 to v4
|
||||
if (typeName === "[object Object]") {
|
||||
typeName = "null";
|
||||
}
|
||||
var methodName = this.getMethodName();
|
||||
if (functionName) {
|
||||
if (typeName && functionName.indexOf(typeName) != 0) {
|
||||
line += typeName + ".";
|
||||
}
|
||||
line += functionName;
|
||||
if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
|
||||
line += " [as " + methodName + "]";
|
||||
}
|
||||
} else {
|
||||
line += typeName + "." + (methodName || "<anonymous>");
|
||||
}
|
||||
} else if (isConstructor) {
|
||||
line += "new " + (functionName || "<anonymous>");
|
||||
} else if (functionName) {
|
||||
line += functionName;
|
||||
} else {
|
||||
line += fileLocation;
|
||||
addSuffix = false;
|
||||
}
|
||||
if (addSuffix) {
|
||||
line += " (" + fileLocation + ")";
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
function cloneCallSite(frame) {
|
||||
var object = {};
|
||||
Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
|
||||
object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name];
|
||||
});
|
||||
object.toString = CallSiteToString;
|
||||
return object;
|
||||
}
|
||||
|
||||
function wrapCallSite(frame) {
|
||||
if(frame.isNative()) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Most call sites will return the source file from getFileName(), but code
|
||||
// passed to eval() ending in "//# sourceURL=..." will return the source file
|
||||
// from getScriptNameOrSourceURL() instead
|
||||
var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
|
||||
if (source) {
|
||||
var line = frame.getLineNumber();
|
||||
var column = frame.getColumnNumber() - 1;
|
||||
|
||||
// Fix position in Node where some (internal) code is prepended.
|
||||
// See https://github.com/evanw/node-source-map-support/issues/36
|
||||
var headerLength = 62;
|
||||
if (line === 1 && column > headerLength && !isInBrowser() && !frame.isEval()) {
|
||||
column -= headerLength;
|
||||
}
|
||||
|
||||
var position = mapSourcePosition({
|
||||
source: source,
|
||||
line: line,
|
||||
column: column
|
||||
});
|
||||
frame = cloneCallSite(frame);
|
||||
frame.getFileName = function() { return position.source; };
|
||||
frame.getLineNumber = function() { return position.line; };
|
||||
frame.getColumnNumber = function() { return position.column + 1; };
|
||||
frame.getScriptNameOrSourceURL = function() { return position.source; };
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Code called using eval() needs special handling
|
||||
var origin = frame.isEval() && frame.getEvalOrigin();
|
||||
if (origin) {
|
||||
origin = mapEvalOrigin(origin);
|
||||
frame = cloneCallSite(frame);
|
||||
frame.getEvalOrigin = function() { return origin; };
|
||||
return frame;
|
||||
}
|
||||
|
||||
// If we get here then we were unable to change the source position
|
||||
return frame;
|
||||
}
|
||||
|
||||
// This function is part of the V8 stack trace API, for more info see:
|
||||
// http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
|
||||
function prepareStackTrace(error, stack) {
|
||||
if (emptyCacheBetweenOperations) {
|
||||
fileContentsCache = {};
|
||||
sourceMapCache = {};
|
||||
}
|
||||
|
||||
return error + stack.map(function(frame) {
|
||||
return '\n at ' + wrapCallSite(frame);
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// Generate position and snippet of original source with pointer
|
||||
function getErrorSource(error) {
|
||||
var match = /\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack);
|
||||
if (match) {
|
||||
var source = match[1];
|
||||
var line = +match[2];
|
||||
var column = +match[3];
|
||||
|
||||
// Support the inline sourceContents inside the source map
|
||||
var contents = fileContentsCache[source];
|
||||
|
||||
// Support files on disk
|
||||
if (!contents && fs && fs.existsSync(source)) {
|
||||
try {
|
||||
contents = fs.readFileSync(source, 'utf8');
|
||||
} catch (er) {
|
||||
contents = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Format the line from the original source code like node does
|
||||
if (contents) {
|
||||
var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
|
||||
if (code) {
|
||||
return source + ':' + line + '\n' + code + '\n' +
|
||||
new Array(column).join(' ') + '^';
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function printErrorAndExit (error) {
|
||||
var source = getErrorSource(error);
|
||||
|
||||
if (source) {
|
||||
console.error();
|
||||
console.error(source);
|
||||
}
|
||||
|
||||
console.error(error.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function shimEmitUncaughtException () {
|
||||
var origEmit = process.emit;
|
||||
|
||||
process.emit = function (type) {
|
||||
if (type === 'uncaughtException') {
|
||||
var hasStack = (arguments[1] && arguments[1].stack);
|
||||
var hasListeners = (this.listeners(type).length > 0);
|
||||
|
||||
if (hasStack && !hasListeners) {
|
||||
return printErrorAndExit(arguments[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return origEmit.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
exports.wrapCallSite = wrapCallSite;
|
||||
exports.getErrorSource = getErrorSource;
|
||||
exports.mapSourcePosition = mapSourcePosition;
|
||||
exports.retrieveSourceMap = retrieveSourceMap;
|
||||
|
||||
exports.install = function(options) {
|
||||
options = options || {};
|
||||
|
||||
if (options.environment) {
|
||||
environment = options.environment;
|
||||
if (["node", "browser", "auto"].indexOf(environment) === -1) {
|
||||
throw new Error("environment " + environment + " was unknown. Available options are {auto, browser, node}")
|
||||
}
|
||||
}
|
||||
|
||||
// Allow sources to be found by methods other than reading the files
|
||||
// directly from disk.
|
||||
if (options.retrieveFile) {
|
||||
if (options.overrideRetrieveFile) {
|
||||
retrieveFileHandlers.length = 0;
|
||||
}
|
||||
|
||||
retrieveFileHandlers.unshift(options.retrieveFile);
|
||||
}
|
||||
|
||||
// Allow source maps to be found by methods other than reading the files
|
||||
// directly from disk.
|
||||
if (options.retrieveSourceMap) {
|
||||
if (options.overrideRetrieveSourceMap) {
|
||||
retrieveMapHandlers.length = 0;
|
||||
}
|
||||
|
||||
retrieveMapHandlers.unshift(options.retrieveSourceMap);
|
||||
}
|
||||
|
||||
// Support runtime transpilers that include inline source maps
|
||||
if (options.hookRequire && !isInBrowser()) {
|
||||
var Module;
|
||||
try {
|
||||
Module = require('module');
|
||||
} catch (err) {
|
||||
// NOP: Loading in catch block to convert webpack error to warning.
|
||||
}
|
||||
var $compile = Module.prototype._compile;
|
||||
|
||||
if (!$compile.__sourceMapSupport) {
|
||||
Module.prototype._compile = function(content, filename) {
|
||||
fileContentsCache[filename] = content;
|
||||
sourceMapCache[filename] = undefined;
|
||||
return $compile.call(this, content, filename);
|
||||
};
|
||||
|
||||
Module.prototype._compile.__sourceMapSupport = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Configure options
|
||||
if (!emptyCacheBetweenOperations) {
|
||||
emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
|
||||
options.emptyCacheBetweenOperations : false;
|
||||
}
|
||||
|
||||
// Install the error reformatter
|
||||
if (!errorFormatterInstalled) {
|
||||
errorFormatterInstalled = true;
|
||||
Error.prepareStackTrace = prepareStackTrace;
|
||||
}
|
||||
|
||||
if (!uncaughtShimInstalled) {
|
||||
var installHandler = 'handleUncaughtExceptions' in options ?
|
||||
options.handleUncaughtExceptions : true;
|
||||
|
||||
// Provide the option to not install the uncaught exception handler. This is
|
||||
// to support other uncaught exception handlers (in test frameworks, for
|
||||
// example). If this handler is not installed and there are no other uncaught
|
||||
// exception handlers, uncaught exceptions will be caught by node's built-in
|
||||
// exception handler and the process will still be terminated. However, the
|
||||
// generated JavaScript code will be shown above the stack trace instead of
|
||||
// the original source code.
|
||||
if (installHandler && hasGlobalProcessEventEmitter()) {
|
||||
uncaughtShimInstalled = true;
|
||||
shimEmitUncaughtException();
|
||||
}
|
||||
}
|
||||
};
|
301
node_modules/protractor/node_modules/source-map/CHANGELOG.md
generated
vendored
Normal file
301
node_modules/protractor/node_modules/source-map/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,301 @@
|
|||
# Change Log
|
||||
|
||||
## 0.5.6
|
||||
|
||||
* Fix for regression when people were using numbers as names in source maps. See
|
||||
#236.
|
||||
|
||||
## 0.5.5
|
||||
|
||||
* Fix "regression" of unsupported, implementation behavior that half the world
|
||||
happens to have come to depend on. See #235.
|
||||
|
||||
* Fix regression involving function hoisting in SpiderMonkey. See #233.
|
||||
|
||||
## 0.5.4
|
||||
|
||||
* Large performance improvements to source-map serialization. See #228 and #229.
|
||||
|
||||
## 0.5.3
|
||||
|
||||
* Do not include unnecessary distribution files. See
|
||||
commit ef7006f8d1647e0a83fdc60f04f5a7ca54886f86.
|
||||
|
||||
## 0.5.2
|
||||
|
||||
* Include browser distributions of the library in package.json's `files`. See
|
||||
issue #212.
|
||||
|
||||
## 0.5.1
|
||||
|
||||
* Fix latent bugs in IndexedSourceMapConsumer.prototype._parseMappings. See
|
||||
ff05274becc9e6e1295ed60f3ea090d31d843379.
|
||||
|
||||
## 0.5.0
|
||||
|
||||
* Node 0.8 is no longer supported.
|
||||
|
||||
* Use webpack instead of dryice for bundling.
|
||||
|
||||
* Big speedups serializing source maps. See pull request #203.
|
||||
|
||||
* Fix a bug with `SourceMapConsumer.prototype.sourceContentFor` and sources that
|
||||
explicitly start with the source root. See issue #199.
|
||||
|
||||
## 0.4.4
|
||||
|
||||
* Fix an issue where using a `SourceMapGenerator` after having created a
|
||||
`SourceMapConsumer` from it via `SourceMapConsumer.fromSourceMap` failed. See
|
||||
issue #191.
|
||||
|
||||
* Fix an issue with where `SourceMapGenerator` would mistakenly consider
|
||||
different mappings as duplicates of each other and avoid generating them. See
|
||||
issue #192.
|
||||
|
||||
## 0.4.3
|
||||
|
||||
* A very large number of performance improvements, particularly when parsing
|
||||
source maps. Collectively about 75% of time shaved off of the source map
|
||||
parsing benchmark!
|
||||
|
||||
* Fix a bug in `SourceMapConsumer.prototype.allGeneratedPositionsFor` and fuzzy
|
||||
searching in the presence of a column option. See issue #177.
|
||||
|
||||
* Fix a bug with joining a source and its source root when the source is above
|
||||
the root. See issue #182.
|
||||
|
||||
* Add the `SourceMapConsumer.prototype.hasContentsOfAllSources` method to
|
||||
determine when all sources' contents are inlined into the source map. See
|
||||
issue #190.
|
||||
|
||||
## 0.4.2
|
||||
|
||||
* Add an `.npmignore` file so that the benchmarks aren't pulled down by
|
||||
dependent projects. Issue #169.
|
||||
|
||||
* Add an optional `column` argument to
|
||||
`SourceMapConsumer.prototype.allGeneratedPositionsFor` and better handle lines
|
||||
with no mappings. Issues #172 and #173.
|
||||
|
||||
## 0.4.1
|
||||
|
||||
* Fix accidentally defining a global variable. #170.
|
||||
|
||||
## 0.4.0
|
||||
|
||||
* The default direction for fuzzy searching was changed back to its original
|
||||
direction. See #164.
|
||||
|
||||
* There is now a `bias` option you can supply to `SourceMapConsumer` to control
|
||||
the fuzzy searching direction. See #167.
|
||||
|
||||
* About an 8% speed up in parsing source maps. See #159.
|
||||
|
||||
* Added a benchmark for parsing and generating source maps.
|
||||
|
||||
## 0.3.0
|
||||
|
||||
* Change the default direction that searching for positions fuzzes when there is
|
||||
not an exact match. See #154.
|
||||
|
||||
* Support for environments using json2.js for JSON serialization. See #156.
|
||||
|
||||
## 0.2.0
|
||||
|
||||
* Support for consuming "indexed" source maps which do not have any remote
|
||||
sections. See pull request #127. This introduces a minor backwards
|
||||
incompatibility if you are monkey patching `SourceMapConsumer.prototype`
|
||||
methods.
|
||||
|
||||
## 0.1.43
|
||||
|
||||
* Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue
|
||||
#148 for some discussion and issues #150, #151, and #152 for implementations.
|
||||
|
||||
## 0.1.42
|
||||
|
||||
* Fix an issue where `SourceNode`s from different versions of the source-map
|
||||
library couldn't be used in conjunction with each other. See issue #142.
|
||||
|
||||
## 0.1.41
|
||||
|
||||
* Fix a bug with getting the source content of relative sources with a "./"
|
||||
prefix. See issue #145 and [Bug 1090768](bugzil.la/1090768).
|
||||
|
||||
* Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the
|
||||
column span of each mapping.
|
||||
|
||||
* Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find
|
||||
all generated positions associated with a given original source and line.
|
||||
|
||||
## 0.1.40
|
||||
|
||||
* Performance improvements for parsing source maps in SourceMapConsumer.
|
||||
|
||||
## 0.1.39
|
||||
|
||||
* Fix a bug where setting a source's contents to null before any source content
|
||||
had been set before threw a TypeError. See issue #131.
|
||||
|
||||
## 0.1.38
|
||||
|
||||
* Fix a bug where finding relative paths from an empty path were creating
|
||||
absolute paths. See issue #129.
|
||||
|
||||
## 0.1.37
|
||||
|
||||
* Fix a bug where if the source root was an empty string, relative source paths
|
||||
would turn into absolute source paths. Issue #124.
|
||||
|
||||
## 0.1.36
|
||||
|
||||
* Allow the `names` mapping property to be an empty string. Issue #121.
|
||||
|
||||
## 0.1.35
|
||||
|
||||
* A third optional parameter was added to `SourceNode.fromStringWithSourceMap`
|
||||
to specify a path that relative sources in the second parameter should be
|
||||
relative to. Issue #105.
|
||||
|
||||
* If no file property is given to a `SourceMapGenerator`, then the resulting
|
||||
source map will no longer have a `null` file property. The property will
|
||||
simply not exist. Issue #104.
|
||||
|
||||
* Fixed a bug where consecutive newlines were ignored in `SourceNode`s.
|
||||
Issue #116.
|
||||
|
||||
## 0.1.34
|
||||
|
||||
* Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103.
|
||||
|
||||
* Fix bug involving source contents and the
|
||||
`SourceMapGenerator.prototype.applySourceMap`. Issue #100.
|
||||
|
||||
## 0.1.33
|
||||
|
||||
* Fix some edge cases surrounding path joining and URL resolution.
|
||||
|
||||
* Add a third parameter for relative path to
|
||||
`SourceMapGenerator.prototype.applySourceMap`.
|
||||
|
||||
* Fix issues with mappings and EOLs.
|
||||
|
||||
## 0.1.32
|
||||
|
||||
* Fixed a bug where SourceMapConsumer couldn't handle negative relative columns
|
||||
(issue 92).
|
||||
|
||||
* Fixed test runner to actually report number of failed tests as its process
|
||||
exit code.
|
||||
|
||||
* Fixed a typo when reporting bad mappings (issue 87).
|
||||
|
||||
## 0.1.31
|
||||
|
||||
* Delay parsing the mappings in SourceMapConsumer until queried for a source
|
||||
location.
|
||||
|
||||
* Support Sass source maps (which at the time of writing deviate from the spec
|
||||
in small ways) in SourceMapConsumer.
|
||||
|
||||
## 0.1.30
|
||||
|
||||
* Do not join source root with a source, when the source is a data URI.
|
||||
|
||||
* Extend the test runner to allow running single specific test files at a time.
|
||||
|
||||
* Performance improvements in `SourceNode.prototype.walk` and
|
||||
`SourceMapConsumer.prototype.eachMapping`.
|
||||
|
||||
* Source map browser builds will now work inside Workers.
|
||||
|
||||
* Better error messages when attempting to add an invalid mapping to a
|
||||
`SourceMapGenerator`.
|
||||
|
||||
## 0.1.29
|
||||
|
||||
* Allow duplicate entries in the `names` and `sources` arrays of source maps
|
||||
(usually from TypeScript) we are parsing. Fixes github issue 72.
|
||||
|
||||
## 0.1.28
|
||||
|
||||
* Skip duplicate mappings when creating source maps from SourceNode; github
|
||||
issue 75.
|
||||
|
||||
## 0.1.27
|
||||
|
||||
* Don't throw an error when the `file` property is missing in SourceMapConsumer,
|
||||
we don't use it anyway.
|
||||
|
||||
## 0.1.26
|
||||
|
||||
* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70.
|
||||
|
||||
## 0.1.25
|
||||
|
||||
* Make compatible with browserify
|
||||
|
||||
## 0.1.24
|
||||
|
||||
* Fix issue with absolute paths and `file://` URIs. See
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=885597
|
||||
|
||||
## 0.1.23
|
||||
|
||||
* Fix issue with absolute paths and sourcesContent, github issue 64.
|
||||
|
||||
## 0.1.22
|
||||
|
||||
* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21.
|
||||
|
||||
## 0.1.21
|
||||
|
||||
* Fixed handling of sources that start with a slash so that they are relative to
|
||||
the source root's host.
|
||||
|
||||
## 0.1.20
|
||||
|
||||
* Fixed github issue #43: absolute URLs aren't joined with the source root
|
||||
anymore.
|
||||
|
||||
## 0.1.19
|
||||
|
||||
* Using Travis CI to run tests.
|
||||
|
||||
## 0.1.18
|
||||
|
||||
* Fixed a bug in the handling of sourceRoot.
|
||||
|
||||
## 0.1.17
|
||||
|
||||
* Added SourceNode.fromStringWithSourceMap.
|
||||
|
||||
## 0.1.16
|
||||
|
||||
* Added missing documentation.
|
||||
|
||||
* Fixed the generating of empty mappings in SourceNode.
|
||||
|
||||
## 0.1.15
|
||||
|
||||
* Added SourceMapGenerator.applySourceMap.
|
||||
|
||||
## 0.1.14
|
||||
|
||||
* The sourceRoot is now handled consistently.
|
||||
|
||||
## 0.1.13
|
||||
|
||||
* Added SourceMapGenerator.fromSourceMap.
|
||||
|
||||
## 0.1.12
|
||||
|
||||
* SourceNode now generates empty mappings too.
|
||||
|
||||
## 0.1.11
|
||||
|
||||
* Added name support to SourceNode.
|
||||
|
||||
## 0.1.10
|
||||
|
||||
* Added sourcesContent support to the customer and generator.
|
28
node_modules/protractor/node_modules/source-map/LICENSE
generated
vendored
Normal file
28
node_modules/protractor/node_modules/source-map/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
Copyright (c) 2009-2011, Mozilla Foundation and contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the Mozilla Foundation nor the names of project
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
729
node_modules/protractor/node_modules/source-map/README.md
generated
vendored
Normal file
729
node_modules/protractor/node_modules/source-map/README.md
generated
vendored
Normal file
|
@ -0,0 +1,729 @@
|
|||
# Source Map
|
||||
|
||||
[](https://travis-ci.org/mozilla/source-map)
|
||||
|
||||
[](https://www.npmjs.com/package/source-map)
|
||||
|
||||
This is a library to generate and consume the source map format
|
||||
[described here][format].
|
||||
|
||||
[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
|
||||
|
||||
## Use with Node
|
||||
|
||||
$ npm install source-map
|
||||
|
||||
## Use on the Web
|
||||
|
||||
<script src="https://raw.githubusercontent.com/mozilla/source-map/master/dist/source-map.min.js" defer></script>
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
<!-- `npm run toc` to regenerate the Table of Contents -->
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
## Table of Contents
|
||||
|
||||
- [Examples](#examples)
|
||||
- [Consuming a source map](#consuming-a-source-map)
|
||||
- [Generating a source map](#generating-a-source-map)
|
||||
- [With SourceNode (high level API)](#with-sourcenode-high-level-api)
|
||||
- [With SourceMapGenerator (low level API)](#with-sourcemapgenerator-low-level-api)
|
||||
- [API](#api)
|
||||
- [SourceMapConsumer](#sourcemapconsumer)
|
||||
- [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap)
|
||||
- [SourceMapConsumer.prototype.computeColumnSpans()](#sourcemapconsumerprototypecomputecolumnspans)
|
||||
- [SourceMapConsumer.prototype.originalPositionFor(generatedPosition)](#sourcemapconsumerprototypeoriginalpositionforgeneratedposition)
|
||||
- [SourceMapConsumer.prototype.generatedPositionFor(originalPosition)](#sourcemapconsumerprototypegeneratedpositionfororiginalposition)
|
||||
- [SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)](#sourcemapconsumerprototypeallgeneratedpositionsfororiginalposition)
|
||||
- [SourceMapConsumer.prototype.hasContentsOfAllSources()](#sourcemapconsumerprototypehascontentsofallsources)
|
||||
- [SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])](#sourcemapconsumerprototypesourcecontentforsource-returnnullonmissing)
|
||||
- [SourceMapConsumer.prototype.eachMapping(callback, context, order)](#sourcemapconsumerprototypeeachmappingcallback-context-order)
|
||||
- [SourceMapGenerator](#sourcemapgenerator)
|
||||
- [new SourceMapGenerator([startOfSourceMap])](#new-sourcemapgeneratorstartofsourcemap)
|
||||
- [SourceMapGenerator.fromSourceMap(sourceMapConsumer)](#sourcemapgeneratorfromsourcemapsourcemapconsumer)
|
||||
- [SourceMapGenerator.prototype.addMapping(mapping)](#sourcemapgeneratorprototypeaddmappingmapping)
|
||||
- [SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)](#sourcemapgeneratorprototypesetsourcecontentsourcefile-sourcecontent)
|
||||
- [SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])](#sourcemapgeneratorprototypeapplysourcemapsourcemapconsumer-sourcefile-sourcemappath)
|
||||
- [SourceMapGenerator.prototype.toString()](#sourcemapgeneratorprototypetostring)
|
||||
- [SourceNode](#sourcenode)
|
||||
- [new SourceNode([line, column, source[, chunk[, name]]])](#new-sourcenodeline-column-source-chunk-name)
|
||||
- [SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])](#sourcenodefromstringwithsourcemapcode-sourcemapconsumer-relativepath)
|
||||
- [SourceNode.prototype.add(chunk)](#sourcenodeprototypeaddchunk)
|
||||
- [SourceNode.prototype.prepend(chunk)](#sourcenodeprototypeprependchunk)
|
||||
- [SourceNode.prototype.setSourceContent(sourceFile, sourceContent)](#sourcenodeprototypesetsourcecontentsourcefile-sourcecontent)
|
||||
- [SourceNode.prototype.walk(fn)](#sourcenodeprototypewalkfn)
|
||||
- [SourceNode.prototype.walkSourceContents(fn)](#sourcenodeprototypewalksourcecontentsfn)
|
||||
- [SourceNode.prototype.join(sep)](#sourcenodeprototypejoinsep)
|
||||
- [SourceNode.prototype.replaceRight(pattern, replacement)](#sourcenodeprototypereplacerightpattern-replacement)
|
||||
- [SourceNode.prototype.toString()](#sourcenodeprototypetostring)
|
||||
- [SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])](#sourcenodeprototypetostringwithsourcemapstartofsourcemap)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
## Examples
|
||||
|
||||
### Consuming a source map
|
||||
|
||||
```js
|
||||
var rawSourceMap = {
|
||||
version: 3,
|
||||
file: 'min.js',
|
||||
names: ['bar', 'baz', 'n'],
|
||||
sources: ['one.js', 'two.js'],
|
||||
sourceRoot: 'http://example.com/www/js/',
|
||||
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
|
||||
};
|
||||
|
||||
var smc = new SourceMapConsumer(rawSourceMap);
|
||||
|
||||
console.log(smc.sources);
|
||||
// [ 'http://example.com/www/js/one.js',
|
||||
// 'http://example.com/www/js/two.js' ]
|
||||
|
||||
console.log(smc.originalPositionFor({
|
||||
line: 2,
|
||||
column: 28
|
||||
}));
|
||||
// { source: 'http://example.com/www/js/two.js',
|
||||
// line: 2,
|
||||
// column: 10,
|
||||
// name: 'n' }
|
||||
|
||||
console.log(smc.generatedPositionFor({
|
||||
source: 'http://example.com/www/js/two.js',
|
||||
line: 2,
|
||||
column: 10
|
||||
}));
|
||||
// { line: 2, column: 28 }
|
||||
|
||||
smc.eachMapping(function (m) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### Generating a source map
|
||||
|
||||
In depth guide:
|
||||
[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/)
|
||||
|
||||
#### With SourceNode (high level API)
|
||||
|
||||
```js
|
||||
function compile(ast) {
|
||||
switch (ast.type) {
|
||||
case 'BinaryExpression':
|
||||
return new SourceNode(
|
||||
ast.location.line,
|
||||
ast.location.column,
|
||||
ast.location.source,
|
||||
[compile(ast.left), " + ", compile(ast.right)]
|
||||
);
|
||||
case 'Literal':
|
||||
return new SourceNode(
|
||||
ast.location.line,
|
||||
ast.location.column,
|
||||
ast.location.source,
|
||||
String(ast.value)
|
||||
);
|
||||
// ...
|
||||
default:
|
||||
throw new Error("Bad AST");
|
||||
}
|
||||
}
|
||||
|
||||
var ast = parse("40 + 2", "add.js");
|
||||
console.log(compile(ast).toStringWithSourceMap({
|
||||
file: 'add.js'
|
||||
}));
|
||||
// { code: '40 + 2',
|
||||
// map: [object SourceMapGenerator] }
|
||||
```
|
||||
|
||||
#### With SourceMapGenerator (low level API)
|
||||
|
||||
```js
|
||||
var map = new SourceMapGenerator({
|
||||
file: "source-mapped.js"
|
||||
});
|
||||
|
||||
map.addMapping({
|
||||
generated: {
|
||||
line: 10,
|
||||
column: 35
|
||||
},
|
||||
source: "foo.js",
|
||||
original: {
|
||||
line: 33,
|
||||
column: 2
|
||||
},
|
||||
name: "christopher"
|
||||
});
|
||||
|
||||
console.log(map.toString());
|
||||
// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
Get a reference to the module:
|
||||
|
||||
```js
|
||||
// Node.js
|
||||
var sourceMap = require('source-map');
|
||||
|
||||
// Browser builds
|
||||
var sourceMap = window.sourceMap;
|
||||
|
||||
// Inside Firefox
|
||||
const sourceMap = require("devtools/toolkit/sourcemap/source-map.js");
|
||||
```
|
||||
|
||||
### SourceMapConsumer
|
||||
|
||||
A SourceMapConsumer instance represents a parsed source map which we can query
|
||||
for information about the original file positions by giving it a file position
|
||||
in the generated source.
|
||||
|
||||
#### new SourceMapConsumer(rawSourceMap)
|
||||
|
||||
The only parameter is the raw source map (either as a string which can be
|
||||
`JSON.parse`'d, or an object). According to the spec, source maps have the
|
||||
following attributes:
|
||||
|
||||
* `version`: Which version of the source map spec this map is following.
|
||||
|
||||
* `sources`: An array of URLs to the original source files.
|
||||
|
||||
* `names`: An array of identifiers which can be referenced by individual
|
||||
mappings.
|
||||
|
||||
* `sourceRoot`: Optional. The URL root from which all sources are relative.
|
||||
|
||||
* `sourcesContent`: Optional. An array of contents of the original source files.
|
||||
|
||||
* `mappings`: A string of base64 VLQs which contain the actual mappings.
|
||||
|
||||
* `file`: Optional. The generated filename this source map is associated with.
|
||||
|
||||
```js
|
||||
var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData);
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.computeColumnSpans()
|
||||
|
||||
Compute the last column for each generated mapping. The last column is
|
||||
inclusive.
|
||||
|
||||
```js
|
||||
// Before:
|
||||
consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
|
||||
// [ { line: 2,
|
||||
// column: 1 },
|
||||
// { line: 2,
|
||||
// column: 10 },
|
||||
// { line: 2,
|
||||
// column: 20 } ]
|
||||
|
||||
consumer.computeColumnSpans();
|
||||
|
||||
// After:
|
||||
consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
|
||||
// [ { line: 2,
|
||||
// column: 1,
|
||||
// lastColumn: 9 },
|
||||
// { line: 2,
|
||||
// column: 10,
|
||||
// lastColumn: 19 },
|
||||
// { line: 2,
|
||||
// column: 20,
|
||||
// lastColumn: Infinity } ]
|
||||
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition)
|
||||
|
||||
Returns the original source, line, and column information for the generated
|
||||
source's line and column positions provided. The only argument is an object with
|
||||
the following properties:
|
||||
|
||||
* `line`: The line number in the generated source.
|
||||
|
||||
* `column`: The column number in the generated source.
|
||||
|
||||
* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or
|
||||
`SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest
|
||||
element that is smaller than or greater than the one we are searching for,
|
||||
respectively, if the exact element cannot be found. Defaults to
|
||||
`SourceMapConsumer.GREATEST_LOWER_BOUND`.
|
||||
|
||||
and an object is returned with the following properties:
|
||||
|
||||
* `source`: The original source file, or null if this information is not
|
||||
available.
|
||||
|
||||
* `line`: The line number in the original source, or null if this information is
|
||||
not available.
|
||||
|
||||
* `column`: The column number in the original source, or null if this
|
||||
information is not available.
|
||||
|
||||
* `name`: The original identifier, or null if this information is not available.
|
||||
|
||||
```js
|
||||
consumer.originalPositionFor({ line: 2, column: 10 })
|
||||
// { source: 'foo.coffee',
|
||||
// line: 2,
|
||||
// column: 2,
|
||||
// name: null }
|
||||
|
||||
consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 })
|
||||
// { source: null,
|
||||
// line: null,
|
||||
// column: null,
|
||||
// name: null }
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition)
|
||||
|
||||
Returns the generated line and column information for the original source,
|
||||
line, and column positions provided. The only argument is an object with
|
||||
the following properties:
|
||||
|
||||
* `source`: The filename of the original source.
|
||||
|
||||
* `line`: The line number in the original source.
|
||||
|
||||
* `column`: The column number in the original source.
|
||||
|
||||
and an object is returned with the following properties:
|
||||
|
||||
* `line`: The line number in the generated source, or null.
|
||||
|
||||
* `column`: The column number in the generated source, or null.
|
||||
|
||||
```js
|
||||
consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 })
|
||||
// { line: 1,
|
||||
// column: 56 }
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)
|
||||
|
||||
Returns all generated line and column information for the original source, line,
|
||||
and column provided. If no column is provided, returns all mappings
|
||||
corresponding to a either the line we are searching for or the next closest line
|
||||
that has any mappings. Otherwise, returns all mappings corresponding to the
|
||||
given line and either the column we are searching for or the next closest column
|
||||
that has any offsets.
|
||||
|
||||
The only argument is an object with the following properties:
|
||||
|
||||
* `source`: The filename of the original source.
|
||||
|
||||
* `line`: The line number in the original source.
|
||||
|
||||
* `column`: Optional. The column number in the original source.
|
||||
|
||||
and an array of objects is returned, each with the following properties:
|
||||
|
||||
* `line`: The line number in the generated source, or null.
|
||||
|
||||
* `column`: The column number in the generated source, or null.
|
||||
|
||||
```js
|
||||
consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" })
|
||||
// [ { line: 2,
|
||||
// column: 1 },
|
||||
// { line: 2,
|
||||
// column: 10 },
|
||||
// { line: 2,
|
||||
// column: 20 } ]
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.hasContentsOfAllSources()
|
||||
|
||||
Return true if we have the embedded source content for every source listed in
|
||||
the source map, false otherwise.
|
||||
|
||||
In other words, if this method returns `true`, then
|
||||
`consumer.sourceContentFor(s)` will succeed for every source `s` in
|
||||
`consumer.sources`.
|
||||
|
||||
```js
|
||||
// ...
|
||||
if (consumer.hasContentsOfAllSources()) {
|
||||
consumerReadyCallback(consumer);
|
||||
} else {
|
||||
fetchSources(consumer, consumerReadyCallback);
|
||||
}
|
||||
// ...
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])
|
||||
|
||||
Returns the original source content for the source provided. The only
|
||||
argument is the URL of the original source file.
|
||||
|
||||
If the source content for the given source is not found, then an error is
|
||||
thrown. Optionally, pass `true` as the second param to have `null` returned
|
||||
instead.
|
||||
|
||||
```js
|
||||
consumer.sources
|
||||
// [ "my-cool-lib.clj" ]
|
||||
|
||||
consumer.sourceContentFor("my-cool-lib.clj")
|
||||
// "..."
|
||||
|
||||
consumer.sourceContentFor("this is not in the source map");
|
||||
// Error: "this is not in the source map" is not in the source map
|
||||
|
||||
consumer.sourceContentFor("this is not in the source map", true);
|
||||
// null
|
||||
```
|
||||
|
||||
#### SourceMapConsumer.prototype.eachMapping(callback, context, order)
|
||||
|
||||
Iterate over each mapping between an original source/line/column and a
|
||||
generated line/column in this source map.
|
||||
|
||||
* `callback`: The function that is called with each mapping. Mappings have the
|
||||
form `{ source, generatedLine, generatedColumn, originalLine, originalColumn,
|
||||
name }`
|
||||
|
||||
* `context`: Optional. If specified, this object will be the value of `this`
|
||||
every time that `callback` is called.
|
||||
|
||||
* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or
|
||||
`SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over
|
||||
the mappings sorted by the generated file's line/column order or the
|
||||
original's source/line/column order, respectively. Defaults to
|
||||
`SourceMapConsumer.GENERATED_ORDER`.
|
||||
|
||||
```js
|
||||
consumer.eachMapping(function (m) { console.log(m); })
|
||||
// ...
|
||||
// { source: 'illmatic.js',
|
||||
// generatedLine: 1,
|
||||
// generatedColumn: 0,
|
||||
// originalLine: 1,
|
||||
// originalColumn: 0,
|
||||
// name: null }
|
||||
// { source: 'illmatic.js',
|
||||
// generatedLine: 2,
|
||||
// generatedColumn: 0,
|
||||
// originalLine: 2,
|
||||
// originalColumn: 0,
|
||||
// name: null }
|
||||
// ...
|
||||
```
|
||||
### SourceMapGenerator
|
||||
|
||||
An instance of the SourceMapGenerator represents a source map which is being
|
||||
built incrementally.
|
||||
|
||||
#### new SourceMapGenerator([startOfSourceMap])
|
||||
|
||||
You may pass an object with the following properties:
|
||||
|
||||
* `file`: The filename of the generated source that this source map is
|
||||
associated with.
|
||||
|
||||
* `sourceRoot`: A root for all relative URLs in this source map.
|
||||
|
||||
* `skipValidation`: Optional. When `true`, disables validation of mappings as
|
||||
they are added. This can improve performance but should be used with
|
||||
discretion, as a last resort. Even then, one should avoid using this flag when
|
||||
running tests, if possible.
|
||||
|
||||
```js
|
||||
var generator = new sourceMap.SourceMapGenerator({
|
||||
file: "my-generated-javascript-file.js",
|
||||
sourceRoot: "http://example.com/app/js/"
|
||||
});
|
||||
```
|
||||
|
||||
#### SourceMapGenerator.fromSourceMap(sourceMapConsumer)
|
||||
|
||||
Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance.
|
||||
|
||||
* `sourceMapConsumer` The SourceMap.
|
||||
|
||||
```js
|
||||
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);
|
||||
```
|
||||
|
||||
#### SourceMapGenerator.prototype.addMapping(mapping)
|
||||
|
||||
Add a single mapping from original source line and column to the generated
|
||||
source's line and column for this source map being created. The mapping object
|
||||
should have the following properties:
|
||||
|
||||
* `generated`: An object with the generated line and column positions.
|
||||
|
||||
* `original`: An object with the original line and column positions.
|
||||
|
||||
* `source`: The original source file (relative to the sourceRoot).
|
||||
|
||||
* `name`: An optional original token name for this mapping.
|
||||
|
||||
```js
|
||||
generator.addMapping({
|
||||
source: "module-one.scm",
|
||||
original: { line: 128, column: 0 },
|
||||
generated: { line: 3, column: 456 }
|
||||
})
|
||||
```
|
||||
|
||||
#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)
|
||||
|
||||
Set the source content for an original source file.
|
||||
|
||||
* `sourceFile` the URL of the original source file.
|
||||
|
||||
* `sourceContent` the content of the source file.
|
||||
|
||||
```js
|
||||
generator.setSourceContent("module-one.scm",
|
||||
fs.readFileSync("path/to/module-one.scm"))
|
||||
```
|
||||
|
||||
#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])
|
||||
|
||||
Applies a SourceMap for a source file to the SourceMap.
|
||||
Each mapping to the supplied source file is rewritten using the
|
||||
supplied SourceMap. Note: The resolution for the resulting mappings
|
||||
is the minimum of this map and the supplied map.
|
||||
|
||||
* `sourceMapConsumer`: The SourceMap to be applied.
|
||||
|
||||
* `sourceFile`: Optional. The filename of the source file.
|
||||
If omitted, sourceMapConsumer.file will be used, if it exists.
|
||||
Otherwise an error will be thrown.
|
||||
|
||||
* `sourceMapPath`: Optional. The dirname of the path to the SourceMap
|
||||
to be applied. If relative, it is relative to the SourceMap.
|
||||
|
||||
This parameter is needed when the two SourceMaps aren't in the same
|
||||
directory, and the SourceMap to be applied contains relative source
|
||||
paths. If so, those relative source paths need to be rewritten
|
||||
relative to the SourceMap.
|
||||
|
||||
If omitted, it is assumed that both SourceMaps are in the same directory,
|
||||
thus not needing any rewriting. (Supplying `'.'` has the same effect.)
|
||||
|
||||
#### SourceMapGenerator.prototype.toString()
|
||||
|
||||
Renders the source map being generated to a string.
|
||||
|
||||
```js
|
||||
generator.toString()
|
||||
// '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}'
|
||||
```
|
||||
|
||||
### SourceNode
|
||||
|
||||
SourceNodes provide a way to abstract over interpolating and/or concatenating
|
||||
snippets of generated JavaScript source code, while maintaining the line and
|
||||
column information associated between those snippets and the original source
|
||||
code. This is useful as the final intermediate representation a compiler might
|
||||
use before outputting the generated JS and source map.
|
||||
|
||||
#### new SourceNode([line, column, source[, chunk[, name]]])
|
||||
|
||||
* `line`: The original line number associated with this source node, or null if
|
||||
it isn't associated with an original line.
|
||||
|
||||
* `column`: The original column number associated with this source node, or null
|
||||
if it isn't associated with an original column.
|
||||
|
||||
* `source`: The original source's filename; null if no filename is provided.
|
||||
|
||||
* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see
|
||||
below.
|
||||
|
||||
* `name`: Optional. The original identifier.
|
||||
|
||||
```js
|
||||
var node = new SourceNode(1, 2, "a.cpp", [
|
||||
new SourceNode(3, 4, "b.cpp", "extern int status;\n"),
|
||||
new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"),
|
||||
new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"),
|
||||
]);
|
||||
```
|
||||
|
||||
#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])
|
||||
|
||||
Creates a SourceNode from generated code and a SourceMapConsumer.
|
||||
|
||||
* `code`: The generated code
|
||||
|
||||
* `sourceMapConsumer` The SourceMap for the generated code
|
||||
|
||||
* `relativePath` The optional path that relative sources in `sourceMapConsumer`
|
||||
should be relative to.
|
||||
|
||||
```js
|
||||
var consumer = new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8"));
|
||||
var node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"),
|
||||
consumer);
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.add(chunk)
|
||||
|
||||
Add a chunk of generated JS to this source node.
|
||||
|
||||
* `chunk`: A string snippet of generated JS code, another instance of
|
||||
`SourceNode`, or an array where each member is one of those things.
|
||||
|
||||
```js
|
||||
node.add(" + ");
|
||||
node.add(otherNode);
|
||||
node.add([leftHandOperandNode, " + ", rightHandOperandNode]);
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.prepend(chunk)
|
||||
|
||||
Prepend a chunk of generated JS to this source node.
|
||||
|
||||
* `chunk`: A string snippet of generated JS code, another instance of
|
||||
`SourceNode`, or an array where each member is one of those things.
|
||||
|
||||
```js
|
||||
node.prepend("/** Build Id: f783haef86324gf **/\n\n");
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent)
|
||||
|
||||
Set the source content for a source file. This will be added to the
|
||||
`SourceMap` in the `sourcesContent` field.
|
||||
|
||||
* `sourceFile`: The filename of the source file
|
||||
|
||||
* `sourceContent`: The content of the source file
|
||||
|
||||
```js
|
||||
node.setSourceContent("module-one.scm",
|
||||
fs.readFileSync("path/to/module-one.scm"))
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.walk(fn)
|
||||
|
||||
Walk over the tree of JS snippets in this node and its children. The walking
|
||||
function is called once for each snippet of JS and is passed that snippet and
|
||||
the its original associated source's line/column location.
|
||||
|
||||
* `fn`: The traversal function.
|
||||
|
||||
```js
|
||||
var node = new SourceNode(1, 2, "a.js", [
|
||||
new SourceNode(3, 4, "b.js", "uno"),
|
||||
"dos",
|
||||
[
|
||||
"tres",
|
||||
new SourceNode(5, 6, "c.js", "quatro")
|
||||
]
|
||||
]);
|
||||
|
||||
node.walk(function (code, loc) { console.log("WALK:", code, loc); })
|
||||
// WALK: uno { source: 'b.js', line: 3, column: 4, name: null }
|
||||
// WALK: dos { source: 'a.js', line: 1, column: 2, name: null }
|
||||
// WALK: tres { source: 'a.js', line: 1, column: 2, name: null }
|
||||
// WALK: quatro { source: 'c.js', line: 5, column: 6, name: null }
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.walkSourceContents(fn)
|
||||
|
||||
Walk over the tree of SourceNodes. The walking function is called for each
|
||||
source file content and is passed the filename and source content.
|
||||
|
||||
* `fn`: The traversal function.
|
||||
|
||||
```js
|
||||
var a = new SourceNode(1, 2, "a.js", "generated from a");
|
||||
a.setSourceContent("a.js", "original a");
|
||||
var b = new SourceNode(1, 2, "b.js", "generated from b");
|
||||
b.setSourceContent("b.js", "original b");
|
||||
var c = new SourceNode(1, 2, "c.js", "generated from c");
|
||||
c.setSourceContent("c.js", "original c");
|
||||
|
||||
var node = new SourceNode(null, null, null, [a, b, c]);
|
||||
node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); })
|
||||
// WALK: a.js : original a
|
||||
// WALK: b.js : original b
|
||||
// WALK: c.js : original c
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.join(sep)
|
||||
|
||||
Like `Array.prototype.join` except for SourceNodes. Inserts the separator
|
||||
between each of this source node's children.
|
||||
|
||||
* `sep`: The separator.
|
||||
|
||||
```js
|
||||
var lhs = new SourceNode(1, 2, "a.rs", "my_copy");
|
||||
var operand = new SourceNode(3, 4, "a.rs", "=");
|
||||
var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()");
|
||||
|
||||
var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]);
|
||||
var joinedNode = node.join(" ");
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.replaceRight(pattern, replacement)
|
||||
|
||||
Call `String.prototype.replace` on the very right-most source snippet. Useful
|
||||
for trimming white space from the end of a source node, etc.
|
||||
|
||||
* `pattern`: The pattern to replace.
|
||||
|
||||
* `replacement`: The thing to replace the pattern with.
|
||||
|
||||
```js
|
||||
// Trim trailing white space.
|
||||
node.replaceRight(/\s*$/, "");
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.toString()
|
||||
|
||||
Return the string representation of this source node. Walks over the tree and
|
||||
concatenates all the various snippets together to one string.
|
||||
|
||||
```js
|
||||
var node = new SourceNode(1, 2, "a.js", [
|
||||
new SourceNode(3, 4, "b.js", "uno"),
|
||||
"dos",
|
||||
[
|
||||
"tres",
|
||||
new SourceNode(5, 6, "c.js", "quatro")
|
||||
]
|
||||
]);
|
||||
|
||||
node.toString()
|
||||
// 'unodostresquatro'
|
||||
```
|
||||
|
||||
#### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])
|
||||
|
||||
Returns the string representation of this tree of source nodes, plus a
|
||||
SourceMapGenerator which contains all the mappings between the generated and
|
||||
original sources.
|
||||
|
||||
The arguments are the same as those to `new SourceMapGenerator`.
|
||||
|
||||
```js
|
||||
var node = new SourceNode(1, 2, "a.js", [
|
||||
new SourceNode(3, 4, "b.js", "uno"),
|
||||
"dos",
|
||||
[
|
||||
"tres",
|
||||
new SourceNode(5, 6, "c.js", "quatro")
|
||||
]
|
||||
]);
|
||||
|
||||
node.toStringWithSourceMap({ file: "my-output-file.js" })
|
||||
// { code: 'unodostresquatro',
|
||||
// map: [object SourceMapGenerator] }
|
||||
```
|
3091
node_modules/protractor/node_modules/source-map/dist/source-map.debug.js
generated
vendored
Normal file
3091
node_modules/protractor/node_modules/source-map/dist/source-map.debug.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3090
node_modules/protractor/node_modules/source-map/dist/source-map.js
generated
vendored
Normal file
3090
node_modules/protractor/node_modules/source-map/dist/source-map.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
2
node_modules/protractor/node_modules/source-map/dist/source-map.min.js
generated
vendored
Normal file
2
node_modules/protractor/node_modules/source-map/dist/source-map.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
node_modules/protractor/node_modules/source-map/dist/source-map.min.js.map
generated
vendored
Normal file
1
node_modules/protractor/node_modules/source-map/dist/source-map.min.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
121
node_modules/protractor/node_modules/source-map/lib/array-set.js
generated
vendored
Normal file
121
node_modules/protractor/node_modules/source-map/lib/array-set.js
generated
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
var util = require('./util');
|
||||
var has = Object.prototype.hasOwnProperty;
|
||||
var hasNativeMap = typeof Map !== "undefined";
|
||||
|
||||
/**
|
||||
* A data structure which is a combination of an array and a set. Adding a new
|
||||
* member is O(1), testing for membership is O(1), and finding the index of an
|
||||
* element is O(1). Removing elements from the set is not supported. Only
|
||||
* strings are supported for membership.
|
||||
*/
|
||||
function ArraySet() {
|
||||
this._array = [];
|
||||
this._set = hasNativeMap ? new Map() : Object.create(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method for creating ArraySet instances from an existing array.
|
||||
*/
|
||||
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
|
||||
var set = new ArraySet();
|
||||
for (var i = 0, len = aArray.length; i < len; i++) {
|
||||
set.add(aArray[i], aAllowDuplicates);
|
||||
}
|
||||
return set;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return how many unique items are in this ArraySet. If duplicates have been
|
||||
* added, than those do not count towards the size.
|
||||
*
|
||||
* @returns Number
|
||||
*/
|
||||
ArraySet.prototype.size = function ArraySet_size() {
|
||||
return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the given string to this set.
|
||||
*
|
||||
* @param String aStr
|
||||
*/
|
||||
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
|
||||
var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
|
||||
var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
|
||||
var idx = this._array.length;
|
||||
if (!isDuplicate || aAllowDuplicates) {
|
||||
this._array.push(aStr);
|
||||
}
|
||||
if (!isDuplicate) {
|
||||
if (hasNativeMap) {
|
||||
this._set.set(aStr, idx);
|
||||
} else {
|
||||
this._set[sStr] = idx;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Is the given string a member of this set?
|
||||
*
|
||||
* @param String aStr
|
||||
*/
|
||||
ArraySet.prototype.has = function ArraySet_has(aStr) {
|
||||
if (hasNativeMap) {
|
||||
return this._set.has(aStr);
|
||||
} else {
|
||||
var sStr = util.toSetString(aStr);
|
||||
return has.call(this._set, sStr);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* What is the index of the given string in the array?
|
||||
*
|
||||
* @param String aStr
|
||||
*/
|
||||
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
|
||||
if (hasNativeMap) {
|
||||
var idx = this._set.get(aStr);
|
||||
if (idx >= 0) {
|
||||
return idx;
|
||||
}
|
||||
} else {
|
||||
var sStr = util.toSetString(aStr);
|
||||
if (has.call(this._set, sStr)) {
|
||||
return this._set[sStr];
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('"' + aStr + '" is not in the set.');
|
||||
};
|
||||
|
||||
/**
|
||||
* What is the element at the given index?
|
||||
*
|
||||
* @param Number aIdx
|
||||
*/
|
||||
ArraySet.prototype.at = function ArraySet_at(aIdx) {
|
||||
if (aIdx >= 0 && aIdx < this._array.length) {
|
||||
return this._array[aIdx];
|
||||
}
|
||||
throw new Error('No element indexed by ' + aIdx);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the array representation of this set (which has the proper indices
|
||||
* indicated by indexOf). Note that this is a copy of the internal array used
|
||||
* for storing the members so that no one can mess with internal state.
|
||||
*/
|
||||
ArraySet.prototype.toArray = function ArraySet_toArray() {
|
||||
return this._array.slice();
|
||||
};
|
||||
|
||||
exports.ArraySet = ArraySet;
|
140
node_modules/protractor/node_modules/source-map/lib/base64-vlq.js
generated
vendored
Normal file
140
node_modules/protractor/node_modules/source-map/lib/base64-vlq.js
generated
vendored
Normal file
|
@ -0,0 +1,140 @@
|
|||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Based on the Base 64 VLQ implementation in Closure Compiler:
|
||||
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
|
||||
*
|
||||
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
var base64 = require('./base64');
|
||||
|
||||
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
|
||||
// length quantities we use in the source map spec, the first bit is the sign,
|
||||
// the next four bits are the actual value, and the 6th bit is the
|
||||
// continuation bit. The continuation bit tells us whether there are more
|
||||
// digits in this value following this digit.
|
||||
//
|
||||
// Continuation
|
||||
// | Sign
|
||||
// | |
|
||||
// V V
|
||||
// 101011
|
||||
|
||||
var VLQ_BASE_SHIFT = 5;
|
||||
|
||||
// binary: 100000
|
||||
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
|
||||
|
||||
// binary: 011111
|
||||
var VLQ_BASE_MASK = VLQ_BASE - 1;
|
||||
|
||||
// binary: 100000
|
||||
var VLQ_CONTINUATION_BIT = VLQ_BASE;
|
||||
|
||||
/**
|
||||
* Converts from a two-complement value to a value where the sign bit is
|
||||
* placed in the least significant bit. For example, as decimals:
|
||||
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
|
||||
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
|
||||
*/
|
||||
function toVLQSigned(aValue) {
|
||||
return aValue < 0
|
||||
? ((-aValue) << 1) + 1
|
||||
: (aValue << 1) + 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts to a two-complement value from a value where the sign bit is
|
||||
* placed in the least significant bit. For example, as decimals:
|
||||
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
|
||||
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
|
||||
*/
|
||||
function fromVLQSigned(aValue) {
|
||||
var isNegative = (aValue & 1) === 1;
|
||||
var shifted = aValue >> 1;
|
||||
return isNegative
|
||||
? -shifted
|
||||
: shifted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base 64 VLQ encoded value.
|
||||
*/
|
||||
exports.encode = function base64VLQ_encode(aValue) {
|
||||
var encoded = "";
|
||||
var digit;
|
||||
|
||||
var vlq = toVLQSigned(aValue);
|
||||
|
||||
do {
|
||||
digit = vlq & VLQ_BASE_MASK;
|
||||
vlq >>>= VLQ_BASE_SHIFT;
|
||||
if (vlq > 0) {
|
||||
// There are still more digits in this value, so we must make sure the
|
||||
// continuation bit is marked.
|
||||
digit |= VLQ_CONTINUATION_BIT;
|
||||
}
|
||||
encoded += base64.encode(digit);
|
||||
} while (vlq > 0);
|
||||
|
||||
return encoded;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes the next base 64 VLQ value from the given string and returns the
|
||||
* value and the rest of the string via the out parameter.
|
||||
*/
|
||||
exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
|
||||
var strLen = aStr.length;
|
||||
var result = 0;
|
||||
var shift = 0;
|
||||
var continuation, digit;
|
||||
|
||||
do {
|
||||
if (aIndex >= strLen) {
|
||||
throw new Error("Expected more digits in base 64 VLQ value.");
|
||||
}
|
||||
|
||||
digit = base64.decode(aStr.charCodeAt(aIndex++));
|
||||
if (digit === -1) {
|
||||
throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
|
||||
}
|
||||
|
||||
continuation = !!(digit & VLQ_CONTINUATION_BIT);
|
||||
digit &= VLQ_BASE_MASK;
|
||||
result = result + (digit << shift);
|
||||
shift += VLQ_BASE_SHIFT;
|
||||
} while (continuation);
|
||||
|
||||
aOutParam.value = fromVLQSigned(result);
|
||||
aOutParam.rest = aIndex;
|
||||
};
|
67
node_modules/protractor/node_modules/source-map/lib/base64.js
generated
vendored
Normal file
67
node_modules/protractor/node_modules/source-map/lib/base64.js
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
|
||||
|
||||
/**
|
||||
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
|
||||
*/
|
||||
exports.encode = function (number) {
|
||||
if (0 <= number && number < intToCharMap.length) {
|
||||
return intToCharMap[number];
|
||||
}
|
||||
throw new TypeError("Must be between 0 and 63: " + number);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode a single base 64 character code digit to an integer. Returns -1 on
|
||||
* failure.
|
||||
*/
|
||||
exports.decode = function (charCode) {
|
||||
var bigA = 65; // 'A'
|
||||
var bigZ = 90; // 'Z'
|
||||
|
||||
var littleA = 97; // 'a'
|
||||
var littleZ = 122; // 'z'
|
||||
|
||||
var zero = 48; // '0'
|
||||
var nine = 57; // '9'
|
||||
|
||||
var plus = 43; // '+'
|
||||
var slash = 47; // '/'
|
||||
|
||||
var littleOffset = 26;
|
||||
var numberOffset = 52;
|
||||
|
||||
// 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
if (bigA <= charCode && charCode <= bigZ) {
|
||||
return (charCode - bigA);
|
||||
}
|
||||
|
||||
// 26 - 51: abcdefghijklmnopqrstuvwxyz
|
||||
if (littleA <= charCode && charCode <= littleZ) {
|
||||
return (charCode - littleA + littleOffset);
|
||||
}
|
||||
|
||||
// 52 - 61: 0123456789
|
||||
if (zero <= charCode && charCode <= nine) {
|
||||
return (charCode - zero + numberOffset);
|
||||
}
|
||||
|
||||
// 62: +
|
||||
if (charCode == plus) {
|
||||
return 62;
|
||||
}
|
||||
|
||||
// 63: /
|
||||
if (charCode == slash) {
|
||||
return 63;
|
||||
}
|
||||
|
||||
// Invalid base64 digit.
|
||||
return -1;
|
||||
};
|
111
node_modules/protractor/node_modules/source-map/lib/binary-search.js
generated
vendored
Normal file
111
node_modules/protractor/node_modules/source-map/lib/binary-search.js
generated
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
exports.GREATEST_LOWER_BOUND = 1;
|
||||
exports.LEAST_UPPER_BOUND = 2;
|
||||
|
||||
/**
|
||||
* Recursive implementation of binary search.
|
||||
*
|
||||
* @param aLow Indices here and lower do not contain the needle.
|
||||
* @param aHigh Indices here and higher do not contain the needle.
|
||||
* @param aNeedle The element being searched for.
|
||||
* @param aHaystack The non-empty array being searched.
|
||||
* @param aCompare Function which takes two elements and returns -1, 0, or 1.
|
||||
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
|
||||
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
|
||||
* closest element that is smaller than or greater than the one we are
|
||||
* searching for, respectively, if the exact element cannot be found.
|
||||
*/
|
||||
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
|
||||
// This function terminates when one of the following is true:
|
||||
//
|
||||
// 1. We find the exact element we are looking for.
|
||||
//
|
||||
// 2. We did not find the exact element, but we can return the index of
|
||||
// the next-closest element.
|
||||
//
|
||||
// 3. We did not find the exact element, and there is no next-closest
|
||||
// element than the one we are searching for, so we return -1.
|
||||
var mid = Math.floor((aHigh - aLow) / 2) + aLow;
|
||||
var cmp = aCompare(aNeedle, aHaystack[mid], true);
|
||||
if (cmp === 0) {
|
||||
// Found the element we are looking for.
|
||||
return mid;
|
||||
}
|
||||
else if (cmp > 0) {
|
||||
// Our needle is greater than aHaystack[mid].
|
||||
if (aHigh - mid > 1) {
|
||||
// The element is in the upper half.
|
||||
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);
|
||||
}
|
||||
|
||||
// The exact needle element was not found in this haystack. Determine if
|
||||
// we are in termination case (3) or (2) and return the appropriate thing.
|
||||
if (aBias == exports.LEAST_UPPER_BOUND) {
|
||||
return aHigh < aHaystack.length ? aHigh : -1;
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Our needle is less than aHaystack[mid].
|
||||
if (mid - aLow > 1) {
|
||||
// The element is in the lower half.
|
||||
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);
|
||||
}
|
||||
|
||||
// we are in termination case (3) or (2) and return the appropriate thing.
|
||||
if (aBias == exports.LEAST_UPPER_BOUND) {
|
||||
return mid;
|
||||
} else {
|
||||
return aLow < 0 ? -1 : aLow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an implementation of binary search which will always try and return
|
||||
* the index of the closest element if there is no exact hit. This is because
|
||||
* mappings between original and generated line/col pairs are single points,
|
||||
* and there is an implicit region between each of them, so a miss just means
|
||||
* that you aren't on the very start of a region.
|
||||
*
|
||||
* @param aNeedle The element you are looking for.
|
||||
* @param aHaystack The array that is being searched.
|
||||
* @param aCompare A function which takes the needle and an element in the
|
||||
* array and returns -1, 0, or 1 depending on whether the needle is less
|
||||
* than, equal to, or greater than the element, respectively.
|
||||
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
|
||||
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
|
||||
* closest element that is smaller than or greater than the one we are
|
||||
* searching for, respectively, if the exact element cannot be found.
|
||||
* Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.
|
||||
*/
|
||||
exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
|
||||
if (aHaystack.length === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,
|
||||
aCompare, aBias || exports.GREATEST_LOWER_BOUND);
|
||||
if (index < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// We have found either the exact element, or the next-closest element than
|
||||
// the one we are searching for. However, there may be more than one such
|
||||
// element. Make sure we always return the smallest of these.
|
||||
while (index - 1 >= 0) {
|
||||
if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
|
||||
break;
|
||||
}
|
||||
--index;
|
||||
}
|
||||
|
||||
return index;
|
||||
};
|
79
node_modules/protractor/node_modules/source-map/lib/mapping-list.js
generated
vendored
Normal file
79
node_modules/protractor/node_modules/source-map/lib/mapping-list.js
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
/*
|
||||
* Copyright 2014 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Determine whether mappingB is after mappingA with respect to generated
|
||||
* position.
|
||||
*/
|
||||
function generatedPositionAfter(mappingA, mappingB) {
|
||||
// Optimized for most common case
|
||||
var lineA = mappingA.generatedLine;
|
||||
var lineB = mappingB.generatedLine;
|
||||
var columnA = mappingA.generatedColumn;
|
||||
var columnB = mappingB.generatedColumn;
|
||||
return lineB > lineA || lineB == lineA && columnB >= columnA ||
|
||||
util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* A data structure to provide a sorted view of accumulated mappings in a
|
||||
* performance conscious manner. It trades a neglibable overhead in general
|
||||
* case for a large speedup in case of mappings being added in order.
|
||||
*/
|
||||
function MappingList() {
|
||||
this._array = [];
|
||||
this._sorted = true;
|
||||
// Serves as infimum
|
||||
this._last = {generatedLine: -1, generatedColumn: 0};
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through internal items. This method takes the same arguments that
|
||||
* `Array.prototype.forEach` takes.
|
||||
*
|
||||
* NOTE: The order of the mappings is NOT guaranteed.
|
||||
*/
|
||||
MappingList.prototype.unsortedForEach =
|
||||
function MappingList_forEach(aCallback, aThisArg) {
|
||||
this._array.forEach(aCallback, aThisArg);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the given source mapping.
|
||||
*
|
||||
* @param Object aMapping
|
||||
*/
|
||||
MappingList.prototype.add = function MappingList_add(aMapping) {
|
||||
if (generatedPositionAfter(this._last, aMapping)) {
|
||||
this._last = aMapping;
|
||||
this._array.push(aMapping);
|
||||
} else {
|
||||
this._sorted = false;
|
||||
this._array.push(aMapping);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the flat, sorted array of mappings. The mappings are sorted by
|
||||
* generated position.
|
||||
*
|
||||
* WARNING: This method returns internal data without copying, for
|
||||
* performance. The return value must NOT be mutated, and should be treated as
|
||||
* an immutable borrow. If you want to take ownership, you must make your own
|
||||
* copy.
|
||||
*/
|
||||
MappingList.prototype.toArray = function MappingList_toArray() {
|
||||
if (!this._sorted) {
|
||||
this._array.sort(util.compareByGeneratedPositionsInflated);
|
||||
this._sorted = true;
|
||||
}
|
||||
return this._array;
|
||||
};
|
||||
|
||||
exports.MappingList = MappingList;
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue