Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

selenium-webdriver

Package Overview
Dependencies
Maintainers
1
Versions
100
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

selenium-webdriver - npm Package Compare versions

Comparing version 2.33.0 to 2.34.0

chrome.js

4

_base.js

@@ -38,3 +38,3 @@ // Copyright 2012 Selenium committers

* If this script was loaded from the Selenium project repo, it will operate in
* development, adjusting how it loads Closure-based dependencies.
* development mode, adjusting how it loads Closure-based dependencies.
* @type {boolean}

@@ -99,3 +99,3 @@ */

return closure.goog.getObjectByName(symbol);
};
}

@@ -102,0 +102,0 @@

@@ -16,32 +16,38 @@ // Copyright 2011 Software Freedom Conservancy. All Rights Reserved.

var base = require('./_base'),
HttpClient = require('./http').HttpClient;
executors = require('./executors');
var goog = base.require('goog'),
AbstractBuilder = base.require('webdriver.AbstractBuilder'),
Browser = base.require('webdriver.Browser'),
Capability = base.require('webdriver.Capability'),
WebDriver = base.require('webdriver.WebDriver'),
HttpExecutor = base.require('webdriver.http.Executor'),
promise = base.require('webdriver.promise');
/**
* Wraps a promised {@link webdriver.CommandExecutor}, ensuring no commands
* are executed until the wrapped executor has been fully built.
* @param {!webdriver.promise.Promise.<!webdriver.CommandExecutor>} delegate The
* promised delegate.
* @constructor
* @implements {webdriver.CommandExecutor}
* @param {!webdriver.Capabilities} capabilities The desired capabilities.
* @return {webdriver.WebDriver} A new WebDriver instance or {@code null}
* if the requested browser is not natively supported in Node.
*/
var DeferredExecutor = function(delegate) {
function createNativeDriver(capabilities) {
switch (capabilities.get(Capability.BROWSER_NAME)) {
case Browser.CHROME:
// Requiring 'chrome' above would create a cycle:
// index -> builder -> chrome -> index
var chrome = require('./chrome');
return chrome.createDriver(capabilities);
/** @override */
this.execute = function(command, callback) {
delegate.then(function(executor) {
executor.execute(command, callback);
}, callback);
};
};
case Browser.PHANTOM_JS:
// Requiring 'phantomjs' would create a cycle:
// index -> builder -> phantomjs -> index
var phantomjs = require('./phantomjs');
return phantomjs.createDriver(capabilities);
default:
return null;
}
}
/**

@@ -57,18 +63,46 @@ * @constructor

/**
* Sets the proxy configuration to use for WebDriver clients created by this
* builder. Any calls to {@link #withCapabilities} after this function will
* overwrite these settings.
* @param {!ProxyConfig} config The configuration to use.
* @return {!Builder} A self reference.
*/
Builder.prototype.setProxy = function(config) {
this.getCapabilities().set(Capability.PROXY, config);
return this;
};
/**
* Sets Chrome-specific options for drivers created by this builder.
* @param {!chrome.Options} options The ChromeDriver options to use.
* @return {!Builder} A self reference.
*/
Builder.prototype.setChromeOptions = function(options) {
var newCapabilities = options.toCapabilities(this.getCapabilities());
return /** @type {!Builder} */(this.withCapabilities(newCapabilities));
};
/**
* @override
*/
Builder.prototype.build = function() {
var serverUrl = this.getServerUrl();
var executor = new DeferredExecutor(promise.when(serverUrl, function(url) {
var client = new HttpClient(url);
return new HttpExecutor(client);
}));
var url = this.getServerUrl();
if (this.getSession()) {
return WebDriver.attachToSession(executor, this.getSession());
} else {
return WebDriver.createSession(executor, this.getCapabilities());
// If a remote server wasn't specified, check for browsers we support
// natively in node before falling back to using the java Selenium server.
if (!url) {
var driver = createNativeDriver(this.getCapabilities());
if (driver) {
return driver;
}
// Nope, fall-back to using the default java server.
url = AbstractBuilder.DEFAULT_SERVER_URL;
}
var executor = executors.createExecutor(url);
return WebDriver.createSession(executor, this.getCapabilities());
};

@@ -75,0 +109,0 @@

@@ -0,1 +1,35 @@

## v2.34.0
* Added the `selenium-webdriver/testing/assert` module. This module
simplifies writing assertions against promised values (see
example in module documentation).
* Added the `webdriver.Capabilities` class.
* Added native support for the ChromeDriver. When using the `Builder`,
requesting chrome without specifying a remote server URL will default to
the native ChromeDriver implementation. The
[ChromeDriver server](https://code.google.com/p/chromedriver/downloads/list)
must be downloaded separately.
// Will start ChromeDriver locally.
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
// Will start ChromeDriver using the remote server.
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
usingServer('http://server:1234/wd/hub').
build();
* Added support for configuring proxies through the builder. For examples, see
`selenium-webdriver/test/proxy_test`.
* Added native support for PhantomJS.
* Changed signature of `SeleniumServer` to `SeleniumServer(jar, options)`.
* Tests are now included in the npm published package. See `README.md` for
execution instructions
* Removed the deprecated `webdriver.Deferred#resolve` and
`webdriver.promise.resolved` functions.
* Removed the ability to connect to an existing session from the Builder. This
feature is intended for use with the browser-based client.
## v2.33.0

@@ -2,0 +36,0 @@

@@ -27,4 +27,4 @@ // Copyright 2012 Selenium committers

exports.By = base.require('webdriver.Locator.Strategy');
exports.Capabilities = base.require('webdriver.Capabilities');
exports.Command = base.require('webdriver.Command');
exports.CommandName = base.require('webdriver.CommandName');
exports.EventEmitter = base.require('webdriver.EventEmitter');

@@ -35,8 +35,7 @@ exports.Session = base.require('webdriver.Session');

exports.__defineGetter__('Key', function() {
return base.require('webdriver.Key');
});
var submodules = {
var closureModules = {
Browser: base.require('webdriver.Browser'),
Capability: base.require('webdriver.Capability'),
CommandName: base.require('webdriver.CommandName'),
Key: base.require('webdriver.Key'),
command: {

@@ -53,3 +52,2 @@ Command: base.require('webdriver.Command'),

},
http: require('./http'),
logging: base.exportPublicApi('webdriver.logging'),

@@ -61,7 +59,6 @@ promise: base.exportPublicApi('webdriver.promise'),

Object.keys(submodules).forEach(function(key) {
Object.keys(closureModules).forEach(function(key) {
exports.__defineGetter__(key, function() {
return submodules[key];
return closureModules[key];
});
});

@@ -98,2 +98,3 @@ // Copyright 2010 WebDriver committers

});
var l = name.length - 'Error'.length;

@@ -100,0 +101,0 @@ if (l < 0 || name.indexOf('Error', l) != l) {

@@ -30,3 +30,3 @@ // Copyright 2012 WebDriver committers

* @define {boolean} NATIVE_JSON indicates whether the code should rely on the
* native {@ocde JSON} functions, if available.
* native {@code JSON} functions, if available.
*

@@ -33,0 +33,0 @@ * <p>The JSON functions can be defined by external libraries like Prototype

@@ -51,3 +51,3 @@ // Copyright 2011 Software Freedom Conservancy. All Rights Reserved.

if (bot.response.isResponseObject(value)) {
return (/** @type {!bot.response.ResponseObject} */value);
return /** @type {!bot.response.ResponseObject} */ (value);
}

@@ -69,3 +69,3 @@ return {

if (bot.response.isResponseObject(error)) {
return (/** @type {!bot.response.ResponseObject} */error);
return /** @type {!bot.response.ResponseObject} */ (error);
}

@@ -76,3 +76,3 @@

return {
'status': (/** @type {bot.ErrorCode} */statusCode),
'status': /** @type {bot.ErrorCode} */ (statusCode),
'value': {

@@ -79,0 +79,0 @@ 'message': (error && error.message || error) + ''

@@ -49,3 +49,3 @@ // Copyright 2011 WebDriver committers

} else {
return goog.userAgent.isVersion(version);
return goog.userAgent.isVersionOrHigher(version);
}

@@ -85,3 +85,2 @@ };

* than the given version. When we are not in a Firefox extension, this is null.
*
* @private {(undefined|function((string|number)): boolean)}

@@ -96,3 +95,2 @@ */

* than the given version. When we are not in a Firefox extension, this is null.
*
* @private {(undefined|function((string|number)): boolean)}

@@ -170,5 +168,4 @@ */

* Android Operating System Version.
*
* @private {string}
* @const
* @private {string}
*/

@@ -192,3 +189,3 @@ bot.userAgent.ANDROID_VERSION_ = (function() {

bot.userAgent.IE_DOC_PRE8 = goog.userAgent.IE &&
!goog.userAgent.isDocumentMode(8);
!goog.userAgent.isDocumentModeOrHigher(8);

@@ -201,3 +198,3 @@

*/
bot.userAgent.IE_DOC_9 = goog.userAgent.isDocumentMode(9);
bot.userAgent.IE_DOC_9 = goog.userAgent.isDocumentModeOrHigher(9);

@@ -211,3 +208,3 @@

bot.userAgent.IE_DOC_PRE9 = goog.userAgent.IE &&
!goog.userAgent.isDocumentMode(9);
!goog.userAgent.isDocumentModeOrHigher(9);

@@ -220,3 +217,3 @@

*/
bot.userAgent.IE_DOC_10 = goog.userAgent.isDocumentMode(10);
bot.userAgent.IE_DOC_10 = goog.userAgent.isDocumentModeOrHigher(10);

@@ -230,3 +227,3 @@

bot.userAgent.IE_DOC_PRE10 = goog.userAgent.IE &&
!goog.userAgent.isDocumentMode(10);
!goog.userAgent.isDocumentModeOrHigher(10);

@@ -233,0 +230,0 @@

// This file has been auto-generated; do not edit by hand
goog.addDependency("../atoms/error.js", ["bot.Error","bot.ErrorCode"], []);
goog.addDependency("../atoms/response.js", ["bot.response","bot.response.ResponseObject"], ["bot.Error","bot.ErrorCode"]);
goog.addDependency("../atoms/json.js", ["bot.json"], ["bot.userAgent","goog.json","goog.userAgent"]);
goog.addDependency("../atoms/userAgent.js", ["bot.userAgent"], ["goog.string","goog.userAgent","goog.userAgent.product","goog.userAgent.product.isVersion"]);

@@ -9,31 +11,39 @@ goog.addDependency("string/string.js", ["goog.string","goog.string.Unicode"], []);

goog.addDependency("json/json.js", ["goog.json","goog.json.Serializer"], []);
goog.addDependency("../webdriver/process.js", ["webdriver.process"], ["goog.Uri","goog.array","goog.json"]);
goog.addDependency("uri/uri.js", ["goog.Uri","goog.Uri.QueryData"], ["goog.array","goog.string","goog.structs","goog.structs.Map","goog.uri.utils","goog.uri.utils.ComponentIndex"]);
goog.addDependency("../webdriver/capabilities.js", ["webdriver.Browser","webdriver.Capability","webdriver.Capabilities"], []);
goog.addDependency("../webdriver/logging.js", ["webdriver.logging"], ["goog.object"]);
goog.addDependency("object/object.js", ["goog.object"], []);
goog.addDependency("../webdriver/actionsequence.js", ["webdriver.ActionSequence"], ["goog.array","webdriver.Button","webdriver.Command","webdriver.CommandName","webdriver.Key"]);
goog.addDependency("array/array.js", ["goog.array","goog.array.ArrayLike"], ["goog.asserts"]);
goog.addDependency("asserts/asserts.js", ["goog.asserts","goog.asserts.AssertionError"], ["goog.debug.Error","goog.string"]);
goog.addDependency("debug/error.js", ["goog.debug.Error"], []);
goog.addDependency("structs/structs.js", ["goog.structs"], ["goog.array","goog.object"]);
goog.addDependency("object/object.js", ["goog.object"], []);
goog.addDependency("structs/map.js", ["goog.structs.Map"], ["goog.iter.Iterator","goog.iter.StopIteration","goog.object","goog.structs"]);
goog.addDependency("iter/iter.js", ["goog.iter","goog.iter.Iterator","goog.iter.StopIteration"], ["goog.array","goog.asserts"]);
goog.addDependency("uri/utils.js", ["goog.uri.utils","goog.uri.utils.ComponentIndex","goog.uri.utils.QueryArray","goog.uri.utils.QueryValue","goog.uri.utils.StandardQueryParam"], ["goog.asserts","goog.string","goog.userAgent"]);
goog.addDependency("../webdriver/button.js", ["webdriver.Button"], []);
goog.addDependency("../webdriver/command.js", ["webdriver.Command","webdriver.CommandExecutor","webdriver.CommandName"], []);
goog.addDependency("../webdriver/key.js", ["webdriver.Key"], []);
goog.addDependency("../webdriver/abstractbuilder.js", ["webdriver.AbstractBuilder"], ["webdriver.process"]);
goog.addDependency("../webdriver/firefoxdomexecutor.js", ["webdriver.FirefoxDomExecutor"], ["bot.response","goog.json","goog.userAgent.product","webdriver.Command","webdriver.CommandName"]);
goog.addDependency("../atoms/response.js", ["bot.response","bot.response.ResponseObject"], ["bot.Error","bot.ErrorCode"]);
goog.addDependency("../webdriver/webdriver.js", ["webdriver.Alert","webdriver.UnhandledAlertError","webdriver.WebDriver","webdriver.WebElement"], ["bot.Error","bot.ErrorCode","bot.response","goog.array","goog.object","webdriver.ActionSequence","webdriver.Command","webdriver.CommandName","webdriver.Key","webdriver.Locator","webdriver.Session","webdriver.logging","webdriver.promise"]);
goog.addDependency("../webdriver/actionsequence.js", ["webdriver.ActionSequence"], ["goog.array","webdriver.Button","webdriver.Command","webdriver.CommandName","webdriver.Key"]);
goog.addDependency("../webdriver/stacktrace.js", ["webdriver.stacktrace","webdriver.stacktrace.Snapshot"], ["goog.array","goog.string","goog.userAgent"]);
goog.addDependency("../webdriver/locators.js", ["webdriver.Locator","webdriver.Locator.Strategy"], ["bot.json","goog.object"]);
goog.addDependency("../atoms/json.js", ["bot.json"], ["bot.userAgent","goog.json","goog.userAgent"]);
goog.addDependency("../webdriver/session.js", ["webdriver.Session"], []);
goog.addDependency("../webdriver/logging.js", ["webdriver.logging"], ["goog.object"]);
goog.addDependency("../webdriver/promise.js", ["webdriver.promise","webdriver.promise.ControlFlow","webdriver.promise.Deferred","webdriver.promise.Promise"], ["goog.array","goog.object","webdriver.EventEmitter","webdriver.stacktrace.Snapshot"]);
goog.addDependency("../webdriver/promise.js", ["webdriver.promise","webdriver.promise.ControlFlow","webdriver.promise.ControlFlow.Timer","webdriver.promise.Deferred","webdriver.promise.Promise"], ["goog.array","goog.debug.Error","goog.object","webdriver.EventEmitter","webdriver.stacktrace.Snapshot"]);
goog.addDependency("../webdriver/events.js", ["webdriver.EventEmitter"], []);
goog.addDependency("../webdriver/stacktrace.js", ["webdriver.stacktrace","webdriver.stacktrace.Snapshot"], ["goog.array","goog.string"]);
goog.addDependency("../webdriver/process.js", ["webdriver.process"], ["goog.Uri","goog.array","goog.json"]);
goog.addDependency("uri/uri.js", ["goog.Uri","goog.Uri.QueryData"], ["goog.array","goog.string","goog.structs","goog.structs.Map","goog.uri.utils","goog.uri.utils.ComponentIndex","goog.uri.utils.StandardQueryParam"]);
goog.addDependency("structs/structs.js", ["goog.structs"], ["goog.array","goog.object"]);
goog.addDependency("structs/map.js", ["goog.structs.Map"], ["goog.iter.Iterator","goog.iter.StopIteration","goog.object"]);
goog.addDependency("iter/iter.js", ["goog.iter","goog.iter.Iterator","goog.iter.StopIteration"], ["goog.array","goog.asserts"]);
goog.addDependency("uri/utils.js", ["goog.uri.utils","goog.uri.utils.ComponentIndex","goog.uri.utils.QueryArray","goog.uri.utils.QueryValue","goog.uri.utils.StandardQueryParam"], ["goog.asserts","goog.string","goog.userAgent"]);
goog.addDependency("../webdriver/webdriver.js", ["webdriver.Alert","webdriver.UnhandledAlertError","webdriver.WebDriver","webdriver.WebElement"], ["bot.Error","bot.ErrorCode","bot.response","goog.array","goog.object","webdriver.ActionSequence","webdriver.Command","webdriver.CommandName","webdriver.Key","webdriver.Locator","webdriver.Session","webdriver.logging","webdriver.promise"]);
goog.addDependency("../webdriver/session.js", ["webdriver.Session"], ["webdriver.Capabilities"]);
goog.addDependency("../webdriver/builder.js", ["webdriver.Builder"], ["webdriver.AbstractBuilder","webdriver.FirefoxDomExecutor","webdriver.WebDriver","webdriver.http.CorsClient","webdriver.http.Executor","webdriver.process"]);
goog.addDependency("../webdriver/abstractbuilder.js", ["webdriver.AbstractBuilder"], ["webdriver.Capabilities","webdriver.process"]);
goog.addDependency("../webdriver/firefoxdomexecutor.js", ["webdriver.FirefoxDomExecutor"], ["bot.response","goog.json","goog.userAgent.product","webdriver.Command","webdriver.CommandName"]);
goog.addDependency("../webdriver/http/corsclient.js", ["webdriver.http.CorsClient"], ["goog.json","webdriver.http.Response"]);
goog.addDependency("../webdriver/http/http.js", ["webdriver.http.Client","webdriver.http.Executor","webdriver.http.Request","webdriver.http.Response"], ["bot.ErrorCode","goog.array","goog.json","webdriver.CommandName","webdriver.promise.Deferred"]);
goog.addDependency("../webdriver/http/xhrclient.js", ["webdriver.http.XhrClient"], ["goog.json","goog.net.XmlHttp","webdriver.http.Response"]);
goog.addDependency("net/xmlhttp.js", ["goog.net.DefaultXmlHttpFactory","goog.net.XmlHttp","goog.net.XmlHttp.OptionType","goog.net.XmlHttp.ReadyState"], ["goog.net.WrapperXmlHttpFactory","goog.net.XmlHttpFactory"]);
goog.addDependency("net/wrapperxmlhttpfactory.js", ["goog.net.WrapperXmlHttpFactory"], ["goog.net.XmlHttpFactory"]);
goog.addDependency("net/xmlhttpfactory.js", ["goog.net.XmlHttpFactory"], []);
goog.addDependency("../webdriver/testing/asserts.js", ["webdriver.testing.Assertion","webdriver.testing.ContainsMatcher","webdriver.testing.NegatedAssertion","webdriver.testing.assert","webdriver.testing.asserts"], ["goog.array","goog.string","goog.labs.testing.AnyOfMatcher","goog.labs.testing.CloseToMatcher","goog.labs.testing.ContainsStringMatcher","goog.labs.testing.EndsWithMatcher","goog.labs.testing.EqualsMatcher","goog.labs.testing.EqualToMatcher","goog.labs.testing.GreaterThanEqualToMatcher","goog.labs.testing.GreaterThanMatcher","goog.labs.testing.LessThanEqualToMatcher","goog.labs.testing.LessThanMatcher","goog.labs.testing.InstanceOfMatcher","goog.labs.testing.IsNotMatcher","goog.labs.testing.IsNullMatcher","goog.labs.testing.IsNullOrUndefinedMatcher","goog.labs.testing.IsUndefinedMatcher","goog.labs.testing.ObjectEqualsMatcher","goog.labs.testing.Matcher","goog.labs.testing.RegexMatcher","goog.labs.testing.StartsWithMatcher","goog.labs.testing.assertThat","webdriver.promise"]);
goog.addDependency("labs/testing/logicmatcher.js", ["goog.labs.testing.AllOfMatcher","goog.labs.testing.AnyOfMatcher","goog.labs.testing.IsNotMatcher"], ["goog.array","goog.labs.testing.Matcher"]);
goog.addDependency("labs/testing/matcher.js", ["goog.labs.testing.Matcher"], []);
goog.addDependency("labs/testing/numbermatcher.js", ["goog.labs.testing.CloseToMatcher","goog.labs.testing.EqualToMatcher","goog.labs.testing.GreaterThanEqualToMatcher","goog.labs.testing.GreaterThanMatcher","goog.labs.testing.LessThanEqualToMatcher","goog.labs.testing.LessThanMatcher"], ["goog.asserts","goog.labs.testing.Matcher"]);
goog.addDependency("labs/testing/stringmatcher.js", ["goog.labs.testing.ContainsStringMatcher","goog.labs.testing.EndsWithMatcher","goog.labs.testing.EqualToIgnoringCaseMatcher","goog.labs.testing.EqualToIgnoringWhitespaceMatcher","goog.labs.testing.EqualsMatcher","goog.labs.testing.RegexMatcher","goog.labs.testing.StartsWithMatcher","goog.labs.testing.StringContainsInOrderMatcher"], ["goog.asserts","goog.labs.testing.Matcher","goog.string"]);
goog.addDependency("labs/testing/objectmatcher.js", ["goog.labs.testing.HasPropertyMatcher","goog.labs.testing.InstanceOfMatcher","goog.labs.testing.IsNullMatcher","goog.labs.testing.IsNullOrUndefinedMatcher","goog.labs.testing.IsUndefinedMatcher","goog.labs.testing.ObjectEqualsMatcher"], ["goog.labs.testing.Matcher","goog.string"]);
goog.addDependency("labs/testing/assertthat.js", ["goog.labs.testing.MatcherError","goog.labs.testing.assertThat"], ["goog.asserts","goog.debug.Error","goog.labs.testing.Matcher"]);

@@ -38,4 +38,7 @@ // Copyright 2006 The Closure Library Authors. All Rights Reserved.

* "--define goog.NATIVE_ARRAY_PROTOTYPES=false" to the JSCompiler.
*
* Setting goog.TRUSTED_SITE to false will automatically set
* NATIVE_ARRAY_PROTOTYPES to false.
*/
goog.NATIVE_ARRAY_PROTOTYPES = true;
goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE);

@@ -159,16 +162,11 @@

/**
* Calls a function for each element in an array.
*
* Calls a function for each element in an array. Skips holes in the array.
* See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}
*
* @param {Array.<T>|goog.array.ArrayLike} arr Array or array
* like object over which to iterate.
* @param {Array.<T>|goog.array.ArrayLike} arr Array or array like object over
* which to iterate.
* @param {?function(this: S, T, number, ?): ?} f The function to call for every
* element.
* This function takes 3 arguments (the element, the index and the array).
* The return value is ignored. The function is called only for indexes of
* the array which have assigned values; it is not called for indexes which
* have been deleted or which have never been assigned values.
* @param {S=} opt_obj The object to be used as the value of 'this'
* within f.
* element. This function takes 3 arguments (the element, the index and the
* array). The return value is ignored.
* @param {S=} opt_obj The object to be used as the value of 'this' within f.
* @template T,S

@@ -454,2 +452,25 @@ */

/**
* Counts the array elements that fulfill the predicate, i.e. for which the
* callback function returns true. Skips holes in the array.
*
* @param {!(Array.<T>|goog.array.ArrayLike)} arr Array or array like object
* over which to iterate.
* @param {function(this: S, T, number, ?): boolean} f The function to call for
* every element. Takes 3 arguments (the element, the index and the array).
* @param {S=} opt_obj The object to be used as the value of 'this' within f.
* @return {number} The number of the matching elements.
* @template T,S
*/
goog.array.count = function(arr, f, opt_obj) {
var count = 0;
goog.array.forEach(arr, function(element, index, arr) {
if (f.call(opt_obj, element, index, arr)) {
++count;
}
}, opt_obj);
return count;
};
/**
* Search an array for the first element that satisfies a given condition and

@@ -786,5 +807,4 @@ * return that element.

// according to section 10.6 in ES5 so check for presence instead.
arr2.hasOwnProperty('callee')) {
Object.prototype.hasOwnProperty.call(arr2, 'callee')) {
arr1.push.apply(arr1, arr2);
} else if (isArrayLike) {

@@ -1245,13 +1265,14 @@ // Otherwise loop over arr2 to prevent copying the object.

* @param {Array.<T>} array The array.
* @param {function(T,number,Array.<T>):?} sorter Function to call for every
* element. This
* takes 3 arguments (the element, the index and the array) and must
* return a valid object key (a string, number, etc), or undefined, if
* that object should not be placed in a bucket.
* @param {function(this:S, T,number,Array.<T>):?} sorter Function to call for
* every element. This takes 3 arguments (the element, the index and the
* array) and must return a valid object key (a string, number, etc), or
* undefined, if that object should not be placed in a bucket.
* @param {S=} opt_obj The object to be used as the value of 'this' within
* sorter.
* @return {!Object} An object, with keys being all of the unique return values
* of sorter, and values being arrays containing the items for
* which the splitter returned that key.
* @template T
* @template T,S
*/
goog.array.bucket = function(array, sorter) {
goog.array.bucket = function(array, sorter, opt_obj) {
var buckets = {};

@@ -1261,3 +1282,3 @@

var value = array[i];
var key = sorter(value, i, array);
var key = sorter.call(opt_obj, value, i, array);
if (goog.isDef(key)) {

@@ -1285,3 +1306,3 @@ // Push the value to the right bucket, creating it if necessary.

* implementation-defined.
* @param {S=} opt_obj The object to be used as the value of 'this'
* @param {S=} opt_obj The object to be used as the value of 'this'
* within keyFunc.

@@ -1301,2 +1322,50 @@ * @return {!Object.<T>} The new object.

/**
* Creates a range of numbers in an arithmetic progression.
*
* Range takes 1, 2, or 3 arguments:
* <pre>
* range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]
* range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]
* range(-2, -5, -1) produces [-2, -3, -4]
* range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.
* </pre>
*
* @param {number} startOrEnd The starting value of the range if an end argument
* is provided. Otherwise, the start value is 0, and this is the end value.
* @param {number=} opt_end The optional end value of the range.
* @param {number=} opt_step The step size between range values. Defaults to 1
* if opt_step is undefined or 0.
* @return {!Array.<number>} An array of numbers for the requested range. May be
* an empty array if adding the step would not converge toward the end
* value.
*/
goog.array.range = function(startOrEnd, opt_end, opt_step) {
var array = [];
var start = 0;
var end = startOrEnd;
var step = opt_step || 1;
if (opt_end !== undefined) {
start = startOrEnd;
end = opt_end;
}
if (step * (end - start) < 0) {
// Sign mismatch: start + step will never reach the end value.
return [];
}
if (step > 0) {
for (var i = start; i < end; i += step) {
array.push(i);
}
} else {
for (var i = start; i > end; i += step) {
array.push(i);
}
}
return array;
};
/**
* Returns an array consisting of the given value repeated N times.

@@ -1303,0 +1372,0 @@ *

@@ -46,3 +46,3 @@ // Copyright 2008 The Closure Library Authors. All Rights Reserved.

*/
goog.asserts.ENABLE_ASSERTS = goog.DEBUG;
goog.define('goog.asserts.ENABLE_ASSERTS', goog.DEBUG);

@@ -269,3 +269,3 @@

* @param {*} value The value to check.
* @param {!Function} type A user-defined constructor.
* @param {function(new: T, ...)} type A user-defined constructor.
* @param {string=} opt_message Error message in case of failure.

@@ -275,3 +275,4 @@ * @param {...*} var_args The items to substitute into the failure message.

* type.
* @return {!Object}
* @return {!T}
* @template T
*/

@@ -283,4 +284,4 @@ goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {

}
return /** @type {!Object} */(value);
return value;
};

@@ -41,3 +41,3 @@ // Copyright 2006 The Closure Library Authors. All Rights Reserved.

*/
var goog = goog || {}; // Identifies this file as the Closure base.
var goog = goog || {};

@@ -52,2 +52,84 @@

/**
* A hook for overriding the define values in uncompiled mode.
*
* In uncompiled mode, {@code CLOSURE_DEFINES} may be defined before loading
* base.js. If a key is defined in {@code CLOSURE_DEFINES}, {@code goog.define}
* will use the value instead of the default value. This allows flags to be
* overwritten without compilation (this is normally accomplished with the
* compiler's "define" flag).
*
* Example:
* <pre>
* var CLOSURE_DEFINES = {'goog.DEBUG', false};
* </pre>
*
* @type {Object.<string, (string|number|boolean)>|undefined}
*/
goog.global.CLOSURE_DEFINES;
/**
* Builds an object structure for the provided namespace path,
* ensuring that names that already exist are not overwritten. For
* example:
* "a.b.c" -> a = {};a.b={};a.b.c={};
* Used by goog.provide and goog.exportSymbol.
* @param {string} name name of the object that this file defines.
* @param {*=} opt_object the object to expose at the end of the path.
* @param {Object=} opt_objectToExportTo The object to add the path to; default
* is |goog.global|.
* @private
*/
goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
var parts = name.split('.');
var cur = opt_objectToExportTo || goog.global;
// Internet Explorer exhibits strange behavior when throwing errors from
// methods externed in this manner. See the testExportSymbolExceptions in
// base_test.html for an example.
if (!(parts[0] in cur) && cur.execScript) {
cur.execScript('var ' + parts[0]);
}
// Certain browsers cannot parse code in the form for((a in b); c;);
// This pattern is produced by the JSCompiler when it collapses the
// statement above into the conditional loop below. To prevent this from
// happening, use a for-loop and reserve the init logic as below.
// Parentheses added to eliminate strict JS warning in Firefox.
for (var part; parts.length && (part = parts.shift());) {
if (!parts.length && opt_object !== undefined) {
// last part and we have an object; use it
cur[part] = opt_object;
} else if (cur[part]) {
cur = cur[part];
} else {
cur = cur[part] = {};
}
}
};
/**
* Defines a named value. In uncompiled mode, the value is retreived from
* CLOSURE_DEFINES if the object is defined and has the property specified,
* and otherwise used the defined defaultValue. When compiled, the default
* can be overridden using compiler command-line options.
*
* @param {string} name The distinguished name to provide.
* @param {string|number|boolean} defaultValue
*/
goog.define = function(name, defaultValue) {
var value = defaultValue;
if (!COMPILED) {
if (goog.global.CLOSURE_DEFINES && Object.prototype.hasOwnProperty.call(
goog.global.CLOSURE_DEFINES, name)) {
value = goog.global.CLOSURE_DEFINES[name];
}
}
goog.exportPath_(name, value);
};
/**
* @define {boolean} DEBUG is provided as a convenience so that debugging code

@@ -82,6 +164,20 @@ * that should not be included in a production js_binary can be easily stripped

*/
goog.LOCALE = 'en'; // default to en
goog.define('goog.LOCALE', 'en'); // default to en
/**
* @define {boolean} Whether this code is running on trusted sites.
*
* On untrusted sites, several native functions can be defined or overridden by
* external libraries like Prototype, Datejs, and JQuery and setting this flag
* to false forces closure to use its own implementations when possible.
*
* If your javascript can be loaded by a third party site and you are wary about
* relying on non-standard implementations, specify
* "--define goog.TRUSTED_SITE=false" to the JSCompiler.
*/
goog.define('goog.TRUSTED_SITE', true);
/**
* Creates object stubs for a namespace. The presence of one or more

@@ -123,2 +219,7 @@ * goog.provide() calls indicate that the file defines the given

* live code in production.
*
* In the case of unit tests, the message may optionally be an exact
* namespace for the test (e.g. 'goog.stringTest'). The linter will then
* ignore the extra provide (if not explicitly defined in the code).
*
* @param {string=} opt_message Optional message to add to the error that's

@@ -162,44 +263,2 @@ * raised when used in production code.

/**
* Builds an object structure for the provided namespace path,
* ensuring that names that already exist are not overwritten. For
* example:
* "a.b.c" -> a = {};a.b={};a.b.c={};
* Used by goog.provide and goog.exportSymbol.
* @param {string} name name of the object that this file defines.
* @param {*=} opt_object the object to expose at the end of the path.
* @param {Object=} opt_objectToExportTo The object to add the path to; default
* is |goog.global|.
* @private
*/
goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
var parts = name.split('.');
var cur = opt_objectToExportTo || goog.global;
// Internet Explorer exhibits strange behavior when throwing errors from
// methods externed in this manner. See the testExportSymbolExceptions in
// base_test.html for an example.
if (!(parts[0] in cur) && cur.execScript) {
cur.execScript('var ' + parts[0]);
}
// Certain browsers cannot parse code in the form for((a in b); c;);
// This pattern is produced by the JSCompiler when it collapses the
// statement above into the conditional loop below. To prevent this from
// happening, use a for-loop and reserve the init logic as below.
// Parentheses added to eliminate strict JS warning in Firefox.
for (var part; parts.length && (part = parts.shift());) {
if (!parts.length && goog.isDef(opt_object)) {
// last part and we have an object; use it
cur[part] = opt_object;
} else if (cur[part]) {
cur = cur[part];
} else {
cur = cur[part] = {};
}
}
};
/**
* Returns an object based on its fully qualified external name. If you are

@@ -253,3 +312,3 @@ * using a compilation pass that renames property names beware that using this

goog.addDependency = function(relPath, provides, requires) {
if (!COMPILED) {
if (goog.DEPENDENCIES_ENABLED) {
var provide, require;

@@ -305,3 +364,3 @@ var path = relPath.replace(/\\/g, '/');

*/
goog.ENABLE_DEBUG_LOADER = true;
goog.define('goog.ENABLE_DEBUG_LOADER', true);

@@ -458,3 +517,10 @@

if (!COMPILED && goog.ENABLE_DEBUG_LOADER) {
/**
* True if goog.dependencies_ is available.
* @const {boolean}
*/
goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;
if (goog.DEPENDENCIES_ENABLED) {
/**

@@ -944,4 +1010,3 @@ * Object used to keep track of urls that have already been added. This

*/
goog.UID_PROPERTY_ = 'closure_uid_' +
Math.floor(Math.random() * 2147483648).toString(36);
goog.UID_PROPERTY_ = 'closure_uid_' + ((Math.random() * 1e9) >>> 0);

@@ -1073,4 +1138,4 @@

*
* @param {Function} fn A function to partially apply.
* @param {Object|undefined} selfObj Specifies the object which |this| should
* @param {?function(this:T, ...)} fn A function to partially apply.
* @param {T} selfObj Specifies the object which |this| should
* point to when the function is run.

@@ -1081,2 +1146,3 @@ * @param {...*} var_args Additional arguments that are partially

* invoked as a method of.
* @template T
* @suppress {deprecated} See above.

@@ -1152,3 +1218,3 @@ */

*/
goog.now = Date.now || (function() {
goog.now = (goog.TRUSTED_SITE && Date.now) || (function() {
// Unary plus operator converts its operand to a number which in the case of

@@ -1503,2 +1569,11 @@ // a date is done by calling getTime().

var caller = arguments.callee.caller;
if (goog.DEBUG) {
if (!caller) {
throw Error('arguments.caller not defined. goog.base() expects not ' +
'to be running in strict mode. See ' +
'http://www.ecma-international.org/ecma-262/5.1/#sec-C');
}
}
if (caller.superClass_) {

@@ -1505,0 +1580,0 @@ // This is a constructor. Call the superclass constructor.

@@ -191,6 +191,6 @@ // Copyright 2006 The Closure Library Authors. All Rights Reserved.

case 'string':
this.serializeString_((/** @type {string} */ object), sb);
this.serializeString_(/** @type {string} */ (object), sb);
break;
case 'number':
this.serializeNumber_((/** @type {number} */ object), sb);
this.serializeNumber_(/** @type {number} */ (object), sb);
break;

@@ -209,3 +209,3 @@ case 'boolean':

if (goog.isArray(object)) {
this.serializeArray((/** @type {!Array} */ object), sb);
this.serializeArray(/** @type {!Array} */ (object), sb);
break;

@@ -216,3 +216,3 @@ }

// need is not very big
this.serializeObject_((/** @type {Object} */ object), sb);
this.serializeObject_(/** @type {Object} */ (object), sb);
break;

@@ -219,0 +219,0 @@ case 'function':

@@ -43,3 +43,3 @@ // Copyright 2006 The Closure Library Authors. All Rights Reserved.

*/
goog.net.XmlHttp.ASSUME_NATIVE_XHR = false;
goog.define('goog.net.XmlHttp.ASSUME_NATIVE_XHR', false);

@@ -127,4 +127,4 @@

goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(
(/** @type {function() : !(XMLHttpRequest|GearsHttpRequest)} */ factory),
(/** @type {function() : !Object}*/ optionsFactory)));
/** @type {function() : !(XMLHttpRequest|GearsHttpRequest)} */ (factory),
/** @type {function() : !Object}*/ (optionsFactory)));
};

@@ -131,0 +131,0 @@

@@ -44,3 +44,3 @@ // Copyright 2006 The Closure Library Authors. All Rights Reserved.

* @param {Object.<K,V>} obj The object over which to iterate.
* @param {function(this:T,K,?,Object.<K,V>):boolean} f The function to call
* @param {function(this:T,V,?,Object.<K,V>):boolean} f The function to call
* for every element. This

@@ -78,3 +78,3 @@ * function takes 3 arguments (the element, the index and the object)

* @param {T=} opt_obj This is used as the 'this' object within f.
* @return {!Object.<T,R>} a new object with the results from f.
* @return {!Object.<K,R>} a new object with the results from f.
* @template T,K,V,R

@@ -97,3 +97,3 @@ */

* @param {Object.<K,V>} obj The object to check.
* @param {function(this:T,K,?,Object.<K,V>):boolean} f The function to
* @param {function(this:T,V,?,Object.<K,V>):boolean} f The function to
* call for every element. This function

@@ -244,3 +244,3 @@ * takes 3 arguments (the element, the index and the object) and should

* @param {...(string|number|!Array.<number|string>)} var_args A number of keys
* (as strings, or nubmers, for array-like objects). Can also be
* (as strings, or numbers, for array-like objects). Can also be
* specified as a single array of keys.

@@ -418,3 +418,3 @@ * @return {*} The resulting value. If, at any point, the value for a key

* @param {string} key The key to add.
* @param {K} value The value to add.
* @param {V} value The value to add.
* @template K,V

@@ -421,0 +421,0 @@ */

@@ -86,2 +86,14 @@ // Copyright 2006 The Closure Library Authors. All Rights Reserved.

/**
* Case-insensitive equality checker.
* @param {string} str1 First string to check.
* @param {string} str2 Second string to check.
* @return {boolean} True if {@code str1} and {@code str2} are the same string,
* ignoring case.
*/
goog.string.caseInsensitiveEquals = function(str1, str2) {
return str1.toLowerCase() == str2.toLowerCase();
};
/**
* Does simple python-style string substitution.

@@ -95,14 +107,14 @@ * subs("foo%s hot%s", "bar", "dog") becomes "foobar hotdog".

goog.string.subs = function(str, var_args) {
// This appears to be slow, but testing shows it compares more or less
// equivalent to the regex.exec method.
for (var i = 1; i < arguments.length; i++) {
// We cast to String in case an argument is a Function. Replacing $&, for
// example, with $$$& stops the replace from subsituting the whole match
// into the resultant string. $$$& in the first replace becomes $$& in the
// second, which leaves $& in the resultant string. Also:
// $$, $`, $', $n $nn
var replacement = String(arguments[i]).replace(/\$/g, '$$$$');
str = str.replace(/\%s/, replacement);
var splitParts = str.split('%s');
var returnString = '';
var subsArguments = Array.prototype.slice.call(arguments, 1);
while (subsArguments.length &&
// Replace up to the last split part. We are inserting in the
// positions between split parts.
splitParts.length > 1) {
returnString += splitParts.shift() + subsArguments.shift();
}
return str;
return returnString + splitParts.join('%s'); // Join unused '%s'
};

@@ -1199,2 +1211,30 @@

/**
* Returns whether the given string is lower camel case (e.g. "isFooBar").
*
* Note that this assumes the string is entirely letters.
* @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms
*
* @param {string} str String to test.
* @return {boolean} Whether the string is lower camel case.
*/
goog.string.isLowerCamelCase = function(str) {
return /^[a-z]+([A-Z][a-z]*)*$/.test(str);
};
/**
* Returns whether the given string is upper camel case (e.g. "FooBarBaz").
*
* Note that this assumes the string is entirely letters.
* @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms
*
* @param {string} str String to test.
* @return {boolean} Whether the string is upper camel case.
*/
goog.string.isUpperCamelCase = function(str) {
return /^([A-Z][a-z]*)+$/.test(str);
};
/**
* Converts a string from selector-case to camelCase (e.g. from

@@ -1302,1 +1342,41 @@ * "multi-part-string" to "multiPartString"), useful for converting

};
/**
* Splits a string on a separator a limited number of times.
*
* This implementation is more similar to Python or Java, where the limit
* parameter specifies the maximum number of splits rather than truncating
* the number of results.
*
* See http://docs.python.org/2/library/stdtypes.html#str.split
* See JavaDoc: http://goo.gl/F2AsY
* See Mozilla reference: http://goo.gl/dZdZs
*
* @param {string} str String to split.
* @param {string} separator The separator.
* @param {number} limit The limit to the number of splits. The resulting array
* will have a maximum length of limit+1. Negative numbers are the same
* as zero.
* @return {!Array.<string>} The string, split.
*/
goog.string.splitLimit = function(str, separator, limit) {
var parts = str.split(separator);
var returnVal = [];
// Only continue doing this while we haven't hit the limit and we have
// parts left.
while (limit > 0 && parts.length) {
returnVal.push(parts.shift());
limit--;
}
// If there are remaining parts, append them to the end.
if (parts.length) {
returnVal.push(parts.join(separator));
}
return returnVal;
};

@@ -22,5 +22,6 @@ // Copyright 2006 The Closure Library Authors. All Rights Reserved.

* This file contains an implementation of a Map structure. It implements a lot
* of the methods used in goog.structs so those functions work on hashes. For
* convenience with common usage the methods accept any type for the key, though
* internally they will be cast to strings.
* of the methods used in goog.structs so those functions work on hashes. This
* is best suited for complex key types. For simple keys such as numbers and
* strings, and where special names like __proto__ are not a concern, consider
* using the lighter-weight utilities in goog.object.
*/

@@ -34,3 +35,2 @@

goog.require('goog.object');
goog.require('goog.structs');

@@ -37,0 +37,0 @@

@@ -153,3 +153,3 @@ // Copyright 2006 The Closure Library Authors. All Rights Reserved.

} else if (goog.isArrayLike(col)) {
goog.array.clear((/** @type {goog.array.ArrayLike} */ col));
goog.array.clear(/** @type {goog.array.ArrayLike} */ (col));
} else {

@@ -156,0 +156,0 @@ goog.object.clear(col);

@@ -24,3 +24,3 @@ // Copyright 2006 The Closure Library Authors. All Rights Reserved.

* Implements RFC 3986 for parsing/formatting URIs.
* http://gbiv.com/protocols/uri/rfc/rfc3986.html
* http://www.ietf.org/rfc/rfc3986.txt
*

@@ -42,2 +42,3 @@ * Some changes have been made to the interface (more like .NETs), though the

goog.require('goog.uri.utils.ComponentIndex');
goog.require('goog.uri.utils.StandardQueryParam');

@@ -254,5 +255,6 @@

/**
* Resolves a relative url string to a this base uri.
* Resolves the given relative URI (a goog.Uri object), using the URI
* represented by this instance as the base URI.
*
* There are several kinds of relative urls:<br>
* There are several kinds of relative URIs:<br>
* 1. foo - replaces the last part of the path, the whole query and fragment<br>

@@ -264,6 +266,6 @@ * 2. /foo - replaces the the path, the query and fragment<br>

*
* Additionally, if relative url has a non-empty path, all ".." and "."
* Additionally, if relative URI has a non-empty path, all ".." and "."
* segments will be resolved, as described in RFC 3986.
*
* @param {goog.Uri} relativeUri The relative url to resolve.
* @param {goog.Uri} relativeUri The relative URI to resolve.
* @return {!goog.Uri} The resolved URI.

@@ -1254,3 +1256,3 @@ */

* it will be included multiple times in the returned array
* @return {!Array} All the keys of the parameters.
* @return {!Array.<string>} All the keys of the parameters.
*/

@@ -1257,0 +1259,0 @@ goog.Uri.QueryData.prototype.getKeys = function() {

@@ -42,3 +42,3 @@ // Copyright 2008 The Closure Library Authors. All Rights Reserved.

* Uses features of RFC 3986 for parsing/formatting URIs:
* http://gbiv.com/protocols/uri/rfc/rfc3986.html
* http://www.ietf.org/rfc/rfc3986.txt
*

@@ -131,3 +131,3 @@ * @author gboyer@google.com (Garrett Boyer) - The "lightened" design.

*
* {@link http://www.gbiv.com/protocols/uri/rfc/rfc3986.html#RFC2234} says
* {@link http://www.ietf.org/rfc/rfc3986.txt} says in Appendix B
* As the "first-match-wins" algorithm is identical to the "greedy"

@@ -200,6 +200,5 @@ * disambiguation method used by POSIX regular expressions, it is natural and

'(?:([^/?#]*)@)?' + // userInfo
'([\\w\\d\\-\\u0100-\\uffff.%]*)' + // domain - restrict to letters,
// digits, dashes, dots, percent
// escapes, and unicode characters.
'([^/#?]*?)' + // domain
'(?::([0-9]+))?' + // port
'(?=[/#?]|$)' + // authority-terminating character
')?' +

@@ -243,2 +242,3 @@ '([^?#]+)?' + // path

goog.uri.utils.split = function(uri) {
goog.uri.utils.phishingProtection_();

@@ -251,5 +251,55 @@ // See @return comment -- never null.

/**
* Safari has a nasty bug where if you have an http URL with a username, e.g.,
* http://evil.com%2F@google.com/
* Safari will report that window.location.href is
* http://evil.com/google.com/
* so that anyone who tries to parse the domain of that URL will get
* the wrong domain. We've seen exploits where people use this to trick
* Safari into loading resources from evil domains.
*
* To work around this, we run a little "Safari phishing check", and throw
* an exception if we see this happening.
*
* There is no convenient place to put this check. We apply it to
* anyone doing URI parsing on Webkit. We're not happy about this, but
* it fixes the problem.
*
* This should be removed once Safari fixes their bug.
*
* Exploit reported by Masato Kinugawa.
*
* @type {boolean}
* @private
*/
goog.uri.utils.needsPhishingProtection_ = goog.userAgent.WEBKIT;
/**
* Check to see if the user is being phished.
* @private
*/
goog.uri.utils.phishingProtection_ = function() {
if (goog.uri.utils.needsPhishingProtection_) {
// Turn protection off, so that we don't recurse.
goog.uri.utils.needsPhishingProtection_ = false;
// Use quoted access, just in case the user isn't using location externs.
var location = goog.global['location'];
if (location) {
var href = location['href'];
if (href) {
var domain = goog.uri.utils.getDomain(href);
if (domain && domain != location['hostname']) {
// Phishing attack
goog.uri.utils.needsPhishingProtection_ = true;
throw Error();
}
}
}
}
};
/**
* @param {?string} uri A possibly null string.

@@ -754,9 +804,13 @@ * @return {?string} The string URI-decoded, or null if uri is null.

* @param {string} key The key, which must already be URI encoded.
* @param {*} value The value, which will be stringized and encoded (assumed
* not already to be encoded).
* @param {*=} opt_value The value, which will be stringized and encoded
* (assumed not already to be encoded). If omitted, undefined, or null, the
* key will be added as a valueless parameter.
* @return {string} The URI with the query parameter added.
*/
goog.uri.utils.appendParam = function(uri, key, value) {
return goog.uri.utils.appendQueryData_(
[uri, '&', key, '=', goog.string.urlEncode(value)]);
goog.uri.utils.appendParam = function(uri, key, opt_value) {
var paramArr = [uri, '&', key];
if (goog.isDefAndNotNull(opt_value)) {
paramArr.push('=', goog.string.urlEncode(opt_value));
}
return goog.uri.utils.appendQueryData_(paramArr);
};

@@ -763,0 +817,0 @@

@@ -28,3 +28,3 @@ // Copyright 2008 The Closure Library Authors. All Rights Reserved.

*/
goog.userAgent.product.ASSUME_FIREFOX = false;
goog.define('goog.userAgent.product.ASSUME_FIREFOX', false);

@@ -35,3 +35,3 @@

*/
goog.userAgent.product.ASSUME_CAMINO = false;
goog.define('goog.userAgent.product.ASSUME_CAMINO', false);

@@ -43,3 +43,3 @@

*/
goog.userAgent.product.ASSUME_IPHONE = false;
goog.define('goog.userAgent.product.ASSUME_IPHONE', false);

@@ -51,3 +51,3 @@

*/
goog.userAgent.product.ASSUME_IPAD = false;
goog.define('goog.userAgent.product.ASSUME_IPAD', false);

@@ -59,3 +59,3 @@

*/
goog.userAgent.product.ASSUME_ANDROID = false;
goog.define('goog.userAgent.product.ASSUME_ANDROID', false);

@@ -66,3 +66,3 @@

*/
goog.userAgent.product.ASSUME_CHROME = false;
goog.define('goog.userAgent.product.ASSUME_CHROME', false);

@@ -73,3 +73,3 @@

*/
goog.userAgent.product.ASSUME_SAFARI = false;
goog.define('goog.userAgent.product.ASSUME_SAFARI', false);

@@ -76,0 +76,0 @@

@@ -31,3 +31,3 @@ // Copyright 2006 The Closure Library Authors. All Rights Reserved.

*/
goog.userAgent.ASSUME_IE = false;
goog.define('goog.userAgent.ASSUME_IE', false);

@@ -38,3 +38,3 @@

*/
goog.userAgent.ASSUME_GECKO = false;
goog.define('goog.userAgent.ASSUME_GECKO', false);

@@ -45,3 +45,3 @@

*/
goog.userAgent.ASSUME_WEBKIT = false;
goog.define('goog.userAgent.ASSUME_WEBKIT', false);

@@ -53,3 +53,3 @@

*/
goog.userAgent.ASSUME_MOBILE_WEBKIT = false;
goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false);

@@ -60,10 +60,11 @@

*/
goog.userAgent.ASSUME_OPERA = false;
goog.define('goog.userAgent.ASSUME_OPERA', false);
/**
* @define {boolean} Whether the {@code goog.userAgent.isVersion} function will
* return true for any version.
* @define {boolean} Whether the
* {@code goog.userAgent.isVersionOrHigher}
* function will return true for any version.
*/
goog.userAgent.ASSUME_ANY_VERSION = false;
goog.define('goog.userAgent.ASSUME_ANY_VERSION', false);

@@ -256,3 +257,3 @@

*/
goog.userAgent.ASSUME_MAC = false;
goog.define('goog.userAgent.ASSUME_MAC', false);

@@ -264,3 +265,3 @@

*/
goog.userAgent.ASSUME_WINDOWS = false;
goog.define('goog.userAgent.ASSUME_WINDOWS', false);

@@ -272,3 +273,3 @@

*/
goog.userAgent.ASSUME_LINUX = false;
goog.define('goog.userAgent.ASSUME_LINUX', false);

@@ -280,6 +281,24 @@

*/
goog.userAgent.ASSUME_X11 = false;
goog.define('goog.userAgent.ASSUME_X11', false);
/**
* @define {boolean} Whether the user agent is running on Android.
*/
goog.define('goog.userAgent.ASSUME_ANDROID', false);
/**
* @define {boolean} Whether the user agent is running on an iPhone.
*/
goog.define('goog.userAgent.ASSUME_IPHONE', false);
/**
* @define {boolean} Whether the user agent is running on an iPad.
*/
goog.define('goog.userAgent.ASSUME_IPAD', false);
/**
* @type {boolean}

@@ -292,3 +311,6 @@ * @private

goog.userAgent.ASSUME_LINUX ||
goog.userAgent.ASSUME_X11;
goog.userAgent.ASSUME_X11 ||
goog.userAgent.ASSUME_ANDROID ||
goog.userAgent.ASSUME_IPHONE ||
goog.userAgent.ASSUME_IPAD;

@@ -334,2 +356,26 @@

'X11');
// Need user agent string for Android/IOS detection
var ua = goog.userAgent.getUserAgentString();
/**
* Whether the user agent is running on Android.
* @type {boolean}
* @private
*/
goog.userAgent.detectedAndroid_ = !!ua && ua.indexOf('Android') >= 0;
/**
* Whether the user agent is running on an iPhone.
* @type {boolean}
* @private
*/
goog.userAgent.detectedIPhone_ = !!ua && ua.indexOf('iPhone') >= 0;
/**
* Whether the user agent is running on an iPad.
* @type {boolean}
* @private
*/
goog.userAgent.detectedIPad_ = !!ua && ua.indexOf('iPad') >= 0;
};

@@ -376,2 +422,26 @@

/**
* Whether the user agent is running on Android.
* @type {boolean}
*/
goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ?
goog.userAgent.ASSUME_ANDROID : goog.userAgent.detectedAndroid_;
/**
* Whether the user agent is running on an iPhone.
* @type {boolean}
*/
goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ?
goog.userAgent.ASSUME_IPHONE : goog.userAgent.detectedIPhone_;
/**
* Whether the user agent is running on an iPad.
* @type {boolean}
*/
goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ?
goog.userAgent.ASSUME_IPAD : goog.userAgent.detectedIPad_;
/**
* @return {string} The string that describes the version number of the user

@@ -457,9 +527,9 @@ * agent.

/**
* Cache for {@link goog.userAgent.isVersion}. Calls to compareVersions are
* surprisingly expensive and as a browsers version number is unlikely to change
* during a session we cache the results.
* @type {Object}
* Cache for {@link goog.userAgent.isVersionOrHigher}.
* Calls to compareVersions are surprisingly expensive and, as a browser's
* version number is unlikely to change during a session, we cache the results.
* @const
* @private
*/
goog.userAgent.isVersionCache_ = {};
goog.userAgent.isVersionOrHigherCache_ = {};

@@ -481,6 +551,6 @@

*/
goog.userAgent.isVersion = function(version) {
goog.userAgent.isVersionOrHigher = function(version) {
return goog.userAgent.ASSUME_ANY_VERSION ||
goog.userAgent.isVersionCache_[version] ||
(goog.userAgent.isVersionCache_[version] =
goog.userAgent.isVersionOrHigherCache_[version] ||
(goog.userAgent.isVersionOrHigherCache_[version] =
goog.string.compareVersions(goog.userAgent.VERSION, version) >= 0);

@@ -491,2 +561,12 @@ };

/**
* Deprecated alias to {@code goog.userAgent.isVersionOrHigher}.
* @param {string|number} version The version to check.
* @return {boolean} Whether the user agent version is higher or the same as
* the given version.
* @deprecated Use goog.userAgent.isVersionOrHigher().
*/
goog.userAgent.isVersion = goog.userAgent.isVersionOrHigher;
/**
* Whether the IE effective document mode is higher or the same as the given

@@ -500,3 +580,3 @@ * document mode version.

*/
goog.userAgent.isDocumentMode = function(documentMode) {
goog.userAgent.isDocumentModeOrHigher = function(documentMode) {
return goog.userAgent.IE && goog.userAgent.DOCUMENT_MODE >= documentMode;

@@ -507,2 +587,11 @@ };

/**
* Deprecated alias to {@code goog.userAgent.isDocumentModeOrHigher}.
* @param {number} version The version to check.
* @return {boolean} Whether the IE effective document mode is higher or the
* same as the given version.
*/
goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;
/**
* For IE version < 7, documentMode is undefined, so attempt to use the

@@ -509,0 +598,0 @@ * CSS1Compat property to see if we are in standards mode. If we are in

@@ -17,2 +17,3 @@ // Copyright 2012 Software Freedom Conservancy. All Rights Reserved.

goog.require('webdriver.Capabilities');
goog.require('webdriver.process');

@@ -48,21 +49,9 @@

this.serverUrl_ = webdriver.process.getEnv(
webdriver.AbstractBuilder.SERVER_URL_ENV,
webdriver.AbstractBuilder.DEFAULT_SERVER_URL);
webdriver.AbstractBuilder.SERVER_URL_ENV);
/**
* ID of an existing WebDriver session that new clients should use.
* Initialized from the value of the
* {@link webdriver.AbstractBuilder.SESSION_ID_ENV} environment variable, but
* may be overridden using
* {@link webdriver.AbstractBuilder#usingSession}.
* @private {string}
*/
this.sessionId_ =
webdriver.process.getEnv(webdriver.AbstractBuilder.SESSION_ID_ENV);
/**
* The desired capabilities to use when creating a new session.
* @private {!Object.<*>}
* @private {!webdriver.Capabilities}
*/
this.capabilities_ = {};
this.capabilities_ = new webdriver.Capabilities();
};

@@ -72,16 +61,2 @@

/**
* Environment variable that defines the session ID of an existing WebDriver
* session to use when creating clients. If set, all new Builder instances will
* default to creating clients that use this session. To create a new session,
* use {@code #useExistingSession(boolean)}. The use of this environment
* variable requires that {@link webdriver.AbstractBuilder.SERVER_URL_ENV} also
* be set.
* @type {string}
* @const
* @see webdriver.process.getEnv
*/
webdriver.AbstractBuilder.SESSION_ID_ENV = 'wdsid';
/**
* Environment variable that defines the URL of the WebDriver server that

@@ -129,30 +104,10 @@ * should be used for all new WebDriver clients. This setting may be overridden

/**
* Configures the builder to create a client that will use an existing WebDriver
* session.
* @param {string} id The existing session ID to use.
* Sets the desired capabilities when requesting a new session. This will
* overwrite any previously set desired capabilities.
* @param {!(Object|webdriver.Capabilities)} capabilities The desired
* capabilities for a new session.
* @return {!webdriver.AbstractBuilder} This Builder instance for chain calling.
*/
webdriver.AbstractBuilder.prototype.usingSession = function(id) {
this.sessionId_ = id;
return this;
};
/**
* @return {string} The ID of the session, if any, this builder is configured
* to reuse.
*/
webdriver.AbstractBuilder.prototype.getSession = function() {
return this.sessionId_;
};
/**
* Sets the desired capabilities when requesting a new session.
* @param {!Object.<*>} capabilities The desired capabilities for a new
* session.
* @return {!webdriver.AbstractBuilder} This Builder instance for chain calling.
*/
webdriver.AbstractBuilder.prototype.withCapabilities = function(capabilities) {
this.capabilities_ = capabilities;
this.capabilities_ = new webdriver.Capabilities(capabilities);
return this;

@@ -163,3 +118,4 @@ };

/**
* @return {!Object.<*>} The current desired capabilities for this builder.
* @return {!webdriver.Capabilities} The current desired capabilities for this
* builder.
*/

@@ -166,0 +122,0 @@ webdriver.AbstractBuilder.prototype.getCapabilities = function() {

@@ -48,5 +48,3 @@ // Copyright 2012 Selenium comitters

/**
* @private {!Array.<{description: string, command: !webdriver.Command}>}
*/
/** @private {!Array.<{description: string, command: !webdriver.Command}>} */
this.actions_ = [];

@@ -111,3 +109,3 @@ };

// string, not the usual JSON object.
var id = (/** @type {!webdriver.WebElement} */location).toWireValue().
var id = /** @type {!webdriver.WebElement} */ (location).toWireValue().
then(function(value) {

@@ -149,3 +147,4 @@ return value['ELEMENT'];

if (opt_elementOrButton) {
this.mouseMove((/** @type {!webdriver.WebElement} */opt_elementOrButton));
this.mouseMove(
/** @type {!webdriver.WebElement} */ (opt_elementOrButton));
}

@@ -152,0 +151,0 @@ button = goog.isDef(opt_button) ? opt_button : webdriver.Button.LEFT;

@@ -158,3 +158,3 @@ // Copyright 2011 Software Freedom Conservancy. All Rights Reserved.

var response = bot.response.checkResponse(
(/** @type {!bot.response.ResponseObject} */goog.json.parse(json)));
/** @type {!bot.response.ResponseObject} */ (goog.json.parse(json)));
} catch (ex) {

@@ -161,0 +161,0 @@ command.callback(ex);

@@ -104,3 +104,3 @@ // Copyright 2011 Software Freedom Conservancy. All Rights Reserved.

callback(null, webdriver.http.Response.fromXmlHttpRequest(
(/** @type {!XMLHttpRequest} */xhr)));
/** @type {!XMLHttpRequest} */ (xhr)));
};

@@ -107,0 +107,0 @@

@@ -91,3 +91,3 @@ // Copyright 2011 Software Freedom Conservancy. All Rights Reserved.

responseObj = webdriver.http.Executor.parseHttpResponse_(
(/** @type {!webdriver.http.Response} */response));
/** @type {!webdriver.http.Response} */ (response));
} catch (ex) {

@@ -148,3 +148,3 @@ e = ex;

try {
return (/** @type {!bot.response.ResponseObject} */goog.json.parse(
return /** @type {!bot.response.ResponseObject} */ (goog.json.parse(
httpResponse.body));

@@ -151,0 +151,0 @@ } catch (ex) {

@@ -113,3 +113,3 @@ // Copyright 2011 Software Freedom Conservancy. All Rights Reserved.

}
return (/**@type {!webdriver.Locator} */locator);
return /**@type {!webdriver.Locator} */ (locator);
};

@@ -116,0 +116,0 @@

@@ -22,12 +22,26 @@ // Copyright 2013 Selenium comitters

/**
* Log level names from WebDriver's JSON wire protocol.
* @enum {string}
*/
webdriver.logging.LevelName = {
ALL: 'ALL',
DEBUG: 'DEBUG',
INFO: 'INFO',
WARNING: 'WARNING',
SEVERE: 'SEVERE',
OFF: 'OFF'
};
/**
* Logging levels.
* @enum {{value: number, name: string}}
* @enum {{value: number, name: webdriver.logging.LevelName}}
*/
webdriver.logging.Level = {
ALL: {value: Number.MIN_VALUE, name: 'ALL'},
DEBUG: {value: 700, name: 'DEBUG'},
INFO: {value: 800, name: 'INFO'},
WARNING: {value: 900, name: 'WARNING'},
SEVERE: {value: 1000, name: 'SEVERE'},
OFF: {value: Number.MAX_VALUE, name: 'OFF'}
ALL: {value: Number.MIN_VALUE, name: webdriver.logging.LevelName.ALL},
DEBUG: {value: 700, name: webdriver.logging.LevelName.DEBUG},
INFO: {value: 800, name: webdriver.logging.LevelName.INFO},
WARNING: {value: 900, name: webdriver.logging.LevelName.WARNING},
SEVERE: {value: 1000, name: webdriver.logging.LevelName.SEVERE},
OFF: {value: Number.MAX_VALUE, name: webdriver.logging.LevelName.OFF}
};

@@ -59,6 +73,11 @@

webdriver.logging.Type = {
/** Logs originating from the browser. */
BROWSER: 'browser',
/** Logs from a WebDriver client. */
CLIENT: 'client',
/** Logs from a WebDriver implementation. */
DRIVER: 'driver',
PROFILER: 'profiler',
/** Logs related to performance. */
PERFORMANCE: 'performance',
/** Logs from the remote server. */
SERVER: 'server'

@@ -69,2 +88,9 @@ };

/**
* A hash describing log preferences.
* @typedef {Object.<webdriver.logging.Type, webdriver.logging.LevelName>}
*/
webdriver.logging.Preferences;
/**
* A single log entry.

@@ -71,0 +97,0 @@ * @param {(!webdriver.logging.Level|string)} level The entry level.

@@ -51,2 +51,3 @@ // Copyright 2011 Software Freedom Conservancy. All Rights Reserved.

goog.provide('webdriver.promise.ControlFlow');
goog.provide('webdriver.promise.ControlFlow.Timer');
goog.provide('webdriver.promise.Deferred');

@@ -56,2 +57,3 @@ goog.provide('webdriver.promise.Promise');

goog.require('goog.array');
goog.require('goog.debug.Error');
goog.require('goog.object');

@@ -271,2 +273,13 @@ goog.require('webdriver.EventEmitter');

/**
* Removes all of the listeners previously registered on this deferred.
* @throws {Error} If this deferred has already been resolved.
*/
function removeAll() {
if (!isPending()) {
throw new Error('This Deferred has already been resolved.');
}
listeners = [];
}
/**
* Notifies all of the listeners registered with this Deferred that its state

@@ -447,6 +460,10 @@ * has changed. Will throw an error if this Deferred has already been

this.fulfill = fulfill;
/** @deprecated Use fulfill instead. This will be removed in 2.34.0 */
this.resolve = this.callback = fulfill;
this.reject = this.errback = reject;
// Only expose this function to our internal classes.
// TODO: find a cleaner way of handling this.
if (this instanceof webdriver.promise.Task_) {
this.removeAll = removeAll;
}
// Export symbols necessary for the contract on this object to work in

@@ -565,15 +582,5 @@ // compiled mode.

/**
* Creates a promise that has been resolved with the given value.
* @param {*=} opt_value The fulfilled promises's value.
* @return {!webdriver.promise.Promise} A fulfilled promise.
* @deprecated Use webdriver.promise.fulfilled(). This will be removed in
* Selenium 2.34.0.
*/
webdriver.promise.resolved = webdriver.promise.fulfilled;
/**
* Creates a promise that has been rejected with the given reason.
* @param {*=} opt_reason The rejection reason; may be any value, but is usually an
* Error or a string.
* @param {*=} opt_reason The rejection reason; may be any value, but is
* usually an Error or a string.
* @return {!webdriver.promise.Promise} The rejected promise.

@@ -837,7 +844,4 @@ */

*
* @param {{clearInterval: function(number),
* clearTimeout: function(number),
* setInterval: function(!Function, number): number,
* setTimeout: function(!Function, number): number}=} opt_timer
* The timer object to use. Should only be set for testing.
* @param {webdriver.promise.ControlFlow.Timer=} opt_timer The timer object
* to use. Should only be set for testing.
* @constructor

@@ -851,6 +855,3 @@ * @extends {webdriver.EventEmitter}

* The timer used by this instance.
* @type {{clearInterval: function(number),
* clearTimeout: function(number),
* setInterval: function(!Function, number): number,
* setTimeout: function(!Function, number): number}}
* @type {webdriver.promise.ControlFlow.Timer}
*/

@@ -872,7 +873,13 @@ this.timer = opt_timer || webdriver.promise.ControlFlow.defaultTimer;

/**
* @typedef {{clearInterval: function(number),
* clearTimeout: function(number),
* setInterval: function(!Function, number): number,
* setTimeout: function(!Function, number): number}}
*/
webdriver.promise.ControlFlow.Timer;
/**
* The default timer object, which uses the global timer functions.
* @type {{clearInterval: function(number),
* clearTimeout: function(number),
* setInterval: function(!Function, number): number,
* setTimeout: function(!Function, number): number}}
* @type {webdriver.promise.ControlFlow.Timer}
*/

@@ -1096,3 +1103,3 @@ webdriver.promise.ControlFlow.defaultTimer = (function() {

/** @type {!Error} */(e).stack = (e.stack || e.stackTrace || '') + [
/** @type {!Error} */(e).stack += [
'\n==== async task ====\n',

@@ -1299,3 +1306,3 @@ history.join('\n==== async task ====\n')

var markTaskComplete = goog.bind(function() {
this.history_.push(task);
this.history_.push(/** @type {!webdriver.promise.Task_} */ (task));
activeFrame.setPendingTask(null);

@@ -1355,3 +1362,3 @@ }, this);

this.activeFrame_ =
(/** @type {webdriver.promise.Frame_} */frame.getParent());
/** @type {webdriver.promise.Frame_} */ (frame.getParent());
}

@@ -1393,3 +1400,3 @@

// enough to recognize this.
var parent = (/** @type {webdriver.promise.Frame_} */
var parent = /** @type {webdriver.promise.Frame_} */ (
this.activeFrame_.getParent());

@@ -1468,7 +1475,11 @@ if (parent) {

} catch (ex) {
removeNewFrame();
removeNewFrame(new webdriver.promise.CanceledTaskError_(ex));
errback(ex);
}
function removeNewFrame() {
/**
* @param {webdriver.promise.CanceledTaskError_=} opt_err If provided, the
* error that triggered the removal of this frame.
*/
function removeNewFrame(opt_err) {
var parent = newFrame.getParent();

@@ -1478,2 +1489,6 @@ if (parent) {

}
if (opt_err) {
newFrame.cancelRemainingTasks(opt_err);
}
self.activeFrame_ = oldFrame;

@@ -1617,2 +1632,11 @@ }

var reject = goog.bind(this.reject, this);
var cancelRemainingTasks = goog.bind(this.cancelRemainingTasks, this);
/** @override */
this.reject = function(e) {
cancelRemainingTasks(new webdriver.promise.CanceledTaskError_(e));
reject(e);
};
/**

@@ -1675,2 +1699,42 @@ * @private {!Array.<!(webdriver.promise.Frame_|webdriver.promise.Task_)>}

/**
* Marks all of the tasks that are descendants of this frame in the execution
* tree as cancelled. This is necessary for callbacks scheduled asynchronous.
* For example:
*
* var someResult;
* webdriver.promise.createFlow(function(flow) {
* someResult = flow.execute(function() {});
* throw Error();
* }).addErrback(function(err) {
* console.log('flow failed: ' + err);
* someResult.then(function() {
* console.log('task succeeded!');
* }, function(err) {
* console.log('task failed! ' + err);
* });
* });
* // flow failed: Error: boom
* // task failed! CanceledTaskError: Task discarded due to a previous
* // task failure: Error: boom
*
* @param {!webdriver.promise.CanceledTaskError_} error The cancellation
* error.
*/
webdriver.promise.Frame_.prototype.cancelRemainingTasks = function(error) {
goog.array.forEach(this.children_, function(child) {
if (child instanceof webdriver.promise.Frame_) {
child.cancelRemainingTasks(error);
} else {
// None of the previously registered listeners should be notified that
// the task is being canceled, however, we need at least one errback
// to prevent the cancellation from bubbling up.
child.removeAll();
child.addErrback(goog.nullFunction);
child.cancel(error);
}
});
};
/**
* @return {webdriver.promise.Task_} The task currently executing

@@ -1808,3 +1872,3 @@ * within this frame, if any.

var ret = this.description_;
if (stack) {
if (stack.length) {
if (this.description_) {

@@ -1819,3 +1883,23 @@ ret += '\n';

/**
* Special error used to signal when a task is canceled because a previous
* task in the same frame failed.
* @param {*} err The error that caused the task cancellation.
* @constructor
* @extends {goog.debug.Error}
* @private
*/
webdriver.promise.CanceledTaskError_ = function(err) {
goog.base(this, 'Task discarded due to a previous task failure: ' + err);
};
goog.inherits(webdriver.promise.CanceledTaskError_, goog.debug.Error);
/** @override */
webdriver.promise.CanceledTaskError_.prototype.name = 'CanceledTaskError';
/**
* The default flow to use if no others are active.

@@ -1822,0 +1906,0 @@ * @private {!webdriver.promise.ControlFlow}

@@ -17,9 +17,11 @@ // Copyright 2011 Software Freedom Conservancy. All Rights Reserved.

goog.require('webdriver.Capabilities');
/**
* Contains information about a WebDriver session.
* @param {string} id The session ID.
* @param {!Object.<*>} capabilities A map describing the capabilities
* of this session.
* @param {!(Object|webdriver.Capabilities)} capabilities The session
* capabilities.
* @constructor

@@ -29,13 +31,7 @@ */

/**
* The session ID.
* @type {string}
*/
this.id = id;
/** @private {string} */
this.id_ = id;
/**
* A map describing the capabilities of this session.
* @type {!Object.<*>}
*/
this.capabilities = capabilities;
/** @private {!webdriver.Capabilities} */
this.caps_ = new webdriver.Capabilities().merge(capabilities);
};

@@ -48,3 +44,3 @@

webdriver.Session.prototype.getId = function() {
return this.id;
return this.id_;
};

@@ -54,6 +50,6 @@

/**
* @return {!Object.<*>} This session's capabilities.
* @return {!webdriver.Capabilities} This session's capabilities.
*/
webdriver.Session.prototype.getCapabilities = function() {
return this.capabilities;
return this.caps_;
};

@@ -68,3 +64,3 @@

webdriver.Session.prototype.getCapability = function(key) {
return this.capabilities[key];
return this.caps_.get(key);
};

@@ -79,3 +75,3 @@

webdriver.Session.prototype.toJSON = function() {
return this.id;
return this.getId();
};

@@ -27,2 +27,3 @@ // Copyright 2009 The Closure Library Authors. All Rights Reserved.

goog.require('goog.string');
goog.require('goog.userAgent');

@@ -43,11 +44,19 @@

/** @private {!Error} */
this.error_ = Error();
var error;
if (webdriver.stacktrace.CAN_CAPTURE_STACK_TRACE_) {
Error.captureStackTrace(this.error_, webdriver.stacktrace.Snapshot);
error = Error();
Error.captureStackTrace(error, webdriver.stacktrace.Snapshot);
} else {
// Opera and Firefox do not generate a stack frame for calls to Error(),
// so just remove 1 extra for the call to this constructor.
// Remove 1 extra frame for the call to this constructor.
this.slice_ += 1;
// IE will only create a stack trace when the Error is thrown.
// We use null.x() to throw an exception instead of throw this.error_
// because the closure compiler may optimize throws to a function call
// in an attempt to minimize the binary size which in turn has the side
// effect of adding an unwanted stack frame.
try {
null.x();
} catch (e) {
error = e;
}
}

@@ -60,3 +69,3 @@

*/
this.stack_ = this.error_.stack;
this.stack_ = webdriver.stacktrace.getStack_(error);
};

@@ -76,5 +85,20 @@

/**
* Whether the current browser supports stack traces.
*
* @type {boolean}
* @const
*/
webdriver.stacktrace.BROWSER_SUPPORTED = (function() {
try {
throw Error();
} catch (e) {
return !!e.stack;
}
})();
/**
* The parsed stack trace. This list is lazily generated the first time it is
* accessed.
* @private {?string}
* @private {Array.<!webdriver.stacktrace.Frame>}
*/

@@ -85,12 +109,10 @@ webdriver.stacktrace.Snapshot.prototype.parsedStack_ = null;

/**
* @return {string} The parsed stack trace.
* @return {!Array.<!webdriver.stacktrace.Frame>} The parsed stack trace.
*/
webdriver.stacktrace.Snapshot.prototype.getStacktrace = function() {
if (goog.isNull(this.parsedStack_)) {
var stack = webdriver.stacktrace.parse(this.error_);
this.parsedStack_ = webdriver.stacktrace.parse_(this.stack_);
if (this.slice_) {
stack = goog.array.slice(stack, this.slice_);
this.parsedStack_ = goog.array.slice(this.parsedStack_, this.slice_);
}
this.parsedStack_ = stack.join('\n');
delete this.error_;
delete this.slice_;

@@ -116,5 +138,4 @@ delete this.stack_;

* @constructor
* @private
*/
webdriver.stacktrace.Frame_ = function(context, name, alias, path) {
webdriver.stacktrace.Frame = function(context, name, alias, path) {

@@ -132,2 +153,20 @@ /** @private {string} */

this.path_ = path || '';
/** @private {string} */
this.url_ = this.path_;
/** @private {number} */
this.line_ = -1;
/** @private {number} */
this.column_ = -1;
if (path) {
var match = /:(\d+)(?::(\d+))?$/.exec(path);
if (match) {
this.line_ = Number(match[1]);
this.column = Number(match[2] || -1);
this.url_ = path.substr(0, match.index);
}
}
};

@@ -138,7 +177,7 @@

* Constant for an anonymous frame.
* @private {!webdriver.stacktrace.Frame_}
* @private {!webdriver.stacktrace.Frame}
* @const
*/
webdriver.stacktrace.ANONYMOUS_FRAME_ =
new webdriver.stacktrace.Frame_('', '', '', '');
new webdriver.stacktrace.Frame('', '', '', '');

@@ -150,3 +189,3 @@

*/
webdriver.stacktrace.Frame_.prototype.getName = function() {
webdriver.stacktrace.Frame.prototype.getName = function() {
return this.name_;

@@ -157,5 +196,29 @@ };

/**
* @return {string} The url or empty string if it is unknown.
*/
webdriver.stacktrace.Frame.prototype.getUrl = function() {
return this.url_;
};
/**
* @return {number} The line number if known or -1 if it is unknown.
*/
webdriver.stacktrace.Frame.prototype.getLine = function() {
return this.line_;
};
/**
* @return {number} The column number if known and -1 if it is unknown.
*/
webdriver.stacktrace.Frame.prototype.getColumn = function() {
return this.column_;
};
/**
* @return {boolean} Whether the stack frame contains an anonymous function.
*/
webdriver.stacktrace.Frame_.prototype.isAnonymous = function() {
webdriver.stacktrace.Frame.prototype.isAnonymous = function() {
return !this.name_ || this.context_ == '[object Object]';

@@ -171,3 +234,3 @@ };

*/
webdriver.stacktrace.Frame_.prototype.toString = function() {
webdriver.stacktrace.Frame.prototype.toString = function() {
var context = this.context_;

@@ -283,3 +346,3 @@ if (context && context !== 'new ') {

webdriver.stacktrace.URL_PATTERN_ =
'((?:http|https|file)://[^\\s)]+|javascript:.*)';
'((?:http|https|file)://[^\\s]+|javascript:.*)';

@@ -310,2 +373,13 @@

/**
* RegExp pattern for function names in the Firefox stack trace.
* Firefox has extended identifiers to deal with inner functions and anonymous
* functions: https://bugzilla.mozilla.org/show_bug.cgi?id=433529#c9
* @private {string}
* @const
*/
webdriver.stacktrace.FIREFOX_FUNCTION_NAME_PATTERN_ =
webdriver.stacktrace.IDENTIFIER_PATTERN_ + '[\\w./<$]*';
/**
* RegExp pattern for function call in the Firefox stack trace.

@@ -317,3 +391,3 @@ * Creates a submatch for the function name.

webdriver.stacktrace.FIREFOX_FUNCTION_CALL_PATTERN_ =
'(' + webdriver.stacktrace.IDENTIFIER_PATTERN_ + ')?' +
'(' + webdriver.stacktrace.FIREFOX_FUNCTION_NAME_PATTERN_ + ')?' +
'(?:\\(.*\\))?@';

@@ -367,2 +441,23 @@

/**
* RegExp pattern for function call in a Chakra (IE) stack trace. This
* expression allows for identifiers like 'Anonymous function', 'eval code',
* and 'Global code'.
* @private {string}
* @const
*/
webdriver.stacktrace.CHAKRA_FUNCTION_CALL_PATTERN_ = '(' +
webdriver.stacktrace.IDENTIFIER_PATTERN_ + '(?:\\s+\\w+)*)';
/**
* Regular expression for parsing on stack frame in Chakra (IE).
* @private {!RegExp}
* @const
*/
webdriver.stacktrace.CHAKRA_STACK_FRAME_REGEXP_ = new RegExp('^ at ' +
webdriver.stacktrace.CHAKRA_FUNCTION_CALL_PATTERN_ +
'\\s*(?:\\((.*)\\))$');
/**
* Placeholder for an unparsable frame in a stack trace generated by

@@ -412,3 +507,3 @@ * {@link goog.testing.stacktrace}.

* @param {string} frameStr The stack frame as string.
* @return {webdriver.stacktrace.Frame_} Stack frame object or null if the
* @return {webdriver.stacktrace.Frame} Stack frame object or null if the
* parsing failed.

@@ -420,3 +515,3 @@ * @private

if (m) {
return new webdriver.stacktrace.Frame_(
return new webdriver.stacktrace.Frame(
m[1] || m[2], m[3], m[4], m[5] || m[6]);

@@ -432,3 +527,3 @@ }

if (m) {
return new webdriver.stacktrace.Frame_('', m[1], '', m[2]);
return new webdriver.stacktrace.Frame('', m[1], '', m[2]);
}

@@ -438,5 +533,10 @@

if (m) {
return new webdriver.stacktrace.Frame_(m[2], m[1] || m[3], '', m[4]);
return new webdriver.stacktrace.Frame(m[2], m[1] || m[3], '', m[4]);
}
m = frameStr.match(webdriver.stacktrace.CHAKRA_STACK_FRAME_REGEXP_);
if (m) {
return new webdriver.stacktrace.Frame('', m[1], '', m[2]);
}
if (frameStr == webdriver.stacktrace.UNKNOWN_CLOSURE_FRAME_ ||

@@ -449,3 +549,3 @@ frameStr == webdriver.stacktrace.ANONYMOUS_CLOSURE_FRAME_) {

if (m) {
return new webdriver.stacktrace.Frame_(m[1], m[2], m[3], m[4] || m[5]);
return new webdriver.stacktrace.Frame(m[1], m[2], m[3], m[4] || m[5]);
}

@@ -460,3 +560,3 @@

* @param {string} frameStr The stack frame as string.
* @return {!webdriver.stacktrace.Frame_} Stack frame object.
* @return {!webdriver.stacktrace.Frame} Stack frame object.
* @private

@@ -476,3 +576,3 @@ */

}
return new webdriver.stacktrace.Frame_('', functionName, '', loc);
return new webdriver.stacktrace.Frame('', functionName, '', loc);
};

@@ -482,2 +582,21 @@

/**
* Get an error's stack trace with the error string trimmed.
* V8 prepends the string representation of an error to its stack trace.
* This function trims the string so that the stack trace can be parsed
* consistently with the other JS engines.
* @param {!(Error|goog.testing.JsUnitException)} error The error.
* @return {string} The stack trace string.
* @private
*/
webdriver.stacktrace.getStack_ = function(error) {
var stack = error.stack || error.stackTrace || '';
var errorStr = error + '\n';
if (goog.string.startsWith(stack, errorStr)) {
stack = stack.substring(errorStr.length);
}
return stack;
};
/**
* Formats an error's stack trace.

@@ -488,7 +607,17 @@ * @param {!(Error|goog.testing.JsUnitException)} error The error to format.

webdriver.stacktrace.format = function(error) {
var stack = webdriver.stacktrace.parse(error).join('\n');
var stack = webdriver.stacktrace.getStack_(error);
var frames = webdriver.stacktrace.parse_(stack);
// Older versions of IE simply return [object Error] for toString(), so
// only use that as a last resort.
var errorStr = '';
if (error.message) {
errorStr = (error.name ? error.name + ': ' : '') + error.message;
} else {
errorStr = error.toString();
}
// Ensure the error is in the V8 style with the error's string representation
// prepended to the stack.
error.stack = error.toString() + '\n' + stack;
error.stack = errorStr + '\n' + frames.join('\n');
return error;

@@ -500,9 +629,8 @@ };

* Parses an Error object's stack trace.
* @param {!(Error|goog.testing.JsUnitException)} error The error.
* @return {!Array.<webdriver.stacktrace.Frame_>} Stack frames. The
* @param {string} stack The stack trace.
* @return {!Array.<!webdriver.stacktrace.Frame>} Stack frames. The
* unrecognized frames will be nulled out.
* @private
*/
webdriver.stacktrace.parse = function(error) {
var stack = error.stack || error.stackTrace;
webdriver.stacktrace.parse_ = function(stack) {
if (!stack) {

@@ -512,11 +640,2 @@ return [];

// V8 prepends the string representation of an error to its stack trace.
// Remove this so the stack trace is parsed consistently with the other JS
// engines.
var errorStr = error + '\n';
if (goog.string.startsWith(stack, errorStr)) {
stack = stack.substring(errorStr.length);
}
var lines = stack.

@@ -528,3 +647,11 @@ replace(/\s*$/, '').

var frame = webdriver.stacktrace.parseStackFrame_(lines[i]);
frames.push(frame || webdriver.stacktrace.ANONYMOUS_FRAME_);
// The first two frames will be:
// webdriver.stacktrace.Snapshot()
// webdriver.stacktrace.get()
// In the case of Opera, sometimes an extra frame is injected in the next
// frame with a reported line number of zero. The next line detects that
// case and skips that frame.
if (!(goog.userAgent.OPERA && i == 2 && frame.getLine() == 0)) {
frames.push(frame || webdriver.stacktrace.ANONYMOUS_FRAME_);
}
}

@@ -539,3 +666,3 @@ return frames;

* this function.
* @return {string} The stack trace in canonical format.
* @return {!Array.<!webdriver.stacktrace.Frame>} The frames of the stack trace.
*/

@@ -542,0 +669,0 @@ webdriver.stacktrace.get = function() {

@@ -64,3 +64,3 @@ // Copyright 2013 Selenium committers

* Retrieves the external IP address for this host.
* @param {string} opt_family The IP family to retrieve. Defaults to "IPv4".
* @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4".
* @return {string} The IP address or undefined if not available.

@@ -75,3 +75,3 @@ */

* Retrieves a loopback address for this machine.
* @param {string} opt_family The IP family to retrieve. Defaults to "IPv4".
* @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4".
* @return {string} The IP address or undefined if not available.

@@ -78,0 +78,0 @@ */

@@ -55,3 +55,3 @@ // Copyright 2013 Selenium committers

return systemRange = range.addErrback(function() {
DEFAULT_IANA_RANGE;
return DEFAULT_IANA_RANGE;
});

@@ -73,3 +73,3 @@ }

} else {
result.resolve(stdout);
result.fulfill(stdout);
}

@@ -96,3 +96,3 @@ });

cmd = 'sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last' +
' | sed -e "s/.*:\s*//"';
' | sed -e "s/.*:\\s*//"';
}

@@ -159,3 +159,3 @@

if (e.code === 'EADDRINUSE') {
result.resolve(false);
result.fulfill(false);
} else {

@@ -168,3 +168,3 @@ result.reject(e);

server.close(function() {
result.resolve(true);
result.fulfill(true);
});

@@ -174,3 +174,3 @@ });

return result.promise;
};
}

@@ -200,3 +200,3 @@

if (isFree) {
deferredPort.resolve(port);
deferredPort.fulfill(port);
} else {

@@ -208,3 +208,3 @@ findPort();

});
};
}

@@ -211,0 +211,0 @@

{
"name": "selenium-webdriver",
"version": "2.33.0",
"version": "2.34.0",
"description": "The official WebDriver JavaScript bindings from the Selenium project",
"keywords": [
"automation",
"selenium",
"testing",
"webdriver",
"webdriverjs"
"automation",
"selenium",
"testing",
"webdriver",
"webdriverjs"
],

@@ -18,8 +18,14 @@ "homepage": "https://code.google.com/p/selenium/",

"repository": {
"type": "git",
"url": "https://code.google.com/p/selenium/"
"type": "git",
"url": "https://code.google.com/p/selenium/"
},
"engines": {
"node": ">= 0.8.x"
"node": ">= 0.8.x"
},
"devDependencies" : {
"mocha" : "~1.10.0"
},
"scripts": {
"test": "node_modules/mocha/bin/mocha -R list --recursive test"
}
}
# selenium-webdriver
## Installation
Install the latest published version using `npm`:
npm install selenium-webdriver
In addition to the npm package, you will to download the WebDriver
implementations you wish to utilize. As of 2.34.0, `selenium-webdriver`
natively supports the [ChromeDriver](https://code.google.com/p/chromedriver/downloads/list).
Simply download a copy and make sure it can be found on your `PATH`. The other
drivers (e.g. Firefox, Internet Explorer, and Safari), still require the
[standalone Selenium server](https://code.google.com/p/selenium/downloads/list).
### Running the tests
_(New in 2.34.0)_ To run the tests, you will need to download a copy of the
[ChromeDriver](https://code.google.com/p/chromedriver/downloads/list) and make
sure it can be found on your `PATH`.
npm test selenium-webdriver
To run the tests against multiple browsers, download the
[Selenium server](https://code.google.com/p/selenium/downloads/list) and
specify its location through the `SELENIUM_SERVER_JAR` environment variable.
You can use the `SELENIUM_BROWSER` environment variable to define a
comma-separated list of browsers you wish to test against. For example:
export SELENIUM_SERVER_JAR=path/to/selenium-server-standalone-2.33.0.jar
SELENIUM_BROWSER=chrome,firefox npm test selenium-webdriver
## Usage
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
withCapabilities({'browserName': 'firefox'}).
withCapabilities(webdriver.Capabilities.chrome()).
build();

@@ -8,0 +41,0 @@

@@ -1,2 +0,1 @@

// Copyright 2013 Selenium committers
// Copyright 2013 Software Freedom Conservancy

@@ -20,3 +19,5 @@ //

os = require('os'),
url = require('url');
path = require('path'),
url = require('url'),
util = require('util');

@@ -31,46 +32,63 @@ var promise = require('../').promise,

/**
* Manages the life and death of the Selenium standalone server. The server
* may be obtained from https://code.google.com/p/selenium/downloads/list.
* Configuration options for a DriverService instance.
* - port: The port to start the server on (must be > 0). If the port is
* provided as a promise, the service will wait for the promise to
* resolve before starting.
* - args: The arguments to pass to the service. If a promise is provided,
* the service will wait for it to resolve before starting.
* - path: The base path on the server for the WebDriver wire protocol
* (e.g. '/wd/hub'). Defaults to '/'.
* - env: The environment variables that should be visible to the server
* process. Defaults to inheriting the current process's environment.
* - stdio: IO configuration for the spawned server process. For more
* information, refer to the documentation of
* {@code child_process.spawn}.
*
* <p>The options argument accepts the following properties:
* <dl>
* <dt>jar
* <dd>Path to the Selenium server jar.
* <dt>port
* <dd>The port to start the server on, or 0 for any free port.
* Defaults to 0.
* <dt>jvmArgs
* <dd>Arguments to pass to the JVM.
* <dt>args
* <dd>Arguments to pass to the server.
* <dt>env
* <dd>Environment to run the server in. Defaults to the current environment.
* <dt>stdio
* <dd>The fd configuration for the child process, as defined by
* child_process.spawn. Defaults to 'ignore'.
* <dt>
* </dl>
* @typedef {{
* port: (number|!webdriver.promise.Promise.<number>),
* args: !(Array.<string>|webdriver.promise.Promise.<!Array.<string>>),
* path: (string|undefined),
* env: (!Object.<string, string>|undefined),
* stdio: (string|!Array.<string|number|!Stream|null|undefined>|undefined)
* }}
*/
var ServiceOptions;
/**
* Manages the life and death of a native executable WebDriver server.
*
* @param {!Object} options A hash describing the server parameters.
* @throws {Error} If the port is < 0.
* <p>It is expected that the driver server implements the
* <a href="http://code.google.com/p/selenium/wiki/JsonWireProtocol">WebDriver
* Wire Protocol</a>. Furthermore, the managed server should support multiple
* concurrent sessions, so that this class may be reused for multiple clients.
*
* @param {string} executable Path to the executable to run.
* @param {!ServiceOptions} options Configuration options for the service.
* @constructor
*/
function SeleniumServer(options) {
this.jar_ = options.jar;
this.port_ = options.port || 0;
this.jvmArgs_ = options.jvmArgs || [];
this.args_ = options.args || [];
this.env_ = options.env;
this.stdio_ = options.stdio || 'ignore';
function DriverService(executable, options) {
if (!this.jar_) {
throw Error('Path to the Selenium jar must be provided');
}
/** @private {string} */
this.executable_ = executable;
if (this.port_ < 0) {
throw Error('Port must be > 0: ' + this.port_);
}
};
/** @private {(number|!webdriver.promise.Promise.<number>)} */
this.port_ = options.port;
/**
* @private {!(Array.<string>|webdriver.promise.Promise.<!Array.<string>>)}
*/
this.args_ = options.args;
/** @private {string} */
this.path_ = options.path || '/';
/** @private {!Object.<string, string>} */
this.env_ = options.env || process.env;
/** @private {(string|!Array.<string|number|!Stream|null|undefined>)} */
this.stdio_ = options.stdio || 'ignore';
}
/**

@@ -81,7 +99,7 @@ * The default amount of time, in milliseconds, to wait for the server to

*/
SeleniumServer.DEFAULT_START_TIMEOUT_MS = 30 * 1000;
DriverService.DEFAULT_START_TIMEOUT_MS = 30 * 1000;
/** @private {child_process.ChildProcess} */
SeleniumServer.prototype.process_ = null;
DriverService.prototype.process_ = null;

@@ -94,3 +112,3 @@

*/
SeleniumServer.prototype.address_ = null;
DriverService.prototype.address_ = null;

@@ -103,3 +121,3 @@

*/
SeleniumServer.prototype.shutdownHook_ = null;
DriverService.prototype.shutdownHook_ = null;

@@ -110,5 +128,5 @@

* the server's address.
* @throws {Error} If the SeleniumServer has not been started.
* @throws {Error} If the server has not been started.
*/
SeleniumServer.prototype.address = function() {
DriverService.prototype.address = function() {
if (this.address_) {

@@ -122,2 +140,10 @@ return this.address_;

/**
* @return {boolean} Whether the underlying service process is running.
*/
DriverService.prototype.isRunning = function() {
return !!this.address_;
};
/**
* Starts the server if it is not already running.

@@ -131,3 +157,3 @@ * @param {number=} opt_timeoutMs How long to wait, in milliseconds, for the

*/
SeleniumServer.prototype.start = function(opt_timeoutMs) {
DriverService.prototype.start = function(opt_timeoutMs) {
if (this.address_) {

@@ -137,47 +163,49 @@ return this.address_;

var timeout = opt_timeoutMs || SeleniumServer.DEFAULT_START_TIMEOUT_MS;
var port = this.port_ || portprober.findFreePort();
var timeout = opt_timeoutMs || DriverService.DEFAULT_START_TIMEOUT_MS;
var self = this;
this.address_ = promise.defer(); // TODO(jleyba): handle cancellation.
this.address_.resolve(promise.when(port, function(port) {
var args = self.jvmArgs_.concat(
'-jar', self.jar_, '-port', port, self.args_);
this.address_ = promise.defer();
this.address_.fulfill(promise.when(this.port_, function(port) {
if (port <= 0) {
throw Error('Port must be > 0: ' + port);
}
return promise.when(self.args_, function(args) {
self.process_ = spawn(self.executable_, args, {
env: self.env_,
stdio: self.stdio_
}).once('exit', onServerExit);
self.process_ = spawn('java', args, {
env: self.env_ || process.env,
stdio: self.stdio_
}).once('exit', function(code, signal) {
if (self.address_.isPending()) {
var error = Error(code == null ?
('Server was killed with ' + signal) :
('Server exited with ' + code));
self.address_.reject(error);
}
process.once('exit', killServer);
if (self.shutdownHook_ && self.shutdownHook_.isPending()) {
self.shutdownHook_.resolve();
}
var serverUrl = url.format({
protocol: 'http',
hostname: net.getAddress() || net.getLoopbackAddress(),
port: port,
pathname: self.path_
});
self.shutdownHook_ = null;
self.address_ = null;
self.process_ = null;
process.removeListener('exit', killServer);
return httpUtil.waitForServer(serverUrl, timeout).then(function() {
return serverUrl;
});
});
}));
process.once('exit', killServer);
return this.address_;
var serverUrl = url.format({
protocol: 'http',
hostname: net.getAddress(),
port: port,
pathname: '/wd/hub'
});
function onServerExit(code, signal) {
if (self.address_.isPending()) {
self.address_.reject(code == null ?
Error('Server was killed with ' + signal) :
Error('Server exited with ' + code));
}
return httpUtil.waitForServer(serverUrl, timeout).then(function() {
return serverUrl;
});
}));
if (self.shutdownHook_ && self.shutdownHook_.isPending()) {
self.shutdownHook_.fulfill();
}
return this.address_;
self.shutdownHook_ = null;
self.address_ = null;
self.process_ = null;
process.removeListener('exit', killServer);
}

@@ -192,11 +220,11 @@ function killServer() {

/**
* Stops the server if it is currently running. This function will kill the
* server immediately. To synchronize with the active control flow, use
* {@link #stop}.
* Stops the service if it is not currently running. This function will kill
* the server immediately. To synchronize with the active control flow, use
* {@link #stop()}.
* @return {!webdriver.promise.Promise} A promise that will be resolved when
* the server has been stopped.
*/
SeleniumServer.prototype.kill = function() {
DriverService.prototype.kill = function() {
if (!this.address_) {
return promise.resolved(); // Not currently running.
return promise.fulfilled(); // Not currently running.
}

@@ -206,3 +234,4 @@

// No process: still starting; wait on address.
// Otherwise, kill process now. Exit handler will resolve shutdown hook.
// Otherwise, kill the process now. Exit handler will resolve the
// shutdown hook.
if (this.process_) {

@@ -228,9 +257,47 @@ this.shutdownHook_ = promise.defer();

*/
SeleniumServer.prototype.stop = function() {
DriverService.prototype.stop = function() {
return promise.controlFlow().execute(this.kill.bind(this));
};
/**
* Manages the life and death of the Selenium standalone server. The server
* may be obtained from https://code.google.com/p/selenium/downloads/list.
* @param {string} jar Path to the Selenium server jar.
* @param {!ServiceOptions} options Configuration options for the server.
* @throws {Error} If an invalid port is specified.
* @constructor
* @extends {DriverService}
*/
function SeleniumServer(jar, options) {
if (options.port < 0)
throw Error('Port must be >= 0: ' + options.port);
var port = options.port || portprober.findFreePort();
var args = promise.when(options.args || [], function(args) {
return promise.when(port, function(port) {
return args.concat('-jar', jar, '-port', port);
});
});
DriverService.call(this, 'java', {
port: port,
args: args,
path: '/wd/hub',
env: options.env,
stdio: options.stdio
});
}
util.inherits(SeleniumServer, DriverService);
// PUBLIC API
/** @constructor */
exports.DriverService = DriverService;
/** @constructor */
exports.SeleniumServer = SeleniumServer;

@@ -78,4 +78,2 @@ // Copyright 2013 Selenium committers

var assert = require('assert');
var flow = require('..').promise.controlFlow();

@@ -133,24 +131,27 @@

* if the test should be suppressed. This function MUST be synchronous.
* @return {!Object} A wrapped version of exports.it that ignores tests as
* indicated by the predicate.
* @return {!Object} An object with wrapped versions of exports.it and
* exports.describe that ignore tests as indicated by the predicate.
*/
function ignore(predicateFn) {
var it = function(title, fn) {
if (predicateFn()) {
exports.xit(title, fn);
} else {
exports.it(title, fn);
}
};
var describe = wrap(exports.xdescribe, exports.describe);
describe.only = wrap(exports.xdescribe, exports.describe.only);
it.only = function(title, fn) {
if (predicateFn()) {
exports.xit(title, fn);
} else {
exports.it(title, fn);
}
var it = wrap(exports.xit, exports.it);
it.only = wrap(exports.xit, exports.it.only);
return {
describe: describe,
it: it
};
return {it: it};
};
function wrap(onSkip, onRun) {
return function(title, fn) {
if (predicateFn()) {
onSkip(title, fn);
} else {
onRun(title, fn);
}
};
}
}

@@ -163,2 +164,3 @@

exports.xdescribe = global.xdescribe;
exports.describe.skip = global.describe.skip;

@@ -165,0 +167,0 @@ exports.after = wrapped(global.after);

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc