aboutsummaryrefslogtreecommitdiff
path: root/node_modules/selenium-webdriver/lib
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-04-20 03:09:25 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-04-24 16:14:29 +0200
commit82f2b76e25a4a67e01ec67e5ebe39d14ad771ea8 (patch)
tree965f6eb89b84d65a62b49008fd972c004832ccd1 /node_modules/selenium-webdriver/lib
parente6e0cbc387c2a77b48e4065c229daa65bf1aa0fa (diff)
Reorganize module loading.
We now use webpack instead of SystemJS, effectively bundling modules into one file (plus commons chunks) for every entry point. This results in a much smaller extension size (almost half). Furthermore we use yarn/npm even for extension run-time dependencies. This relieves us from manually vendoring and building dependencies. It's also easier to understand for new developers familiar with node.
Diffstat (limited to 'node_modules/selenium-webdriver/lib')
-rw-r--r--node_modules/selenium-webdriver/lib/README5
-rw-r--r--node_modules/selenium-webdriver/lib/actions.js8
-rw-r--r--node_modules/selenium-webdriver/lib/by.js2
-rw-r--r--node_modules/selenium-webdriver/lib/capabilities.js8
-rw-r--r--node_modules/selenium-webdriver/lib/error.js19
-rw-r--r--node_modules/selenium-webdriver/lib/events.js2
-rw-r--r--node_modules/selenium-webdriver/lib/firefox/amd64/libnoblur64.sobin41623 -> 0 bytes
-rw-r--r--node_modules/selenium-webdriver/lib/firefox/i386/libnoblur.sobin36934 -> 0 bytes
-rw-r--r--node_modules/selenium-webdriver/lib/firefox/webdriver.json3
-rw-r--r--node_modules/selenium-webdriver/lib/firefox/webdriver.xpibin707042 -> 703396 bytes
-rw-r--r--node_modules/selenium-webdriver/lib/http.js102
-rw-r--r--node_modules/selenium-webdriver/lib/input.js2
-rw-r--r--node_modules/selenium-webdriver/lib/promise.js286
-rw-r--r--node_modules/selenium-webdriver/lib/symbols.js2
-rw-r--r--node_modules/selenium-webdriver/lib/test/index.js6
-rw-r--r--node_modules/selenium-webdriver/lib/until.js2
-rw-r--r--node_modules/selenium-webdriver/lib/webdriver.js24
17 files changed, 310 insertions, 161 deletions
diff --git a/node_modules/selenium-webdriver/lib/README b/node_modules/selenium-webdriver/lib/README
index 583293864..c39abbece 100644
--- a/node_modules/selenium-webdriver/lib/README
+++ b/node_modules/selenium-webdriver/lib/README
@@ -1,6 +1,5 @@
This directory contains modules internal to selenium-webdriver that are not
intended for general consumption. They may change at any time.
-With the exception of the test/ directory, all files under this directory
-may only depend on built-in JavaScript features and other modules in the
-directory.
+All files in this directory and the atoms/ subdirectory may only depend on
+built-in JavaScript features and other modules in this directory.
diff --git a/node_modules/selenium-webdriver/lib/actions.js b/node_modules/selenium-webdriver/lib/actions.js
index 1b059bbbf..0e34f3783 100644
--- a/node_modules/selenium-webdriver/lib/actions.js
+++ b/node_modules/selenium-webdriver/lib/actions.js
@@ -128,7 +128,7 @@ class ActionSequence {
}
/**
- * Moves the mouse. The location to move to may be specified in terms of the
+ * Moves the mouse. The location to move to may be specified in terms of the
* mouse's current location, an offset relative to the top-left corner of an
* element, or an element (in which case the middle of the element is used).
*
@@ -333,7 +333,7 @@ class ActionSequence {
/**
* Performs a modifier key press. The modifier key is <em>not released</em>
* until {@link #keyUp} or {@link #sendKeys} is called. The key press will be
- * targetted at the currently focused element.
+ * targeted at the currently focused element.
*
* @param {!input.Key} key The modifier key to push. Must be one of
* {ALT, CONTROL, SHIFT, COMMAND, META}.
@@ -347,7 +347,7 @@ class ActionSequence {
}
/**
- * Performs a modifier key release. The release is targetted at the currently
+ * Performs a modifier key release. The release is targeted at the currently
* focused element.
* @param {!input.Key} key The modifier key to release. Must be one of
* {ALT, CONTROL, SHIFT, COMMAND, META}.
@@ -363,7 +363,7 @@ class ActionSequence {
/**
* Simulates typing multiple keys. Each modifier key encountered in the
* sequence will not be released until it is encountered again. All key events
- * will be targetted at the currently focused element.
+ * will be targeted at the currently focused element.
*
* @param {...(string|!input.Key|!Array<(string|!input.Key)>)} var_args
* The keys to type.
diff --git a/node_modules/selenium-webdriver/lib/by.js b/node_modules/selenium-webdriver/lib/by.js
index ac448e683..8c718be64 100644
--- a/node_modules/selenium-webdriver/lib/by.js
+++ b/node_modules/selenium-webdriver/lib/by.js
@@ -153,7 +153,7 @@ class By {
}
/**
- * Locates eleemnts by the ID attribute. This locator uses the CSS selector
+ * Locates elements by the ID attribute. This locator uses the CSS selector
* `*[id="$ID"]`, _not_ `document.getElementById`.
*
* @param {string} id The ID to search for.
diff --git a/node_modules/selenium-webdriver/lib/capabilities.js b/node_modules/selenium-webdriver/lib/capabilities.js
index 61396d54d..65b290f5f 100644
--- a/node_modules/selenium-webdriver/lib/capabilities.js
+++ b/node_modules/selenium-webdriver/lib/capabilities.js
@@ -103,7 +103,7 @@ const Capability = {
*/
PROXY: 'proxy',
- /** Whether the driver supports changing the brower's orientation. */
+ /** Whether the driver supports changing the browser's orientation. */
ROTATABLE: 'rotatable',
/**
@@ -130,7 +130,7 @@ const Capability = {
/**
* Defines how the driver should handle unexpected alerts. The value should
- * be one of "accept", "dismiss", or "ignore.
+ * be one of "accept", "dismiss", or "ignore".
*/
UNEXPECTED_ALERT_BEHAVIOR: 'unexpectedAlertBehavior',
@@ -367,7 +367,7 @@ class Capabilities extends Map {
/**
* Sets the logging preferences. Preferences may be specified as a
- * {@link ./logging.Preferences} instance, or a as a map of log-type to
+ * {@link ./logging.Preferences} instance, or as a map of log-type to
* log-level.
* @param {!(./logging.Preferences|Object<string>)} prefs The logging
* preferences.
@@ -408,7 +408,7 @@ class Capabilities extends Map {
/**
* Sets the default action to take with an unexpected alert before returning
* an error.
- * @param {string} behavior The desired behavior; should be "accept",
+ * @param {string} behavior The desired behavior should be "accept",
* "dismiss", or "ignore". Defaults to "dismiss".
* @return {!Capabilities} A self reference.
*/
diff --git a/node_modules/selenium-webdriver/lib/error.js b/node_modules/selenium-webdriver/lib/error.js
index 555e5cbc5..82f81b07c 100644
--- a/node_modules/selenium-webdriver/lib/error.js
+++ b/node_modules/selenium-webdriver/lib/error.js
@@ -311,7 +311,7 @@ class UnknownMethodError extends WebDriverError {
/**
- * Reports an unsupport operation.
+ * Reports an unsupported operation.
*/
class UnsupportedOperationError extends WebDriverError {
/** @param {string=} opt_error the error message, if any. */
@@ -462,17 +462,29 @@ function checkResponse(data) {
return data;
}
+/**
+ * Tests if the given value is a valid error response object according to the
+ * W3C WebDriver spec.
+ *
+ * @param {?} data The value to test.
+ * @return {boolean} Whether the given value data object is a valid error
+ * response.
+ * @see https://w3c.github.io/webdriver/webdriver-spec.html#protocol
+ */
+function isErrorResponse(data) {
+ return data && typeof data === 'object' && typeof data.error === 'string';
+}
/**
* Throws an error coded from the W3C protocol. A generic error will be thrown
- * if the privded `data` is not a valid encoded error.
+ * if the provided `data` is not a valid encoded error.
*
* @param {{error: string, message: string}} data The error data to decode.
* @throws {WebDriverError} the decoded error.
* @see https://w3c.github.io/webdriver/webdriver-spec.html#protocol
*/
function throwDecodedError(data) {
- if (data && typeof data === 'object' && typeof data.error === 'string') {
+ if (isErrorResponse(data)) {
let ctor = ERROR_CODE_TO_TYPE.get(data.error) || WebDriverError;
throw new ctor(data.message);
}
@@ -551,5 +563,6 @@ module.exports = {
checkResponse: checkResponse,
checkLegacyResponse: checkLegacyResponse,
encodeError: encodeError,
+ isErrorResponse: isErrorResponse,
throwDecodedError: throwDecodedError,
};
diff --git a/node_modules/selenium-webdriver/lib/events.js b/node_modules/selenium-webdriver/lib/events.js
index 65e63de8c..82b34803e 100644
--- a/node_modules/selenium-webdriver/lib/events.js
+++ b/node_modules/selenium-webdriver/lib/events.js
@@ -22,7 +22,7 @@
*/
class Listener {
/**
- * @param {!Function} fn The acutal listener function.
+ * @param {!Function} fn The actual listener function.
* @param {(Object|undefined)} scope The object in whose scope to invoke the
* listener.
* @param {boolean} oneshot Whether this listener should only be used once.
diff --git a/node_modules/selenium-webdriver/lib/firefox/amd64/libnoblur64.so b/node_modules/selenium-webdriver/lib/firefox/amd64/libnoblur64.so
deleted file mode 100644
index 248c32db5..000000000
--- a/node_modules/selenium-webdriver/lib/firefox/amd64/libnoblur64.so
+++ /dev/null
Binary files differ
diff --git a/node_modules/selenium-webdriver/lib/firefox/i386/libnoblur.so b/node_modules/selenium-webdriver/lib/firefox/i386/libnoblur.so
deleted file mode 100644
index 004062c7b..000000000
--- a/node_modules/selenium-webdriver/lib/firefox/i386/libnoblur.so
+++ /dev/null
Binary files differ
diff --git a/node_modules/selenium-webdriver/lib/firefox/webdriver.json b/node_modules/selenium-webdriver/lib/firefox/webdriver.json
index 38601a28c..0dbe56bbd 100644
--- a/node_modules/selenium-webdriver/lib/firefox/webdriver.json
+++ b/node_modules/selenium-webdriver/lib/firefox/webdriver.json
@@ -37,7 +37,6 @@
"network.http.phishy-userpass-length": 255,
"offline-apps.allow_by_default": true,
"prompts.tab_modal.enabled": false,
- "security.csp.enable": false,
"security.fileuri.origin_policy": 3,
"security.fileuri.strict_origin_policy": false,
"signon.rememberSignons": false,
@@ -61,6 +60,8 @@
"dom.max_script_run_time": 30,
"dom.report_all_js_exceptions": true,
"javascript.options.showInConsole": true,
+ "network.captive-portal-service.enabled": false,
+ "security.csp.enable": false,
"startup.homepage_welcome_url": "about:blank",
"startup.homepage_welcome_url.additional": "about:blank",
"webdriver_accept_untrusted_certs": true,
diff --git a/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi b/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi
index f9a51cf4f..a7b0fa3a7 100644
--- a/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi
+++ b/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi
Binary files differ
diff --git a/node_modules/selenium-webdriver/lib/http.js b/node_modules/selenium-webdriver/lib/http.js
index 68bc43213..136a48e63 100644
--- a/node_modules/selenium-webdriver/lib/http.js
+++ b/node_modules/selenium-webdriver/lib/http.js
@@ -25,17 +25,26 @@
'use strict';
-const fs = require('fs');
-const path = require('path');
-
const cmd = require('./command');
-const devmode = require('./devmode');
const error = require('./error');
const logging = require('./logging');
const promise = require('./promise');
const Session = require('./session').Session;
const WebElement = require('./webdriver').WebElement;
+const {getAttribute, isDisplayed} = (function() {
+ try {
+ return {
+ getAttribute: require('./atoms/getAttribute.js'),
+ isDisplayed: require('./atoms/is-displayed.js')
+ };
+ } catch (ex) {
+ throw Error(
+ 'Failed to import atoms modules. If running in devmode, you need to run'
+ + ' `./go node:atoms` from the project root: ' + ex);
+ }
+})();
+
/**
* Converts a headers map to a HTTP header block string.
@@ -116,43 +125,15 @@ class Response {
const DEV_ROOT = '../../../../buck-out/gen/javascript/';
-/** @enum {string} */
+/** @enum {!Function} */
const Atom = {
- GET_ATTRIBUTE: devmode
- ? path.join(__dirname, DEV_ROOT, 'webdriver/atoms/getAttribute.js')
- : path.join(__dirname, 'atoms/getAttribute.js'),
- IS_DISPLAYED: devmode
- ? path.join(__dirname, DEV_ROOT, 'atoms/fragments/is-displayed.js')
- : path.join(__dirname, 'atoms/isDisplayed.js'),
+ GET_ATTRIBUTE: getAttribute,
+ IS_DISPLAYED: isDisplayed
};
-const ATOMS = /** !Map<string, !Promise<string>> */new Map();
const LOG = logging.getLogger('webdriver.http');
-/**
- * @param {Atom} file The atom file to load.
- * @return {!Promise<string>} A promise that will resolve to the contents of the
- * file.
- */
-function loadAtom(file) {
- if (ATOMS.has(file)) {
- return ATOMS.get(file);
- }
- let contents = /** !Promise<string> */new Promise((resolve, reject) => {
- LOG.finest(() => `Loading atom ${file}`);
- fs.readFile(file, 'utf8', function(err, data) {
- if (err) {
- reject(err);
- } else {
- resolve(data);
- }
- });
- });
- ATOMS.set(file, contents);
- return contents;
-}
-
function post(path) { return resource('POST', path); }
function del(path) { return resource('DELETE', path); }
@@ -168,17 +149,26 @@ var CommandSpec;
var CommandTransformer;
+class InternalTypeError extends TypeError {}
+
+
/**
* @param {!cmd.Command} command The initial command.
* @param {Atom} atom The name of the atom to execute.
* @return {!Promise<!cmd.Command>} The transformed command to execute.
*/
function toExecuteAtomCommand(command, atom, ...params) {
- return loadAtom(atom).then(atom => {
- return new cmd.Command(cmd.Name.EXECUTE_SCRIPT)
+ return new Promise((resolve, reject) => {
+ if (typeof atom !== 'function') {
+ reject(new InternalTypeError('atom is not a function: ' + typeof atom));
+ return;
+ }
+
+ let newCmd = new cmd.Command(cmd.Name.EXECUTE_SCRIPT)
.setParameter('sessionId', command.getParameter('sessionId'))
.setParameter('script', `return (${atom}).apply(null, arguments)`)
.setParameter('args', params.map(param => command.getParameter(param)));
+ resolve(newCmd);
});
}
@@ -269,6 +259,8 @@ const W3C_COMMAND_MAP = new Map([
[cmd.Name.GET_ELEMENT_ATTRIBUTE, (cmd) => {
return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'id', 'name');
}],
+ [cmd.Name.GET_ELEMENT_LOCATION, get('/session/:sessionId/element/:id/rect')],
+ [cmd.Name.GET_ELEMENT_SIZE, get('/session/:sessionId/element/:id/rect')],
[cmd.Name.IS_ELEMENT_DISPLAYED, (cmd) => {
return toExecuteAtomCommand(cmd, Atom.IS_DISPLAYED, 'id');
}],
@@ -437,7 +429,8 @@ class Executor {
this.log_.finer(() => `>>>\n${request}\n<<<\n${response}`);
let parsed =
- parseHttpResponse(/** @type {!Response} */ (response), this.w3c);
+ parseHttpResponse(
+ command, /** @type {!Response} */ (response), this.w3c);
if (command.getName() === cmd.Name.NEW_SESSION
|| command.getName() === cmd.Name.DESCRIBE_SESSION) {
@@ -447,7 +440,7 @@ class Executor {
}
// The remote end is a W3C compliant server if there is no `status`
- // field in the response. This is not appliable for the DESCRIBE_SESSION
+ // field in the response. This is not applicable for the DESCRIBE_SESSION
// command, which is not defined in the W3C spec.
if (command.getName() === cmd.Name.NEW_SESSION) {
this.w3c = this.w3c || !('status' in parsed);
@@ -485,29 +478,42 @@ function tryParse(str) {
/**
* Callback used to parse {@link Response} objects from a
* {@link HttpClient}.
+ *
+ * @param {!cmd.Command} command The command the response is for.
* @param {!Response} httpResponse The HTTP response to parse.
* @param {boolean} w3c Whether the response should be processed using the
* W3C wire protocol.
* @return {?} The parsed response.
* @throws {WebDriverError} If the HTTP response is an error.
*/
-function parseHttpResponse(httpResponse, w3c) {
+function parseHttpResponse(command, httpResponse, w3c) {
let parsed = tryParse(httpResponse.body);
if (parsed !== undefined) {
+ if (httpResponse.status < 200) {
+ // This should never happen, but throw the raw response so
+ // users report it.
+ throw new error.WebDriverError(
+ `Unexpected HTTP response:\n${httpResponse}`);
+ }
+
if (w3c) {
if (httpResponse.status > 399) {
error.throwDecodedError(parsed);
}
+ return parsed;
+ }
- if (httpResponse.status < 200) {
- // This should never happen, but throw the raw response so
- // users report it.
- throw new error.WebDriverError(
- `Unexpected HTTP response:\n${httpResponse}`);
- }
- } else {
- error.checkLegacyResponse(parsed);
+ // If this is a new session command, we need to check for a W3C compliant
+ // error object. This is necessary since a successful new session command
+ // is what puts the executor into W3C mode.
+ if (httpResponse.status > 399
+ && (command.getName() == cmd.Name.NEW_SESSION
+ || command.getName() === cmd.Name.DESCRIBE_SESSION)
+ && error.isErrorResponse(parsed)) {
+ error.throwDecodedError(parsed);
}
+
+ error.checkLegacyResponse(parsed);
return parsed;
}
diff --git a/node_modules/selenium-webdriver/lib/input.js b/node_modules/selenium-webdriver/lib/input.js
index 058530ebc..4ea938d45 100644
--- a/node_modules/selenium-webdriver/lib/input.js
+++ b/node_modules/selenium-webdriver/lib/input.js
@@ -144,7 +144,7 @@ class FileDetector {
/**
* Handles the file specified by the given path, preparing it for use with
* the current browser. If the path does not refer to a valid file, it will
- * be returned unchanged, otherwisee a path suitable for use with the current
+ * be returned unchanged, otherwise a path suitable for use with the current
* browser will be returned.
*
* This default implementation is a no-op. Subtypes may override this function
diff --git a/node_modules/selenium-webdriver/lib/promise.js b/node_modules/selenium-webdriver/lib/promise.js
index 32d0c98e6..b26cd23ff 100644
--- a/node_modules/selenium-webdriver/lib/promise.js
+++ b/node_modules/selenium-webdriver/lib/promise.js
@@ -48,7 +48,7 @@
* > e => console.error('FAILURE: ' + e));
* > ```
* >
- * > The motiviation behind this change and full deprecation plan are documented
+ * > The motivation behind this change and full deprecation plan are documented
* > in [issue 2969](https://github.com/SeleniumHQ/selenium/issues/2969).
* >
* >
@@ -87,8 +87,7 @@
* The control flow is based on the concept of tasks and task queues. Tasks are
* functions that define the basic unit of work for the control flow to execute.
* Each task is scheduled via {@link ControlFlow#execute()}, which will return
- * a {@link ManagedPromise ManagedPromise} that will be resolved with the task's
- * result.
+ * a {@link ManagedPromise} that will be resolved with the task's result.
*
* A task queue contains all of the tasks scheduled within a single turn of the
* [JavaScript event loop][JSEL]. The control flow will create a new task queue
@@ -103,13 +102,13 @@
*
* Whenever the control flow creates a new task queue, it will automatically
* begin executing tasks in the next available turn of the event loop. This
- * execution is scheduled using a "micro-task" timer, such as a (native)
- * `ManagedPromise.then()` callback.
+ * execution is [scheduled as a microtask][MicrotasksArticle] like e.g. a
+ * (native) `Promise.then()` callback.
*
* setTimeout(() => console.log('a'));
- * ManagedPromise.resolve().then(() => console.log('b')); // A native promise.
+ * Promise.resolve().then(() => console.log('b')); // A native promise.
* flow.execute(() => console.log('c'));
- * ManagedPromise.resolve().then(() => console.log('d'));
+ * Promise.resolve().then(() => console.log('d'));
* setTimeout(() => console.log('fin'));
* // b
* // c
@@ -118,13 +117,13 @@
* // fin
*
* In the example above, b/c/d is logged before a/fin because native promises
- * and this module use "micro-task" timers, which have a higher priority than
- * "macro-tasks" like `setTimeout`.
+ * and this module use "microtask" timers, which have a higher priority than
+ * "macrotasks" like `setTimeout`.
*
* ## Task Execution
*
- * Upon creating a task queue, and whenever an exisiting queue completes a task,
- * the control flow will schedule a micro-task timer to process any scheduled
+ * Upon creating a task queue, and whenever an existing queue completes a task,
+ * the control flow will schedule a microtask timer to process any scheduled
* tasks. This ensures no task is ever started within the same turn of the
* JavaScript event loop in which it was scheduled, nor is a task ever started
* within the same turn that another finishes.
@@ -140,13 +139,13 @@
* discarded and the task's promised result (previously returned by
* {@link ControlFlow#execute()}) is immediately rejected with the thrown
* error.
- * 3. The task function returns sucessfully.
+ * 3. The task function returns successfully.
*
* If a task function created a new task queue, the control flow will wait for
* that queue to complete before processing the task result. If the queue
* completes without error, the flow will settle the task's promise with the
- * value originaly returned by the task function. On the other hand, if the task
- * queue termintes with an error, the task's promise will be rejected with that
+ * value originally returned by the task function. On the other hand, if the task
+ * queue terminates with an error, the task's promise will be rejected with that
* error.
*
* flow.execute(function() {
@@ -161,7 +160,7 @@
* ## ManagedPromise Integration
*
* In addition to the {@link ControlFlow} class, the promise module also exports
- * a [ManagedPromise/A+] {@linkplain ManagedPromise implementation} that is deeply
+ * a [Promises/A+] {@linkplain ManagedPromise implementation} that is deeply
* integrated with the ControlFlow. First and foremost, each promise
* {@linkplain ManagedPromise#then() callback} is scheduled with the
* control flow as a task. As a result, each callback is invoked in its own turn
@@ -328,7 +327,7 @@
* Even though a subtask's promised result will never resolve while the task
* function is on the stack, it will be treated as a promise resolved within the
* task. In all other scenarios, a task's promise behaves just like a normal
- * promise. In the sample below, `C/D` is loggged before `B` because the
+ * promise. In the sample below, `C/D` is logged before `B` because the
* resolution of `subtask1` interrupts the flow of the enclosing task. Within
* the final subtask, `E/F` is logged in order because `subtask1` is a resolved
* promise when that task runs.
@@ -467,17 +466,17 @@
*
* ES6 promises do not require users to handle a promise rejections. This can
* result in subtle bugs as the rejections are silently "swallowed" by the
- * ManagedPromise class.
+ * Promise class.
*
- * ManagedPromise.reject(Error('boom'));
+ * Promise.reject(Error('boom'));
* // ... *crickets* ...
*
* Selenium's promise module, on the other hand, requires that every rejection
* be explicitly handled. When a {@linkplain ManagedPromise ManagedPromise} is
* rejected and no callbacks are defined on that promise, it is considered an
- * _unhandled rejection_ and reproted to the active task queue. If the rejection
+ * _unhandled rejection_ and reported to the active task queue. If the rejection
* remains unhandled after a single turn of the [event loop][JSEL] (scheduled
- * with a micro-task), it will propagate up the stack.
+ * with a microtask), it will propagate up the stack.
*
* ## Error Propagation
*
@@ -534,7 +533,7 @@
*
* When a subtask is discarded due to an unreported rejection in its parent
* frame, the existing callbacks on that task will never settle and the
- * callbacks will not be invoked. If a new callback is attached ot the subtask
+ * callbacks will not be invoked. If a new callback is attached to the subtask
* _after_ it has been discarded, it is handled the same as adding a callback
* to a cancelled promise: the error-callback path is invoked. This behavior is
* intended to handle cases where the user saves a reference to a task promise,
@@ -582,9 +581,9 @@
*
* Bottom line: you __*must*__ handle rejected promises.
*
- * # ManagedPromise/A+ Compatibility
+ * # Promises/A+ Compatibility
*
- * This `promise` module is compliant with the [ManagedPromise/A+][] specification
+ * This `promise` module is compliant with the [Promises/A+] specification
* except for sections `2.2.6.1` and `2.2.6.2`:
*
* >
@@ -595,10 +594,10 @@
* > must execute in the order of their originating calls to `then`.
* >
*
- * Specifically, the conformance tests contains the following scenario (for
+ * Specifically, the conformance tests contain the following scenario (for
* brevity, only the fulfillment version is shown):
*
- * var p1 = ManagedPromise.resolve();
+ * var p1 = Promise.resolve();
* p1.then(function() {
* console.log('A');
* p1.then(() => console.log('B'));
@@ -609,7 +608,7 @@
* // B
*
* Since the [ControlFlow](#scheduling_callbacks) executes promise callbacks as
- * tasks, with this module, the result would be
+ * tasks, with this module, the result would be:
*
* var p2 = promise.fulfilled();
* p2.then(function() {
@@ -623,7 +622,8 @@
*
* [JSEL]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
* [GF]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
- * [ManagedPromise/A+]: https://promisesaplus.com/
+ * [Promises/A+]: https://promisesaplus.com/
+ * [MicrotasksArticle]: https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
*/
'use strict';
@@ -667,7 +667,7 @@ function getUid(obj) {
/**
- * Runs the given function after a micro-task yield.
+ * Runs the given function after a microtask yield.
* @param {function()} fn The function to run.
*/
function asyncRun(fn) {
@@ -942,7 +942,7 @@ class Thenable {
/**
* Marker interface for objects that allow consumers to request the cancellation
- * of a promies-based operation. A cancelled promise will be rejected with a
+ * of a promise-based operation. A cancelled promise will be rejected with a
* {@link CancellationError}.
*
* This interface is considered package-private and should not be used outside
@@ -1003,6 +1003,9 @@ const PromiseState = {
*/
const ON_CANCEL_HANDLER = new WeakMap;
+const SKIP_LOG = Symbol('skip-log');
+const FLOW_LOG = logging.getLogger('promise.ControlFlow');
+
/**
* Represents the eventual value of a completed operation. Each promise may be
@@ -1025,14 +1028,29 @@ class ManagedPromise {
* functions, one for fulfilling the promise and another for rejecting it.
* @param {ControlFlow=} opt_flow The control flow
* this instance was created under. Defaults to the currently active flow.
+ * @param {?=} opt_skipLog An internal parameter used to skip logging the
+ * creation of this promise. This parameter has no effect unless it is
+ * strictly equal to an internal symbol. In other words, this parameter
+ * is always ignored for external code.
*/
- constructor(resolver, opt_flow) {
+ constructor(resolver, opt_flow, opt_skipLog) {
if (!usePromiseManager()) {
throw TypeError(
'Unable to create a managed promise instance: the promise manager has'
+ ' been disabled by the SELENIUM_PROMISE_MANAGER environment'
+ ' variable: ' + process.env['SELENIUM_PROMISE_MANAGER']);
+ } else if (opt_skipLog !== SKIP_LOG) {
+ FLOW_LOG.warning(() => {
+ let e =
+ captureStackTrace(
+ 'ManagedPromiseError',
+ 'Creating a new managed Promise. This call will fail when the'
+ + ' promise manager is disabled',
+ ManagedPromise)
+ return e.stack;
+ });
}
+
getUid(this);
/** @private {!ControlFlow} */
@@ -1308,7 +1326,7 @@ class ManagedPromise {
* @param {!Function} fn The function to use as the top of the stack when
* recording the callback's creation point.
* @return {!ManagedPromise<R>} A new promise which will be resolved with the
- * esult of the invoked callback.
+ * result of the invoked callback.
* @template R
* @private
*/
@@ -1384,6 +1402,37 @@ function isPending(promise) {
/**
+ * Structural interface for a deferred promise resolver.
+ * @record
+ * @template T
+ */
+function Resolver() {}
+
+
+/**
+ * The promised value for this resolver.
+ * @type {!Thenable<T>}
+ */
+Resolver.prototype.promise;
+
+
+/**
+ * Resolves the promised value with the given `value`.
+ * @param {T|Thenable<T>} value
+ * @return {void}
+ */
+Resolver.prototype.resolve;
+
+
+/**
+ * Rejects the promised value with the given `reason`.
+ * @param {*} reason
+ * @return {void}
+ */
+Resolver.prototype.reject;
+
+
+/**
* Represents a value that will be resolved at some point in the future. This
* class represents the protected "producer" half of a ManagedPromise - each Deferred
* has a {@code promise} property that may be returned to consumers for
@@ -1395,20 +1444,25 @@ function isPending(promise) {
* {@link ControlFlow} as an unhandled failure.
*
* @template T
+ * @implements {Resolver<T>}
*/
class Deferred {
/**
* @param {ControlFlow=} opt_flow The control flow this instance was
* created under. This should only be provided during unit tests.
+ * @param {?=} opt_skipLog An internal parameter used to skip logging the
+ * creation of this promise. This parameter has no effect unless it is
+ * strictly equal to an internal symbol. In other words, this parameter
+ * is always ignored for external code.
*/
- constructor(opt_flow) {
+ constructor(opt_flow, opt_skipLog) {
var fulfill, reject;
/** @type {!ManagedPromise<T>} */
this.promise = new ManagedPromise(function(f, r) {
fulfill = f;
reject = r;
- }, opt_flow);
+ }, opt_flow, opt_skipLog);
var self = this;
var checkNotSelf = function(value) {
@@ -1421,16 +1475,24 @@ class Deferred {
* Resolves this deferred with the given value. It is safe to call this as a
* normal function (with no bound "this").
* @param {(T|IThenable<T>|Thenable)=} opt_value The fulfilled value.
+ * @const
*/
- this.fulfill = function(opt_value) {
+ this.resolve = function(opt_value) {
checkNotSelf(opt_value);
fulfill(opt_value);
};
/**
+ * An alias for {@link #resolve}.
+ * @const
+ */
+ this.fulfill = this.resolve;
+
+ /**
* Rejects this promise with the given reason. It is safe to call this as a
* normal function (with no bound "this").
* @param {*=} opt_reason The rejection reason.
+ * @const
*/
this.reject = function(opt_reason) {
checkNotSelf(opt_reason);
@@ -1487,36 +1549,76 @@ function delayed(ms) {
/**
- * Creates a new deferred object.
- * @return {!Deferred<T>} The new deferred object.
+ * Creates a new deferred resolver.
+ *
+ * If the promise manager is currently enabled, this function will return a
+ * {@link Deferred} instance. Otherwise, it will return a resolver for a
+ * {@linkplain NativePromise native promise}.
+ *
+ * @return {!Resolver<T>} A new deferred resolver.
* @template T
*/
function defer() {
- return new Deferred();
+ if (usePromiseManager()) {
+ return new Deferred();
+ }
+ let resolve, reject;
+ let promise = new NativePromise((_resolve, _reject) => {
+ resolve = _resolve;
+ reject = _reject;
+ });
+ return {promise, resolve, reject};
}
/**
* Creates a promise that has been resolved with the given value.
+ *
+ * If the promise manager is currently enabled, this function will return a
+ * {@linkplain ManagedPromise managed promise}. Otherwise, it will return a
+ * {@linkplain NativePromise native promise}.
+ *
* @param {T=} opt_value The resolved value.
- * @return {!ManagedPromise<T>} The resolved promise.
- * @deprecated Use {@link ManagedPromise#resolve Promise.resolve(value)}.
+ * @return {!Thenable<T>} The resolved promise.
* @template T
*/
function fulfilled(opt_value) {
- return ManagedPromise.resolve(opt_value);
+ let ctor = usePromiseManager() ? ManagedPromise : NativePromise;
+ if (opt_value instanceof ctor) {
+ return /** @type {!Thenable} */(opt_value);
+ }
+
+ if (usePromiseManager()) {
+ // We can skip logging warnings about creating a managed promise because
+ // this function will automatically switch to use a native promise when
+ // the promise manager is disabled.
+ return new ManagedPromise(
+ resolve => resolve(opt_value), undefined, SKIP_LOG);
+ }
+ return NativePromise.resolve(opt_value);
}
/**
* Creates a promise that has been rejected with the given reason.
+ *
+ * If the promise manager is currently enabled, this function will return a
+ * {@linkplain ManagedPromise managed promise}. Otherwise, it will return a
+ * {@linkplain NativePromise native promise}.
+ *
* @param {*=} opt_reason The rejection reason; may be any value, but is
* usually an Error or a string.
- * @return {!ManagedPromise<?>} The rejected promise.
- * @deprecated Use {@link ManagedPromise#reject Promise.reject(reason)}.
+ * @return {!Thenable<?>} The rejected promise.
*/
function rejected(opt_reason) {
- return ManagedPromise.reject(opt_reason);
+ if (usePromiseManager()) {
+ // We can skip logging warnings about creating a managed promise because
+ // this function will automatically switch to use a native promise when
+ // the promise manager is disabled.
+ return new ManagedPromise(
+ (_, reject) => reject(opt_reason), undefined, SKIP_LOG);
+ }
+ return NativePromise.reject(opt_reason);
}
@@ -1610,21 +1712,17 @@ function thenFinally(promise, callback) {
* @param {Function=} opt_errback The function to call when the value is
* rejected.
* @return {!Thenable} A new promise.
+ * @deprecated Use `promise.fulfilled(value).then(opt_callback, opt_errback)`
*/
function when(value, opt_callback, opt_errback) {
- if (Thenable.isImplementation(value)) {
- return value.then(opt_callback, opt_errback);
- }
-
- return createPromise(resolve => resolve(value))
- .then(opt_callback, opt_errback);
+ return fulfilled(value).then(opt_callback, opt_errback);
}
/**
* Invokes the appropriate callback function as soon as a promised `value` is
- * resolved. This function is similar to `when()`, except it does not return
- * a new promise.
+ * resolved.
+ *
* @param {*} value The value to observe.
* @param {Function} callback The function to call when the value is
* resolved successfully.
@@ -1826,7 +1924,7 @@ function filter(arr, fn, opt_self) {
*/
function fullyResolved(value) {
if (isPromise(value)) {
- return when(value, fullyResolveValue);
+ return fulfilled(value).then(fullyResolveValue);
}
return fullyResolveValue(value);
}
@@ -1973,7 +2071,7 @@ class Scheduler {
/**
* Schedules a task to wait for a condition to hold.
*
- * If the condition is defined as a function, it may return any value. Promies
+ * If the condition is defined as a function, it may return any value. Promise
* will be resolved before testing if the condition holds (resolution time
* counts towards the timeout). Once resolved, values are always evaluated as
* booleans.
@@ -1997,7 +2095,7 @@ class Scheduler {
* @param {string=} opt_message An optional error message to include if the
* wait times out; defaults to the empty string.
* @return {!Thenable<T>} A promise that will be fulfilled
- * when the condition has been satisified. The promise shall be rejected
+ * when the condition has been satisfied. The promise shall be rejected
* if the wait times out waiting for the condition.
* @throws {TypeError} If condition is not a function or promise or if timeout
* is not a number >= 0.
@@ -2018,6 +2116,10 @@ function usePromiseManager() {
/**
+ * Creates a new promise with the given `resolver` function. If the promise
+ * manager is currently enabled, the returned promise will be a
+ * {@linkplain ManagedPromise} instance. Otherwise, it will be a native promise.
+ *
* @param {function(
* function((T|IThenable<T>|Thenable|null)=),
* function(*=))} resolver
@@ -2040,7 +2142,7 @@ function createPromise(resolver) {
* @param {string=} opt_message An optional error message to include if the
* wait times out; defaults to the empty string.
* @return {!Thenable<T>} A promise that will be fulfilled
- * when the condition has been satisified. The promise shall be rejected
+ * when the condition has been satisfied. The promise shall be rejected
* if the wait times out waiting for the condition.
* @throws {TypeError} If condition is not a function or promise or if timeout
* is not a number >= 0.
@@ -2164,7 +2266,7 @@ const SIMPLE_SCHEDULER = new SimpleScheduler;
/**
* Handles the execution of scheduled tasks, each of which may be an
* asynchronous operation. The control flow will ensure tasks are executed in
- * the ordered scheduled, starting each task only once those before it have
+ * the order scheduled, starting each task only once those before it have
* completed.
*
* Each task scheduled within this flow may return a {@link ManagedPromise} to
@@ -2172,21 +2274,21 @@ const SIMPLE_SCHEDULER = new SimpleScheduler;
* promises to be resolved before marking the task as completed.
*
* Tasks and each callback registered on a {@link ManagedPromise} will be run
- * in their own ControlFlow frame. Any tasks scheduled within a frame will take
+ * in their own ControlFlow frame. Any tasks scheduled within a frame will take
* priority over previously scheduled tasks. Furthermore, if any of the tasks in
* the frame fail, the remainder of the tasks in that frame will be discarded
* and the failure will be propagated to the user through the callback/task's
* promised result.
*
* Each time a ControlFlow empties its task queue, it will fire an
- * {@link ControlFlow.EventType.IDLE IDLE} event. Conversely,
- * whenever the flow terminates due to an unhandled error, it will remove all
+ * {@link ControlFlow.EventType.IDLE IDLE} event. Conversely, whenever
+ * the flow terminates due to an unhandled error, it will remove all
* remaining tasks in its queue and fire an
* {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION UNCAUGHT_EXCEPTION} event.
* If there are no listeners registered with the flow, the error will be
* rethrown to the global error handler.
*
- * Refer to the {@link ./promise} module documentation for a detailed
+ * Refer to the {@link ./promise} module documentation for a detailed
* explanation of how the ControlFlow coordinates task execution.
*
* @implements {Scheduler}
@@ -2212,7 +2314,7 @@ class ControlFlow extends events.EventEmitter {
this.taskQueues_ = null;
/**
- * Micro task that controls shutting down the control flow. Upon shut down,
+ * Microtask that controls shutting down the control flow. Upon shut down,
* the flow will emit an
* {@link ControlFlow.EventType.IDLE} event. Idle events
* always follow a brief timeout in order to catch latent errors from the
@@ -2221,8 +2323,8 @@ class ControlFlow extends events.EventEmitter {
* by the promise system until the next turn of the event loop:
*
* // Schedule 1 task that fails.
- * var result = promise.controlFlow().schedule('example',
- * function() { return promise.rejected('failed'); });
+ * var result = promise.controlFlow().execute(
+ * () => promise.rejected('failed'), 'example');
* // Set a callback on the result. This delays reporting the unhandled
* // failure for 1 turn of the event loop.
* result.then(function() {});
@@ -2246,7 +2348,7 @@ class ControlFlow extends events.EventEmitter {
/**
* Returns a string representation of this control flow, which is its current
* {@linkplain #getSchedule() schedule}, sans task stack traces.
- * @return {string} The string representation of this contorl flow.
+ * @return {string} The string representation of this control flow.
* @override
*/
toString() {
@@ -2258,8 +2360,7 @@ class ControlFlow extends events.EventEmitter {
* control flow stack and cause rejections within parent tasks. If error
* propagation is disabled, tasks will not be aborted when an unhandled
* promise rejection is detected, but the rejection _will_ trigger an
- * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION}
- * event.
+ * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} event.
*
* The default behavior is to propagate all unhandled rejections. _The use
* of this option is highly discouraged._
@@ -2293,7 +2394,7 @@ class ControlFlow extends events.EventEmitter {
* {@code opt_includeStackTraces === true}, the string will include the
* stack trace from when each task was scheduled.
* @param {string=} opt_includeStackTraces Whether to include the stack traces
- * from when each task was scheduled. Defaults to false.
+ * from when each task was scheduled. Defaults to false.
* @return {string} String representation of this flow's internal state.
*/
getSchedule(opt_includeStackTraces) {
@@ -2345,7 +2446,7 @@ class ControlFlow extends events.EventEmitter {
}
/**
- * Returns the currently actively task queue for this flow. If there is no
+ * Returns the currently active task queue for this flow. If there is no
* active queue, one will be created.
* @return {!TaskQueue} the currently active task queue for this flow.
* @private
@@ -2377,15 +2478,31 @@ class ControlFlow extends events.EventEmitter {
}
if (!this.hold_) {
- var holdIntervalMs = 2147483647; // 2^31-1; max timer length for Node.js
+ let holdIntervalMs = 2147483647; // 2^31-1; max timer length for Node.js
this.hold_ = setInterval(function() {}, holdIntervalMs);
}
- var task = new Task(
+ let task = new Task(
this, fn, opt_description || '<anonymous>',
- {name: 'Task', top: ControlFlow.prototype.execute});
+ {name: 'Task', top: ControlFlow.prototype.execute},
+ true);
+
+ let q = this.getActiveQueue_();
+
+ for (let i = q.tasks_.length; i > 0; i--) {
+ let previousTask = q.tasks_[i - 1];
+ if (previousTask.userTask_) {
+ FLOW_LOG.warning(() => {
+ return `Detected scheduling of an unchained task.
+When the promise manager is disabled, unchained tasks will not wait for
+previously scheduled tasks to finish before starting to execute.
+New task: ${task.promise.stack_.stack}
+Previous task: ${previousTask.promise.stack_.stack}`.split(/\n/).join('\n ');
+ });
+ break;
+ }
+ }
- var q = this.getActiveQueue_();
q.enqueue(task);
this.emit(ControlFlow.EventType.SCHEDULE_TASK, task.description);
return task.promise;
@@ -2393,7 +2510,7 @@ class ControlFlow extends events.EventEmitter {
/** @override */
promise(resolver) {
- return new ManagedPromise(resolver, this);
+ return new ManagedPromise(resolver, this, SKIP_LOG);
}
/** @override */
@@ -2622,7 +2739,7 @@ class MicroTask {
}
/**
- * Runs the given function after a micro-task yield.
+ * Runs the given function after a microtask yield.
* @param {function()} fn The function to run.
*/
static run(fn) {
@@ -2662,9 +2779,11 @@ class Task extends Deferred {
* @param {string} description A description of the task for debugging.
* @param {{name: string, top: !Function}=} opt_stackOptions Options to use
* when capturing the stacktrace for when this task was created.
+ * @param {boolean=} opt_isUserTask Whether this task was explicitly scheduled
+ * by the use of the promise manager.
*/
- constructor(flow, fn, description, opt_stackOptions) {
- super(flow);
+ constructor(flow, fn, description, opt_stackOptions, opt_isUserTask) {
+ super(flow, SKIP_LOG);
getUid(this);
/** @type {function(): (T|!ManagedPromise<T>)} */
@@ -2676,6 +2795,9 @@ class Task extends Deferred {
/** @type {TaskQueue} */
this.queue = null;
+ /** @private @const {boolean} */
+ this.userTask_ = !!opt_isUserTask;
+
/**
* Whether this task is considered block. A blocked task may be registered
* in a task queue, but will be dropped if it is still blocked when it
@@ -2889,7 +3011,7 @@ class TaskQueue extends events.EventEmitter {
}
// Now that all of the remaining tasks have been silently cancelled (e.g. no
- // exisitng callbacks on those tasks will fire), clear the silence bit on
+ // existing callbacks on those tasks will fire), clear the silence bit on
// the cancellation error. This ensures additional callbacks registered in
// the future will actually execute.
cancellation.silent_ = false;
@@ -2935,7 +3057,7 @@ class TaskQueue extends events.EventEmitter {
this.subQ_.once('end', () => { // On task completion.
this.subQ_ = null;
- this.pending_ && this.pending_.task.fulfill(result);
+ this.pending_ && this.pending_.task.resolve(result);
});
this.subQ_.once('error', e => { // On task failure.
@@ -3068,7 +3190,7 @@ class TaskQueue extends events.EventEmitter {
}
return task;
}
-};
+}
@@ -3214,7 +3336,7 @@ function consume(generatorFn, opt_self, ...var_args) {
function pump(fn, opt_arg) {
if (ret instanceof ManagedPromise && !isPending(ret)) {
- return; // Defererd was cancelled; silently abort.
+ return; // Deferred was cancelled; silently abort.
}
try {
@@ -3246,6 +3368,7 @@ module.exports = {
MultipleUnhandledRejectionError: MultipleUnhandledRejectionError,
Thenable: Thenable,
Promise: ManagedPromise,
+ Resolver: Resolver,
Scheduler: Scheduler,
all: all,
asap: asap,
@@ -3254,6 +3377,7 @@ module.exports = {
consume: consume,
controlFlow: controlFlow,
createFlow: createFlow,
+ createPromise: createPromise,
defer: defer,
delayed: delayed,
filter: filter,
@@ -3275,7 +3399,7 @@ module.exports = {
* The promise manager is currently enabled by default, but may be disabled
* by setting the environment variable `SELENIUM_PROMISE_MANAGER=0` or by
* setting this property to false. Setting this property will always take
- * precedence ove the use of the environment variable.
+ * precedence over the use of the environment variable.
*
* @return {boolean} Whether the promise manager is enabled.
* @see <https://github.com/SeleniumHQ/selenium/issues/2969>
diff --git a/node_modules/selenium-webdriver/lib/symbols.js b/node_modules/selenium-webdriver/lib/symbols.js
index d5c62504e..6c7cd1d9d 100644
--- a/node_modules/selenium-webdriver/lib/symbols.js
+++ b/node_modules/selenium-webdriver/lib/symbols.js
@@ -30,7 +30,7 @@ module.exports = {
* available, the serialize method will return a promise that will be resolved
* with the serialized form.
*
- * Note that the described method is analgous to objects that define a
+ * Note that the described method is analogous to objects that define a
* `toJSON()` method, except the serialized result may be a promise, or
* another object with a promised property.
*/
diff --git a/node_modules/selenium-webdriver/lib/test/index.js b/node_modules/selenium-webdriver/lib/test/index.js
index ba34ddab4..b3275ccbb 100644
--- a/node_modules/selenium-webdriver/lib/test/index.js
+++ b/node_modules/selenium-webdriver/lib/test/index.js
@@ -24,6 +24,7 @@ var build = require('./build'),
webdriver = require('../../'),
flow = webdriver.promise.controlFlow(),
firefox = require('../../firefox'),
+ logging = require('../../lib/logging'),
safari = require('../../safari'),
remote = require('../../remote'),
testing = require('../../testing'),
@@ -56,6 +57,11 @@ var noMarionette = /^0|false$/i.test(process.env['SELENIUM_GECKODRIVER']);
var startServer = !!serverJar && !remoteUrl;
var nativeRun = !serverJar && !remoteUrl;
+if (/^1|true$/i.test(process.env['SELENIUM_VERBOSE'])) {
+ logging.installConsoleHandler();
+ logging.getLogger('webdriver.http').setLevel(logging.Level.ALL);
+}
+
var browsersToTest = (function() {
var permitRemoteBrowsers = !!remoteUrl || !!serverJar;
var permitUnknownBrowsers = !nativeRun;
diff --git a/node_modules/selenium-webdriver/lib/until.js b/node_modules/selenium-webdriver/lib/until.js
index 0cc6f5ea3..b0e68b88b 100644
--- a/node_modules/selenium-webdriver/lib/until.js
+++ b/node_modules/selenium-webdriver/lib/until.js
@@ -72,7 +72,7 @@ const webdriver = require('./webdriver'),
exports.ableToSwitchToFrame = function ableToSwitchToFrame(frame) {
var condition;
if (typeof frame === 'number' || frame instanceof webdriver.WebElement) {
- condition = attemptToSwitchFrames;
+ condition = driver => attemptToSwitchFrames(driver, frame);
} else {
condition = function(driver) {
let locator = /** @type {!(By|Function)} */(frame);
diff --git a/node_modules/selenium-webdriver/lib/webdriver.js b/node_modules/selenium-webdriver/lib/webdriver.js
index 081d77bda..c8d04e82a 100644
--- a/node_modules/selenium-webdriver/lib/webdriver.js
+++ b/node_modules/selenium-webdriver/lib/webdriver.js
@@ -457,12 +457,12 @@ class IWebDriver {
* while evaluating the condition, they will be allowed to propagate. In the
* event a condition returns a {@link promise.Promise promise}, the polling
* loop will wait for it to be resolved and use the resolved value for whether
- * the condition has been satisified. Note the resolution time for a promise
+ * the condition has been satisfied. Note the resolution time for a promise
* is factored into whether a wait has timed out.
*
* Note, if the provided condition is a {@link WebElementCondition}, then
* the wait will return a {@link WebElementPromise} that will resolve to the
- * element that satisified the condition.
+ * element that satisfied the condition.
*
* _Example:_ waiting up to 10 seconds for an element to be present on the
* page.
@@ -779,7 +779,7 @@ class WebDriver {
'WebDriver.createSession()');
if (typeof opt_onQuit === 'function') {
session = session.catch(err => {
- return Promise.resolve(opt_onQuit.call(void 0)).then(_ => {throw err});
+ return Promise.resolve(opt_onQuit.call(void 0)).then(_ => {throw err;});
});
}
const ctor = opt_ctor || WebDriver;
@@ -850,7 +850,7 @@ class WebDriver {
new command.Command(command.Name.QUIT),
'WebDriver.quit()');
// Delete our session ID when the quit command finishes; this will allow us
- // to throw an error when attemnpting to use a driver post-quit.
+ // to throw an error when attempting to use a driver post-quit.
return /** @type {!promise.Thenable} */(promise.finally(result, () => {
this.session_ = this.flow_.promise((_, reject) => {
reject(new error.NoSuchSessionError(
@@ -1181,7 +1181,7 @@ class Navigation {
/**
* Provides methods for managing browser and driver state.
*
- * This class should never be instantiated directly. Insead, obtain an instance
+ * This class should never be instantiated directly. Instead, obtain an instance
* with {@linkplain WebDriver#manage() webdriver.manage()}.
*/
class Options {
@@ -1427,7 +1427,7 @@ Options.Cookie.prototype.expiry;
/**
* An interface for managing timeout behavior for WebDriver instances.
*
- * This class should never be instantiated directly. Insead, obtain an instance
+ * This class should never be instantiated directly. Instead, obtain an instance
* with
*
* webdriver.manage().timeouts()
@@ -2009,7 +2009,7 @@ class WebElement {
* 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
+ * processed in the key sequence, that key state is toggled until one of the
* following occurs:
*
* - The modifier key is encountered again in the sequence. At this point the
@@ -2028,13 +2028,13 @@ class WebElement {
* Key.chord(Key.CONTROL, "a"),
* "now text is");
*
- * - The end of the keysequence is encountered. When there are no more keys
+ * - The end of the key sequence 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 element. This is analogous to the user clicking "Browse..." and entering
* the path into the file select dialog.
*
* var form = driver.findElement(By.css('form'));
@@ -2050,7 +2050,7 @@ class WebElement {
*
* __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
+ * punctuation keys will be synthesized according to a standard QWERTY en-us
* keyboard layout.
*
* @param {...(number|string|!IThenable<(number|string)>)} var_args The
@@ -2214,7 +2214,7 @@ class WebElement {
/**
* Schedules a command to query whether the DOM element represented by this
- * instance is enabled, as dicted by the {@code disabled} attribute.
+ * instance is enabled, as dictated by the {@code disabled} attribute.
* @return {!promise.Thenable<boolean>} A promise that will be
* resolved with whether this element is currently enabled.
*/
@@ -2327,7 +2327,7 @@ class WebElementPromise extends WebElement {
if (promise.CancellableThenable.isImplementation(el)) {
/** @type {!promise.CancellableThenable} */(el).cancel(opt_reason);
}
- }
+ };
/** @override */
this.then = el.then.bind(el);