selenium-webdriver 3.3.0 → 4.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGES.md +273 -0
  2. package/NOTICE +1 -1
  3. package/README.md +28 -36
  4. package/chrome.js +221 -146
  5. package/edge.js +43 -118
  6. package/example/chrome_android.js +8 -9
  7. package/example/chrome_mobile_emulation.js +9 -10
  8. package/example/firefox_channels.js +23 -19
  9. package/example/google_search.js +3 -3
  10. package/example/google_search_test.js +39 -27
  11. package/example/headless.js +55 -0
  12. package/example/logging.js +40 -7
  13. package/firefox.js +769 -0
  14. package/http/index.js +41 -4
  15. package/http/util.js +11 -6
  16. package/ie.js +57 -98
  17. package/index.js +182 -115
  18. package/io/index.js +59 -0
  19. package/io/zip.js +214 -0
  20. package/jasmine.json +11 -0
  21. package/lib/actions.js +68 -63
  22. package/lib/atoms/get-attribute.js +9 -0
  23. package/lib/atoms/is-displayed.js +73 -78
  24. package/lib/by.js +9 -1
  25. package/lib/capabilities.js +303 -201
  26. package/lib/command.js +28 -50
  27. package/lib/error.js +113 -42
  28. package/lib/http.js +167 -135
  29. package/lib/input.js +1044 -8
  30. package/lib/promise.js +222 -3331
  31. package/lib/proxy.js +134 -39
  32. package/lib/test/bootstrap_jasmine.js +28 -0
  33. package/lib/test/data/actions/click.html +24 -0
  34. package/lib/test/data/actions/drag.html +77 -0
  35. package/lib/test/data/actions/record_click.html +21 -0
  36. package/lib/test/data/chrome/download.html +2 -0
  37. package/lib/test/data/click_tests/disabled_element.html +12 -0
  38. package/lib/test/data/content-editable.html +10 -0
  39. package/lib/test/data/firefox/webextension.xpi +0 -0
  40. package/lib/test/data/inputs.html +42 -0
  41. package/lib/test/data/key_logger.html +34 -0
  42. package/lib/test/data/nestedElements.html +10 -1
  43. package/lib/test/data/scrolling_tests/page_with_partially_hidden_element.html +14 -0
  44. package/lib/test/data/selectPage.html +12 -0
  45. package/lib/test/data/simpleTest.html +5 -0
  46. package/lib/test/data/single_text_input.html +12 -0
  47. package/lib/test/data/upload_invisible.html +45 -0
  48. package/lib/test/fileserver.js +23 -19
  49. package/lib/test/index.js +30 -244
  50. package/lib/test/resources.js +0 -1
  51. package/lib/webdriver.js +770 -939
  52. package/net/index.js +21 -25
  53. package/net/portprober.js +51 -68
  54. package/package.json +6 -4
  55. package/remote/index.js +18 -30
  56. package/safari.js +42 -129
  57. package/test/actions_test.js +173 -18
  58. package/test/builder_test.js +106 -0
  59. package/test/chrome/devtools_test.js +93 -0
  60. package/test/chrome/options_test.js +48 -154
  61. package/test/chrome/service_test.js +7 -7
  62. package/test/cookie_test.js +77 -63
  63. package/test/element_finding_test.js +206 -201
  64. package/test/execute_script_test.js +115 -114
  65. package/test/fingerprint_test.js +16 -15
  66. package/test/firefox_test.js +251 -0
  67. package/test/http/http_test.js +18 -1
  68. package/test/http/util_test.js +2 -2
  69. package/test/{io_test.js → io/io_test.js} +40 -1
  70. package/test/io/zip_test.js +127 -0
  71. package/test/lib/by_test.js +21 -0
  72. package/test/lib/error_test.js +55 -8
  73. package/test/lib/http_test.js +18 -130
  74. package/test/lib/input_test.js +1379 -0
  75. package/test/lib/promise_test.js +473 -908
  76. package/test/lib/webdriver_test.js +357 -825
  77. package/test/logging_test.js +37 -43
  78. package/test/page_loading_test.js +70 -86
  79. package/test/proxy_test.js +64 -72
  80. package/test/rect_test.js +14 -25
  81. package/test/remote_test.js +13 -32
  82. package/test/safari_test.js +7 -71
  83. package/test/stale_element_test.js +20 -23
  84. package/test/tag_name_test.js +10 -9
  85. package/test/upload_test.js +27 -35
  86. package/test/window_test.js +72 -85
  87. package/testing/index.js +386 -315
  88. package/.npmignore +0 -2
  89. package/example/async_await_test.js +0 -68
  90. package/example/google_search_generator.js +0 -50
  91. package/example/parallel_flows.js +0 -54
  92. package/firefox/binary.js +0 -344
  93. package/firefox/extension.js +0 -187
  94. package/firefox/index.js +0 -722
  95. package/firefox/profile.js +0 -430
  96. package/lib/atoms/getAttribute.js +0 -12
  97. package/lib/events.js +0 -210
  98. package/lib/firefox/webdriver.json +0 -70
  99. package/lib/firefox/webdriver.xpi +0 -0
  100. package/lib/test/data/firefox/jetpack-sample.xpi +0 -0
  101. package/lib/test/data/firefox/sample.xpi +0 -0
  102. package/lib/test/promise.js +0 -79
  103. package/opera.js +0 -405
  104. package/phantomjs.js +0 -282
  105. package/test/firefox/extension_test.js +0 -96
  106. package/test/firefox/firefox_test.js +0 -226
  107. package/test/firefox/profile_test.js +0 -185
  108. package/test/lib/events_test.js +0 -177
  109. package/test/lib/promise_aplus_test.js +0 -78
  110. package/test/lib/promise_error_test.js +0 -884
  111. package/test/lib/promise_flow_test.js +0 -2288
  112. package/test/lib/promise_generator_test.js +0 -310
  113. package/test/phantomjs/execute_phantomjs_test.js +0 -59
  114. package/test/session_test.js +0 -54
  115. package/test/testing/assert_test.js +0 -373
  116. package/test/testing/index_test.js +0 -224
  117. package/testing/assert.js +0 -378
package/edge.js CHANGED
@@ -70,121 +70,44 @@
70
70
 
71
71
  'use strict';
72
72
 
73
- const fs = require('fs'),
74
- util = require('util');
75
-
76
- const http = require('./http'),
77
- io = require('./io'),
78
- capabilities = require('./lib/capabilities'),
79
- promise = require('./lib/promise'),
80
- Symbols = require('./lib/symbols'),
81
- webdriver = require('./lib/webdriver'),
82
- portprober = require('./net/portprober'),
83
- remote = require('./remote');
73
+ const fs = require('fs');
74
+ const util = require('util');
75
+
76
+ const http = require('./http');
77
+ const io = require('./io');
78
+ const portprober = require('./net/portprober');
79
+ const promise = require('./lib/promise');
80
+ const remote = require('./remote');
81
+ const Symbols = require('./lib/symbols');
82
+ const webdriver = require('./lib/webdriver');
83
+ const {Browser, Capabilities} = require('./lib/capabilities');
84
84
 
85
85
  const EDGEDRIVER_EXE = 'MicrosoftWebDriver.exe';
86
86
 
87
87
 
88
88
  /**
89
- * Option keys.
90
- * @enum {string}
89
+ * _Synchronously_ attempts to locate the edge driver executable on the current
90
+ * system.
91
+ *
92
+ * @return {?string} the located executable, or `null`.
91
93
  */
92
- const CAPABILITY_KEY = {
93
- PAGE_LOAD_STRATEGY: 'pageLoadStrategy'
94
- };
94
+ function locateSynchronously() {
95
+ return process.platform === 'win32'
96
+ ? io.findInPath(EDGEDRIVER_EXE, true) : null;
97
+ }
95
98
 
96
99
 
97
100
  /**
98
101
  * Class for managing MicrosoftEdgeDriver specific options.
99
102
  */
100
- class Options {
101
- constructor() {
102
- /** @private {!Object} */
103
- this.options_ = {};
104
-
105
- /** @private {?capabilities.ProxyConfig} */
106
- this.proxy_ = null;
107
- }
108
-
109
- /**
110
- * Extracts the MicrosoftEdgeDriver specific options from the given
111
- * capabilities object.
112
- * @param {!capabilities.Capabilities} caps The capabilities object.
113
- * @return {!Options} The MicrosoftEdgeDriver options.
114
- */
115
- static fromCapabilities(caps) {
116
- var options = new Options();
117
- var map = options.options_;
118
-
119
- Object.keys(CAPABILITY_KEY).forEach(function(key) {
120
- key = CAPABILITY_KEY[key];
121
- if (caps.has(key)) {
122
- map[key] = caps.get(key);
123
- }
124
- });
125
-
126
- if (caps.has(capabilities.Capability.PROXY)) {
127
- options.setProxy(caps.get(capabilities.Capability.PROXY));
128
- }
129
-
130
- return options;
131
- }
132
-
133
- /**
134
- * Sets the proxy settings for the new session.
135
- * @param {capabilities.ProxyConfig} proxy The proxy configuration to use.
136
- * @return {!Options} A self reference.
137
- */
138
- setProxy(proxy) {
139
- this.proxy_ = proxy;
140
- return this;
141
- }
142
-
103
+ class Options extends Capabilities {
143
104
  /**
144
- * Sets the page load strategy for Edge.
145
- * Supported values are "normal", "eager", and "none";
146
- *
147
- * @param {string} pageLoadStrategy The page load strategy to use.
148
- * @return {!Options} A self reference.
105
+ * @param {(Capabilities|Map<string, ?>|Object)=} other Another set of
106
+ * capabilities to initialize this instance from.
149
107
  */
150
- setPageLoadStrategy(pageLoadStrategy) {
151
- this.options_[CAPABILITY_KEY.PAGE_LOAD_STRATEGY] =
152
- pageLoadStrategy.toLowerCase();
153
- return this;
154
- }
155
-
156
- /**
157
- * Converts this options instance to a {@link capabilities.Capabilities}
158
- * object.
159
- * @param {capabilities.Capabilities=} opt_capabilities The capabilities to
160
- * merge these options into, if any.
161
- * @return {!capabilities.Capabilities} The capabilities.
162
- */
163
- toCapabilities(opt_capabilities) {
164
- var caps = opt_capabilities || capabilities.Capabilities.edge();
165
- if (this.proxy_) {
166
- caps.set(capabilities.Capability.PROXY, this.proxy_);
167
- }
168
- Object.keys(this.options_).forEach(function(key) {
169
- caps.set(key, this.options_[key]);
170
- }, this);
171
- return caps;
172
- }
173
-
174
- /**
175
- * Converts this instance to its JSON wire protocol representation. Note this
176
- * function is an implementation not intended for general use.
177
- * @return {{pageLoadStrategy: (string|undefined)}}
178
- * The JSON wire protocol representation of this instance.
179
- */
180
- [Symbols.serialize]() {
181
- var json = {};
182
- for (var key in this.options_) {
183
- if (this.options_[key] != null) {
184
- json[key] = this.options_[key];
185
- }
186
- }
187
- return json;
108
+ constructor(other = undefined) {
109
+ super(other);
110
+ this.setBrowserName(Browser.EDGE);
188
111
  }
189
112
  }
190
113
 
@@ -202,7 +125,7 @@ class ServiceBuilder extends remote.DriverService.Builder {
202
125
  * MicrosoftEdgeDriver cannot be found on the PATH.
203
126
  */
204
127
  constructor(opt_exe) {
205
- let exe = opt_exe || io.findInPath(EDGEDRIVER_EXE, true);
128
+ let exe = opt_exe || locateSynchronously();
206
129
  if (!exe) {
207
130
  throw Error(
208
131
  'The ' + EDGEDRIVER_EXE + ' could not be found on the current PATH. ' +
@@ -218,6 +141,14 @@ class ServiceBuilder extends remote.DriverService.Builder {
218
141
  // (or can we?), force the DriverService to use "localhost".
219
142
  this.setHostname('localhost');
220
143
  }
144
+
145
+ /**
146
+ * Enables verbose logging.
147
+ * @return {!ServiceBuilder} A self reference.
148
+ */
149
+ enableVerboseLogging() {
150
+ return this.addArguments('--verbose');
151
+ }
221
152
  }
222
153
 
223
154
 
@@ -261,25 +192,18 @@ class Driver extends webdriver.WebDriver {
261
192
  /**
262
193
  * Creates a new browser session for Microsoft's Edge browser.
263
194
  *
264
- * @param {(capabilities.Capabilities|Options)=} opt_config The configuration
265
- * options.
266
- * @param {remote.DriverService=} opt_service The session to use; will use
195
+ * @param {(Capabilities|Options)=} options The configuration options.
196
+ * @param {remote.DriverService=} service The session to use; will use
267
197
  * the {@linkplain #getDefaultService default service} by default.
268
- * @param {promise.ControlFlow=} opt_flow The control flow to use, or
269
- * {@code null} to use the currently active flow.
270
198
  * @return {!Driver} A new driver instance.
271
199
  */
272
- static createSession(opt_config, opt_service, opt_flow) {
273
- var service = opt_service || getDefaultService();
274
- var client = service.start().then(url => new http.HttpClient(url));
275
- var executor = new http.Executor(client);
276
-
277
- var caps =
278
- opt_config instanceof Options ? opt_config.toCapabilities() :
279
- (opt_config || capabilities.Capabilities.edge());
200
+ static createSession(options, service = getDefaultService()) {
201
+ let client = service.start().then(url => new http.HttpClient(url));
202
+ let executor = new http.Executor(client);
280
203
 
281
- return /** @type {!Driver} */(webdriver.WebDriver.createSession(
282
- executor, caps, opt_flow, this, () => service.kill()));
204
+ options = options || new Options();
205
+ return /** @type {!Driver} */(super.createSession(
206
+ executor, options, () => service.kill()));
283
207
  }
284
208
 
285
209
  /**
@@ -299,3 +223,4 @@ exports.Options = Options;
299
223
  exports.ServiceBuilder = ServiceBuilder;
300
224
  exports.getDefaultService = getDefaultService;
301
225
  exports.setDefaultService = setDefaultService;
226
+ exports.locateSynchronously = locateSynchronously;
@@ -23,21 +23,20 @@
23
23
 
24
24
  'use strict';
25
25
 
26
- const {Builder, By, promise, until} = require('..');
26
+ const {Builder, By, Key, until} = require('..');
27
27
  const {Options} = require('../chrome');
28
28
 
29
- promise.consume(function* () {
29
+ (async function() {
30
30
  let driver;
31
31
  try {
32
- driver = yield new Builder()
32
+ driver = await new Builder()
33
33
  .forBrowser('chrome')
34
34
  .setChromeOptions(new Options().androidChrome())
35
35
  .build();
36
- yield driver.get('http://www.google.com/ncr');
37
- yield driver.findElement(By.name('q')).sendKeys('webdriver');
38
- yield driver.findElement(By.name('btnG')).click();
39
- yield driver.wait(until.titleIs('webdriver - Google Search'), 1000);
36
+ await driver.get('http://www.google.com/ncr');
37
+ await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
38
+ await driver.wait(until.titleIs('webdriver - Google Search'), 1000);
40
39
  } finally {
41
- yield driver && driver.quit();
40
+ await driver && driver.quit();
42
41
  }
43
- }).then(_ => console.log('SUCCESS'), err => console.error('ERROR: ' + err));
42
+ })().then(_ => console.log('SUCCESS'), err => console.error('ERROR: ' + err));
@@ -22,22 +22,21 @@
22
22
 
23
23
  'use strict';
24
24
 
25
- const {Builder, By, promise, until} = require('..');
25
+ const {Builder, By, Key, until} = require('..');
26
26
  const {Options} = require('../chrome');
27
27
 
28
- promise.consume(function* () {
28
+ (async function() {
29
29
  let driver;
30
30
  try {
31
- driver = yield new Builder()
31
+ driver = await new Builder()
32
32
  .forBrowser('chrome')
33
33
  .setChromeOptions(
34
- new Options().setMobileEmulation({deviceName: 'Google Nexus 5'}))
34
+ new Options().setMobileEmulation({deviceName: 'Nexus 5X'}))
35
35
  .build();
36
- yield driver.get('http://www.google.com/ncr');
37
- yield driver.findElement(By.name('q')).sendKeys('webdriver');
38
- yield driver.findElement(By.name('btnG')).click();
39
- yield driver.wait(until.titleIs('webdriver - Google Search'), 1000);
36
+ await driver.get('http://www.google.com/ncr');
37
+ await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
38
+ await driver.wait(until.titleIs('webdriver - Google Search'), 1000);
40
39
  } finally {
41
- yield driver && driver.quit();
40
+ await driver && driver.quit();
42
41
  }
43
- }).then(_ => console.log('SUCCESS'), err => console.error('ERROR: ' + err));
42
+ })().then(_ => console.log('SUCCESS'), err => console.error('ERROR: ' + err));
@@ -27,28 +27,37 @@
27
27
 
28
28
  'use strict';
29
29
 
30
- const {Builder, By, promise, until} = require('..');
30
+ const {Builder, By, Key, promise, until} = require('..');
31
31
  const {Channel, Options} = require('../firefox');
32
32
 
33
33
  let i = 0;
34
34
  function resposition(driver) {
35
- return driver.manage().window().setSize(600, 400)
36
- .then(_ => driver.manage().window().setPosition(300 * (i++), 0));
35
+ return driver.manage().window().setRect({
36
+ width: 600,
37
+ height: 400,
38
+ x: 300 * (i++),
39
+ y: 0
40
+ });
37
41
  }
38
42
 
39
- function doSearch(driver) {
40
- // Start on the base about page.
41
- return driver.get('about:')
43
+ async function doSearch(driver) {
44
+ try {
45
+ // Start on the base about page.
46
+ await driver.get('about:')
42
47
  // Reposition so users can see the three windows.
43
- .then(_ => resposition(driver))
48
+ await resposition(driver);
44
49
  // Pause so users can see the magic.
45
- .then(_ => promise.delayed(750))
50
+ await promise.delayed(750);
46
51
  // Now do the rest.
47
- .then(_ => driver.get('http://www.google.com/ncr'))
48
- .then(_ => driver.findElement(By.name('q')).sendKeys('webdriver'))
49
- .then(_ => driver.findElement(By.name('btnG')).click())
50
- .then(_ => driver.wait(until.titleIs('webdriver - Google Search'), 1000))
51
- .then(_ => driver.quit());
52
+ await driver.get('http://www.google.com/ncr');
53
+ await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
54
+ await driver.wait(until.titleIs('webdriver - Google Search'), 1000);
55
+ console.log('Success!');
56
+ } catch (ex) {
57
+ console.log('An error occured! ' + ex);
58
+ } finally {
59
+ await driver.quit();
60
+ }
52
61
  }
53
62
 
54
63
  function createDriver(channel) {
@@ -56,17 +65,12 @@ function createDriver(channel) {
56
65
  return new Builder().forBrowser('firefox').setFirefoxOptions(options).build();
57
66
  }
58
67
 
59
- // NOTE: disabling the promise manager so searches all run concurrently.
60
- // For more on the promise manager and its pending deprecation, see
61
- // https://github.com/SeleniumHQ/selenium/issues/2969
62
- promise.USE_PROMISE_MANAGER = false;
63
-
64
68
  Promise.all([
65
69
  doSearch(createDriver(Channel.RELEASE)),
66
70
  doSearch(createDriver(Channel.AURORA)), // Developer Edition.
67
71
  doSearch(createDriver(Channel.NIGHTLY)),
68
72
  ]).then(_ => {
69
- console.log('Success!');
73
+ console.log('All done!');
70
74
  }, err => {
71
75
  console.error('An error occured! ' + err);
72
76
  setTimeout(() => {throw err}, 0);
@@ -37,14 +37,14 @@
37
37
  * node selenium-webdriver/example/google_search.js
38
38
  */
39
39
 
40
- const {Builder, By, until} = require('..');
40
+ const {Builder, By, Key, until} = require('..');
41
41
 
42
42
  var driver = new Builder()
43
43
  .forBrowser('firefox')
44
44
  .build();
45
45
 
46
46
  driver.get('http://www.google.com/ncr')
47
- .then(_ => driver.findElement(By.name('q')).sendKeys('webdriver'))
48
- .then(_ => driver.findElement(By.name('btnG')).click())
47
+ .then(_ =>
48
+ driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN))
49
49
  .then(_ => driver.wait(until.titleIs('webdriver - Google Search'), 1000))
50
50
  .then(_ => driver.quit());
@@ -18,44 +18,56 @@
18
18
  /**
19
19
  * @fileoverview An example test that may be run using Mocha.
20
20
  *
21
+ * This example uses the `selenium-webdriver/testing.suite` function, which will
22
+ * automatically run tests against every available WebDriver browser on the
23
+ * current system. Alternatively, you may use the `SELENIUM_BROWSER`
24
+ * environment variable to narrow the scope at runtime.
25
+ *
21
26
  * Usage:
22
27
  *
28
+ * # Automatically determine which browsers to run against.
23
29
  * mocha -t 10000 selenium-webdriver/example/google_search_test.js
24
30
  *
25
- * You can change which browser is started with the SELENIUM_BROWSER environment
26
- * variable:
27
- *
31
+ * # Configure tests to only run against Google Chrome.
28
32
  * SELENIUM_BROWSER=chrome \
29
33
  * mocha -t 10000 selenium-webdriver/example/google_search_test.js
30
34
  */
31
35
 
32
- const {Builder, By, until} = require('..');
33
- const test = require('../testing');
36
+ const assert = require('assert');
34
37
 
35
- test.describe('Google Search', function() {
36
- let driver;
38
+ const {Browser, By, Key, until} = require('..');
39
+ const {ignore, suite} = require('../testing');
37
40
 
38
- test.before(function *() {
39
- driver = yield new Builder().forBrowser('firefox').build();
40
- });
41
+ suite(function(env) {
42
+ describe('Google Search', function() {
43
+ let driver;
41
44
 
42
- // You can write tests either using traditional promises.
43
- it('works with promises', function() {
44
- return driver.get('http://www.google.com')
45
- .then(_ => driver.findElement(By.name('q')).sendKeys('webdriver'))
46
- .then(_ => driver.findElement(By.name('btnG')).click())
47
- .then(_ => driver.wait(until.titleIs('webdriver - Google Search'), 1000));
48
- });
45
+ before(async function() {
46
+ // env.builder() returns a Builder instance preconfigured for the
47
+ // envrionment's target browser (you may still define browser specific
48
+ // options if necessary (i.e. firefox.Options or chrome.Options)).
49
+ driver = await env.builder().build();
50
+ });
49
51
 
50
- // Or you can define the test as a generator function. The test will wait for
51
- // any yielded promises to resolve before invoking the next step in the
52
- // generator.
53
- test.it('works with generators', function*() {
54
- yield driver.get('http://www.google.com/ncr');
55
- yield driver.findElement(By.name('q')).sendKeys('webdriver');
56
- yield driver.findElement(By.name('btnG')).click();
57
- yield driver.wait(until.titleIs('webdriver - Google Search'), 1000);
58
- });
52
+ it('demo', async function() {
53
+ await driver.get('https://www.google.com/ncr');
54
+ await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
55
+ await driver.wait(until.titleIs('webdriver - Google Search'), 1000);
56
+ });
57
+
58
+ // The ignore function returns wrappers around describe & it that will
59
+ // suppress tests if the provided predicate returns true. You may provide
60
+ // any synchronous predicate. The env.browsers(...) function generates a
61
+ // predicate that will suppress tests if the env targets one of the
62
+ // specified browsers.
63
+ //
64
+ // This example is always configured to skip Chrome.
65
+ ignore(env.browsers(Browser.CHROME)).it('demo 2', async function() {
66
+ await driver.get('http://www.google.com/ncr');
67
+ let url = await driver.getCurrentUrl();
68
+ assert.equal(url, 'https://www.google.com/');
69
+ });
59
70
 
60
- test.after(() => driver.quit());
71
+ after(() => driver && driver.quit());
72
+ });
61
73
  });
@@ -0,0 +1,55 @@
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
+ /**
19
+ * @fileoverview An example of running Chrome or Firefox in headless mode.
20
+ *
21
+ * To run with Chrome, ensure you have Chrome 59+ installed and that
22
+ * chromedriver 2.30+ is present on your system PATH:
23
+ * <https://sites.google.com/a/chromium.org/chromedriver/downloads>
24
+ *
25
+ * SELENIUM_BROWSER=chrome node selenium-webdriver/example/headless.js
26
+ *
27
+ * To run with Firefox, ensure you have Firefox 57+ installed and that
28
+ * geckodriver 0.19.0+ is present on your system PATH:
29
+ * <https://github.com/mozilla/geckodriver/releases>
30
+ *
31
+ * SELENIUM_BROWSER=firefox node selenium-webdriver/example/headless.js
32
+ */
33
+
34
+ const chrome = require('../chrome');
35
+ const firefox = require('../firefox');
36
+ const {Builder, By, Key, until} = require('..');
37
+
38
+ const width = 640;
39
+ const height = 480;
40
+
41
+ let driver = new Builder()
42
+ .forBrowser('chrome')
43
+ .setChromeOptions(
44
+ new chrome.Options().headless().windowSize({width, height}))
45
+ .setFirefoxOptions(
46
+ new firefox.Options().headless().windowSize({width, height}))
47
+ .build();
48
+
49
+ driver.get('http://www.google.com/ncr')
50
+ .then(_ =>
51
+ driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN))
52
+ .then(_ => driver.wait(until.titleIs('webdriver - Google Search'), 1000))
53
+ .then(
54
+ _ => driver.quit(),
55
+ e => driver.quit().then(() => { throw e; }));
@@ -21,15 +21,48 @@
21
21
 
22
22
  'use strict';
23
23
 
24
- const {Builder, By, logging, until} = require('..');
24
+ const chrome = require('../chrome');
25
+ const firefox = require('../firefox');
26
+ const edge = require('../edge');
27
+ const {Builder, By, Key, logging, until} = require('..');
25
28
 
26
29
  logging.installConsoleHandler();
27
30
  logging.getLogger('webdriver.http').setLevel(logging.Level.ALL);
28
31
 
29
- var driver = new Builder().forBrowser('firefox').build();
32
+ (async function() {
33
+ let driver;
34
+ try {
35
+ driver = await new Builder()
36
+ // Default to using Firefox. This can be overridden at runtime by
37
+ // setting the SELENIUM_BROWSER environment variable:
38
+ //
39
+ // SELENIUM_BROWSER=chrome node selenium-webdriver/example/logging.js
40
+ .forBrowser('firefox')
41
+ // Configure the service for each browser to enable verbose logging and
42
+ // to inherit the stdio settings from the current process. The builder
43
+ // will only start the service if needed for the selected browser.
44
+ .setChromeService(
45
+ new chrome.ServiceBuilder()
46
+ .enableVerboseLogging()
47
+ .setStdio('inherit'))
48
+ .setEdgeService(
49
+ process.platform === 'win32'
50
+ ? new edge.ServiceBuilder()
51
+ .enableVerboseLogging()
52
+ .setStdio('inherit')
53
+ : null)
54
+ .setFirefoxService(
55
+ new firefox.ServiceBuilder()
56
+ .enableVerboseLogging()
57
+ .setStdio('inherit'))
58
+ .build();
30
59
 
31
- driver.get('http://www.google.com/ncr')
32
- .then(_ => driver.findElement(By.name('q')).sendKeys('webdriver'))
33
- .then(_ => driver.findElement(By.name('btnG')).click())
34
- .then(_ => driver.wait(until.titleIs('webdriver - Google Search'), 1000))
35
- .then(_ => driver.quit());
60
+ await driver.get('http://www.google.com/ncr');
61
+ await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
62
+ await driver.wait(until.titleIs('webdriver - Google Search'), 1000);
63
+ } finally {
64
+ if (driver) {
65
+ await driver.quit();
66
+ }
67
+ }
68
+ })();