Conexio amb la api

This commit is contained in:
janmaroto 2022-02-09 18:30:03 +01:00
commit b12369cb47
48513 changed files with 7391639 additions and 7 deletions

75
node_modules/protractor/.circleci/config.yml generated vendored Executable file
View file

@ -0,0 +1,75 @@
version: 2
jobs:
build:
docker:
- image: circleci/node:10.16-browsers
environment:
# Fix issue with selenium-server in containers.
# See http://github.com/SeleniumHQ/docker-selenium/issues/87
DBUS_SESSION_BUS_ADDRESS: /dev/null
CHROME_REVISION: 652421
CHROMEDRIVER_VERSION: 75.0.3770.90
# To find this revision number:
# 1. Find the exact chrome version you want: https://en.wikipedia.org/wiki/Google_Chrome_version_history
# 2. Put that version in this tool: https://omahaproxy.appspot.com/
# 3. Take the bumber from "Branch Base Position"
# 4. Look for the closest number to that revision in the snapshots: https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/
# CHROME 74 - 638880
# CHROME 75 - 652421
# CHROME 79 - 706915
steps:
- checkout
- run:
name: Install Dependencies
command: |
sudo apt-get update
sudo apt-get install python-pip openjdk-8-jdk tcpdump
# Install a specific version of Chrome (not latest)
sudo rm -rf /opt/google
sudo rm /usr/local/bin/chromedriver
wget -q -O chrome.zip https://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/${CHROME_REVISION}/chrome-linux.zip
unzip chrome.zip
rm chrome.zip
sudo ln -sf ${PWD}/chrome-linux/chrome /usr/bin/chromium
sudo ln -sf /usr/bin/chromium /usr/bin/chromium-browser
sudo groupadd -r chrome && sudo useradd -r -g chrome -G audio,video chrome
sudo mkdir -p /home/chrome/reports
sudo chown -R chrome:chrome /home/chrome
- restore_cache:
key: node_modules-{{ .Branch }}-{{ checksum "package-lock.json" }}
- run:
name: NPM Install
command: |
npm i
cd testapp && npm i
- save_cache:
key: node_modules-{{ .Branch }}-{{ checksum "package-lock.json" }}
paths:
- "node_modules"
- "testapp/node_modules"
- run:
name: Lint
command: ./node_modules/.bin/gulp lint
- run:
name: Selenium Start
background: true
command: |
./node_modules/.bin/webdriver-manager update --versions.standalone=3.141.59 --versions.chrome=${CHROMEDRIVER_VERSION} --versions.gecko=v0.26.0
sudo cp ./node_modules/webdriver-manager/selenium/chromedriver_${CHROMEDRIVER_VERSION} /usr/local/bin/chromedriver
./node_modules/.bin/webdriver-manager start --versions.standalone=3.141.59 --versions.chrome=${CHROMEDRIVER_VERSION} --versions.gecko=v0.26.0
- run:
name: TestApp Start
background: true
command: |
npm start
- run:
name: Test
command: npm test

1
node_modules/protractor/.jshintignore generated vendored Executable file
View file

@ -0,0 +1 @@
./spec/built/*

4288
node_modules/protractor/CHANGELOG.md generated vendored Executable file

File diff suppressed because it is too large Load diff

74
node_modules/protractor/CONTRIBUTING.md generated vendored Executable file
View 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.

151
node_modules/protractor/DEVELOPER.md generated vendored Executable file
View file

@ -0,0 +1,151 @@
# Building and Testing Protractor
This document describes building, testing, releasing Protractor and provides an overview of
the repository layout.
## Prerequisite software
The prerequisite software (Node.js, npm, git, jdk) are the same as for angular. See
https://github.com/angular/angular/blob/master/docs/DEVELOPER.md#prerequisite-software
## Getting the sources
Fork Protractor from github, then clone your fork with:
```shell
git clone git@github.com:<github username>/protractor.git
# Go to the Protractor directory:
cd protractor/
# Add the main protractor repository as an upstream remote to your repository:
git remote add upstream https://github.com/angular/protractor.git
```
## Installing and Building
All Protractor dependencies come from npm. Install with:
```shell
npm install
```
This will also trigger our build step. The build step runs the TypeScript compiler
and copies necessary files into the output `built` directory. To run the build step
independently, run:
```shell
npm run prepublish
```
You can see the other available npm scripts in `package.json`. Note that most of these
scripts just call our `gulp` commands, which can be seen in `gulpfile.js`.
## Formatting
Protractor uses clang-format to format the source code. If the source code is not properly formatted,
the CI will fail and the PR can not be merged.
You can automatically format your code by running:
```shell
npm run format
```
You can check that you will pass lint tests with:
```shell
gulp lint
# or if you don't have gulp installed globally:
./node_modules/.bin/gulp lint
```
## Code layout
`docs/` contains markdown documentation files.
`lib/` contains the actual Protractor code.
`scripts/` contains scripts used for CI setup and running tests.
`spec/` contains e2e and unit tests and configuration files for tests.
`testapp/` contains the code for the Angular applications that e2e tests run against.
`website/` contains code for generating Protractor API documentation and the website at protractortest.org.
Most of the code is written in TypeScript, with the exception of a few js files.
`lib/debugger` is for element explorer, `browser.pause` and `browser.explore`.
`lib/driverProviders` controls how WebDriver instances are created.
`lib/frameworks` contains adapters for test frameworks such as Jasmine and Mocha.
`lib/selenium-webdriver` and `lib/webdriver-js-extender` are used ONLY for API documentation generation.
## Lightning Code Walkthrough
TBD.
## Testing
Run `npm test` to run the full test suite. This assumes that you have the testapp and a
selenium server running. Start these as separate processes with:
```shell
webdriver-manager update
webdriver-manager start
```
and
```shell
npm start
```
This suite is described in `scripts/test.js`. It uses some small helper functions to run commands
as child processes and capture the results, so that we can run protractor commands which should
result in failures and verify that we get the expected number and type of failures.
The suite contains unit tests, end to end tests using the built binary, and interactive tests.
Interactive tests are for testing `browser.pause` and element explorer.
End to end tests all have configuration files which live in `spec/`. Many tests do not need
an actual Selenium server backing them and use the `mockSelenium` configuration, which saves
time by not connecting to a real selenium server.
## Important dependencies
Protractor has very close dependencies with several other projects under the Angular umbrella:
`jasminewd2` is an extension of the Jasmine test framework that adds utilities for
working with selenium-webdriver. [jasminewd](https://github.com/angular/jasminewd)
`blocking-proxy` is a separate binary, which handles traffic between a test script and
webdriver. It can be turned on via a protractor configuration file, and in the future
all logic to wait for Angular will be handled through the blocking proxy.
[blocking-proxy](https://github.com/angular/blocking-proxy)
`webdriver-manager` is a separate binary which manages installing and starting up
the various binaries necessary for running webdriver tests. These binaries include
specific drivers for various browsers (e.g. chromedriver) and the selenium standalone
server. [webdriver-manager](https://github.com/angular/webdriver-manager)
`webdriver-js-extender` extends selenium-webdriver to add Appium commands.
[webdriver-js-extender](https://github.com/angular/webdriver-js-extender)
## Continuous Integration
PRs or changes submitted to master will automatically trigger continuous integration on two
different services - Travis, and Circle CI. We use Travis for tests run with SauceLabs because
we have more vm time on Travis and their integration with SauceLabs is smooth. CircleCI gives us
greater control over the vm, which allows us to run tests against local browsers and get better
logs.
Travis runs e2e tests via SauceLabs against a variety of browsers. The essential browsers run a
more complete test suite, `specified by spec/ciFullConf.js`. We also run a set of smoke tests
against a larger set of browsers, which is allowed to fail - this is configured in
`spec/ciSmokeConf.js`. This is due to flakiness in IE, Safari and older browser versions.
We also run a small set of tests using BrowserStack to verify that our integration with their
Selenium farm works.
Circle CI runs a slightly modified version of `npm test` in a single VM. It installs
the browsers it needs locally. Circle CI runs unit tests and a set of e2e tests against Chrome.
## Releasing
See [release.md](https://github.com/angular/protractor/blob/master/release.md) for full instructions.

21
node_modules/protractor/LICENSE generated vendored Executable file
View 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 Executable file
View file

@ -0,0 +1,37 @@
Protractor [![Build Status](https://travis-ci.org/angular/protractor.svg?branch=master)](https://travis-ci.org/angular/protractor) [![CircleCI Status](https://circleci.com/gh/angular/protractor.svg?style=shield)](https://circleci.com/gh/angular/protractor) [![Join the chat at https://gitter.im/angular/protractor](https://badges.gitter.im/angular/protractor.svg)](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, youre 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
View 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
View 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
View file

@ -0,0 +1,3 @@
#!/usr/bin/env node
require('webdriver-manager');

13
node_modules/protractor/built/bpRunner.d.ts generated vendored Executable file
View file

@ -0,0 +1,13 @@
/// <reference types="node" />
/// <reference types="q" />
import { ChildProcess } from 'child_process';
import * as q from 'q';
import { Config } from './config';
export declare class BlockingProxyRunner {
private config;
bpProcess: ChildProcess;
port: number;
constructor(config: Config);
start(): q.Promise<{}>;
checkSupportedConfig(): void;
}

59
node_modules/protractor/built/bpRunner.js generated vendored Executable file
View file

@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const child_process_1 = require("child_process");
const q = require("q");
const logger_1 = require("./logger");
const BP_PATH = require.resolve('blocking-proxy/built/lib/bin.js');
let logger = new logger_1.Logger('BlockingProxy');
class BlockingProxyRunner {
constructor(config) {
this.config = config;
}
start() {
return q.Promise((resolve, reject) => {
this.checkSupportedConfig();
let args = [
'--fork',
'--seleniumAddress',
this.config.seleniumAddress,
];
if (this.config.webDriverLogDir) {
args.push('--logDir', this.config.webDriverLogDir);
}
if (this.config.highlightDelay) {
args.push('--highlightDelay', this.config.highlightDelay.toString());
}
this.bpProcess = child_process_1.fork(BP_PATH, args, { silent: true });
logger.info('Starting BlockingProxy with args: ' + args.toString());
this.bpProcess
.on('message', (data) => {
this.port = data['port'];
resolve(data['port']);
})
.on('error', (err) => {
reject(new Error('Unable to start BlockingProxy ' + err));
})
.on('exit', (code, signal) => {
reject(new Error('BP exited with ' + code));
logger.error('Exited with ' + code);
logger.error('signal ' + signal);
});
this.bpProcess.stdout.on('data', (msg) => {
logger.debug(msg.toString().trim());
});
this.bpProcess.stderr.on('data', (msg) => {
logger.error(msg.toString().trim());
});
process.on('exit', () => {
this.bpProcess.kill();
});
});
}
checkSupportedConfig() {
if (this.config.directConnect) {
throw new Error('BlockingProxy not yet supported with directConnect!');
}
}
}
exports.BlockingProxyRunner = BlockingProxyRunner;
//# sourceMappingURL=bpRunner.js.map

10
node_modules/protractor/built/breakpointhook.js generated vendored Executable file
View file

@ -0,0 +1,10 @@
module.exports = function() {
return true;
};
/**
* The reason this file exists is so that we can set a breakpoint via
* script name, and then control when that breakpoint is set in
* our library code by importing and calling this function. The
* breakpoint will always be on line 2.
*/

474
node_modules/protractor/built/browser.d.ts generated vendored Executable file
View file

@ -0,0 +1,474 @@
import { BPClient } from 'blocking-proxy';
import { Navigation, promise as wdpromise, WebDriver, WebElement, WebElementPromise } from 'selenium-webdriver';
import { ExtendedWebDriver } from 'webdriver-js-extender';
import { ElementArrayFinder, ElementFinder } from './element';
import { ProtractorExpectedConditions } from './expectedConditions';
import { Locator, ProtractorBy } from './locators';
import { Plugins } from './plugins';
export declare class AbstractWebDriver {
}
export interface AbstractWebDriver extends WebDriver {
}
export declare class AbstractExtendedWebDriver extends AbstractWebDriver {
}
export interface AbstractExtendedWebDriver extends ExtendedWebDriver {
}
export interface ElementHelper extends Function {
(locator: Locator): ElementFinder;
all: (locator: Locator) => ElementArrayFinder;
}
/**
* @alias browser
* @constructor
* @extends {webdriver_extensions.ExtendedWebDriver}
* @param {webdriver.WebDriver} webdriver
* @param {string=} opt_baseUrl A base URL to run get requests against.
* @param {string|webdriver.promise.Promise<string>=} opt_rootElement Selector element that has an
* ng-app in scope.
* @param {boolean=} opt_untrackOutstandingTimeouts Whether Protractor should
* stop tracking outstanding $timeouts.
*/
export declare class ProtractorBrowser extends AbstractExtendedWebDriver {
/**
* @type {ProtractorBy}
*/
static By: ProtractorBy;
/**
* @type {ExpectedConditions}
*/
ExpectedConditions: ProtractorExpectedConditions;
/**
* The wrapped webdriver instance. Use this to interact with pages that do
* not contain Angular (such as a log-in screen).
*
* @type {webdriver_extensions.ExtendedWebDriver}
*/
driver: ExtendedWebDriver;
/**
* The client used to control the BlockingProxy. If unset, BlockingProxy is
* not being used and Protractor will handle client-side synchronization.
*/
bpClient: BPClient;
/**
* Helper function for finding elements.
*
* @type {function(webdriver.Locator): ElementFinder}
*/
element: ElementHelper;
/**
* Shorthand function for finding elements by css.
*
* @type {function(string): ElementFinder}
*/
$: (query: string) => ElementFinder;
/**
* Shorthand function for finding arrays of elements by css.
*
* @type {function(string): ElementArrayFinder}
*/
$$: (query: string) => ElementArrayFinder;
/**
* All get methods will be resolved against this base URL. Relative URLs are =
* resolved the way anchor tags resolve.
*
* @type {string}
*/
baseUrl: string;
/**
* The css selector for an element on which to find Angular. This is usually
* 'body' but if your ng-app is on a subsection of the page it may be
* a subelement.
*
* This property is deprecated - please use angularAppRoot() instead.
*
* @deprecated
* @type {string}
*/
rootEl: string;
private internalRootEl;
/**
* Set the css selector for an element on which to find Angular. This is usually
* 'body' but if your ng-app is on a subsection of the page it may be
* a subelement.
*
* The change will be made within WebDriver's control flow, so that commands after
* this method is called use the new app root. Pass nothing to get a promise that
* resolves to the value of the selector.
*
* @param {string|webdriver.promise.Promise<string>} value The new selector.
* @returns A promise that resolves with the value of the selector.
*/
angularAppRoot(value?: string | wdpromise.Promise<string>): wdpromise.Promise<string>;
/**
* If true, Protractor will not attempt to synchronize with the page before
* performing actions. This can be harmful because Protractor will not wait
* until $timeouts and $http calls have been processed, which can cause
* tests to become flaky. This should be used only when necessary, such as
* when a page continuously polls an API using $timeout.
*
* Initialized to `false` by the runner.
*
* This property is deprecated - please use waitForAngularEnabled instead.
*
* @deprecated
* @type {boolean}
*/
ignoreSynchronization: boolean;
private internalIgnoreSynchronization;
/**
* Timeout in milliseconds to wait for pages to load when calling `get`.
*
* @type {number}
*/
getPageTimeout: number;
/**
* An object that holds custom test parameters.
*
* @type {Object}
*/
params: any;
/**
* Resolved when the browser is ready for use. Resolves to the browser, so
* you can do:
*
* forkedBrowser = await browser.forkNewDriverInstance().ready;
*
* Set by the runner.
*
* @type {webdriver.promise.Promise.<ProtractorBrowser>}
*/
ready: wdpromise.Promise<ProtractorBrowser>;
plugins_: Plugins;
/**
* The reset URL to use between page loads.
*
* @type {string}
*/
resetUrl: string;
/**
* If true, Protractor will track outstanding $timeouts and report them in the
* error message if Protractor fails to synchronize with Angular in time.
* @private {boolean}
*/
trackOutstandingTimeouts_: boolean;
allScriptsTimeout: number;
/**
* Information about mock modules that will be installed during every
* get().
*
* @type {Array<{name: string, script: function|string, args:
* Array.<string>}>}
*/
mockModules_: {
name: string;
script: string | Function;
args: any[];
}[];
/**
* If specified, start a debugger server at specified port instead of repl
* when running element explorer.
* @public {number}
*/
debuggerServerPort: number;
/**
* If true, Protractor will interpret any angular apps it comes across as
* hybrid angular1/angular2 apps.
*
* @type {boolean}
*/
ng12Hybrid: boolean;
[key: string]: any;
constructor(webdriverInstance: WebDriver, opt_baseUrl?: string, opt_rootElement?: string | wdpromise.Promise<string>, opt_untrackOutstandingTimeouts?: boolean, opt_blockingProxyUrl?: string);
/**
* If set to false, Protractor will not wait for Angular $http and $timeout
* tasks to complete before interacting with the browser. This can cause
* flaky tests, but should be used if, for instance, your app continuously
* polls an API with $timeout.
*
* Call waitForAngularEnabled() without passing a value to read the current
* state without changing it.
*/
waitForAngularEnabled(enabled?: boolean | wdpromise.Promise<boolean>): wdpromise.Promise<boolean>;
/**
* Get the processed configuration object that is currently being run. This
* will contain the specs and capabilities properties of the current runner
* instance.
*
* Set by the runner.
*
* @returns {webdriver.promise.Promise} A promise which resolves to the
* capabilities object.
*/
getProcessedConfig(): wdpromise.Promise<any>;
/**
* Fork another instance of browser for use in interactive tests.
*
* @example
* // Running with control flow enabled
* var fork = browser.forkNewDriverInstance();
* fork.get('page1'); // 'page1' gotten by forked browser
*
* // Running with control flow disabled
* var forked = await browser.forkNewDriverInstance().ready;
* await forked.get('page1'); // 'page1' gotten by forked browser
*
* @param {boolean=} useSameUrl Whether to navigate to current url on creation
* @param {boolean=} copyMockModules Whether to apply same mock modules on creation
* @param {boolean=} copyConfigUpdates Whether to copy over changes to `baseUrl` and similar
* properties initialized to values in the the config. Defaults to `true`
*
* @returns {ProtractorBrowser} A browser instance.
*/
forkNewDriverInstance(useSameUrl?: boolean, copyMockModules?: boolean, copyConfigUpdates?: boolean): ProtractorBrowser;
/**
* Restart the browser. This is done by closing this browser instance and creating a new one.
* A promise resolving to the new instance is returned, and if this function was called on the
* global `browser` instance then Protractor will automatically overwrite the global `browser`
* variable.
*
* When restarting a forked browser, it is the caller's job to overwrite references to the old
* instance.
*
* This function behaves slightly differently depending on if the webdriver control flow is
* enabled. If the control flow is enabled, the global `browser` object is synchronously
* replaced. If the control flow is disabled, the global `browser` is replaced asynchronously
* after the old driver quits.
*
* Set by the runner.
*
* @example
* // Running against global browser, with control flow enabled
* browser.get('page1');
* browser.restart();
* browser.get('page2'); // 'page2' gotten by restarted browser
*
* // Running against global browser, with control flow disabled
* await browser.get('page1');
* await browser.restart();
* await browser.get('page2'); // 'page2' gotten by restarted browser
*
* // Running against forked browsers, with the control flow enabled
* // In this case, you may prefer `restartSync` (documented below)
* var forked = browser.forkNewDriverInstance();
* fork.get('page1');
* fork.restart().then(function(fork) {
* fork.get('page2'); // 'page2' gotten by restarted fork
* });
*
* // Running against forked browsers, with the control flow disabled
* var forked = await browser.forkNewDriverInstance().ready;
* await fork.get('page1');
* fork = await fork.restart();
* await fork.get('page2'); // 'page2' gotten by restarted fork
*
* // Unexpected behavior can occur if you save references to the global `browser`
* var savedBrowser = browser;
* browser.get('foo').then(function() {
* console.log(browser === savedBrowser); // false
* });
* browser.restart();
*
* @returns {webdriver.promise.Promise<ProtractorBrowser>} A promise resolving to the restarted
* browser
*/
restart(): wdpromise.Promise<ProtractorBrowser>;
/**
* Like `restart`, but instead of returning a promise resolving to the new browser instance,
* returns the new browser instance directly. Can only be used when the control flow is enabled.
*
* @example
* // Running against global browser
* browser.get('page1');
* browser.restartSync();
* browser.get('page2'); // 'page2' gotten by restarted browser
*
* // Running against forked browsers
* var forked = browser.forkNewDriverInstance();
* fork.get('page1');
* fork = fork.restartSync();
* fork.get('page2'); // 'page2' gotten by restarted fork
*
* @throws {TypeError} Will throw an error if the control flow is not enabled
* @returns {ProtractorBrowser} The restarted browser
*/
restartSync(): ProtractorBrowser;
/**
* Instead of using a single root element, search through all angular apps
* available on the page when finding elements or waiting for stability.
* Only compatible with Angular2.
*/
useAllAngular2AppRoots(): void;
/**
* The same as {@code webdriver.WebDriver.prototype.executeScript},
* but with a customized description for debugging.
*
* @private
* @param {!(string|Function)} script The script to execute.
* @param {string} description A description of the command for debugging.
* @param {...*} var_args The arguments to pass to the script.
* @returns {!webdriver.promise.Promise.<T>} A promise that will resolve to
* the scripts return value.
* @template T
*/
executeScriptWithDescription(script: string | Function, description: string, ...scriptArgs: any[]): wdpromise.Promise<any>;
/**
* The same as {@code webdriver.WebDriver.prototype.executeAsyncScript},
* but with a customized description for debugging.
*
* @private
* @param {!(string|Function)} script The script to execute.
* @param {string} description A description for debugging purposes.
* @param {...*} var_args The arguments to pass to the script.
* @returns {!webdriver.promise.Promise.<T>} A promise that will resolve to
* the
* scripts return value.
* @template T
*/
private executeAsyncScript_(script, description, ...scriptArgs);
/**
* Instruct webdriver to wait until Angular has finished rendering and has
* no outstanding $http or $timeout calls before continuing.
* Note that Protractor automatically applies this command before every
* WebDriver action.
*
* @param {string=} opt_description An optional description to be added
* to webdriver logs.
* @returns {!webdriver.promise.Promise} A promise that will resolve to the
* scripts return value.
*/
waitForAngular(opt_description?: string): wdpromise.Promise<any>;
/**
* Waits for Angular to finish rendering before searching for elements.
* @see webdriver.WebDriver.findElement
* @returns {!webdriver.WebElementPromise} A promise that will be resolved to
* the located {@link webdriver.WebElement}.
*/
findElement(locator: Locator): WebElementPromise;
/**
* Waits for Angular to finish rendering before searching for elements.
* @see webdriver.WebDriver.findElements
* @returns {!webdriver.promise.Promise} A promise that will be resolved to an
* array of the located {@link webdriver.WebElement}s.
*/
findElements(locator: Locator): wdpromise.Promise<WebElement[]>;
/**
* Tests if an element is present on the page.
* @see webdriver.WebDriver.isElementPresent
* @returns {!webdriver.promise.Promise} A promise that will resolve to whether
* the element is present on the page.
*/
isElementPresent(locatorOrElement: Locator | WebElement | ElementFinder): wdpromise.Promise<any>;
/**
* Add a module to load before Angular whenever Protractor.get is called.
* Modules will be registered after existing modules already on the page,
* so any module registered here will override preexisting modules with the
* same name.
*
* @example
* browser.addMockModule('modName', function() {
* angular.module('modName', []).value('foo', 'bar');
* });
*
* @param {!string} name The name of the module to load or override.
* @param {!string|Function} script The JavaScript to load the module.
* Note that this will be executed in the browser context, so it cannot
* access variables from outside its scope.
* @param {...*} varArgs Any additional arguments will be provided to
* the script and may be referenced using the `arguments` object.
*/
addMockModule(name: string, script: string | Function, ...moduleArgs: any[]): void;
/**
* Clear the list of registered mock modules.
*/
clearMockModules(): void;
/**
* Remove a registered mock module.
*
* @example
* browser.removeMockModule('modName');
*
* @param {!string} name The name of the module to remove.
*/
removeMockModule(name: string): void;
/**
* Get a list of the current mock modules.
*
* @returns {Array.<!string|Function>} The list of mock modules.
*/
getRegisteredMockModules(): Array<string | Function>;
/**
* Add the base mock modules used for all Protractor tests.
*
* @private
*/
private addBaseMockModules_();
/**
* @see webdriver.WebDriver.get
*
* Navigate to the given destination and loads mock modules before
* Angular. Assumes that the page being loaded uses Angular.
* If you need to access a page which does not have Angular on load, use
* the wrapped webdriver directly.
*
* @example
* browser.get('https://angularjs.org/');
* expect(browser.getCurrentUrl()).toBe('https://angularjs.org/');
*
* @param {string} destination Destination URL.
* @param {number=} opt_timeout Number of milliseconds to wait for Angular to
* start.
*/
get(destination: string, timeout?: number): wdpromise.Promise<any>;
/**
* @see webdriver.WebDriver.refresh
*
* Makes a full reload of the current page and loads mock modules before
* Angular. Assumes that the page being loaded uses Angular.
* If you need to access a page which does not have Angular on load, use
* the wrapped webdriver directly.
*
* @param {number=} opt_timeout Number of milliseconds to wait for Angular to start.
*/
refresh(opt_timeout?: number): wdpromise.Promise<any>;
/**
* Mixin navigation methods back into the navigation object so that
* they are invoked as before, i.e. driver.navigate().refresh()
*/
navigate(): Navigation;
/**
* Browse to another page using in-page navigation.
*
* @example
* browser.get('http://angular.github.io/protractor/#/tutorial');
* browser.setLocation('api');
* expect(browser.getCurrentUrl())
* .toBe('http://angular.github.io/protractor/#/api');
*
* @param {string} url In page URL using the same syntax as $location.url()
* @returns {!webdriver.promise.Promise} A promise that will resolve once
* page has been changed.
*/
setLocation(url: string): wdpromise.Promise<any>;
/**
* Deprecated, use `browser.getCurrentUrl()` instead.
*
* Despite its name, this function will generally return `$location.url()`, though in some
* cases it will return `$location.absUrl()` instead. This function is only here for legacy
* users, and will probably be removed in Protractor 6.0.
*
* @deprecated Please use `browser.getCurrentUrl()`
* @example
* browser.get('http://angular.github.io/protractor/#/api');
* expect(browser.getLocationAbsUrl())
* .toBe('http://angular.github.io/protractor/#/api');
* @returns {webdriver.promise.Promise<string>} The current absolute url from
* AngularJS.
*/
getLocationAbsUrl(): wdpromise.Promise<any>;
/**
* Determine if the control flow is enabled.
*
* @returns true if the control flow is enabled, false otherwise.
*/
controlFlowIsEnabled(): any;
}

863
node_modules/protractor/built/browser.js generated vendored Executable file
View file

@ -0,0 +1,863 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const blocking_proxy_1 = require("blocking-proxy");
const selenium_webdriver_1 = require("selenium-webdriver");
const url = require("url");
const webdriver_js_extender_1 = require("webdriver-js-extender");
const element_1 = require("./element");
const expectedConditions_1 = require("./expectedConditions");
const locators_1 = require("./locators");
const logger_1 = require("./logger");
const clientSideScripts = require('./clientsidescripts');
// TODO: fix the typings for selenium-webdriver/lib/command
const Command = require('selenium-webdriver/lib/command').Command;
const CommandName = require('selenium-webdriver/lib/command').Name;
// jshint browser: true
const DEFER_LABEL = 'NG_DEFER_BOOTSTRAP!';
const DEFAULT_RESET_URL = 'data:text/html,<html></html>';
const DEFAULT_GET_PAGE_TIMEOUT = 10000;
let logger = new logger_1.Logger('protractor');
// TODO(cnishina): either remove for loop entirely since this does not export anything
// the user might need since everything is composed (with caveat that this could be a
// potential breaking change) or export the types with `export * from 'selenium-webdriver'`;
/*
* Mix in other webdriver functionality to be accessible via protractor.
*/
for (let foo in require('selenium-webdriver')) {
exports[foo] = require('selenium-webdriver')[foo];
}
// Explicitly define types for webdriver.WebDriver and ExtendedWebDriver.
// We do this because we use composition over inheritance to implement polymorphism, and therefore
// we don't want to inherit WebDriver's constructor.
class AbstractWebDriver {
}
exports.AbstractWebDriver = AbstractWebDriver;
class AbstractExtendedWebDriver extends AbstractWebDriver {
}
exports.AbstractExtendedWebDriver = AbstractExtendedWebDriver;
/**
* Mix a function from one object onto another. The function will still be
* called in the context of the original object. Any arguments of type
* `ElementFinder` will be unwrapped to their underlying `WebElement` instance
*
* @private
* @param {Object} to
* @param {Object} from
* @param {string} fnName
* @param {function=} setupFn
*/
function ptorMixin(to, from, fnName, setupFn) {
to[fnName] = function () {
const args = arguments;
for (let i = 0; i < args.length; i++) {
if (args[i] instanceof element_1.ElementFinder) {
args[i] = args[i].getWebElement();
}
}
const run = () => {
return from[fnName].apply(from, args);
};
if (setupFn) {
const setupResult = setupFn();
if (setupResult && (typeof setupResult.then === 'function')) {
return setupResult.then(run);
}
}
return run();
};
}
;
/**
* Build the helper 'element' function for a given instance of Browser.
*
* @private
* @param {Browser} browser A browser instance.
* @returns {function(webdriver.Locator): ElementFinder}
*/
function buildElementHelper(browser) {
let element = ((locator) => {
return new element_1.ElementArrayFinder(browser).all(locator).toElementFinder_();
});
element.all = (locator) => {
return new element_1.ElementArrayFinder(browser).all(locator);
};
return element;
}
;
/**
* @alias browser
* @constructor
* @extends {webdriver_extensions.ExtendedWebDriver}
* @param {webdriver.WebDriver} webdriver
* @param {string=} opt_baseUrl A base URL to run get requests against.
* @param {string|webdriver.promise.Promise<string>=} opt_rootElement Selector element that has an
* ng-app in scope.
* @param {boolean=} opt_untrackOutstandingTimeouts Whether Protractor should
* stop tracking outstanding $timeouts.
*/
class ProtractorBrowser extends AbstractExtendedWebDriver {
constructor(webdriverInstance, opt_baseUrl, opt_rootElement, opt_untrackOutstandingTimeouts, opt_blockingProxyUrl) {
super();
// These functions should delegate to the webdriver instance, but should
// wait for Angular to sync up before performing the action. This does not
// include functions which are overridden by protractor below.
let methodsToSync = ['getCurrentUrl', 'getPageSource', 'getTitle'];
let extendWDInstance;
try {
extendWDInstance = webdriver_js_extender_1.extend(webdriverInstance);
}
catch (e) {
// Probably not a driver that can be extended (e.g. gotten using
// `directConnect: true` in the config)
extendWDInstance = webdriverInstance;
}
// Mix all other driver functionality into Protractor.
Object.getOwnPropertyNames(selenium_webdriver_1.WebDriver.prototype).forEach(method => {
if (!this[method] && typeof extendWDInstance[method] === 'function') {
if (methodsToSync.indexOf(method) !== -1) {
ptorMixin(this, extendWDInstance, method, this.waitForAngular.bind(this));
}
else {
ptorMixin(this, extendWDInstance, method);
}
}
});
this.driver = extendWDInstance;
if (opt_blockingProxyUrl) {
logger.info('Starting BP client for ' + opt_blockingProxyUrl);
this.bpClient = new blocking_proxy_1.BPClient(opt_blockingProxyUrl);
}
this.element = buildElementHelper(this);
this.$ = element_1.build$(this.element, selenium_webdriver_1.By);
this.$$ = element_1.build$$(this.element, selenium_webdriver_1.By);
this.baseUrl = opt_baseUrl || '';
this.getPageTimeout = DEFAULT_GET_PAGE_TIMEOUT;
this.params = {};
this.resetUrl = DEFAULT_RESET_URL;
let ng12Hybrid_ = false;
Object.defineProperty(this, 'ng12Hybrid', {
get: function () {
return ng12Hybrid_;
},
set: function (ng12Hybrid) {
if (ng12Hybrid) {
logger.warn('You have set ng12Hybrid. As of Protractor 4.1.0, ' +
'Protractor can automatically infer if you are using an ' +
'ngUpgrade app (as long as ng1 is loaded before you call ' +
'platformBrowserDynamic()), and this flag is no longer needed ' +
'for most users');
}
ng12Hybrid_ = ng12Hybrid;
}
});
this.ready = this.angularAppRoot(opt_rootElement || '')
.then(() => {
return this.driver.getSession();
})
.then((session) => {
// Internet Explorer does not accept data URLs, which are the default
// reset URL for Protractor.
// Safari accepts data urls, but SafariDriver fails after one is used.
// PhantomJS produces a "Detected a page unload event" if we use data urls
let browserName = session.getCapabilities().get('browserName');
if (browserName === 'internet explorer' || browserName === 'safari' ||
browserName === 'phantomjs' || browserName === 'MicrosoftEdge') {
this.resetUrl = 'about:blank';
}
return this;
});
this.trackOutstandingTimeouts_ = !opt_untrackOutstandingTimeouts;
this.mockModules_ = [];
this.addBaseMockModules_();
// set up expected conditions
this.ExpectedConditions = new expectedConditions_1.ProtractorExpectedConditions(this);
}
/**
* The css selector for an element on which to find Angular. This is usually
* 'body' but if your ng-app is on a subsection of the page it may be
* a subelement.
*
* This property is deprecated - please use angularAppRoot() instead.
*
* @deprecated
* @type {string}
*/
set rootEl(value) {
this.angularAppRoot(value);
}
get rootEl() {
return this.internalRootEl;
}
/**
* Set the css selector for an element on which to find Angular. This is usually
* 'body' but if your ng-app is on a subsection of the page it may be
* a subelement.
*
* The change will be made within WebDriver's control flow, so that commands after
* this method is called use the new app root. Pass nothing to get a promise that
* resolves to the value of the selector.
*
* @param {string|webdriver.promise.Promise<string>} value The new selector.
* @returns A promise that resolves with the value of the selector.
*/
angularAppRoot(value = null) {
return this.driver.controlFlow().execute(() => {
if (value != null) {
return selenium_webdriver_1.promise.when(value).then((value) => {
this.internalRootEl = value;
if (this.bpClient) {
const bpCommandPromise = this.bpClient.setWaitParams(value);
// Convert to webdriver promise as best as possible
return selenium_webdriver_1.promise.when(bpCommandPromise).then(() => this.internalRootEl);
}
return this.internalRootEl;
});
}
return selenium_webdriver_1.promise.when(this.internalRootEl);
}, `Set angular root selector to ${value}`);
}
/**
* If true, Protractor will not attempt to synchronize with the page before
* performing actions. This can be harmful because Protractor will not wait
* until $timeouts and $http calls have been processed, which can cause
* tests to become flaky. This should be used only when necessary, such as
* when a page continuously polls an API using $timeout.
*
* Initialized to `false` by the runner.
*
* This property is deprecated - please use waitForAngularEnabled instead.
*
* @deprecated
* @type {boolean}
*/
set ignoreSynchronization(value) {
this.waitForAngularEnabled(!value);
}
get ignoreSynchronization() {
return this.internalIgnoreSynchronization;
}
/**
* If set to false, Protractor will not wait for Angular $http and $timeout
* tasks to complete before interacting with the browser. This can cause
* flaky tests, but should be used if, for instance, your app continuously
* polls an API with $timeout.
*
* Call waitForAngularEnabled() without passing a value to read the current
* state without changing it.
*/
waitForAngularEnabled(enabled = null) {
if (enabled != null) {
const ret = this.driver.controlFlow().execute(() => {
return selenium_webdriver_1.promise.when(enabled).then((enabled) => {
if (this.bpClient) {
logger.debug('Setting waitForAngular' + !enabled);
const bpCommandPromise = this.bpClient.setWaitEnabled(enabled);
// Convert to webdriver promise as best as possible
return selenium_webdriver_1.promise.when(bpCommandPromise).then(() => enabled);
}
});
}, `Set proxy synchronization enabled to ${enabled}`);
this.internalIgnoreSynchronization = !enabled;
return ret;
}
return selenium_webdriver_1.promise.when(!this.ignoreSynchronization);
}
/**
* Get the processed configuration object that is currently being run. This
* will contain the specs and capabilities properties of the current runner
* instance.
*
* Set by the runner.
*
* @returns {webdriver.promise.Promise} A promise which resolves to the
* capabilities object.
*/
getProcessedConfig() {
return null;
}
/**
* Fork another instance of browser for use in interactive tests.
*
* @example
* // Running with control flow enabled
* var fork = browser.forkNewDriverInstance();
* fork.get('page1'); // 'page1' gotten by forked browser
*
* // Running with control flow disabled
* var forked = await browser.forkNewDriverInstance().ready;
* await forked.get('page1'); // 'page1' gotten by forked browser
*
* @param {boolean=} useSameUrl Whether to navigate to current url on creation
* @param {boolean=} copyMockModules Whether to apply same mock modules on creation
* @param {boolean=} copyConfigUpdates Whether to copy over changes to `baseUrl` and similar
* properties initialized to values in the the config. Defaults to `true`
*
* @returns {ProtractorBrowser} A browser instance.
*/
forkNewDriverInstance(useSameUrl, copyMockModules, copyConfigUpdates = true) {
return null;
}
/**
* Restart the browser. This is done by closing this browser instance and creating a new one.
* A promise resolving to the new instance is returned, and if this function was called on the
* global `browser` instance then Protractor will automatically overwrite the global `browser`
* variable.
*
* When restarting a forked browser, it is the caller's job to overwrite references to the old
* instance.
*
* This function behaves slightly differently depending on if the webdriver control flow is
* enabled. If the control flow is enabled, the global `browser` object is synchronously
* replaced. If the control flow is disabled, the global `browser` is replaced asynchronously
* after the old driver quits.
*
* Set by the runner.
*
* @example
* // Running against global browser, with control flow enabled
* browser.get('page1');
* browser.restart();
* browser.get('page2'); // 'page2' gotten by restarted browser
*
* // Running against global browser, with control flow disabled
* await browser.get('page1');
* await browser.restart();
* await browser.get('page2'); // 'page2' gotten by restarted browser
*
* // Running against forked browsers, with the control flow enabled
* // In this case, you may prefer `restartSync` (documented below)
* var forked = browser.forkNewDriverInstance();
* fork.get('page1');
* fork.restart().then(function(fork) {
* fork.get('page2'); // 'page2' gotten by restarted fork
* });
*
* // Running against forked browsers, with the control flow disabled
* var forked = await browser.forkNewDriverInstance().ready;
* await fork.get('page1');
* fork = await fork.restart();
* await fork.get('page2'); // 'page2' gotten by restarted fork
*
* // Unexpected behavior can occur if you save references to the global `browser`
* var savedBrowser = browser;
* browser.get('foo').then(function() {
* console.log(browser === savedBrowser); // false
* });
* browser.restart();
*
* @returns {webdriver.promise.Promise<ProtractorBrowser>} A promise resolving to the restarted
* browser
*/
restart() {
return;
}
/**
* Like `restart`, but instead of returning a promise resolving to the new browser instance,
* returns the new browser instance directly. Can only be used when the control flow is enabled.
*
* @example
* // Running against global browser
* browser.get('page1');
* browser.restartSync();
* browser.get('page2'); // 'page2' gotten by restarted browser
*
* // Running against forked browsers
* var forked = browser.forkNewDriverInstance();
* fork.get('page1');
* fork = fork.restartSync();
* fork.get('page2'); // 'page2' gotten by restarted fork
*
* @throws {TypeError} Will throw an error if the control flow is not enabled
* @returns {ProtractorBrowser} The restarted browser
*/
restartSync() {
return;
}
/**
* Instead of using a single root element, search through all angular apps
* available on the page when finding elements or waiting for stability.
* Only compatible with Angular2.
*/
useAllAngular2AppRoots() {
// The empty string is an invalid css selector, so we use it to easily
// signal to scripts to not find a root element.
this.angularAppRoot('');
}
/**
* The same as {@code webdriver.WebDriver.prototype.executeScript},
* but with a customized description for debugging.
*
* @private
* @param {!(string|Function)} script The script to execute.
* @param {string} description A description of the command for debugging.
* @param {...*} var_args The arguments to pass to the script.
* @returns {!webdriver.promise.Promise.<T>} A promise that will resolve to
* the scripts return value.
* @template T
*/
executeScriptWithDescription(script, description, ...scriptArgs) {
if (typeof script === 'function') {
script = 'return (' + script + ').apply(null, arguments);';
}
return this.driver.schedule(new Command(CommandName.EXECUTE_SCRIPT)
.setParameter('script', script)
.setParameter('args', scriptArgs), description);
}
/**
* The same as {@code webdriver.WebDriver.prototype.executeAsyncScript},
* but with a customized description for debugging.
*
* @private
* @param {!(string|Function)} script The script to execute.
* @param {string} description A description for debugging purposes.
* @param {...*} var_args The arguments to pass to the script.
* @returns {!webdriver.promise.Promise.<T>} A promise that will resolve to
* the
* scripts return value.
* @template T
*/
executeAsyncScript_(script, description, ...scriptArgs) {
if (typeof script === 'function') {
script = 'return (' + script + ').apply(null, arguments);';
}
return this.driver.schedule(new Command(CommandName.EXECUTE_ASYNC_SCRIPT)
.setParameter('script', script)
.setParameter('args', scriptArgs), description);
}
/**
* Instruct webdriver to wait until Angular has finished rendering and has
* no outstanding $http or $timeout calls before continuing.
* Note that Protractor automatically applies this command before every
* WebDriver action.
*
* @param {string=} opt_description An optional description to be added
* to webdriver logs.
* @returns {!webdriver.promise.Promise} A promise that will resolve to the
* scripts return value.
*/
waitForAngular(opt_description) {
let description = opt_description ? ' - ' + opt_description : '';
if (this.ignoreSynchronization) {
return this.driver.controlFlow().execute(() => {
return true;
}, 'Ignore Synchronization Protractor.waitForAngular()');
}
let runWaitForAngularScript = () => {
if (this.plugins_.skipAngularStability() || this.bpClient) {
return this.driver.controlFlow().execute(() => {
return selenium_webdriver_1.promise.when(null);
}, 'bpClient or plugin stability override');
}
else {
// Need to wrap this so that we read rootEl in the control flow, not synchronously.
return this.angularAppRoot().then((rootEl) => {
return this.executeAsyncScript_(clientSideScripts.waitForAngular, 'Protractor.waitForAngular()' + description, rootEl);
});
}
};
return runWaitForAngularScript()
.then((browserErr) => {
if (browserErr) {
throw new Error('Error while waiting for Protractor to ' +
'sync with the page: ' + JSON.stringify(browserErr));
}
})
.then(() => {
return this.driver.controlFlow()
.execute(() => {
return this.plugins_.waitForPromise(this);
}, 'Plugins.waitForPromise()')
.then(() => {
return this.driver.wait(() => {
return this.plugins_.waitForCondition(this).then((results) => {
return results.reduce((x, y) => x && y, true);
});
}, this.allScriptsTimeout, 'Plugins.waitForCondition()');
});
}, (err) => {
let timeout;
if (/asynchronous script timeout/.test(err.message)) {
// Timeout on Chrome
timeout = /-?[\d\.]*\ seconds/.exec(err.message);
}
else if (/Timed out waiting for async script/.test(err.message)) {
// Timeout on Firefox
timeout = /-?[\d\.]*ms/.exec(err.message);
}
else if (/Timed out waiting for an asynchronous script/.test(err.message)) {
// Timeout on Safari
timeout = /-?[\d\.]*\ ms/.exec(err.message);
}
if (timeout) {
let errMsg = `Timed out waiting for asynchronous Angular tasks to finish after ` +
`${timeout}. This may be because the current page is not an Angular ` +
`application. Please see the FAQ for more details: ` +
`https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular`;
if (description.indexOf(' - Locator: ') == 0) {
errMsg += '\nWhile waiting for element with locator' + description;
}
let pendingTimeoutsPromise;
if (this.trackOutstandingTimeouts_) {
pendingTimeoutsPromise = this.executeScriptWithDescription('return window.NG_PENDING_TIMEOUTS', 'Protractor.waitForAngular() - getting pending timeouts' + description);
}
else {
pendingTimeoutsPromise = selenium_webdriver_1.promise.when({});
}
let pendingHttpsPromise = this.executeScriptWithDescription(clientSideScripts.getPendingHttpRequests, 'Protractor.waitForAngular() - getting pending https' + description, this.internalRootEl);
return selenium_webdriver_1.promise.all([pendingTimeoutsPromise, pendingHttpsPromise])
.then((arr) => {
let pendingTimeouts = arr[0] || [];
let pendingHttps = arr[1] || [];
let key, pendingTasks = [];
for (key in pendingTimeouts) {
if (pendingTimeouts.hasOwnProperty(key)) {
pendingTasks.push(' - $timeout: ' + pendingTimeouts[key]);
}
}
for (key in pendingHttps) {
pendingTasks.push(' - $http: ' + pendingHttps[key].url);
}
if (pendingTasks.length) {
errMsg += '. \nThe following tasks were pending:\n';
errMsg += pendingTasks.join('\n');
}
err.message = errMsg;
throw err;
}, () => {
err.message = errMsg;
throw err;
});
}
else {
throw err;
}
});
}
/**
* Waits for Angular to finish rendering before searching for elements.
* @see webdriver.WebDriver.findElement
* @returns {!webdriver.WebElementPromise} A promise that will be resolved to
* the located {@link webdriver.WebElement}.
*/
findElement(locator) {
return this.element(locator).getWebElement();
}
/**
* Waits for Angular to finish rendering before searching for elements.
* @see webdriver.WebDriver.findElements
* @returns {!webdriver.promise.Promise} A promise that will be resolved to an
* array of the located {@link webdriver.WebElement}s.
*/
findElements(locator) {
return this.element.all(locator).getWebElements();
}
/**
* Tests if an element is present on the page.
* @see webdriver.WebDriver.isElementPresent
* @returns {!webdriver.promise.Promise} A promise that will resolve to whether
* the element is present on the page.
*/
isElementPresent(locatorOrElement) {
let element;
if (locatorOrElement instanceof element_1.ElementFinder) {
element = locatorOrElement;
}
else if (locatorOrElement instanceof selenium_webdriver_1.WebElement) {
element = element_1.ElementFinder.fromWebElement_(this, locatorOrElement);
}
else {
element = this.element(locatorOrElement);
}
return element.isPresent();
}
/**
* Add a module to load before Angular whenever Protractor.get is called.
* Modules will be registered after existing modules already on the page,
* so any module registered here will override preexisting modules with the
* same name.
*
* @example
* browser.addMockModule('modName', function() {
* angular.module('modName', []).value('foo', 'bar');
* });
*
* @param {!string} name The name of the module to load or override.
* @param {!string|Function} script The JavaScript to load the module.
* Note that this will be executed in the browser context, so it cannot
* access variables from outside its scope.
* @param {...*} varArgs Any additional arguments will be provided to
* the script and may be referenced using the `arguments` object.
*/
addMockModule(name, script, ...moduleArgs) {
this.mockModules_.push({ name: name, script: script, args: moduleArgs });
}
/**
* Clear the list of registered mock modules.
*/
clearMockModules() {
this.mockModules_ = [];
this.addBaseMockModules_();
}
/**
* Remove a registered mock module.
*
* @example
* browser.removeMockModule('modName');
*
* @param {!string} name The name of the module to remove.
*/
removeMockModule(name) {
for (let i = 0; i < this.mockModules_.length; ++i) {
if (this.mockModules_[i].name == name) {
this.mockModules_.splice(i--, 1);
}
}
}
/**
* Get a list of the current mock modules.
*
* @returns {Array.<!string|Function>} The list of mock modules.
*/
getRegisteredMockModules() {
return this.mockModules_.map(module => module.script);
}
;
/**
* Add the base mock modules used for all Protractor tests.
*
* @private
*/
addBaseMockModules_() {
this.addMockModule('protractorBaseModule_', clientSideScripts.protractorBaseModuleFn, this.trackOutstandingTimeouts_);
}
/**
* @see webdriver.WebDriver.get
*
* Navigate to the given destination and loads mock modules before
* Angular. Assumes that the page being loaded uses Angular.
* If you need to access a page which does not have Angular on load, use
* the wrapped webdriver directly.
*
* @example
* browser.get('https://angularjs.org/');
* expect(browser.getCurrentUrl()).toBe('https://angularjs.org/');
*
* @param {string} destination Destination URL.
* @param {number=} opt_timeout Number of milliseconds to wait for Angular to
* start.
*/
get(destination, timeout = this.getPageTimeout) {
destination = this.baseUrl.indexOf('file://') === 0 ? this.baseUrl + destination :
url.resolve(this.baseUrl, destination);
if (this.ignoreSynchronization) {
return this.driver.get(destination)
.then(() => this.driver.controlFlow().execute(() => this.plugins_.onPageLoad(this)))
.then(() => null);
}
let msg = (str) => {
return 'Protractor.get(' + destination + ') - ' + str;
};
return this.driver.controlFlow()
.execute(() => {
return selenium_webdriver_1.promise.when(null);
})
.then(() => {
if (this.bpClient) {
return this.driver.controlFlow().execute(() => {
return this.bpClient.setWaitEnabled(false);
});
}
})
.then(() => {
// Go to reset url
return this.driver.get(this.resetUrl);
})
.then(() => {
// Set defer label and navigate
return this.executeScriptWithDescription('window.name = "' + DEFER_LABEL + '" + window.name;' +
'window.location.replace("' + destination + '");', msg('reset url'));
})
.then(() => {
// We need to make sure the new url has loaded before
// we try to execute any asynchronous scripts.
return this.driver.wait(() => {
return this.executeScriptWithDescription('return window.location.href;', msg('get url'))
.then((url) => {
return url !== this.resetUrl;
}, (err) => {
if (err.code == 13 || err.name === 'JavascriptError') {
// Ignore the error, and continue trying. This is
// because IE driver sometimes (~1%) will throw an
// unknown error from this execution. See
// https://github.com/angular/protractor/issues/841
// This shouldn't mask errors because it will fail
// with the timeout anyway.
return false;
}
else {
throw err;
}
});
}, timeout, 'waiting for page to load for ' + timeout + 'ms');
})
.then(() => {
// Run Plugins
return this.driver.controlFlow().execute(() => {
return this.plugins_.onPageLoad(this);
});
})
.then(() => {
// Make sure the page is an Angular page.
return this
.executeAsyncScript_(clientSideScripts.testForAngular, msg('test for angular'), Math.floor(timeout / 1000), this.ng12Hybrid)
.then((angularTestResult) => {
let angularVersion = angularTestResult.ver;
if (!angularVersion) {
let message = angularTestResult.message;
logger.error(`Could not find Angular on page ${destination} : ${message}`);
throw new Error(`Angular could not be found on the page ${destination}. ` +
`If this is not an Angular application, you may need to turn off waiting for Angular.
Please see
https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular-on-page-load`);
}
return angularVersion;
}, (err) => {
throw new Error('Error while running testForAngular: ' + err.message);
});
})
.then((angularVersion) => {
// Load Angular Mocks
if (angularVersion === 1) {
// At this point, Angular will pause for us until angular.resumeBootstrap is called.
let moduleNames = [];
let modulePromise = selenium_webdriver_1.promise.when(null);
for (const { name, script, args } of this.mockModules_) {
moduleNames.push(name);
let executeScriptArgs = [script, msg('add mock module ' + name), ...args];
modulePromise = modulePromise.then(() => this.executeScriptWithDescription.apply(this, executeScriptArgs)
.then(null, (err) => {
throw new Error('Error while running module script ' + name + ': ' + err.message);
}));
}
return modulePromise.then(() => this.executeScriptWithDescription('window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__ = ' +
'angular.resumeBootstrap(arguments[0]);', msg('resume bootstrap'), moduleNames));
}
else {
// TODO: support mock modules in Angular2. For now, error if someone
// has tried to use one.
if (this.mockModules_.length > 1) {
throw 'Trying to load mock modules on an Angular v2+ app is not yet supported.';
}
}
})
.then(() => {
// Reset bpClient sync
if (this.bpClient) {
return this.driver.controlFlow().execute(() => {
return this.bpClient.setWaitEnabled(!this.internalIgnoreSynchronization);
});
}
})
.then(() => {
// Run Plugins
return this.driver.controlFlow().execute(() => {
return this.plugins_.onPageStable(this);
});
})
.then(() => null);
}
/**
* @see webdriver.WebDriver.refresh
*
* Makes a full reload of the current page and loads mock modules before
* Angular. Assumes that the page being loaded uses Angular.
* If you need to access a page which does not have Angular on load, use
* the wrapped webdriver directly.
*
* @param {number=} opt_timeout Number of milliseconds to wait for Angular to start.
*/
refresh(opt_timeout) {
if (this.ignoreSynchronization) {
return this.driver.navigate().refresh();
}
return this
.executeScriptWithDescription('return window.location.href', 'Protractor.refresh() - getUrl')
.then((href) => {
return this.get(href, opt_timeout);
});
}
/**
* Mixin navigation methods back into the navigation object so that
* they are invoked as before, i.e. driver.navigate().refresh()
*/
navigate() {
let nav = this.driver.navigate();
ptorMixin(nav, this, 'refresh');
return nav;
}
/**
* Browse to another page using in-page navigation.
*
* @example
* browser.get('http://angular.github.io/protractor/#/tutorial');
* browser.setLocation('api');
* expect(browser.getCurrentUrl())
* .toBe('http://angular.github.io/protractor/#/api');
*
* @param {string} url In page URL using the same syntax as $location.url()
* @returns {!webdriver.promise.Promise} A promise that will resolve once
* page has been changed.
*/
setLocation(url) {
return this.waitForAngular()
.then(() => this.angularAppRoot())
.then((rootEl) => this.executeScriptWithDescription(clientSideScripts.setLocation, 'Protractor.setLocation()', rootEl, url)
.then((browserErr) => {
if (browserErr) {
throw 'Error while navigating to \'' + url +
'\' : ' + JSON.stringify(browserErr);
}
}));
}
/**
* Deprecated, use `browser.getCurrentUrl()` instead.
*
* Despite its name, this function will generally return `$location.url()`, though in some
* cases it will return `$location.absUrl()` instead. This function is only here for legacy
* users, and will probably be removed in Protractor 6.0.
*
* @deprecated Please use `browser.getCurrentUrl()`
* @example
* browser.get('http://angular.github.io/protractor/#/api');
* expect(browser.getLocationAbsUrl())
* .toBe('http://angular.github.io/protractor/#/api');
* @returns {webdriver.promise.Promise<string>} The current absolute url from
* AngularJS.
*/
getLocationAbsUrl() {
logger.warn('`browser.getLocationAbsUrl()` is deprecated, please use `browser.getCurrentUrl` instead.');
return this.waitForAngular()
.then(() => this.angularAppRoot())
.then((rootEl) => this.executeScriptWithDescription(clientSideScripts.getLocationAbsUrl, 'Protractor.getLocationAbsUrl()', rootEl));
}
/**
* Determine if the control flow is enabled.
*
* @returns true if the control flow is enabled, false otherwise.
*/
controlFlowIsEnabled() {
if (selenium_webdriver_1.promise.USE_PROMISE_MANAGER !== undefined) {
return selenium_webdriver_1.promise.USE_PROMISE_MANAGER;
}
else {
// True for old versions of `selenium-webdriver`, probably false in >=5.0.0
return !!selenium_webdriver_1.promise.ControlFlow;
}
}
}
/**
* @type {ProtractorBy}
*/
ProtractorBrowser.By = new locators_1.ProtractorBy();
exports.ProtractorBrowser = ProtractorBrowser;
//# sourceMappingURL=browser.js.map

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

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

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

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

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

619
node_modules/protractor/built/config.d.ts generated vendored Executable file
View file

@ -0,0 +1,619 @@
import { WebDriver } from 'selenium-webdriver';
import { PluginConfig } from './plugins';
export interface Config {
[key: string]: any;
/**
* The location of the standalone Selenium Server jar file, relative
* to the location of webdriver-manager. If no other method of starting
* Selenium Server is found, this will default to
* node_modules/protractor/node_modules/webdriver-manager/selenium/<jar file>
*/
seleniumServerJar?: string;
/**
* The timeout milliseconds waiting for a local standalone Selenium Server to start.
*
* default: 30000ms
*/
seleniumServerStartTimeout?: number;
/**
* Can be an object which will be passed to the SeleniumServer class as args.
* See a full list of options at
* https://github.com/SeleniumHQ/selenium/blob/master/javascript/node/selenium-webdriver/remote/index.js
* If you specify `args` or `port` in this object, it will overwrite the
* values set via the deprecated config values `seleniumPort` and
* `seleniumArgs`.
*/
localSeleniumStandaloneOpts?: {
/**
* The port to start the Selenium Server on, or null if the server should
* find its own unused port.
*/
port?: any;
/**
* Additional command line options to pass to selenium. For example,
* if you need to change the browser timeout, use
* seleniumArgs: ['-browserTimeout=60']
*/
args?: any;
/**
* Additional command line jvm options to pass to selenium. For example,
* if you need to change the browser driver, use
* jvmArgs: ['-Dwebdriver.ie.driver=IEDriverServer_Win32_2.53.1.exe']
*/
jvmArgs?: string[];
};
/**
* ChromeDriver location is used to help find the chromedriver binary. This will be passed to the
* Selenium jar as the system property webdriver.chrome.driver. If the value is not set when
* launching locally, it will use the default values downloaded from webdriver-manager.
*
* example:
* chromeDriver: './node_modules/webdriver-manager/selenium/chromedriver_2.20'
*/
chromeDriver?: string;
/**
* geckoDriver location is used to help find the gecko binary. This will be passed to the Selenium
* jar as the system property webdriver.gecko.driver. If the value is not set when launching
* locally, it will use the default values downloaded from webdriver-manager.
*/
geckoDriver?: string;
/**
* The address of a running Selenium Server. If specified, Protractor will
* connect to an already running instance of Selenium. This usually looks like
* seleniumAddress: 'http://localhost:4444/wd/hub'
*/
seleniumAddress?: string;
/**
* The selenium session id allows Protractor to attach to an existing selenium
* browser session. The selenium session is maintained after the test has
* completed. Ignored if seleniumAddress is null.
*/
seleniumSessionId?: string;
/**
* The address of a proxy server to use for communicating to Sauce Labs REST APIs via the
* saucelabs node module. For example, the Sauce Labs Proxy can be setup with: sauceProxy:
* 'http://localhost:3128'
*/
sauceProxy?: string;
/**
* The proxy address that WebDriver (e.g. Selenium commands) traffic will go through
* which is tied to the browser session.
*/
webDriverProxy?: string;
/**
* If specified, connect to webdriver through a proxy that manages client-side
* synchronization. Blocking Proxy is an experimental feature and may change
* without notice.
*/
useBlockingProxy?: boolean;
/**
* If specified, Protractor will connect to the Blocking Proxy at the given
* url instead of starting it's own.
*/
blockingProxyUrl?: string;
/**
* If the sauceUser and sauceKey are specified, seleniumServerJar will be
* ignored. The tests will be run remotely using Sauce Labs.
*/
sauceUser?: string;
/**
* If the sauceUser and sauceKey are specified, seleniumServerJar will be
* ignored. The tests will be run remotely using Sauce Labs.
*/
sauceKey?: string;
/**
* If you run your tests on SauceLabs you can specify the region you want to run your tests
* in via the `sauceRegion` property. Available short handles for regions are:
* us: us-west-1 (default)
* eu: eu-central-1
*/
sauceRegion?: string;
/**
* Use sauceAgent if you need custom HTTP agent to connect to saucelabs.com APIs.
* This is needed if your computer is behind a corporate proxy.
*
* To match sauce agent implementation, use
* [HttpProxyAgent](https://github.com/TooTallNate/node-http-proxy-agent)
* to generate the agent or use sauceProxy as an alternative. If a
* sauceProxy is provided, the sauceAgent will be overridden.
*/
sauceAgent?: any;
/**
* Use sauceBuild if you want to group test capabilites by a build ID
*/
sauceBuild?: string;
/**
* If true, Protractor will use http:// protocol instead of https:// to
* connect to Sauce Labs defined by sauceSeleniumAddress.
*
* default: false
*/
sauceSeleniumUseHttp?: boolean;
/**
* Use sauceSeleniumAddress if you need to customize the URL Protractor
* uses to connect to sauce labs (for example, if you are tunneling selenium
* traffic through a sauce connect tunnel). Default is
* ondemand.saucelabs.com:443/wd/hub
*/
sauceSeleniumAddress?: string;
/**
* If testobjectUser and testobjectKey are specified, kobitonUser, kobitonKey, browserstackUser,
* browserStackKey and seleniumServerJar will be ignored. The tests will be run remotely using
* TestObject.
*/
testobjectUser?: string;
/**
* If testobjectUser and testobjectKey are specified, kobitonUser, kobitonKey, browserStackUser,
* browserStackKey and seleniumServerJar will be ignored. The tests will be run remotely using
* TestObject.
*/
testobjectKey?: string;
/**
* If kobitonUser and kobitonKey are specified, testobjectUser, testojbectKey, browserstackUser,
* browserStackKey and seleniumServerJar will be ignored. The tests will be run remotely using
* TestObject.
*/
kobitonUser?: string;
/**
* If kobitonUser and kobitonKey are specified, testobjectUser, testojbectKey, browserStackUser,
* browserStackKey and seleniumServerJar will be ignored. The tests will be run remotely using
* TestObject.
*/
kobitonKey?: string;
/**
* If browserstackUser and browserstackKey are specified, seleniumServerJar
* will be ignored. The tests will be run remotely using BrowserStack.
*/
browserstackUser?: string;
/**
* If browserstackUser and browserstackKey are specified, seleniumServerJar
* will be ignored. The tests will be run remotely using BrowserStack.
*/
browserstackKey?: string;
/**
* Proxy server to be used for connecting to BrowserStack APIs
* e.g. "http://proxy.example.com:1234".
* This should be used when you are behind a proxy server.
*/
browserstackProxy?: string;
/**
* If true, Protractor will connect directly to the browser Drivers
* at the locations specified by chromeDriver and firefoxPath. Only Chrome
* and Firefox are supported for direct connect.
*
* default: false
*/
directConnect?: boolean;
/**
* Path to the firefox application binary. If null, will attempt to find
* firefox in the default locations.
*/
firefoxPath?: string;
seleniumWebDriver?: WebDriver;
/**
* Use default globals: 'protractor', 'browser', '$', '$$', 'element', 'by'.
* These also exist as properties of the protractor namespace:
* 'protractor.browser', 'protractor.$', 'protractor.$$',
* 'protractor.element', 'protractor.by', and 'protractor.By'.
*
* When no globals is set to true, the only available global variable will be
* 'protractor'.
*/
noGlobals?: boolean;
/**
* Required. Spec patterns are relative to the location of this config.
*
* Example:
* specs: [
* 'spec/*_spec.js'
* ]
*/
specs?: Array<string>;
/**
* Patterns to exclude specs.
*/
exclude?: Array<string> | string;
/**
* Alternatively, suites may be used. When run without a command line
* parameter, all suites will run. If run with --suite=smoke or
* --suite=smoke,full only the patterns matched by the specified suites will
* run.
*
* Example:
* suites: {
* smoke: 'spec/smoketests/*.js',
* full: 'spec/*.js'
* }
*/
suites?: any;
/**
* If you would like protractor to use a specific suite by default instead of
* all suites, you can put that in the config file as well.
*/
suite?: string;
/**
* Protractor can launch your tests on one or more browsers. If you are
* testing on a single browser, use the capabilities option. If you are
* testing on multiple browsers, use the multiCapabilities array.
*
* For a list of available capabilities, see
* https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities
* In addition, you may specify count, shardTestFiles, and maxInstances.
*
* Example:
* capabilities: {
* browserName: 'chrome',
* name: 'Unnamed Job',
* logName: 'Chrome - English',
* count: 1,
* shardTestFiles: false,
* maxInstances: 1,
* specs: ['spec/chromeOnlySpec.js'],
* exclude: ['spec/doNotRunInChromeSpec.js'],
* seleniumAddress: 'http://localhost:4444/wd/hub'
* }
*/
capabilities?: {
[key: string]: any;
browserName?: string;
/**
* Name of the process executing this capability. Not used directly by
* protractor or the browser, but instead pass directly to third parties
* like BrowserStack and SauceLabs as the name of the job running this
* test
*/
name?: string;
/**
* User defined name for the capability that will display in the results
* log. Defaults to the browser name
*/
logName?: string;
/**
* Number of times to run this set of capabilities (in parallel, unless
* limited by maxSessions). Default is 1.
*/
count?: number;
/**
* If this is set to be true, specs will be sharded by file (i.e. all
* files to be run by this set of capabilities will run in parallel).
* Default is false.
*/
shardTestFiles?: boolean;
/**
* Maximum number of browser instances that can run in parallel for this
* set of capabilities. This is only needed if shardTestFiles is true.
* Default is 1.
*/
maxInstances?: number;
/**
* Additional spec files to be run on this capability only.
*/
specs?: string[];
/**
* Spec files to be excluded on this capability only.
*/
exclude?: string[];
/**
* Optional: override global seleniumAddress on this capability only.
*/
seleniumAddress?: string;
};
/**
* If you would like to run more than one instance of WebDriver on the same
* tests, use multiCapabilities, which takes an array of capabilities.
* If this is specified, capabilities will be ignored.
*/
multiCapabilities?: Array<any>;
/**
* If you need to resolve multiCapabilities asynchronously (i.e. wait for
* server/proxy, set firefox profile, etc), you can specify a function here
* which will return either `multiCapabilities` or a promise to
* `multiCapabilities`.
*
* If this returns a promise, it is resolved immediately after
* `beforeLaunch` is run, and before any driver is set up. If this is
* specified, both capabilities and multiCapabilities will be ignored.
*/
getMultiCapabilities?: any;
/**
* Maximum number of total browser sessions to run. Tests are queued in
* sequence if number of browser sessions is limited by this parameter.
* Use a number less than 1 to denote unlimited. Default is unlimited.
*/
maxSessions?: number;
/**
* Whether or not to buffer output when running tests on multiple browsers
* in parallel. By default, when running multiple browser sessions, the
* results are buffered and not logged until the test run finishes. If true,
* when running multiple sessions in parallel results will be logged when
* each test finishes.
*/
verboseMultiSessions?: boolean;
/**
* A base URL for your application under test. Calls to protractor.get()
* with relative paths will be resolved against this URL (via url.resolve)
*/
baseUrl?: string;
/**
* A CSS Selector for a DOM element within your Angular application.
* Protractor will attempt to automatically find your application, but it is
* necessary to set rootElement in certain cases.
*
* In Angular 1, Protractor will use the element your app bootstrapped to by
* default. If that doesn't work, it will then search for hooks in `body` or
* `ng-app` elements (details here: https://git.io/v1b2r).
*
* In later versions of Angular, Protractor will try to hook into all angular
* apps on the page. Use rootElement to limit the scope of which apps
* Protractor waits for and searches within.
*/
rootElement?: string;
/**
* The timeout in milliseconds for each script run on the browser. This
* should be longer than the maximum time your application needs to
* stabilize between tasks.
*/
allScriptsTimeout?: number;
/**
* How long to wait for a page to load.
*/
getPageTimeout?: number;
/**
* A callback function called once configs are read but before any
* environment setup. This will only run once, and before onPrepare.
*
* You can specify a file containing code to run by setting beforeLaunch to
* the filename string.
*
* At this point, global variable 'protractor' object will NOT be set up,
* and globals from the test framework will NOT be available. The main
* purpose of this function should be to bring up test dependencies.
*/
beforeLaunch?: () => void;
/**
* A callback function called once protractor is ready and available, and
* before the specs are executed. If multiple capabilities are being run,
* this will run once per capability.
*
* You can specify a file containing code to run by setting onPrepare to
* the filename string. onPrepare can optionally return a promise, which
* Protractor will wait for before continuing execution. This can be used if
* the preparation involves any asynchronous calls, e.g. interacting with
* the browser. Otherwise Protractor cannot guarantee order of execution
* and may start the tests before preparation finishes.
*
* At this point, global variable 'protractor' object will be set up, and
* globals from the test framework will be available. For example, if you
* are using Jasmine, you can add a reporter with:
*
* jasmine.getEnv().addReporter(new jasmine.JUnitXmlReporter(
* 'outputdir/', true, true));
*
* If you need access back to the current configuration object,
* use a pattern like the following:
*
* return browser.getProcessedConfig().then(function(config) {
* // config.capabilities is the CURRENT capability being run, if
* // you are using multiCapabilities.
* console.log('Executing capability', config.capabilities);
* });
*/
onPrepare?: () => void;
/**
* A callback function called once tests are finished. onComplete can
* optionally return a promise, which Protractor will wait for before
* shutting down webdriver.
*
* At this point, tests will be done but global objects will still be
* available.
*/
onComplete?: () => void;
/**
* A callback function called once the tests have finished running and
* the WebDriver instance has been shut down. It is passed the exit code
* (0 if the tests passed). This is called once per capability.
*/
onCleanUp?: (exitCode: number) => void;
/**
* A callback function called once all tests have finished running and
* the WebDriver instance has been shut down. It is passed the exit code
* (0 if the tests passed). afterLaunch must return a promise if you want
* asynchronous code to be executed before the program exits.
* This is called only once before the program exits (after onCleanUp).
*/
afterLaunch?: (exitCode: number) => void;
/**
* The params object will be passed directly to the Protractor instance,
* and can be accessed from your test as browser.params. It is an arbitrary
* object and can contain anything you may need in your test.
* This can be changed via the command line as:
* --params.login.user "Joe"
*
* Example:
* params: {
* login: {
* user: 'Jane',
* password: '1234'
* }
* }
*/
params?: any;
/**
* If set, protractor will save the test output in json format at this path.
* The path is relative to the location of this config.
*/
resultJsonOutputFile?: any;
/**
* If true, protractor will restart the browser between each test. Default
* value is false.
*
* CAUTION: This will cause your tests to slow down drastically.
*/
restartBrowserBetweenTests?: boolean;
/**
* Protractor will track outstanding $timeouts by default, and report them
* in the error message if Protractor fails to synchronize with Angular in
* time. In order to do this Protractor needs to decorate $timeout.
*
* CAUTION: If your app decorates $timeout, you must turn on this flag. This
* is false by default.
*/
untrackOutstandingTimeouts?: boolean;
/**
* If set, Protractor will ignore uncaught exceptions instead of exiting
* without an error code. The exceptions will still be logged as warnings.
*/
ignoreUncaughtExceptions?: boolean;
/**
* If set, will create a log file in the given directory with a readable log of
* the webdriver commands it executes.
*
* This is an experimental feature. Enabling this will also turn on Blocking Proxy
* synchronization, which is also experimental.
*/
webDriverLogDir?: string;
/**
* If set, Protractor will pause the specified amount of time (in milliseconds)
* before interactions with browser elements (ie, sending keys, clicking). It will
* also highlight the element it's about to interact with.
*
* This is an experimental feature. Enabling this will also turn on Blocking Proxy
* synchronization, which is also experimental.
*/
highlightDelay?: number;
/**
* Protractor log level
*
* default: INFO
*/
logLevel?: 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
/**
* Test framework to use. This may be one of: jasmine, mocha or custom.
* Default value is 'jasmine'
*
* When the framework is set to "custom" you'll need to additionally
* set frameworkPath with the path relative to the config file or absolute:
*
* framework: 'custom',
* frameworkPath: './frameworks/my_custom_jasmine.js',
*
* See github.com/angular/protractor/blob/master/lib/frameworks/README.md
* to comply with the interface details of your custom implementation.
*
* Jasmine is fully supported as test and assertion frameworks.
* Mocha has limited support. You will need to include your
* own assertion framework (such as Chai) if working with Mocha.
*/
framework?: string;
/**
* Options to be passed to jasmine.
*
* See https://github.com/jasmine/jasmine-npm/blob/master/lib/jasmine.js
* for the exact options available.
*/
jasmineNodeOpts?: {
[key: string]: any;
/**
* If true, print colors to the terminal.
*/
showColors?: boolean;
/**
* Default time to wait in ms before a test fails.
*/
defaultTimeoutInterval?: number;
/**
* Function called to print jasmine results.
*/
print?: () => void;
/**
* If set, only execute specs whose names match the pattern, which is
* internally compiled to a RegExp.
*/
grep?: string;
/**
* Inverts 'grep' matches
*/
invertGrep?: boolean;
/**
* If true, run specs in semi-random order
*/
random?: boolean;
/**
* Set the randomization seed if randomization is turned on
*/
seed?: string;
};
/**
* Options to be passed to Mocha.
*
* See the full list at http://mochajs.org/
*/
mochaOpts?: {
[key: string]: any;
ui?: string;
reporter?: string;
};
/**
* See docs/plugins.md
*/
plugins?: PluginConfig[];
/**
* Turns off source map support. Stops protractor from registering global
* variable `source-map-support`. Defaults to `false`
*/
skipSourceMapSupport?: boolean;
/**
* Turns off WebDriver's environment variables overrides to ignore any
* environment variable and to only use the configuration in this file.
* Defaults to `false`
*/
disableEnvironmentOverrides?: boolean;
/**
* Tells Protractor to interpret any angular apps it comes across as hybrid
* angular1/angular2 apps (i.e. apps using ngUpgrade)
* Defaults to `false`
*
* @type {boolean}
*/
ng12Hybrid?: boolean;
/**
* Protractor will exit with an error if it sees any command line flags it doesn't
* recognize. Set disableChecks true to disable this check.
*/
disableChecks?: boolean;
/**
* Enable/disable the WebDriver Control Flow.
*
* WebDriverJS (and by extention, Protractor) uses a Control Flow to manage the order in which
* commands are executed and promises are resolved (see docs/control-flow.md for details).
* However, as syntax like `async`/`await` are being introduced, WebDriverJS has decided to
* deprecate the control flow, and have users manage the asynchronous activity themselves
* (details here: https://github.com/SeleniumHQ/selenium/issues/2969).
*
* At the moment, the WebDriver Control Flow is still enabled by default. You can disable it by
* setting the environment variable `SELENIUM_PROMISE_MANAGER` to `0`. In a webdriver release in
* Q4 2017, the Control Flow will be disabled by default, but you will be able to re-enable it by
* setting `SELENIUM_PROMISE_MANAGER` to `1`. At a later point, the control flow will be removed
* for good.
*
* If you don't like managing environment variables, you can set this option in your config file,
* and Protractor will handle enabling/disabling the control flow for you. Setting this option
* is higher priority than the `SELENIUM_PROMISE_MANAGER` environment variable.
*
* @type {boolean=}
*/
SELENIUM_PROMISE_MANAGER?: boolean;
seleniumArgs?: any[];
jvmArgs?: string[];
configDir?: string;
troubleshoot?: boolean;
seleniumPort?: number;
mockSelenium?: boolean;
v8Debug?: any;
nodeDebug?: boolean;
debuggerServerPort?: number;
frameworkPath?: string;
elementExplorer?: any;
debug?: boolean;
unknownFlags_?: string[];
}

3
node_modules/protractor/built/config.js generated vendored Executable file
View file

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=config.js.map

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

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

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

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

47
node_modules/protractor/built/debugger.d.ts generated vendored Executable file
View file

@ -0,0 +1,47 @@
import { promise as wdpromise } from 'selenium-webdriver';
import { ProtractorBrowser } from './browser';
export declare class DebugHelper {
private browserUnderDebug_;
/**
* Set to true when we validate that the debug port is open. Since the debug
* port is held open forever once the debugger is attached, it's important
* we only do validation once.
*/
debuggerValidated_: boolean;
dbgCodeExecutor: any;
constructor(browserUnderDebug_: ProtractorBrowser);
initBlocking(debuggerClientPath: string, onStartFn: Function, opt_debugPort?: number): void;
init(debuggerClientPath: string, onStartFn: Function, opt_debugPort?: number): void;
/**
* 1) Set up helper functions for debugger clients to call on (e.g.
* execute code, get autocompletion).
* 2) Enter process into debugger mode. (i.e. process._debugProcess).
* 3) Invoke the debugger client specified by debuggerClientPath.
*
* @param {string} debuggerClientPath Absolute path of debugger client to use.
* @param {boolean} blockUntilExit Whether to block the flow until process exit or resume
* immediately.
* @param {Function} onStartFn Function to call when the debugger starts. The
* function takes a single parameter, which represents whether this is the
* first time that the debugger is called.
* @param {number=} opt_debugPort Optional port to use for the debugging
* process.
*
* @return {Promise} If blockUntilExit, a promise resolved when the debugger process
* exits. Otherwise, resolved when the debugger process is ready to begin.
*/
init_(debuggerClientPath: string, blockUntilExit: boolean, onStartFn: Function, opt_debugPort?: number): wdpromise.Promise<{}>;
/**
* Validates that the port is free to use. This will only validate the first
* time it is called. The reason is that on subsequent calls, the port will
* already be bound to the debugger, so it will not be available, but that is
* okay.
*
* @returns {Promise<boolean>} A promise that becomes ready when the
* validation
* is done. The promise will resolve to a boolean which represents whether
* this is the first time that the debugger is called.
*/
private validatePortAvailability_(port);
isAttached(): boolean;
}

233
node_modules/protractor/built/debugger.js generated vendored Executable file
View file

@ -0,0 +1,233 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const net = require("net");
const selenium_webdriver_1 = require("selenium-webdriver");
const util = require("util");
const logger_1 = require("./logger");
let breakpointHook = require('./breakpointhook.js');
let logger = new logger_1.Logger('protractor');
class DebugHelper {
constructor(browserUnderDebug_) {
this.browserUnderDebug_ = browserUnderDebug_;
}
initBlocking(debuggerClientPath, onStartFn, opt_debugPort) {
this.init_(debuggerClientPath, true, onStartFn, opt_debugPort);
}
init(debuggerClientPath, onStartFn, opt_debugPort) {
this.init_(debuggerClientPath, false, onStartFn, opt_debugPort);
}
/**
* 1) Set up helper functions for debugger clients to call on (e.g.
* execute code, get autocompletion).
* 2) Enter process into debugger mode. (i.e. process._debugProcess).
* 3) Invoke the debugger client specified by debuggerClientPath.
*
* @param {string} debuggerClientPath Absolute path of debugger client to use.
* @param {boolean} blockUntilExit Whether to block the flow until process exit or resume
* immediately.
* @param {Function} onStartFn Function to call when the debugger starts. The
* function takes a single parameter, which represents whether this is the
* first time that the debugger is called.
* @param {number=} opt_debugPort Optional port to use for the debugging
* process.
*
* @return {Promise} If blockUntilExit, a promise resolved when the debugger process
* exits. Otherwise, resolved when the debugger process is ready to begin.
*/
init_(debuggerClientPath, blockUntilExit, onStartFn, opt_debugPort) {
const vm_ = require('vm');
let flow = selenium_webdriver_1.promise.controlFlow();
let context = { require: require };
global.list = (locator) => {
return global.protractor.browser.findElements(locator).then((arr) => {
let found = [];
for (let i = 0; i < arr.length; ++i) {
arr[i].getText().then((text) => {
found.push(text);
});
}
return found;
});
};
for (let key in global) {
context[key] = global[key];
}
let sandbox = vm_.createContext(context);
let debuggingDone = selenium_webdriver_1.promise.defer();
// We run one flow.execute block for the debugging session. All
// subcommands should be scheduled under this task.
let executePromise = flow.execute(() => {
process['debugPort'] = opt_debugPort || process['debugPort'];
this.validatePortAvailability_(process['debugPort']).then((firstTime) => {
onStartFn(firstTime);
let args = [process.pid, process['debugPort']];
if (this.browserUnderDebug_.debuggerServerPort) {
args.push(this.browserUnderDebug_.debuggerServerPort);
}
let nodedebug = require('child_process').fork(debuggerClientPath, args);
process.on('exit', function () {
nodedebug.kill('SIGTERM');
});
nodedebug
.on('message', (m) => {
if (m === 'ready') {
breakpointHook();
if (!blockUntilExit) {
debuggingDone.fulfill();
}
}
})
.on('exit', () => {
// Clear this so that we know it's ok to attach a debugger
// again.
this.dbgCodeExecutor = null;
debuggingDone.fulfill();
});
});
return debuggingDone.promise;
}, 'debugging tasks');
// Helper used only by debuggers at './debugger/modes/*.js' to insert code
// into the control flow, via debugger 'evaluate' protocol.
// In order to achieve this, we maintain a task at the top of the control
// flow, so that we can insert frames into it.
// To be able to simulate callback/asynchronous code, we poll this object
// whenever `breakpointHook` is called.
this.dbgCodeExecutor = {
execPromise_: undefined,
execPromiseResult_: undefined,
execPromiseError_: undefined,
// A dummy repl server to make use of its completion function.
replServer_: require('repl').start({
input: { on: function () { }, resume: function () { } },
// dummy readable stream
output: { write: function () { } },
useGlobal: true
}),
// Execute a function, which could yield a value or a promise,
// and allow its result to be accessed synchronously
execute_: function (execFn_) {
this.execPromiseResult_ = this.execPromiseError_ = undefined;
this.execPromise_ = execFn_();
// Note: This needs to be added after setting execPromise to execFn,
// or else we cause this.execPromise_ to get stuck in pending mode
// at our next breakpoint.
this.execPromise_.then((result) => {
this.execPromiseResult_ = result;
breakpointHook();
}, (err) => {
this.execPromiseError_ = err;
breakpointHook();
});
},
// Execute a piece of code.
// Result is a string representation of the evaluation.
execute: function (code) {
let execFn_ = () => {
// Run code through vm so that we can maintain a local scope which is
// isolated from the rest of the execution.
let res;
try {
res = vm_.runInContext(code, sandbox);
}
catch (e) {
res = selenium_webdriver_1.promise.when('Error while evaluating command: ' + e);
}
if (!selenium_webdriver_1.promise.isPromise(res)) {
res = selenium_webdriver_1.promise.when(res);
}
return res.then((res) => {
if (res === undefined) {
return undefined;
}
else {
// The '' forces res to be expanded into a string instead of just
// '[Object]'. Then we remove the extra space caused by the ''
// using substring.
return util.format.apply(this, ['', res]).substring(1);
}
});
};
this.execute_(execFn_);
},
// Autocomplete for a line.
// Result is a JSON representation of the autocomplete response.
complete: function (line) {
let execFn_ = () => {
let deferred = selenium_webdriver_1.promise.defer();
this.replServer_.complete(line, (err, res) => {
if (err) {
deferred.reject(err);
}
else {
deferred.fulfill(JSON.stringify(res));
}
});
return deferred.promise;
};
this.execute_(execFn_);
},
// Code finished executing.
resultReady: function () {
return !(this.execPromise_.state_ === 'pending');
},
// Get asynchronous results synchronously.
// This will throw if result is not ready.
getResult: function () {
if (!this.resultReady()) {
throw new Error('Result not ready');
}
if (this.execPromiseError_) {
throw this.execPromiseError_;
}
return this.execPromiseResult_;
}
};
return executePromise;
}
/**
* Validates that the port is free to use. This will only validate the first
* time it is called. The reason is that on subsequent calls, the port will
* already be bound to the debugger, so it will not be available, but that is
* okay.
*
* @returns {Promise<boolean>} A promise that becomes ready when the
* validation
* is done. The promise will resolve to a boolean which represents whether
* this is the first time that the debugger is called.
*/
validatePortAvailability_(port) {
if (this.debuggerValidated_) {
return selenium_webdriver_1.promise.when(false);
}
let doneDeferred = selenium_webdriver_1.promise.defer();
// Resolve doneDeferred if port is available.
let tester = net.connect({ port: port }, () => {
doneDeferred.reject('Port ' + port + ' is already in use. Please specify ' +
'another port to debug.');
});
tester.once('error', (err) => {
if (err.code === 'ECONNREFUSED') {
tester
.once('close', () => {
doneDeferred.fulfill(true);
})
.end();
}
else {
doneDeferred.reject('Unexpected failure testing for port ' + port + ': ' + JSON.stringify(err));
}
});
return doneDeferred.promise.then((firstTime) => {
this.debuggerValidated_ = true;
return firstTime;
}, (err) => {
console.error(err);
return process.exit(1);
});
}
isAttached() {
return !!this.dbgCodeExecutor;
}
}
exports.DebugHelper = DebugHelper;
//# sourceMappingURL=debugger.js.map

157
node_modules/protractor/built/debugger/clients/explorer.js generated vendored Executable file
View file

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

83
node_modules/protractor/built/debugger/clients/wddebugger.js generated vendored Executable file
View file

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

113
node_modules/protractor/built/debugger/debuggerCommons.js generated vendored Executable file
View file

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

127
node_modules/protractor/built/debugger/modes/commandRepl.js generated vendored Executable file
View file

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

143
node_modules/protractor/built/debugger/modes/debuggerRepl.js generated vendored Executable file
View file

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

View file

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

View file

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

View file

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

View file

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

22
node_modules/protractor/built/driverProviders/direct.d.ts generated vendored Executable file
View file

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

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

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

View file

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

View file

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

14
node_modules/protractor/built/driverProviders/hosted.d.ts generated vendored Executable file
View file

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

28
node_modules/protractor/built/driverProviders/hosted.js generated vendored Executable file
View file

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

15
node_modules/protractor/built/driverProviders/index.d.ts generated vendored Executable file
View file

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

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

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

13
node_modules/protractor/built/driverProviders/kobiton.d.ts generated vendored Executable file
View file

@ -0,0 +1,13 @@
/// <reference types="q" />
import * as q from 'q';
import { Config } from '../config';
import { DriverProvider } from './driverProvider';
export declare class Kobiton 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>;
}

33
node_modules/protractor/built/driverProviders/kobiton.js generated vendored Executable file
View file

@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* This is an implementation of the Kobiton 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('kobiton');
class Kobiton 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() {
let deferred = q.defer();
this.config_.capabilities['kobitonUser'] = this.config_.kobitonUser;
this.config_.capabilities['kobitonKey'] = this.config_.kobitonKey;
this.config_.seleniumAddress = 'https://' + this.config_.kobitonUser + ':' +
this.config_.kobitonKey + '@api.kobiton.com/wd/hub';
logger.info('Using Kobiton selenium server at ' + this.config_.seleniumAddress);
deferred.resolve();
return deferred.promise;
}
}
exports.Kobiton = Kobiton;
//# sourceMappingURL=kobiton.js.map

30
node_modules/protractor/built/driverProviders/local.d.ts generated vendored Executable file
View file

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

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

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

29
node_modules/protractor/built/driverProviders/mock.d.ts generated vendored Executable file
View file

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

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

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

29
node_modules/protractor/built/driverProviders/sauce.d.ts generated vendored Executable file
View file

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

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

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

View file

@ -0,0 +1,13 @@
/// <reference types="q" />
import * as q from 'q';
import { Config } from '../config';
import { DriverProvider } from './driverProvider';
export declare class TestObject 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>;
}

32
node_modules/protractor/built/driverProviders/testObject.js generated vendored Executable file
View file

@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* This is an implementation of the TestObject 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('testobject');
class TestObject 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() {
let deferred = q.defer();
this.config_.capabilities['testobject.user'] = this.config_.testobjectUser;
this.config_.capabilities['testobject_api_key'] = this.config_.testobjectKey;
this.config_.seleniumAddress = 'https://us1.appium.testobject.com/wd/hub';
logger.info('Using TestObject selenium server at ' + this.config_.seleniumAddress);
deferred.resolve();
return deferred.promise;
}
}
exports.TestObject = TestObject;
//# sourceMappingURL=testObject.js.map

View file

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

View file

@ -0,0 +1,52 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* This is an implementation of the Use Existing WebDriver 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('useExistingWebDriver');
class UseExistingWebDriver 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() {
const defer = q.defer();
this.config_.seleniumWebDriver.getSession().then((session) => {
logger.info('Using session id - ' + session.getId());
return defer.resolve();
});
return q(undefined);
}
/**
* Getting a new driver by attaching an existing session.
*
* @public
* @return {WebDriver} webdriver instance
*/
getNewDriver() {
const newDriver = this.config_.seleniumWebDriver;
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.UseExistingWebDriver = UseExistingWebDriver;
//# sourceMappingURL=useExistingWebDriver.js.map

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

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

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

File diff suppressed because it is too large Load diff

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

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

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

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

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

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

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

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

View file

@ -0,0 +1,10 @@
// This is spec file is automatically added by protractor to implement our
// `afterEach` functionality for jasmine and mocha.
var hooks = require('./setupAfterEach').hooks;
afterEach(function() {
if (hooks.afterEach) {
return hooks.afterEach();
}
});

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

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

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

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

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

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

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

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

29
node_modules/protractor/built/frameworks/setupAfterEach.js generated vendored Executable file
View file

@ -0,0 +1,29 @@
/**
* Setup afterEach hook for jasmine/mocha tests.
*
* One of the main purposes of this file is to give `__protractor_internal_afterEach_setup_spec.js`
* a place to look up `runner.afterEach` at runtime without using globals.
* This file needs to be separate from `__protractor_internal_afterEach_setup_spec.js` so that that
* file is not prematurely executed.
*/
var path = require('path');
// Queried by `protractor_internal_afterEach_setup_spec.js` for the `afterEach` hook
var hooks = {
afterEach: null
};
exports.hooks = hooks;
/**
* Setup `runner.afterEach` to be called after every spec.
*
* @param {Runner} runner The current Protractor Runner.
* @param {Array} specs Array of Directory Path Strings. Must be a reference to the same array
* instance used by the framework
*/
exports.setup = function(runner, specs) {
hooks.afterEach = runner.afterEach.bind(runner);
specs.push(path.resolve(__dirname, '__protractor_internal_afterEach_setup_spec.js'));
};

29
node_modules/protractor/built/index.d.ts generated vendored Executable file
View file

@ -0,0 +1,29 @@
import { ElementHelper, ProtractorBrowser } from './browser';
import { ElementArrayFinder, ElementFinder } from './element';
import { ProtractorExpectedConditions } from './expectedConditions';
import { ProtractorBy } from './locators';
import { Ptor } from './ptor';
export { ActionSequence, Browser, Builder, Button, Capabilities, Capability, error, EventEmitter, FileDetector, Key, logging, promise, Session, until, WebDriver, WebElement, WebElementPromise } from 'selenium-webdriver';
export { ElementHelper, ProtractorBrowser } from './browser';
export { Config } from './config';
export { ElementArrayFinder, ElementFinder } from './element';
export { ProtractorExpectedConditions } from './expectedConditions';
export { Locator, ProtractorBy } from './locators';
export { PluginConfig, ProtractorPlugin } from './plugins';
export { Ptor } from './ptor';
export { Runner } from './runner';
export declare let utils: {
firefox: any;
http: any;
remote: any;
};
export declare let Command: any;
export declare let CommandName: any;
export declare let protractor: Ptor;
export declare let browser: ProtractorBrowser;
export declare let $: (search: string) => ElementFinder;
export declare let $$: (search: string) => ElementArrayFinder;
export declare let element: ElementHelper;
export declare let By: ProtractorBy;
export declare let by: ProtractorBy;
export declare let ExpectedConditions: ProtractorExpectedConditions;

54
node_modules/protractor/built/index.js generated vendored Executable file
View file

@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// Re-export selenium-webdriver types.
var selenium_webdriver_1 = require("selenium-webdriver");
exports.ActionSequence = selenium_webdriver_1.ActionSequence;
exports.Browser = selenium_webdriver_1.Browser;
exports.Builder = selenium_webdriver_1.Builder;
exports.Button = selenium_webdriver_1.Button;
exports.Capabilities = selenium_webdriver_1.Capabilities;
exports.Capability = selenium_webdriver_1.Capability;
exports.error = selenium_webdriver_1.error;
exports.EventEmitter = selenium_webdriver_1.EventEmitter;
exports.FileDetector = selenium_webdriver_1.FileDetector;
exports.Key = selenium_webdriver_1.Key;
exports.logging = selenium_webdriver_1.logging;
exports.promise = selenium_webdriver_1.promise;
exports.Session = selenium_webdriver_1.Session;
exports.until = selenium_webdriver_1.until;
exports.WebDriver = selenium_webdriver_1.WebDriver;
exports.WebElement = selenium_webdriver_1.WebElement;
exports.WebElementPromise = selenium_webdriver_1.WebElementPromise;
// Re-export public types.
var browser_1 = require("./browser");
exports.ProtractorBrowser = browser_1.ProtractorBrowser;
var element_1 = require("./element");
exports.ElementArrayFinder = element_1.ElementArrayFinder;
exports.ElementFinder = element_1.ElementFinder;
var expectedConditions_1 = require("./expectedConditions");
exports.ProtractorExpectedConditions = expectedConditions_1.ProtractorExpectedConditions;
var locators_1 = require("./locators");
exports.ProtractorBy = locators_1.ProtractorBy;
var ptor_1 = require("./ptor");
exports.Ptor = ptor_1.Ptor;
var runner_1 = require("./runner");
exports.Runner = runner_1.Runner;
exports.utils = {
firefox: require('selenium-webdriver/firefox'),
http: require('selenium-webdriver/http'),
remote: require('selenium-webdriver/remote')
};
exports.Command = require('selenium-webdriver/lib/command').Command;
exports.CommandName = require('selenium-webdriver/lib/command').Name;
Object.defineProperty(exports, 'protractor', { get: () => global['protractor'] });
function registerGlobal(name) {
Object.defineProperty(exports, name, { get: () => exports.protractor ? exports.protractor[name] : undefined });
}
registerGlobal('browser');
registerGlobal('$');
registerGlobal('$$');
registerGlobal('element');
registerGlobal('By');
registerGlobal('by');
registerGlobal('ExpectedConditions');
//# sourceMappingURL=index.js.map

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

50
node_modules/protractor/built/ptor.d.ts generated vendored Executable file
View file

@ -0,0 +1,50 @@
import * as webdriver from 'selenium-webdriver';
import * as chrome from 'selenium-webdriver/chrome';
import * as firefox from 'selenium-webdriver/firefox';
import * as http from 'selenium-webdriver/http';
import * as remote from 'selenium-webdriver/remote';
import { ElementHelper, ProtractorBrowser } from './browser';
import { ElementArrayFinder, ElementFinder } from './element';
import { ProtractorExpectedConditions } from './expectedConditions';
import { ProtractorBy } from './locators';
export declare class Ptor {
browser: ProtractorBrowser;
$: (search: string) => ElementFinder;
$$: (search: string) => ElementArrayFinder;
element: ElementHelper;
By: ProtractorBy;
by: ProtractorBy;
wrapDriver: (webdriver: webdriver.WebDriver, baseUrl?: string, rootElement?: string, untrackOutstandingTimeouts?: boolean) => ProtractorBrowser;
ExpectedConditions: ProtractorExpectedConditions;
ProtractorBrowser: any;
ElementFinder: any;
ElementArrayFinder: any;
ProtractorBy: any;
ProtractorExpectedConditions: any;
ActionSequence: typeof webdriver.ActionSequence;
Browser: webdriver.IBrowser;
Builder: typeof webdriver.Builder;
Button: webdriver.IButton;
Capabilities: typeof webdriver.Capabilities;
Capability: webdriver.ICapability;
EventEmitter: typeof webdriver.EventEmitter;
FileDetector: typeof webdriver.FileDetector;
Key: webdriver.IKey;
Session: typeof webdriver.Session;
WebDriver: typeof webdriver.WebDriver;
WebElement: typeof webdriver.WebElement;
WebElementPromise: typeof webdriver.WebElementPromise;
error: typeof webdriver.error;
logging: typeof webdriver.logging;
promise: typeof webdriver.promise;
until: typeof webdriver.until;
Command: any;
CommandName: any;
utils: {
firefox: typeof firefox;
http: typeof http;
remote: typeof remote;
chrome: typeof chrome;
};
}
export declare let protractor: Ptor;

47
node_modules/protractor/built/ptor.js generated vendored Executable file
View file

@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const webdriver = require("selenium-webdriver");
const chrome = require("selenium-webdriver/chrome");
const firefox = require("selenium-webdriver/firefox");
const http = require("selenium-webdriver/http");
const remote = require("selenium-webdriver/remote");
class Ptor {
constructor() {
this.$ = function (search) {
return null;
};
this.$$ = function (search) {
return null;
};
// Export protractor classes.
this.ProtractorBrowser = require('./browser').ProtractorBrowser;
this.ElementFinder = require('./element').ElementFinder;
this.ElementArrayFinder = require('./element').ElementArrayFinder;
this.ProtractorBy = require('./locators').ProtractorBy;
this.ProtractorExpectedConditions = require('./expectedConditions').ProtractorExpectedConditions;
// Export selenium webdriver.
this.ActionSequence = webdriver.ActionSequence;
this.Browser = webdriver.Browser;
this.Builder = webdriver.Builder;
this.Button = webdriver.Button;
this.Capabilities = webdriver.Capabilities;
this.Capability = webdriver.Capability;
this.EventEmitter = webdriver.EventEmitter;
this.FileDetector = webdriver.FileDetector;
this.Key = webdriver.Key;
this.Session = webdriver.Session;
this.WebDriver = webdriver.WebDriver;
this.WebElement = webdriver.WebElement;
this.WebElementPromise = webdriver.WebElementPromise;
this.error = webdriver.error;
this.logging = webdriver.logging;
this.promise = webdriver.promise;
this.until = webdriver.until;
this.Command = require('selenium-webdriver/lib/command').Command;
this.CommandName = require('selenium-webdriver/lib/command').Name;
this.utils = { firefox: firefox, http: http, remote: remote, chrome: chrome };
}
}
exports.Ptor = Ptor;
exports.protractor = new Ptor();
//# sourceMappingURL=ptor.js.map

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

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

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

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

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

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

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

216
node_modules/protractor/built/selenium-webdriver/locators.js generated vendored Executable file
View file

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

765
node_modules/protractor/built/selenium-webdriver/webdriver.js generated vendored Executable file
View file

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

47
node_modules/protractor/built/webdriver-js-extender/index.js generated vendored Executable file
View file

@ -0,0 +1,47 @@
// Used to provide better protractor documentation for methods given by
// `webdriver-js-extender`.
/**
* @fileoverview Extra methods provided by webdriver-js-extender.
*/
goog.provide('webdriver_extensions');
// /////////////////////////////////////////////////////////////////////////////
// //
// // webdriver_extensions.ExtendedWebDriver
// //
// /////////////////////////////////////////////////////////////////////////////
/**
* Protractor's `browser` object is a wrapper for an instance of
* `ExtendedWebDriver`, provided by `webdriver-js-extender`, which itself is
* just an instance of `selenium-webdriver`'s WebDriver with some extra methods
* added in. The `browser` object inherits all of WebDriver's and
* ExtendedWebDriver's methods, but only the methods most useful to Protractor
* users are documented here.
*
* ***If you are not using an appium server, `browser` may sometimes inherit
* directly from a normal `WebDriver` instance, and thus not inherit any of
* the extra methods defined by `webdriver-js-extender`. Even when `browser`
* does inherit from `ExtendedWebDriver`, these extra methods will only work if
* your server implements the Appium API.***
*
* More information about `webdriver-js-extender` can be found on the [GitHub
* repo](https://github.com/angular/webdriver-js-extender).
* @alias ExtendedWebDriver
* @constructor
* @extends {webdriver.WebDriver}
*/
webdriver_extensions.ExtendedWebDriver = function() {};
/**
* Various appium commands, including the commands implemented by `wd`. The
* names may be different however, and commands which are implemented already by
* `selenium-webdriver` are not re-implemented by `webdriver-js-extender`.
*
* See the [GitHub repo](https://github.com/angular/webdriver-js-extender) for
* details.
*
* @returns {!webdriver.promise.Promise.<*>}
*/
webdriver_extensions.ExtendedWebDriver.prototype.Appium_Commands = function() {};

27
node_modules/protractor/example/angular_material/conf.js generated vendored Executable file
View file

@ -0,0 +1,27 @@
// 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: [
'input_spec.js',
'mat_paginator_spec.js'
],
// Disable promise manager because we are going to use async/await
SELENIUM_PROMISE_MANAGER: false,
// Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
}
};

View file

@ -0,0 +1,15 @@
describe('angular-material input component page', function() {
const EC = protractor.ExpectedConditions;
it('Should change input component value', async() => {
await browser.get('https://material.angular.io/components/input/examples');
await browser.wait(EC.elementToBeClickable($('.mat-button-wrapper>.mat-icon')), 5000);
const emailInputField = $$('.mat-form-field-infix>input').get(1);
await emailInputField.sendKeys('invalid');
expect($('mat-error').isPresent()).toBe(true);
});
});

View file

@ -0,0 +1,31 @@
describe('angular-material paginator component page', () => {
const EC = protractor.ExpectedConditions;
beforeAll(async() => {
await browser.get('https://material.angular.io/components/paginator/examples');
await browser.wait(EC.elementToBeClickable($('.mat-button-wrapper>.mat-icon')), 5000);
});
it('Should navigate to next page', async() => {
await $('button[aria-label=\'Next page\']').click();
await expect($('.mat-paginator-range-label').getAttribute('innerText')).toEqual('11 - 20 of 100');
});
it('Should navigate to previous page', async() => {
await $('button[aria-label=\'Previous page\']').click();
await expect($('.mat-paginator-range-label').getAttribute('innerText')).toEqual('1 - 10 of 100');
});
it('Should change list length to 5 items per page', async() => {
await $('mat-select>div').click();
const fiveItemsOption = $$('mat-option>.mat-option-text').first();
await fiveItemsOption.click();
await expect($('.mat-paginator-range-label').getAttribute('innerText')).toEqual('1 - 5 of 100');
});
});

21
node_modules/protractor/example/conf.js generated vendored Executable file
View 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 Executable file
View 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');
});
});
});

89
node_modules/protractor/exampleTypescript/README.md generated vendored Executable file
View file

@ -0,0 +1,89 @@
# Protractor with Typescript
Typescript provides code auto completion and helpful hints with a text editor like Microsoft's Visual Studio Code or another text editor with Typescript support.
Note that this example uses TypeScript 2.0.
## Examples
There are two examples in this directory:
* Simple Protractor example
* Similar to the [github protractor example](https://github.com/angular/protractor/tree/master/example)
* Files `conf.ts` and `spec.ts`
* Page objects example
* Follows the [protractortest.org page objects example](http://www.protractortest.org/#/page-objects)
* Files `confPageObjects.ts`, `specPageObjects.ts`, and `angularPage.ts`
## File organization
```
exampleTypescript/
|- node_modules/ // downloaded node modules
|- tmp/ // compiled javascript output
|
|- .gitignore // since typescript produces javascript, we should not
| // commit javascript to the repo
|- angularPage.ts // page object example
|- confPageObjects.ts // configuration for the page objects example
|- package.json // node dependencies for the project
|- README.md // this file
|- spec.ts // spec for the simple protractor example
|- specPageObjects.ts // spec for the page objects example
|- tsconfig.json // typescript transpile configuration
```
## Getting started
This package.json references the local protractor directory with `"protractor": "file: ../"`. For the type declarations to work, from the protractor directory run an `npm install` to generate the declarations file.
Next, install the exampleTypescript node_modules with:
```
npm install
```
## Protractor typings
To use Protractor types, you'll need to import `protractor`. After this is imported, you should have autocompletion hints when typing.
```
import {browser, element, by, By, $, $$, ExpectedConditions} from 'protractor';
```
Although the Protractor configuration file can be written in javascript, creating it in typescript will have some hints. These hints and the reference configuration can be found in `lib/config.ts`. Below we are importing the Config interface and applying that interface to the config variable:
```
import {Config} from 'protractor';
export let config: Config = {
...
}
```
## Ambient typings
Protractor also uses ambient types including jasmine, jasminewd2, and node. These are brought in via the `tsconfig.json` file, which uses npm module resolution to get types from `node_modules/@types`.
If you are using the jasmine framework for your tests, make sure to do:
```
npm install --save-dev @types/jasmine @types/jasminewd2
```
## Compiling your code
To convert your typescript to javascript (transpiling), you'll use the Typescript compiler (tsc). If you install typescript globally, the command is `tsc`. If it is not installed globally, the typescript compiler can be executed with `npm run tsc`.
## Running Protractor
After transpiling your code to javascript, you'll run Protractor like before: `protractor conf.js`
## Helpful links
* [TypescriptLang.org tutorial](http://www.typescriptlang.org/docs/tutorial.html)
* [TypescriptLang.org tsconfig.json](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html)
* [Typescript gitter](https://gitter.im/Microsoft/TypeScript)
* [Typescript stackoverflow](http://stackoverflow.com/questions/tagged/typescript)

26
node_modules/protractor/exampleTypescript/angularPage.ts generated vendored Executable file
View file

@ -0,0 +1,26 @@
// Because this file references protractor, you'll need to have it as a project
// dependency to use 'protractor/globals'. Here is the full list of imports:
//
// import {browser, element, by, By, $, $$, ExpectedConditions}
// from 'protractor/globals';
//
import {browser, element, by} from 'protractor';
export class AngularHomepage {
nameInput = element(by.model('yourName'));
greeting = element(by.binding('yourName'));
get() {
browser.get('http://www.angularjs.org');
}
setName(name: string) {
this.nameInput.sendKeys(name);
}
// getGreeting returns a webdriver.promise.Promise.<string>. For simplicity
// setting the return value to any
getGreeting(): any {
return this.greeting.getText();
}
}

View file

@ -0,0 +1,34 @@
Compiling `async`/`await` syntax
================================
`async`/`await` syntax is currently accessible via typescript if you compile
using `--target ES2015` or above.
Debugging with `async`/`await`
==============================
Disabling the promise manager will break Protractor's debugging and
`browser.pause()`. However, because your tests won't be using the promise
manager, you can debug them using standard Node debugging tools. For
example, you can use the Chrome inspector to debug the test in this
directory (protractor/exampleTypescript) with `npm run debug`. You should see something like
```
Debugger listening on port 9229.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/f48502b0-76a3-4659-92d1-bef07a222859
```
Open that URL in chrome, and you'll get an inspector that can be
used to debug your test. Instead of browser.pause, you can add `debugger`
to create a breakpoint. Note that sourcemaps don't work in the inspector
in Node v6, but do work in Node v7 (due to https://github.com/nodejs/node/issues/8369).
More detail about how to use [chrome
inspector](/docs/debugging.md#disabled-control-flow)
More Examples
=============
More examples can be found under [`/spec/ts/`](/spec/ts).

Some files were not shown because too many files have changed in this diff Show more