node_modules/selenium-webdriver/chrome.js

Maintainability

75.83

Lines of code

479

Created with Raphaël 2.1.002550751002014-12-3

2014-12-4
Maintainability: 75.83

Created with Raphaël 2.1.001252503755002014-12-3

2014-12-4
Lines of Code: 479

Difficulty

35.52

Estimated Errors

2.32

Function weight

By Complexity

Created with Raphaël 2.1.0Options.fromCapabilities7

By SLOC

Created with Raphaël 2.1.0Options.fromCapabilities28
1
// Copyright 2013 Selenium committers
2
// Copyright 2013 Software Freedom Conservancy
3
//
4
// Licensed under the Apache License, Version 2.0 (the "License");
5
// you may not use this file except in compliance with the License.
6
//     You may obtain a copy of the License at
7
//
8
// http://www.apache.org/licenses/LICENSE-2.0
9
//
10
// Unless required by applicable law or agreed to in writing, software
11
// distributed under the License is distributed on an "AS IS" BASIS,
12
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
// See the License for the specific language governing permissions and
14
// limitations under the License.
15
 
16
'use strict';
Column: 1 "Use the function form of "use strict"."
17
 
18
var fs = require('fs'),
Column: 10 "'require' is not defined."
19
    util = require('util');
Column: 12 "'require' is not defined."
20
 
21
var webdriver = require('./index'),
Column: 17 "'require' is not defined."
22
    executors = require('./executors'),
Column: 17 "'require' is not defined."
23
    io = require('./io'),
Column: 10 "'require' is not defined."
24
    portprober = require('./net/portprober'),
Column: 18 "'require' is not defined."
25
    remote = require('./remote');
Column: 14 "'require' is not defined."
26
 
27
 
28
/**
29
 * Name of the ChromeDriver executable.
30
 * @type {string}
31
 * @const
32
 */
33
var CHROMEDRIVER_EXE =
34
    process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver';
Column: 5 "'process' is not defined."
35
 
36
 
37
/**
38
 * Creates {@link remote.DriverService} instances that manage a ChromeDriver
39
 * server.
40
 * @param {string=} opt_exe Path to the server executable to use. If omitted,
41
 *     the builder will attempt to locate the chromedriver on the current
42
 *     PATH.
43
 * @throws {Error} If provided executable does not exist, or the chromedriver
44
 *     cannot be found on the PATH.
45
 * @constructor
46
 */
47
var ServiceBuilder = function(opt_exe) {
48
  /** @private {string} */
49
  this.exe_ = opt_exe || io.findInPath(CHROMEDRIVER_EXE, true);
50
  if (!this.exe_) {
51
    throw Error(
52
        'The ChromeDriver could not be found on the current PATH. Please ' +
53
        'download the latest version of the ChromeDriver from ' +
54
        'http://chromedriver.storage.googleapis.com/index.html and ensure ' +
55
        'it can be found on your PATH.');
56
  }
57
 
58
  if (!fs.existsSync(this.exe_)) {
59
    throw Error('File does not exist: ' + this.exe_);
60
  }
61
 
62
  /** @private {!Array.<string>} */
63
  this.args_ = [];
64
  this.stdio_ = 'ignore';
65
};
66
 
67
 
68
/** @private {number} */
69
ServiceBuilder.prototype.port_ = 0;
70
 
71
 
72
/** @private {(string|!Array.<string|number|!Stream|null|undefined>)} */
73
ServiceBuilder.prototype.stdio_ = 'ignore';
74
 
75
 
76
/** @private {Object.<string, string>} */
77
ServiceBuilder.prototype.env_ = null;
78
 
79
 
80
/**
81
 * Sets the port to start the ChromeDriver on.
82
 * @param {number} port The port to use, or 0 for any free port.
83
 * @return {!ServiceBuilder} A self reference.
84
 * @throws {Error} If the port is invalid.
85
 */
86
ServiceBuilder.prototype.usingPort = function(port) {
87
  if (port < 0) {
88
    throw Error('port must be >= 0: ' + port);
89
  }
90
  this.port_ = port;
91
  return this;
92
};
93
 
94
 
95
/**
96
 * Sets the path of the log file the driver should log to. If a log file is
97
 * not specified, the driver will log to stderr.
98
 * @param {string} path Path of the log file to use.
99
 * @return {!ServiceBuilder} A self reference.
100
 */
101
ServiceBuilder.prototype.loggingTo = function(path) {
102
  this.args_.push('--log-path=' + path);
103
  return this;
104
};
105
 
106
 
107
/**
108
 * Enables verbose logging.
109
 * @return {!ServiceBuilder} A self reference.
110
 */
111
ServiceBuilder.prototype.enableVerboseLogging = function() {
112
  this.args_.push('--verbose');
113
  return this;
114
};
115
 
116
 
117
/**
118
 * Sets the number of threads the driver should use to manage HTTP requests.
119
 * By default, the driver will use 4 threads.
120
 * @param {number} n The number of threads to use.
121
 * @return {!ServiceBuilder} A self reference.
122
 */
123
ServiceBuilder.prototype.setNumHttpThreads = function(n) {
124
  this.args_.push('--http-threads=' + n);
125
  return this;
126
};
127
 
128
 
129
/**
130
 * Sets the base path for WebDriver REST commands (e.g. "/wd/hub").
131
 * By default, the driver will accept commands relative to "/".
132
 * @param {string} path The base path to use.
133
 * @return {!ServiceBuilder} A self reference.
134
 */
135
ServiceBuilder.prototype.setUrlBasePath = function(path) {
136
  this.args_.push('--url-base=' + path);
137
  return this;
138
};
139
 
140
 
141
/**
142
 * Defines the stdio configuration for the driver service. See
143
 * {@code child_process.spawn} for more information.
144
 * @param {(string|!Array.<string|number|!Stream|null|undefined>)} config The
145
 *     configuration to use.
146
 * @return {!ServiceBuilder} A self reference.
147
 */
148
ServiceBuilder.prototype.setStdio = function(config) {
149
  this.stdio_ = config;
150
  return this;
151
};
152
 
153
 
154
/**
155
 * Defines the environment to start the server under. This settings will be
156
 * inherited by every browser session started by the server.
157
 * @param {!Object.<string, string>} env The environment to use.
158
 * @return {!ServiceBuilder} A self reference.
159
 */
160
ServiceBuilder.prototype.withEnvironment = function(env) {
161
  this.env_ = env;
162
  return this;
163
};
164
 
165
 
166
/**
167
 * Creates a new DriverService using this instance's current configuration.
168
 * @return {remote.DriverService} A new driver service using this instance's
169
 *     current configuration.
170
 * @throws {Error} If the driver exectuable was not specified and a default
171
 *     could not be found on the current PATH.
172
 */
173
ServiceBuilder.prototype.build = function() {
174
  var port = this.port_ || portprober.findFreePort();
175
  var args = this.args_.concat();  // Defensive copy.
176
 
177
  return new remote.DriverService(this.exe_, {
178
    loopback: true,
179
    port: port,
180
    args: webdriver.promise.when(port, function(port) {
181
      return args.concat('--port=' + port);
182
    }),
183
    env: this.env_,
184
    stdio: this.stdio_
185
  });
186
};
187
 
188
 
189
/** @type {remote.DriverService} */
190
var defaultService = null;
191
 
192
 
193
/**
194
 * Sets the default service to use for new ChromeDriver instances.
195
 * @param {!remote.DriverService} service The service to use.
196
 * @throws {Error} If the default service is currently running.
197
 */
198
function setDefaultService(service) {
199
  if (defaultService && defaultService.isRunning()) {
200
    throw Error(
201
        'The previously configured ChromeDriver service is still running. ' +
202
        'You must shut it down before you may adjust its configuration.');
203
  }
204
  defaultService = service;
205
}
206
 
207
 
208
/**
209
 * Returns the default ChromeDriver service. If such a service has not been
210
 * configured, one will be constructed using the default configuration for
211
 * a ChromeDriver executable found on the system PATH.
212
 * @return {!remote.DriverService} The default ChromeDriver service.
213
 */
214
function getDefaultService() {
215
  if (!defaultService) {
216
    defaultService = new ServiceBuilder().build();
217
  }
218
  return defaultService;
219
}
220
 
221
 
222
/**
223
 * @type {string}
224
 * @const
225
 */
226
var OPTIONS_CAPABILITY_KEY = 'chromeOptions';
227
 
228
 
229
/**
230
 * Class for managing ChromeDriver specific options.
231
 * @constructor
232
 */
233
var Options = function() {
234
  /** @private {!Array.<string>} */
235
  this.args_ = [];
236
 
237
  /** @private {!Array.<(string|!Buffer)>} */
238
  this.extensions_ = [];
239
};
240
 
241
 
242
/**
243
 * Extracts the ChromeDriver specific options from the given capabilities
244
 * object.
245
 * @param {!webdriver.Capabilities} capabilities The capabilities object.
246
 * @return {!Options} The ChromeDriver options.
247
 */
248
Options.fromCapabilities = function(capabilities) {
249
  var options = new Options();
250
 
251
  var o = capabilities.get(OPTIONS_CAPABILITY_KEY);
252
  if (o instanceof Options) {
253
    options = o;
254
  } else if (o) {
255
    options.
256
        addArguments(o.args || []).
257
        addExtensions(o.extensions || []).
258
        detachDriver(!!o.detach).
259
        setChromeBinaryPath(o.binary).
260
        setChromeLogFile(o.logFile).
261
        setLocalState(o.localState).
262
        setUserPreferences(o.prefs);
263
  }
264
 
265
  if (capabilities.has(webdriver.Capability.PROXY)) {
266
    options.setProxy(capabilities.get(webdriver.Capability.PROXY));
267
  }
268
 
269
  if (capabilities.has(webdriver.Capability.LOGGING_PREFS)) {
270
    options.setLoggingPrefs(
271
        capabilities.get(webdriver.Capability.LOGGING_PREFS));
272
  }
273
 
274
  return options;
275
};
276
 
277
 
278
/**
279
 * Add additional command line arguments to use when launching the Chrome
280
 * browser.  Each argument may be specified with or without the "--" prefix
281
 * (e.g. "--foo" and "foo"). Arguments with an associated value should be
282
 * delimited by an "=": "foo=bar".
283
 * @param {...(string|!Array.<string>)} var_args The arguments to add.
284
 * @return {!Options} A self reference.
285
 */
286
Options.prototype.addArguments = function(var_args) {
287
  this.args_ = this.args_.concat.apply(this.args_, arguments);
288
  return this;
289
};
290
 
291
 
292
/**
293
 * Add additional extensions to install when launching Chrome. Each extension
294
 * should be specified as the path to the packed CRX file, or a Buffer for an
295
 * extension.
296
 * @param {...(string|!Buffer|!Array.<(string|!Buffer)>)} var_args The
297
 *     extensions to add.
298
 * @return {!Options} A self reference.
299
 */
300
Options.prototype.addExtensions = function(var_args) {
301
  this.extensions_ = this.extensions_.concat.apply(
302
      this.extensions_, arguments);
303
  return this;
304
};
305
 
306
 
307
/**
308
 * Sets the path to the Chrome binary to use. On Mac OS X, this path should
309
 * reference the actual Chrome executable, not just the application binary
310
 * (e.g. "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome").
311
 *
312
 * The binary path be absolute or relative to the chromedriver server
313
 * executable, but it must exist on the machine that will launch Chrome.
314
 *
315
 * @param {string} path The path to the Chrome binary to use.
316
 * @return {!Options} A self reference.
317
 */
318
Options.prototype.setChromeBinaryPath = function(path) {
319
  this.binary_ = path;
320
  return this;
321
};
322
 
323
 
324
/**
325
 * Sets whether to leave the started Chrome browser running if the controlling
326
 * ChromeDriver service is killed before {@link webdriver.WebDriver#quit()} is
327
 * called.
328
 * @param {boolean} detach Whether to leave the browser running if the
329
 *     chromedriver service is killed before the session.
330
 * @return {!Options} A self reference.
331
 */
332
Options.prototype.detachDriver = function(detach) {
333
  this.detach_ = detach;
334
  return this;
335
};
336
 
337
 
338
/**
339
 * Sets the user preferences for Chrome's user profile. See the "Preferences"
340
 * file in Chrome's user data directory for examples.
341
 * @param {!Object} prefs Dictionary of user preferences to use.
342
 * @return {!Options} A self reference.
343
 */
344
Options.prototype.setUserPreferences = function(prefs) {
345
  this.prefs_ = prefs;
346
  return this;
347
};
348
 
349
 
350
/**
351
 * Sets the logging preferences for the new session.
352
 * @param {!webdriver.logging.Preferences} prefs The logging preferences.
353
 * @return {!Options} A self reference.
354
 */
355
Options.prototype.setLoggingPrefs = function(prefs) {
356
  this.logPrefs_ = prefs;
357
  return this;
358
};
359
 
360
 
361
/**
362
 * Sets preferences for the "Local State" file in Chrome's user data
363
 * directory.
364
 * @param {!Object} state Dictionary of local state preferences.
365
 * @return {!Options} A self reference.
366
 */
367
Options.prototype.setLocalState = function(state) {
368
  this.localState_ = state;
369
  return this;
370
};
371
 
372
 
373
/**
374
 * Sets the path to Chrome's log file. This path should exist on the machine
375
 * that will launch Chrome.
376
 * @param {string} path Path to the log file to use.
377
 * @return {!Options} A self reference.
378
 */
379
Options.prototype.setChromeLogFile = function(path) {
380
  this.logFile_ = path;
381
  return this;
382
};
383
 
384
 
385
/**
386
 * Sets the proxy settings for the new session.
387
 * @param {webdriver.ProxyConfig} proxy The proxy configuration to use.
388
 * @return {!Options} A self reference.
389
 */
390
Options.prototype.setProxy = function(proxy) {
391
  this.proxy_ = proxy;
392
  return this;
393
};
394
 
395
 
396
/**
397
 * Converts this options instance to a {@link webdriver.Capabilities} object.
398
 * @param {webdriver.Capabilities=} opt_capabilities The capabilities to merge
399
 *     these options into, if any.
400
 * @return {!webdriver.Capabilities} The capabilities.
401
 */
402
Options.prototype.toCapabilities = function(opt_capabilities) {
403
  var capabilities = opt_capabilities || webdriver.Capabilities.chrome();
404
  capabilities.
405
      set(webdriver.Capability.PROXY, this.proxy_).
406
      set(webdriver.Capability.LOGGING_PREFS, this.logPrefs_).
407
      set(OPTIONS_CAPABILITY_KEY, this);
408
  return capabilities;
409
};
410
 
411
 
412
/**
413
 * Converts this instance to its JSON wire protocol representation. Note this
414
 * function is an implementation not intended for general use.
415
 * @return {{args: !Array.<string>,
416
 *           binary: (string|undefined),
417
 *           detach: boolean,
418
 *           extensions: !Array.<string>,
419
 *           localState: (Object|undefined),
420
 *           logFile: (string|undefined),
421
 *           prefs: (Object|undefined)}} The JSON wire protocol representation
422
 *     of this instance.
423
 */
424
Options.prototype.toJSON = function() {
425
  return {
426
    args: this.args_,
427
    binary: this.binary_,
428
    detach: !!this.detach_,
429
    extensions: this.extensions_.map(function(extension) {
430
      if (Buffer.isBuffer(extension)) {
Column: 11 "'Buffer' is not defined."
431
        return extension.toString('base64');
432
      }
433
      return fs.readFileSync(extension, 'base64');
434
    }),
435
    localState: this.localState_,
436
    logFile: this.logFile_,
437
    prefs: this.prefs_
438
  };
439
};
440
 
441
 
442
/**
443
 * Creates a new ChromeDriver session.
444
 * @param {(webdriver.Capabilities|Options)=} opt_options The session options.
445
 * @param {remote.DriverService=} opt_service The session to use; will use
446
 *     the {@link getDefaultService default service} by default.
447
 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow to use, or
448
 *     {@code null} to use the currently active flow.
449
 * @return {!webdriver.WebDriver} A new WebDriver instance.
450
 * @deprecated Use {@link Driver new Driver()}.
451
 */
452
function createDriver(opt_options, opt_service, opt_flow) {
453
  return new Driver(opt_options, opt_service, opt_flow);
454
}
455
 
456
 
457
/**
458
 * Creates a new WebDriver client for Chrome.
459
 *
460
 * @param {(webdriver.Capabilities|Options)=} opt_config The configuration
461
 *     options.
462
 * @param {remote.DriverService=} opt_service The session to use; will use
463
 *     the {@link getDefaultService default service} by default.
464
 * @param {webdriver.promise.ControlFlow=} opt_flow The control flow to use, or
465
 *     {@code null} to use the currently active flow.
466
 * @constructor
467
 * @extends {webdriver.WebDriver}
468
 */
469
var Driver = function(opt_config, opt_service, opt_flow) {
470
  var service = opt_service || getDefaultService();
471
  var executor = executors.createExecutor(service.start());
472
 
473
  var capabilities =
474
      opt_config instanceof Options ? opt_config.toCapabilities() :
475
      (opt_config || webdriver.Capabilities.chrome());
476
 
477
  var driver = webdriver.WebDriver.createSession(
478
      executor, capabilities, opt_flow);
479
 
480
  webdriver.WebDriver.call(
481
      this, driver.getSession(), executor, driver.controlFlow());
482
};
483
util.inherits(Driver, webdriver.WebDriver);
484
 
485
 
486
// PUBLIC API
487
 
488
 
489
exports.Driver = Driver;
Column: 1 "'exports' is not defined."
490
exports.Options = Options;
Column: 1 "'exports' is not defined."
491
exports.ServiceBuilder = ServiceBuilder;
Column: 1 "'exports' is not defined."
492
exports.createDriver = createDriver;
Column: 1 "'exports' is not defined."
493
exports.getDefaultService = getDefaultService;
Column: 1 "'exports' is not defined."
494
exports.setDefaultService = setDefaultService;
Column: 1 "'exports' is not defined."