451 lines
12 KiB
JavaScript
451 lines
12 KiB
JavaScript
|
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||
|
// or more contributor license agreements. See the NOTICE file
|
||
|
// distributed with this work for additional information
|
||
|
// regarding copyright ownership. The SFC licenses this file
|
||
|
// to you under the Apache License, Version 2.0 (the
|
||
|
// "License"); you may not use this file except in compliance
|
||
|
// with the License. You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing,
|
||
|
// software distributed under the License is distributed on an
|
||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
// KIND, either express or implied. See the License for the
|
||
|
// specific language governing permissions and limitations
|
||
|
// under the License.
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
/**
|
||
|
* @fileoverview Defines types related to describing the capabilities of a
|
||
|
* WebDriver session.
|
||
|
*/
|
||
|
|
||
|
const Symbols = require('./symbols');
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Recognized browser names.
|
||
|
* @enum {string}
|
||
|
*/
|
||
|
const Browser = {
|
||
|
ANDROID: 'android',
|
||
|
CHROME: 'chrome',
|
||
|
EDGE: 'MicrosoftEdge',
|
||
|
FIREFOX: 'firefox',
|
||
|
IE: 'internet explorer',
|
||
|
INTERNET_EXPLORER: 'internet explorer',
|
||
|
IPAD: 'iPad',
|
||
|
IPHONE: 'iPhone',
|
||
|
OPERA: 'opera',
|
||
|
PHANTOM_JS: 'phantomjs',
|
||
|
SAFARI: 'safari',
|
||
|
HTMLUNIT: 'htmlunit'
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Common Capability keys.
|
||
|
* @enum {string}
|
||
|
*/
|
||
|
const Capability = {
|
||
|
|
||
|
/**
|
||
|
* Indicates whether a driver should accept all SSL certs by default. This
|
||
|
* capability only applies when requesting a new session. To query whether
|
||
|
* a driver can handle insecure SSL certs, see {@link #SECURE_SSL}.
|
||
|
*/
|
||
|
ACCEPT_SSL_CERTS: 'acceptSslCerts',
|
||
|
|
||
|
|
||
|
/**
|
||
|
* The browser name. Common browser names are defined in the {@link Browser}
|
||
|
* enum.
|
||
|
*/
|
||
|
BROWSER_NAME: 'browserName',
|
||
|
|
||
|
/**
|
||
|
* Defines how elements should be scrolled into the viewport for interaction.
|
||
|
* This capability will be set to zero (0) if elements are aligned with the
|
||
|
* top of the viewport, or one (1) if aligned with the bottom. The default
|
||
|
* behavior is to align with the top of the viewport.
|
||
|
*/
|
||
|
ELEMENT_SCROLL_BEHAVIOR: 'elementScrollBehavior',
|
||
|
|
||
|
/**
|
||
|
* Whether the driver is capable of handling modal alerts (e.g. alert,
|
||
|
* confirm, prompt). To define how a driver <i>should</i> handle alerts,
|
||
|
* use {@link #UNEXPECTED_ALERT_BEHAVIOR}.
|
||
|
*/
|
||
|
HANDLES_ALERTS: 'handlesAlerts',
|
||
|
|
||
|
/**
|
||
|
* Key for the logging driver logging preferences.
|
||
|
*/
|
||
|
LOGGING_PREFS: 'loggingPrefs',
|
||
|
|
||
|
/**
|
||
|
* Whether this session generates native events when simulating user input.
|
||
|
*/
|
||
|
NATIVE_EVENTS: 'nativeEvents',
|
||
|
|
||
|
/**
|
||
|
* Describes the platform the browser is running on. Will be one of
|
||
|
* ANDROID, IOS, LINUX, MAC, UNIX, or WINDOWS. When <i>requesting</i> a
|
||
|
* session, ANY may be used to indicate no platform preference (this is
|
||
|
* semantically equivalent to omitting the platform capability).
|
||
|
*/
|
||
|
PLATFORM: 'platform',
|
||
|
|
||
|
/**
|
||
|
* Describes the proxy configuration to use for a new WebDriver session.
|
||
|
*/
|
||
|
PROXY: 'proxy',
|
||
|
|
||
|
/** Whether the driver supports changing the brower's orientation. */
|
||
|
ROTATABLE: 'rotatable',
|
||
|
|
||
|
/**
|
||
|
* Whether a driver is only capable of handling secure SSL certs. To request
|
||
|
* that a driver accept insecure SSL certs by default, use
|
||
|
* {@link #ACCEPT_SSL_CERTS}.
|
||
|
*/
|
||
|
SECURE_SSL: 'secureSsl',
|
||
|
|
||
|
/** Whether the driver supports manipulating the app cache. */
|
||
|
SUPPORTS_APPLICATION_CACHE: 'applicationCacheEnabled',
|
||
|
|
||
|
/** Whether the driver supports locating elements with CSS selectors. */
|
||
|
SUPPORTS_CSS_SELECTORS: 'cssSelectorsEnabled',
|
||
|
|
||
|
/** Whether the browser supports JavaScript. */
|
||
|
SUPPORTS_JAVASCRIPT: 'javascriptEnabled',
|
||
|
|
||
|
/** Whether the driver supports controlling the browser's location info. */
|
||
|
SUPPORTS_LOCATION_CONTEXT: 'locationContextEnabled',
|
||
|
|
||
|
/** Whether the driver supports taking screenshots. */
|
||
|
TAKES_SCREENSHOT: 'takesScreenshot',
|
||
|
|
||
|
/**
|
||
|
* Defines how the driver should handle unexpected alerts. The value should
|
||
|
* be one of "accept", "dismiss", or "ignore.
|
||
|
*/
|
||
|
UNEXPECTED_ALERT_BEHAVIOR: 'unexpectedAlertBehavior',
|
||
|
|
||
|
/** Defines the browser version. */
|
||
|
VERSION: 'version'
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Describes how a proxy should be configured for a WebDriver session.
|
||
|
* @record
|
||
|
*/
|
||
|
function ProxyConfig() {}
|
||
|
|
||
|
/**
|
||
|
* The proxy type. Must be one of {"manual", "pac", "system"}.
|
||
|
* @type {string}
|
||
|
*/
|
||
|
ProxyConfig.prototype.proxyType;
|
||
|
|
||
|
/**
|
||
|
* URL for the PAC file to use. Only used if {@link #proxyType} is "pac".
|
||
|
* @type {(string|undefined)}
|
||
|
*/
|
||
|
ProxyConfig.prototype.proxyAutoconfigUrl;
|
||
|
|
||
|
/**
|
||
|
* The proxy host for FTP requests. Only used if {@link #proxyType} is "manual".
|
||
|
* @type {(string|undefined)}
|
||
|
*/
|
||
|
ProxyConfig.prototype.ftpProxy;
|
||
|
|
||
|
/**
|
||
|
* The proxy host for HTTP requests. Only used if {@link #proxyType} is
|
||
|
* "manual".
|
||
|
* @type {(string|undefined)}
|
||
|
*/
|
||
|
ProxyConfig.prototype.httpProxy;
|
||
|
|
||
|
/**
|
||
|
* The proxy host for HTTPS requests. Only used if {@link #proxyType} is
|
||
|
* "manual".
|
||
|
* @type {(string|undefined)}
|
||
|
*/
|
||
|
ProxyConfig.prototype.sslProxy;
|
||
|
|
||
|
/**
|
||
|
* A comma delimited list of hosts which should bypass all proxies. Only used if
|
||
|
* {@link #proxyType} is "manual".
|
||
|
* @type {(string|undefined)}
|
||
|
*/
|
||
|
ProxyConfig.prototype.noProxy;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Converts a generic hash object to a map.
|
||
|
* @param {!Object<string, ?>} hash The hash object.
|
||
|
* @return {!Map<string, ?>} The converted map.
|
||
|
*/
|
||
|
function toMap(hash) {
|
||
|
let m = new Map;
|
||
|
for (let key in hash) {
|
||
|
if (hash.hasOwnProperty(key)) {
|
||
|
m.set(key, hash[key]);
|
||
|
}
|
||
|
}
|
||
|
return m;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Describes a set of capabilities for a WebDriver session.
|
||
|
*/
|
||
|
class Capabilities extends Map {
|
||
|
/**
|
||
|
* @param {(Capabilities|Map<string, ?>|Object)=} opt_other Another set of
|
||
|
* capabilities to initialize this instance from.
|
||
|
*/
|
||
|
constructor(opt_other) {
|
||
|
if (opt_other && !(opt_other instanceof Map)) {
|
||
|
opt_other = toMap(opt_other);
|
||
|
}
|
||
|
super(opt_other);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for Android.
|
||
|
*/
|
||
|
static android() {
|
||
|
return new Capabilities()
|
||
|
.set(Capability.BROWSER_NAME, Browser.ANDROID)
|
||
|
.set(Capability.PLATFORM, 'ANDROID');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for Chrome.
|
||
|
*/
|
||
|
static chrome() {
|
||
|
return new Capabilities().set(Capability.BROWSER_NAME, Browser.CHROME);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for Microsoft Edge.
|
||
|
*/
|
||
|
static edge() {
|
||
|
return new Capabilities()
|
||
|
.set(Capability.BROWSER_NAME, Browser.EDGE)
|
||
|
.set(Capability.PLATFORM, 'WINDOWS');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for Firefox.
|
||
|
*/
|
||
|
static firefox() {
|
||
|
return new Capabilities().set(Capability.BROWSER_NAME, Browser.FIREFOX);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for Internet Explorer.
|
||
|
*/
|
||
|
static ie() {
|
||
|
return new Capabilities().
|
||
|
set(Capability.BROWSER_NAME, Browser.INTERNET_EXPLORER).
|
||
|
set(Capability.PLATFORM, 'WINDOWS');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for iPad.
|
||
|
*/
|
||
|
static ipad() {
|
||
|
return new Capabilities().
|
||
|
set(Capability.BROWSER_NAME, Browser.IPAD).
|
||
|
set(Capability.PLATFORM, 'MAC');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for iPhone.
|
||
|
*/
|
||
|
static iphone() {
|
||
|
return new Capabilities().
|
||
|
set(Capability.BROWSER_NAME, Browser.IPHONE).
|
||
|
set(Capability.PLATFORM, 'MAC');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for Opera.
|
||
|
*/
|
||
|
static opera() {
|
||
|
return new Capabilities().
|
||
|
set(Capability.BROWSER_NAME, Browser.OPERA);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for PhantomJS.
|
||
|
*/
|
||
|
static phantomjs() {
|
||
|
return new Capabilities().
|
||
|
set(Capability.BROWSER_NAME, Browser.PHANTOM_JS);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for Safari.
|
||
|
*/
|
||
|
static safari() {
|
||
|
return new Capabilities().
|
||
|
set(Capability.BROWSER_NAME, Browser.SAFARI).
|
||
|
set(Capability.PLATFORM, 'MAC');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for HTMLUnit.
|
||
|
*/
|
||
|
static htmlunit() {
|
||
|
return new Capabilities().
|
||
|
set(Capability.BROWSER_NAME, Browser.HTMLUNIT);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Capabilities} A basic set of capabilities for HTMLUnit
|
||
|
* with enabled Javascript.
|
||
|
*/
|
||
|
static htmlunitwithjs() {
|
||
|
return new Capabilities().
|
||
|
set(Capability.BROWSER_NAME, Browser.HTMLUNIT).
|
||
|
set(Capability.SUPPORTS_JAVASCRIPT, true);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return {!Object<string, ?>} The JSON representation of this instance.
|
||
|
* Note, the returned object may contain nested promised values.
|
||
|
* @suppress {checkTypes} Suppress [] access on a struct (state inherited from
|
||
|
* Map).
|
||
|
*/
|
||
|
[Symbols.serialize]() {
|
||
|
return serialize(this);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Merges another set of capabilities into this instance.
|
||
|
* @param {!(Capabilities|Map<String, ?>|Object<string, ?>)} other The other
|
||
|
* set of capabilities to merge.
|
||
|
* @return {!Capabilities} A self reference.
|
||
|
*/
|
||
|
merge(other) {
|
||
|
if (!other) {
|
||
|
throw new TypeError('no capabilities provided for merge');
|
||
|
}
|
||
|
|
||
|
if (!(other instanceof Map)) {
|
||
|
other = toMap(other);
|
||
|
}
|
||
|
|
||
|
for (let key of other.keys()) {
|
||
|
this.set(key, other.get(key));
|
||
|
}
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {string} key The capability key.
|
||
|
* @param {*} value The capability value.
|
||
|
* @return {!Capabilities} A self reference.
|
||
|
* @throws {TypeError} If the `key` is not a string.
|
||
|
* @override
|
||
|
*/
|
||
|
set(key, value) {
|
||
|
if (typeof key !== 'string') {
|
||
|
throw new TypeError('Capability keys must be strings: ' + typeof key);
|
||
|
}
|
||
|
super.set(key, value);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the logging preferences. Preferences may be specified as a
|
||
|
* {@link ./logging.Preferences} instance, or a as a map of log-type to
|
||
|
* log-level.
|
||
|
* @param {!(./logging.Preferences|Object<string>)} prefs The logging
|
||
|
* preferences.
|
||
|
* @return {!Capabilities} A self reference.
|
||
|
*/
|
||
|
setLoggingPrefs(prefs) {
|
||
|
return this.set(Capability.LOGGING_PREFS, prefs);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the proxy configuration for this instance.
|
||
|
* @param {ProxyConfig} proxy The desired proxy configuration.
|
||
|
* @return {!Capabilities} A self reference.
|
||
|
*/
|
||
|
setProxy(proxy) {
|
||
|
return this.set(Capability.PROXY, proxy);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets whether native events should be used.
|
||
|
* @param {boolean} enabled Whether to enable native events.
|
||
|
* @return {!Capabilities} A self reference.
|
||
|
*/
|
||
|
setEnableNativeEvents(enabled) {
|
||
|
return this.set(Capability.NATIVE_EVENTS, enabled);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets how elements should be scrolled into view for interaction.
|
||
|
* @param {number} behavior The desired scroll behavior: either 0 to align
|
||
|
* with the top of the viewport or 1 to align with the bottom.
|
||
|
* @return {!Capabilities} A self reference.
|
||
|
*/
|
||
|
setScrollBehavior(behavior) {
|
||
|
return this.set(Capability.ELEMENT_SCROLL_BEHAVIOR, behavior);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the default action to take with an unexpected alert before returning
|
||
|
* an error.
|
||
|
* @param {string} behavior The desired behavior; should be "accept",
|
||
|
* "dismiss", or "ignore". Defaults to "dismiss".
|
||
|
* @return {!Capabilities} A self reference.
|
||
|
*/
|
||
|
setAlertBehavior(behavior) {
|
||
|
return this.set(Capability.UNEXPECTED_ALERT_BEHAVIOR, behavior);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Serializes a capabilities object. This is defined as a standalone function
|
||
|
* so it may be type checked (where Capabilities[Symbols.serialize] has type
|
||
|
* checking disabled since it is defined with [] access on a struct).
|
||
|
*
|
||
|
* @param {!Capabilities} caps The capabilities to serialize.
|
||
|
* @return {!Object<string, ?>} The JSON representation of this instance.
|
||
|
* Note, the returned object may contain nested promised values.
|
||
|
*/
|
||
|
function serialize(caps) {
|
||
|
let ret = {};
|
||
|
for (let key of caps.keys()) {
|
||
|
let cap = caps.get(key);
|
||
|
if (cap !== undefined && cap !== null) {
|
||
|
ret[key] = cap;
|
||
|
}
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
|
||
|
// PUBLIC API
|
||
|
|
||
|
|
||
|
module.exports = {
|
||
|
Browser: Browser,
|
||
|
Capabilities: Capabilities,
|
||
|
Capability: Capability,
|
||
|
ProxyConfig: ProxyConfig
|
||
|
};
|