UNPKG

12.3 kBJavaScriptView Raw
1// Licensed to the Software Freedom Conservancy (SFC) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The SFC licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18'use strict';
19
20/**
21 * @fileoverview Defines types related to describing the capabilities of a
22 * WebDriver session.
23 */
24
25const Symbols = require('./symbols');
26
27
28/**
29 * Recognized browser names.
30 * @enum {string}
31 */
32const Browser = {
33 ANDROID: 'android',
34 CHROME: 'chrome',
35 EDGE: 'MicrosoftEdge',
36 FIREFOX: 'firefox',
37 IE: 'internet explorer',
38 INTERNET_EXPLORER: 'internet explorer',
39 IPAD: 'iPad',
40 IPHONE: 'iPhone',
41 OPERA: 'opera',
42 PHANTOM_JS: 'phantomjs',
43 SAFARI: 'safari',
44 HTMLUNIT: 'htmlunit'
45};
46
47
48/**
49 * Common Capability keys.
50 * @enum {string}
51 */
52const Capability = {
53
54 /**
55 * Indicates whether a driver should accept all SSL certs by default. This
56 * capability only applies when requesting a new session. To query whether
57 * a driver can handle insecure SSL certs, see {@link #SECURE_SSL}.
58 */
59 ACCEPT_SSL_CERTS: 'acceptSslCerts',
60
61
62 /**
63 * The browser name. Common browser names are defined in the {@link Browser}
64 * enum.
65 */
66 BROWSER_NAME: 'browserName',
67
68 /**
69 * Defines how elements should be scrolled into the viewport for interaction.
70 * This capability will be set to zero (0) if elements are aligned with the
71 * top of the viewport, or one (1) if aligned with the bottom. The default
72 * behavior is to align with the top of the viewport.
73 */
74 ELEMENT_SCROLL_BEHAVIOR: 'elementScrollBehavior',
75
76 /**
77 * Whether the driver is capable of handling modal alerts (e.g. alert,
78 * confirm, prompt). To define how a driver <i>should</i> handle alerts,
79 * use {@link #UNEXPECTED_ALERT_BEHAVIOR}.
80 */
81 HANDLES_ALERTS: 'handlesAlerts',
82
83 /**
84 * Key for the logging driver logging preferences.
85 */
86 LOGGING_PREFS: 'loggingPrefs',
87
88 /**
89 * Whether this session generates native events when simulating user input.
90 */
91 NATIVE_EVENTS: 'nativeEvents',
92
93 /**
94 * Describes the platform the browser is running on. Will be one of
95 * ANDROID, IOS, LINUX, MAC, UNIX, or WINDOWS. When <i>requesting</i> a
96 * session, ANY may be used to indicate no platform preference (this is
97 * semantically equivalent to omitting the platform capability).
98 */
99 PLATFORM: 'platform',
100
101 /**
102 * Describes the proxy configuration to use for a new WebDriver session.
103 */
104 PROXY: 'proxy',
105
106 /** Whether the driver supports changing the brower's orientation. */
107 ROTATABLE: 'rotatable',
108
109 /**
110 * Whether a driver is only capable of handling secure SSL certs. To request
111 * that a driver accept insecure SSL certs by default, use
112 * {@link #ACCEPT_SSL_CERTS}.
113 */
114 SECURE_SSL: 'secureSsl',
115
116 /** Whether the driver supports manipulating the app cache. */
117 SUPPORTS_APPLICATION_CACHE: 'applicationCacheEnabled',
118
119 /** Whether the driver supports locating elements with CSS selectors. */
120 SUPPORTS_CSS_SELECTORS: 'cssSelectorsEnabled',
121
122 /** Whether the browser supports JavaScript. */
123 SUPPORTS_JAVASCRIPT: 'javascriptEnabled',
124
125 /** Whether the driver supports controlling the browser's location info. */
126 SUPPORTS_LOCATION_CONTEXT: 'locationContextEnabled',
127
128 /** Whether the driver supports taking screenshots. */
129 TAKES_SCREENSHOT: 'takesScreenshot',
130
131 /**
132 * Defines how the driver should handle unexpected alerts. The value should
133 * be one of "accept", "dismiss", or "ignore.
134 */
135 UNEXPECTED_ALERT_BEHAVIOR: 'unexpectedAlertBehavior',
136
137 /** Defines the browser version. */
138 VERSION: 'version'
139};
140
141
142/**
143 * Describes how a proxy should be configured for a WebDriver session.
144 * @record
145 */
146function ProxyConfig() {}
147
148/**
149 * The proxy type. Must be one of {"manual", "pac", "system"}.
150 * @type {string}
151 */
152ProxyConfig.prototype.proxyType;
153
154/**
155 * URL for the PAC file to use. Only used if {@link #proxyType} is "pac".
156 * @type {(string|undefined)}
157 */
158ProxyConfig.prototype.proxyAutoconfigUrl;
159
160/**
161 * The proxy host for FTP requests. Only used if {@link #proxyType} is "manual".
162 * @type {(string|undefined)}
163 */
164ProxyConfig.prototype.ftpProxy;
165
166/**
167 * The proxy host for HTTP requests. Only used if {@link #proxyType} is
168 * "manual".
169 * @type {(string|undefined)}
170 */
171ProxyConfig.prototype.httpProxy;
172
173/**
174 * The proxy host for HTTPS requests. Only used if {@link #proxyType} is
175 * "manual".
176 * @type {(string|undefined)}
177 */
178ProxyConfig.prototype.sslProxy;
179
180/**
181 * A comma delimited list of hosts which should bypass all proxies. Only used if
182 * {@link #proxyType} is "manual".
183 * @type {(string|undefined)}
184 */
185ProxyConfig.prototype.noProxy;
186
187
188/**
189 * Converts a generic hash object to a map.
190 * @param {!Object<string, ?>} hash The hash object.
191 * @return {!Map<string, ?>} The converted map.
192 */
193function toMap(hash) {
194 let m = new Map;
195 for (let key in hash) {
196 if (hash.hasOwnProperty(key)) {
197 m.set(key, hash[key]);
198 }
199 }
200 return m;
201}
202
203
204/**
205 * Describes a set of capabilities for a WebDriver session.
206 */
207class Capabilities extends Map {
208 /**
209 * @param {(Capabilities|Map<string, ?>|Object)=} opt_other Another set of
210 * capabilities to initialize this instance from.
211 */
212 constructor(opt_other) {
213 if (opt_other && !(opt_other instanceof Map)) {
214 opt_other = toMap(opt_other);
215 }
216 super(opt_other);
217 }
218
219 /**
220 * @return {!Capabilities} A basic set of capabilities for Android.
221 */
222 static android() {
223 return new Capabilities()
224 .set(Capability.BROWSER_NAME, Browser.ANDROID)
225 .set(Capability.PLATFORM, 'ANDROID');
226 }
227
228 /**
229 * @return {!Capabilities} A basic set of capabilities for Chrome.
230 */
231 static chrome() {
232 return new Capabilities().set(Capability.BROWSER_NAME, Browser.CHROME);
233 }
234
235 /**
236 * @return {!Capabilities} A basic set of capabilities for Microsoft Edge.
237 */
238 static edge() {
239 return new Capabilities()
240 .set(Capability.BROWSER_NAME, Browser.EDGE)
241 .set(Capability.PLATFORM, 'WINDOWS');
242 }
243
244 /**
245 * @return {!Capabilities} A basic set of capabilities for Firefox.
246 */
247 static firefox() {
248 return new Capabilities().set(Capability.BROWSER_NAME, Browser.FIREFOX);
249 }
250
251 /**
252 * @return {!Capabilities} A basic set of capabilities for Internet Explorer.
253 */
254 static ie() {
255 return new Capabilities().
256 set(Capability.BROWSER_NAME, Browser.INTERNET_EXPLORER).
257 set(Capability.PLATFORM, 'WINDOWS');
258 }
259
260 /**
261 * @return {!Capabilities} A basic set of capabilities for iPad.
262 */
263 static ipad() {
264 return new Capabilities().
265 set(Capability.BROWSER_NAME, Browser.IPAD).
266 set(Capability.PLATFORM, 'MAC');
267 }
268
269 /**
270 * @return {!Capabilities} A basic set of capabilities for iPhone.
271 */
272 static iphone() {
273 return new Capabilities().
274 set(Capability.BROWSER_NAME, Browser.IPHONE).
275 set(Capability.PLATFORM, 'MAC');
276 }
277
278 /**
279 * @return {!Capabilities} A basic set of capabilities for Opera.
280 */
281 static opera() {
282 return new Capabilities().
283 set(Capability.BROWSER_NAME, Browser.OPERA);
284 }
285
286 /**
287 * @return {!Capabilities} A basic set of capabilities for PhantomJS.
288 */
289 static phantomjs() {
290 return new Capabilities().
291 set(Capability.BROWSER_NAME, Browser.PHANTOM_JS);
292 }
293
294 /**
295 * @return {!Capabilities} A basic set of capabilities for Safari.
296 */
297 static safari() {
298 return new Capabilities().
299 set(Capability.BROWSER_NAME, Browser.SAFARI).
300 set(Capability.PLATFORM, 'MAC');
301 }
302
303 /**
304 * @return {!Capabilities} A basic set of capabilities for HTMLUnit.
305 */
306 static htmlunit() {
307 return new Capabilities().
308 set(Capability.BROWSER_NAME, Browser.HTMLUNIT);
309 }
310
311 /**
312 * @return {!Capabilities} A basic set of capabilities for HTMLUnit
313 * with enabled Javascript.
314 */
315 static htmlunitwithjs() {
316 return new Capabilities().
317 set(Capability.BROWSER_NAME, Browser.HTMLUNIT).
318 set(Capability.SUPPORTS_JAVASCRIPT, true);
319 }
320
321 /**
322 * @return {!Object<string, ?>} The JSON representation of this instance.
323 * Note, the returned object may contain nested promised values.
324 * @suppress {checkTypes} Suppress [] access on a struct (state inherited from
325 * Map).
326 */
327 [Symbols.serialize]() {
328 return serialize(this);
329 }
330
331 /**
332 * Merges another set of capabilities into this instance.
333 * @param {!(Capabilities|Map<String, ?>|Object<string, ?>)} other The other
334 * set of capabilities to merge.
335 * @return {!Capabilities} A self reference.
336 */
337 merge(other) {
338 if (!other) {
339 throw new TypeError('no capabilities provided for merge');
340 }
341
342 if (!(other instanceof Map)) {
343 other = toMap(other);
344 }
345
346 for (let key of other.keys()) {
347 this.set(key, other.get(key));
348 }
349
350 return this;
351 }
352
353 /**
354 * @param {string} key The capability key.
355 * @param {*} value The capability value.
356 * @return {!Capabilities} A self reference.
357 * @throws {TypeError} If the `key` is not a string.
358 * @override
359 */
360 set(key, value) {
361 if (typeof key !== 'string') {
362 throw new TypeError('Capability keys must be strings: ' + typeof key);
363 }
364 super.set(key, value);
365 return this;
366 }
367
368 /**
369 * Sets the logging preferences. Preferences may be specified as a
370 * {@link ./logging.Preferences} instance, or a as a map of log-type to
371 * log-level.
372 * @param {!(./logging.Preferences|Object<string>)} prefs The logging
373 * preferences.
374 * @return {!Capabilities} A self reference.
375 */
376 setLoggingPrefs(prefs) {
377 return this.set(Capability.LOGGING_PREFS, prefs);
378 }
379
380 /**
381 * Sets the proxy configuration for this instance.
382 * @param {ProxyConfig} proxy The desired proxy configuration.
383 * @return {!Capabilities} A self reference.
384 */
385 setProxy(proxy) {
386 return this.set(Capability.PROXY, proxy);
387 }
388
389 /**
390 * Sets whether native events should be used.
391 * @param {boolean} enabled Whether to enable native events.
392 * @return {!Capabilities} A self reference.
393 */
394 setEnableNativeEvents(enabled) {
395 return this.set(Capability.NATIVE_EVENTS, enabled);
396 }
397
398 /**
399 * Sets how elements should be scrolled into view for interaction.
400 * @param {number} behavior The desired scroll behavior: either 0 to align
401 * with the top of the viewport or 1 to align with the bottom.
402 * @return {!Capabilities} A self reference.
403 */
404 setScrollBehavior(behavior) {
405 return this.set(Capability.ELEMENT_SCROLL_BEHAVIOR, behavior);
406 }
407
408 /**
409 * Sets the default action to take with an unexpected alert before returning
410 * an error.
411 * @param {string} behavior The desired behavior; should be "accept",
412 * "dismiss", or "ignore". Defaults to "dismiss".
413 * @return {!Capabilities} A self reference.
414 */
415 setAlertBehavior(behavior) {
416 return this.set(Capability.UNEXPECTED_ALERT_BEHAVIOR, behavior);
417 }
418}
419
420
421/**
422 * Serializes a capabilities object. This is defined as a standalone function
423 * so it may be type checked (where Capabilities[Symbols.serialize] has type
424 * checking disabled since it is defined with [] access on a struct).
425 *
426 * @param {!Capabilities} caps The capabilities to serialize.
427 * @return {!Object<string, ?>} The JSON representation of this instance.
428 * Note, the returned object may contain nested promised values.
429 */
430function serialize(caps) {
431 let ret = {};
432 for (let key of caps.keys()) {
433 let cap = caps.get(key);
434 if (cap !== undefined && cap !== null) {
435 ret[key] = cap;
436 }
437 }
438 return ret;
439}
440
441
442// PUBLIC API
443
444
445module.exports = {
446 Browser: Browser,
447 Capabilities: Capabilities,
448 Capability: Capability,
449 ProxyConfig: ProxyConfig
450};