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/io/zip.js ADDED
@@ -0,0 +1,214 @@
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
+ const jszip = require('jszip');
21
+ const path = require('path');
22
+
23
+ const io = require('./index');
24
+ const {InvalidArgumentError} = require('../lib/error');
25
+
26
+ /**
27
+ * Manages a zip archive.
28
+ */
29
+ class Zip {
30
+ constructor() {
31
+ /** @private @const */
32
+ this.z_ = new jszip;
33
+
34
+ /** @private @const {!Set<!Promise<?>>} */
35
+ this.pendingAdds_ = new Set;
36
+ }
37
+
38
+ /**
39
+ * Adds a file to this zip.
40
+ *
41
+ * @param {string} filePath path to the file to add.
42
+ * @param {string=} zipPath path to the file in the zip archive, defaults
43
+ * to the basename of `filePath`.
44
+ * @return {!Promise<?>} a promise that will resolve when added.
45
+ */
46
+ addFile(filePath, zipPath = path.basename(filePath)) {
47
+ let add = io.read(filePath)
48
+ .then(buffer => this.z_.file(/** @type {string} */(zipPath), buffer));
49
+ this.pendingAdds_.add(add);
50
+ return add.then(
51
+ () => this.pendingAdds_.delete(add),
52
+ (e) => {
53
+ this.pendingAdds_.delete(add);
54
+ throw e;
55
+ });
56
+ }
57
+
58
+ /**
59
+ * Recursively adds a directory and all of its contents to this archive.
60
+ *
61
+ * @param {string} dirPath path to the directory to add.
62
+ * @param {string=} zipPath path to the folder in the archive to add the
63
+ * directory contents to. Defaults to the root folder.
64
+ * @return {!Promise<?>} returns a promise that will resolve when the
65
+ * the operation is complete.
66
+ */
67
+ addDir(dirPath, zipPath = '') {
68
+ return io.walkDir(dirPath).then(entries => {
69
+ let archive = this.z_;
70
+ if (zipPath) {
71
+ archive = archive.folder(zipPath);
72
+ }
73
+
74
+ let files = [];
75
+ entries.forEach(spec => {
76
+ if (spec.dir) {
77
+ archive.folder(spec.path);
78
+ } else {
79
+ files.push(
80
+ this.addFile(
81
+ path.join(dirPath, spec.path),
82
+ path.join(zipPath, spec.path)));
83
+ }
84
+ });
85
+
86
+ return Promise.all(files);
87
+ });
88
+ }
89
+
90
+ /**
91
+ * @param {string} path File path to test for within the archive.
92
+ * @return {boolean} Whether this zip archive contains an entry with the given
93
+ * path.
94
+ */
95
+ has(path) {
96
+ return this.z_.file(path) !== null;
97
+ }
98
+
99
+ /**
100
+ * Returns the contents of the file in this zip archive with the given `path`.
101
+ * The returned promise will be rejected with an {@link InvalidArgumentError}
102
+ * if either `path` does not exist within the archive, or if `path` refers
103
+ * to a directory.
104
+ *
105
+ * @param {string} path the path to the file whose contents to return.
106
+ * @return {!Promise<!Buffer>} a promise that will be resolved with the file's
107
+ * contents as a buffer.
108
+ */
109
+ getFile(path) {
110
+ let file = this.z_.file(path);
111
+ if (!file) {
112
+ return Promise.reject(
113
+ new InvalidArgumentError(`No such file in zip archive: ${path}`));
114
+ }
115
+
116
+ if (file.dir) {
117
+ return Promise.reject(
118
+ new InvalidArgumentError(
119
+ `The requested file is a directory: ${path}`));
120
+ }
121
+
122
+ return Promise.resolve(file.async('nodebuffer'));
123
+ }
124
+
125
+ /**
126
+ * Returns the compressed data for this archive in a buffer. _This method will
127
+ * not wait for any outstanding {@link #addFile add}
128
+ * {@link #addDir operations} before encoding the archive._
129
+ *
130
+ * @param {string} compression The desired compression.
131
+ * Must be `STORE` (the default) or `DEFLATE`.
132
+ * @return {!Promise<!Buffer>} a promise that will resolve with this archive
133
+ * as a buffer.
134
+ */
135
+ toBuffer(compression = 'STORE') {
136
+ if (compression !== 'STORE' && compression !== 'DEFLATE') {
137
+ return Promise.reject(
138
+ new InvalidArgumentError(
139
+ `compression must be one of {STORE, DEFLATE}, got ${compression}`));
140
+ }
141
+ return Promise.resolve(
142
+ this.z_.generateAsync({compression, type: 'nodebuffer'}));
143
+ }
144
+ }
145
+
146
+
147
+ /**
148
+ * Asynchronously opens a zip archive.
149
+ *
150
+ * @param {string} path to the zip archive to load.
151
+ * @return {!Promise<!Zip>} a promise that will resolve with the opened
152
+ * archive.
153
+ */
154
+ function load(path) {
155
+ return io.read(path).then(data => {
156
+ let zip = new Zip;
157
+ return zip.z_.loadAsync(data).then(() => zip);
158
+ });
159
+ }
160
+
161
+
162
+ /**
163
+ * Asynchronously unzips an archive file.
164
+ *
165
+ * @param {string} src path to the source file to unzip.
166
+ * @param {string} dst path to the destination directory.
167
+ * @return {!Promise<string>} a promise that will resolve with `dst` once the
168
+ * archive has been unzipped.
169
+ */
170
+ function unzip(src, dst) {
171
+ return load(src).then(zip => {
172
+ let promisedDirs = new Map;
173
+ let promises = [];
174
+
175
+ zip.z_.forEach((relPath, file) => {
176
+ let p;
177
+ if (file.dir) {
178
+ p = createDir(relPath);
179
+ } else {
180
+ let dirname = path.dirname(relPath);
181
+ if (dirname === '.') {
182
+ p = writeFile(relPath, file);
183
+ } else {
184
+ p = createDir(dirname).then(() => writeFile(relPath, file));
185
+ }
186
+ }
187
+ promises.push(p);
188
+ });
189
+
190
+ return Promise.all(promises).then(() => dst);
191
+
192
+ function createDir(dir) {
193
+ let p = promisedDirs.get(dir);
194
+ if (!p) {
195
+ p = io.mkdirp(path.join(dst, dir));
196
+ promisedDirs.set(dir, p);
197
+ }
198
+ return p;
199
+ }
200
+
201
+ function writeFile(relPath, file) {
202
+ return file.async('nodebuffer')
203
+ .then(buffer => io.write(path.join(dst, relPath), buffer));
204
+ }
205
+ });
206
+ }
207
+
208
+
209
+ // PUBLIC API
210
+
211
+
212
+ exports.Zip = Zip;
213
+ exports.load = load;
214
+ exports.unzip = unzip;
package/jasmine.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "spec_dir": "test",
3
+ "spec_files": [
4
+ "**/*_test.js"
5
+ ],
6
+ "helpers": [
7
+ "../lib/test/bootstrap_jasmine.js"
8
+ ],
9
+ "stopSpecOnExpectationFailure": false,
10
+ "random": false
11
+ }
package/lib/actions.js CHANGED
@@ -70,7 +70,7 @@ function checkModifierKey(key) {
70
70
  *
71
71
  * Sample usage:
72
72
  *
73
- * driver.actions().
73
+ * new LegacyActions(driver).
74
74
  * keyDown(Key.SHIFT).
75
75
  * click(element1).
76
76
  * click(element2).
@@ -78,8 +78,14 @@ function checkModifierKey(key) {
78
78
  * keyUp(Key.SHIFT).
79
79
  * perform();
80
80
  *
81
+ * @deprecated This class is strongly deprecated and will be removed once
82
+ * [Google's Chrome][Chrome] and [Microsoft's Edge][Edge] browsers
83
+ * support the new action sequence API.
84
+ *
85
+ * [Chrome]: https://chromium.googlesource.com/chromium/src/+/master/docs/chromedriver_status.md
86
+ * [Edge]: https://docs.microsoft.com/en-us/microsoft-edge/webdriver
81
87
  */
82
- class ActionSequence {
88
+ class LegacyActionSequence {
83
89
  /**
84
90
  * @param {!./webdriver.WebDriver} driver The driver that should be used to
85
91
  * perform this action sequence.
@@ -110,21 +116,17 @@ class ActionSequence {
110
116
  /**
111
117
  * Executes this action sequence.
112
118
  *
113
- * @return {!./promise.Thenable} A promise that will be resolved once
114
- * this sequence has completed.
119
+ * @return {!Promise} A promise that will be resolved once this sequence has
120
+ * completed.
115
121
  */
116
- perform() {
122
+ async perform() {
117
123
  // Make a protected copy of the scheduled actions. This will protect against
118
124
  // users defining additional commands before this sequence is actually
119
125
  // executed.
120
126
  let actions = this.actions_.concat();
121
- let driver = this.driver_;
122
- return driver.controlFlow().execute(function() {
123
- let results = actions.map(action => {
124
- return driver.schedule(action.command, action.description);
125
- });
126
- return Promise.all(results);
127
- }, 'ActionSequence.perform');
127
+ for (let action of actions) {
128
+ await this.driver_.execute(action.command);
129
+ }
128
130
  }
129
131
 
130
132
  /**
@@ -140,10 +142,10 @@ class ActionSequence {
140
142
  * an offset within that element. The offset should be specified in pixels
141
143
  * relative to the top-left corner of the element's bounding box. If
142
144
  * omitted, the element's center will be used as the target offset.
143
- * @return {!ActionSequence} A self reference.
145
+ * @return {!LegacyActionSequence} A self reference.
144
146
  */
145
147
  mouseMove(location, opt_offset) {
146
- let cmd = new command.Command(command.Name.MOVE_TO);
148
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_MOUSE_MOVE);
147
149
 
148
150
  if (typeof location.x === 'number') {
149
151
  setOffset(/** @type {{x: number, y: number}} */(location));
@@ -176,7 +178,7 @@ class ActionSequence {
176
178
  * @param {input.Button=} opt_button The button to use. Defaults to
177
179
  * {@link input.Button.LEFT}. Ignored if the previous argument is
178
180
  * provided as a button.
179
- * @return {!ActionSequence} A self reference.
181
+ * @return {!LegacyActionSequence} A self reference.
180
182
  * @private
181
183
  */
182
184
  scheduleMouseAction_(
@@ -219,11 +221,11 @@ class ActionSequence {
219
221
  * @param {input.Button=} opt_button The button to use. Defaults to
220
222
  * {@link input.Button.LEFT}. Ignored if a button is provided as the
221
223
  * first argument.
222
- * @return {!ActionSequence} A self reference.
224
+ * @return {!LegacyActionSequence} A self reference.
223
225
  */
224
226
  mouseDown(opt_elementOrButton, opt_button) {
225
227
  return this.scheduleMouseAction_('mouseDown',
226
- command.Name.MOUSE_DOWN, opt_elementOrButton, opt_button);
228
+ command.Name.LEGACY_ACTION_MOUSE_DOWN, opt_elementOrButton, opt_button);
227
229
  }
228
230
 
229
231
  /**
@@ -245,11 +247,11 @@ class ActionSequence {
245
247
  * @param {input.Button=} opt_button The button to use. Defaults to
246
248
  * {@link input.Button.LEFT}. Ignored if a button is provided as the
247
249
  * first argument.
248
- * @return {!ActionSequence} A self reference.
250
+ * @return {!LegacyActionSequence} A self reference.
249
251
  */
250
252
  mouseUp(opt_elementOrButton, opt_button) {
251
253
  return this.scheduleMouseAction_('mouseUp',
252
- command.Name.MOUSE_UP, opt_elementOrButton, opt_button);
254
+ command.Name.LEGACY_ACTION_MOUSE_UP, opt_elementOrButton, opt_button);
253
255
  }
254
256
 
255
257
  /**
@@ -261,7 +263,7 @@ class ActionSequence {
261
263
  * @param {(!./webdriver.WebElement|{x: number, y: number})} location The
262
264
  * location to drag to, either as another WebElement or an offset in
263
265
  * pixels.
264
- * @return {!ActionSequence} A self reference.
266
+ * @return {!LegacyActionSequence} A self reference.
265
267
  */
266
268
  dragAndDrop(element, location) {
267
269
  return this.mouseDown(element).mouseMove(location).mouseUp();
@@ -282,11 +284,11 @@ class ActionSequence {
282
284
  * @param {input.Button=} opt_button The button to use. Defaults to
283
285
  * {@link input.Button.LEFT}. Ignored if a button is provided as the
284
286
  * first argument.
285
- * @return {!ActionSequence} A self reference.
287
+ * @return {!LegacyActionSequence} A self reference.
286
288
  */
287
289
  click(opt_elementOrButton, opt_button) {
288
290
  return this.scheduleMouseAction_('click',
289
- command.Name.CLICK, opt_elementOrButton, opt_button);
291
+ command.Name.LEGACY_ACTION_CLICK, opt_elementOrButton, opt_button);
290
292
  }
291
293
 
292
294
  /**
@@ -307,11 +309,12 @@ class ActionSequence {
307
309
  * @param {input.Button=} opt_button The button to use. Defaults to
308
310
  * {@link input.Button.LEFT}. Ignored if a button is provided as the
309
311
  * first argument.
310
- * @return {!ActionSequence} A self reference.
312
+ * @return {!LegacyActionSequence} A self reference.
311
313
  */
312
314
  doubleClick(opt_elementOrButton, opt_button) {
313
315
  return this.scheduleMouseAction_('doubleClick',
314
- command.Name.DOUBLE_CLICK, opt_elementOrButton, opt_button);
316
+ command.Name.LEGACY_ACTION_DOUBLE_CLICK, opt_elementOrButton,
317
+ opt_button);
315
318
  }
316
319
 
317
320
  /**
@@ -320,11 +323,11 @@ class ActionSequence {
320
323
  * @param {string} description A simple descriptive label for the scheduled
321
324
  * action.
322
325
  * @param {!Array<(string|!input.Key)>} keys The keys to send.
323
- * @return {!ActionSequence} A self reference.
326
+ * @return {!LegacyActionSequence} A self reference.
324
327
  * @private
325
328
  */
326
329
  scheduleKeyboardAction_(description, keys) {
327
- let cmd = new command.Command(command.Name.SEND_KEYS_TO_ACTIVE_ELEMENT)
330
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_SEND_KEYS)
328
331
  .setParameter('value', keys);
329
332
  this.schedule_(description, cmd);
330
333
  return this;
@@ -337,7 +340,7 @@ class ActionSequence {
337
340
  *
338
341
  * @param {!input.Key} key The modifier key to push. Must be one of
339
342
  * {ALT, CONTROL, SHIFT, COMMAND, META}.
340
- * @return {!ActionSequence} A self reference.
343
+ * @return {!LegacyActionSequence} A self reference.
341
344
  * @throws {error.InvalidArgumentError} If the key is not a valid modifier
342
345
  * key.
343
346
  */
@@ -351,7 +354,7 @@ class ActionSequence {
351
354
  * focused element.
352
355
  * @param {!input.Key} key The modifier key to release. Must be one of
353
356
  * {ALT, CONTROL, SHIFT, COMMAND, META}.
354
- * @return {!ActionSequence} A self reference.
357
+ * @return {!LegacyActionSequence} A self reference.
355
358
  * @throws {error.InvalidArgumentError} If the key is not a valid modifier
356
359
  * key.
357
360
  */
@@ -367,7 +370,7 @@ class ActionSequence {
367
370
  *
368
371
  * @param {...(string|!input.Key|!Array<(string|!input.Key)>)} var_args
369
372
  * The keys to type.
370
- * @return {!ActionSequence} A self reference.
373
+ * @return {!LegacyActionSequence} A self reference.
371
374
  * @throws {Error} If the key is not a valid modifier key.
372
375
  */
373
376
  sendKeys(var_args) {
@@ -386,14 +389,20 @@ class ActionSequence {
386
389
  *
387
390
  * Sample usage:
388
391
  *
389
- * driver.touchActions().
392
+ * new LegacyActions(driver).
390
393
  * tapAndHold({x: 0, y: 0}).
391
394
  * move({x: 3, y: 4}).
392
395
  * release({x: 10, y: 10}).
393
396
  * perform();
394
397
  *
398
+ * @deprecated This class is strongly deprecated and will be removed once
399
+ * [Google's Chrome][Chrome] and [Microsoft's Edge][Edge] browsers
400
+ * support the new action sequence API.
401
+ *
402
+ * [Chrome]: https://chromium.googlesource.com/chromium/src/+/master/docs/chromedriver_status.md
403
+ * [Edge]: https://docs.microsoft.com/en-us/microsoft-edge/webdriver
395
404
  */
396
- class TouchSequence {
405
+ class LegacyTouchSequence {
397
406
  /**
398
407
  * @param {!./webdriver.WebDriver} driver The driver that should be used to
399
408
  * perform this action sequence.
@@ -422,31 +431,27 @@ class TouchSequence {
422
431
 
423
432
  /**
424
433
  * Executes this action sequence.
425
- * @return {!./promise.Thenable} A promise that will be resolved once
426
- * this sequence has completed.
434
+ * @return {!Promise} A promise that will be resolved once this sequence has
435
+ * completed.
427
436
  */
428
- perform() {
437
+ async perform() {
429
438
  // Make a protected copy of the scheduled actions. This will protect against
430
439
  // users defining additional commands before this sequence is actually
431
440
  // executed.
432
441
  let actions = this.actions_.concat();
433
- let driver = this.driver_;
434
- return driver.controlFlow().execute(function() {
435
- let results = actions.map(action => {
436
- return driver.schedule(action.command, action.description);
437
- });
438
- return Promise.all(results);
439
- }, 'TouchSequence.perform');
442
+ for (let action of actions) {
443
+ await this.driver_.execute(action.command);
444
+ }
440
445
  }
441
446
 
442
447
  /**
443
448
  * Taps an element.
444
449
  *
445
450
  * @param {!./webdriver.WebElement} elem The element to tap.
446
- * @return {!TouchSequence} A self reference.
451
+ * @return {!LegacyTouchSequence} A self reference.
447
452
  */
448
453
  tap(elem) {
449
- let cmd = new command.Command(command.Name.TOUCH_SINGLE_TAP).
454
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_TOUCH_SINGLE_TAP).
450
455
  setParameter('element', elem.getId());
451
456
 
452
457
  this.schedule_('tap', cmd);
@@ -457,10 +462,10 @@ class TouchSequence {
457
462
  * Double taps an element.
458
463
  *
459
464
  * @param {!./webdriver.WebElement} elem The element to double tap.
460
- * @return {!TouchSequence} A self reference.
465
+ * @return {!LegacyTouchSequence} A self reference.
461
466
  */
462
467
  doubleTap(elem) {
463
- let cmd = new command.Command(command.Name.TOUCH_DOUBLE_TAP).
468
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_TOUCH_DOUBLE_TAP).
464
469
  setParameter('element', elem.getId());
465
470
 
466
471
  this.schedule_('doubleTap', cmd);
@@ -471,10 +476,10 @@ class TouchSequence {
471
476
  * Long press on an element.
472
477
  *
473
478
  * @param {!./webdriver.WebElement} elem The element to long press.
474
- * @return {!TouchSequence} A self reference.
479
+ * @return {!LegacyTouchSequence} A self reference.
475
480
  */
476
481
  longPress(elem) {
477
- let cmd = new command.Command(command.Name.TOUCH_LONG_PRESS).
482
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_TOUCH_LONG_PRESS).
478
483
  setParameter('element', elem.getId());
479
484
 
480
485
  this.schedule_('longPress', cmd);
@@ -485,10 +490,10 @@ class TouchSequence {
485
490
  * Touch down at the given location.
486
491
  *
487
492
  * @param {{x: number, y: number}} location The location to touch down at.
488
- * @return {!TouchSequence} A self reference.
493
+ * @return {!LegacyTouchSequence} A self reference.
489
494
  */
490
495
  tapAndHold(location) {
491
- let cmd = new command.Command(command.Name.TOUCH_DOWN).
496
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_TOUCH_DOWN).
492
497
  setParameter('x', location.x).
493
498
  setParameter('y', location.y);
494
499
 
@@ -500,10 +505,10 @@ class TouchSequence {
500
505
  * Move a held {@linkplain #tapAndHold touch} to the specified location.
501
506
  *
502
507
  * @param {{x: number, y: number}} location The location to move to.
503
- * @return {!TouchSequence} A self reference.
508
+ * @return {!LegacyTouchSequence} A self reference.
504
509
  */
505
510
  move(location) {
506
- let cmd = new command.Command(command.Name.TOUCH_MOVE).
511
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_TOUCH_MOVE).
507
512
  setParameter('x', location.x).
508
513
  setParameter('y', location.y);
509
514
 
@@ -515,10 +520,10 @@ class TouchSequence {
515
520
  * Release a held {@linkplain #tapAndHold touch} at the specified location.
516
521
  *
517
522
  * @param {{x: number, y: number}} location The location to release at.
518
- * @return {!TouchSequence} A self reference.
523
+ * @return {!LegacyTouchSequence} A self reference.
519
524
  */
520
525
  release(location) {
521
- let cmd = new command.Command(command.Name.TOUCH_UP).
526
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_TOUCH_UP).
522
527
  setParameter('x', location.x).
523
528
  setParameter('y', location.y);
524
529
 
@@ -530,10 +535,10 @@ class TouchSequence {
530
535
  * Scrolls the touch screen by the given offset.
531
536
  *
532
537
  * @param {{x: number, y: number}} offset The offset to scroll to.
533
- * @return {!TouchSequence} A self reference.
538
+ * @return {!LegacyTouchSequence} A self reference.
534
539
  */
535
540
  scroll(offset) {
536
- let cmd = new command.Command(command.Name.TOUCH_SCROLL).
541
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_TOUCH_SCROLL).
537
542
  setParameter('xoffset', offset.x).
538
543
  setParameter('yoffset', offset.y);
539
544
 
@@ -547,10 +552,10 @@ class TouchSequence {
547
552
  *
548
553
  * @param {!./webdriver.WebElement} elem The element where scroll starts.
549
554
  * @param {{x: number, y: number}} offset The offset to scroll to.
550
- * @return {!TouchSequence} A self reference.
555
+ * @return {!LegacyTouchSequence} A self reference.
551
556
  */
552
557
  scrollFromElement(elem, offset) {
553
- let cmd = new command.Command(command.Name.TOUCH_SCROLL).
558
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_TOUCH_SCROLL).
554
559
  setParameter('element', elem.getId()).
555
560
  setParameter('xoffset', offset.x).
556
561
  setParameter('yoffset', offset.y);
@@ -564,10 +569,10 @@ class TouchSequence {
564
569
  *
565
570
  * @param {{xspeed: number, yspeed: number}} speed The speed to flick in each
566
571
  direction, in pixels per second.
567
- * @return {!TouchSequence} A self reference.
572
+ * @return {!LegacyTouchSequence} A self reference.
568
573
  */
569
574
  flick(speed) {
570
- let cmd = new command.Command(command.Name.TOUCH_FLICK).
575
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_TOUCH_FLICK).
571
576
  setParameter('xspeed', speed.xspeed).
572
577
  setParameter('yspeed', speed.yspeed);
573
578
 
@@ -581,10 +586,10 @@ class TouchSequence {
581
586
  * @param {!./webdriver.WebElement} elem The element where flick starts.
582
587
  * @param {{x: number, y: number}} offset The offset to flick to.
583
588
  * @param {number} speed The speed to flick at in pixels per second.
584
- * @return {!TouchSequence} A self reference.
589
+ * @return {!LegacyTouchSequence} A self reference.
585
590
  */
586
591
  flickElement(elem, offset, speed) {
587
- let cmd = new command.Command(command.Name.TOUCH_FLICK).
592
+ let cmd = new command.Command(command.Name.LEGACY_ACTION_TOUCH_FLICK).
588
593
  setParameter('element', elem.getId()).
589
594
  setParameter('xoffset', offset.x).
590
595
  setParameter('yoffset', offset.y).
@@ -599,6 +604,6 @@ class TouchSequence {
599
604
  // PUBLIC API
600
605
 
601
606
  module.exports = {
602
- ActionSequence: ActionSequence,
603
- TouchSequence: TouchSequence,
607
+ LegacyActionSequence,
608
+ LegacyTouchSequence,
604
609
  };
@@ -0,0 +1,9 @@
1
+ // GENERATED CODE - DO NOT EDIT
2
+ module.exports = function(){return function(){var d=this;function f(a){return"string"==typeof a};function h(a,b){this.code=a;this.a=l[a]||m;this.message=b||"";a=this.a.replace(/((?:^|\s+)[a-z])/g,function(a){return a.toUpperCase().replace(/^[\s\xa0]+/g,"")});b=a.length-5;if(0>b||a.indexOf("Error",b)!=b)a+="Error";this.name=a;a=Error(this.message);a.name=this.name;this.stack=a.stack||""}
3
+ (function(){var a=Error;function b(){}b.prototype=a.prototype;h.b=a.prototype;h.prototype=new b;h.prototype.constructor=h;h.a=function(b,c,g){for(var e=Array(arguments.length-2),k=2;k<arguments.length;k++)e[k-2]=arguments[k];return a.prototype[c].apply(b,e)}})();var m="unknown error",l={15:"element not selectable",11:"element not visible"};l[31]=m;l[30]=m;l[24]="invalid cookie domain";l[29]="invalid element coordinates";l[12]="invalid element state";l[32]="invalid selector";l[51]="invalid selector";
4
+ l[52]="invalid selector";l[17]="javascript error";l[405]="unsupported operation";l[34]="move target out of bounds";l[27]="no such alert";l[7]="no such element";l[8]="no such frame";l[23]="no such window";l[28]="script timeout";l[33]="session not created";l[10]="stale element reference";l[21]="timeout";l[25]="unable to set cookie";l[26]="unexpected alert open";l[13]=m;l[9]="unknown command";h.prototype.toString=function(){return this.name+": "+this.message};var n;a:{var p=d.navigator;if(p){var q=p.userAgent;if(q){n=q;break a}}n=""}function r(a){return-1!=n.indexOf(a)};function t(a,b){for(var e=a.length,c=f(a)?a.split(""):a,g=0;g<e;g++)g in c&&b.call(void 0,c[g],g,a)};function v(){return r("iPhone")&&!r("iPod")&&!r("iPad")};function w(){return(r("Chrome")||r("CriOS"))&&!r("Edge")};var x=r("Opera"),y=r("Trident")||r("MSIE"),z=r("Edge"),A=r("Gecko")&&!(-1!=n.toLowerCase().indexOf("webkit")&&!r("Edge"))&&!(r("Trident")||r("MSIE"))&&!r("Edge"),aa=-1!=n.toLowerCase().indexOf("webkit")&&!r("Edge");function B(){var a=d.document;return a?a.documentMode:void 0}var C;
5
+ a:{var D="",E=function(){var a=n;if(A)return/rv\:([^\);]+)(\)|;)/.exec(a);if(z)return/Edge\/([\d\.]+)/.exec(a);if(y)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(aa)return/WebKit\/(\S+)/.exec(a);if(x)return/(?:Version)[ \/]?(\S+)/.exec(a)}();E&&(D=E?E[1]:"");if(y){var F=B();if(null!=F&&F>parseFloat(D)){C=String(F);break a}}C=D}var G;var H=d.document;G=H&&y?B()||("CSS1Compat"==H.compatMode?parseInt(C,10):5):void 0;var ba=r("Firefox"),ca=v()||r("iPod"),da=r("iPad"),I=r("Android")&&!(w()||r("Firefox")||r("Opera")||r("Silk")),ea=w(),J=r("Safari")&&!(w()||r("Coast")||r("Opera")||r("Edge")||r("Silk")||r("Android"))&&!(v()||r("iPad")||r("iPod"));function K(a){return(a=a.exec(n))?a[1]:""}(function(){if(ba)return K(/Firefox\/([0-9.]+)/);if(y||z||x)return C;if(ea)return v()||r("iPad")||r("iPod")?K(/CriOS\/([0-9.]+)/):K(/Chrome\/([0-9.]+)/);if(J&&!(v()||r("iPad")||r("iPod")))return K(/Version\/([0-9.]+)/);if(ca||da){var a=/Version\/(\S+).*Mobile\/(\S+)/.exec(n);if(a)return a[1]+"."+a[2]}else if(I)return(a=K(/Android\s+([0-9.]+)/))?a:K(/Version\/([0-9.]+)/);return""})();var L,M=function(){if(!A)return!1;var a=d.Components;if(!a)return!1;try{if(!a.classes)return!1}catch(g){return!1}var b=a.classes,a=a.interfaces,e=b["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator),c=b["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo).version;L=function(a){e.compare(c,""+a)};return!0}(),N=y&&!(8<=Number(G)),fa=y&&!(9<=Number(G));I&&M&&L(2.3);I&&M&&L(4);J&&M&&L(6);var ga={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},O={IMG:" ",BR:"\n"};function P(a,b,e){if(!(a.nodeName in ga))if(3==a.nodeType)e?b.push(String(a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in O)b.push(O[a.nodeName]);else for(a=a.firstChild;a;)P(a,b,e),a=a.nextSibling};function Q(a,b){b=b.toLowerCase();return"style"==b?ha(a.style.cssText):N&&"value"==b&&R(a,"INPUT")?a.value:fa&&!0===a[b]?String(a.getAttribute(b)):(a=a.getAttributeNode(b))&&a.specified?a.value:null}var ia=/[;]+(?=(?:(?:[^"]*"){2})*[^"]*$)(?=(?:(?:[^']*'){2})*[^']*$)(?=(?:[^()]*\([^()]*\))*[^()]*$)/;
6
+ function ha(a){var b=[];t(a.split(ia),function(a){var c=a.indexOf(":");0<c&&(a=[a.slice(0,c),a.slice(c+1)],2==a.length&&b.push(a[0].toLowerCase(),":",a[1],";"))});b=b.join("");return b=";"==b.charAt(b.length-1)?b:b+";"}function S(a,b){N&&"value"==b&&R(a,"OPTION")&&null===Q(a,"value")?(b=[],P(a,b,!1),a=b.join("")):a=a[b];return a}function R(a,b){b&&"string"!==typeof b&&(b=b.toString());return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}
7
+ function T(a){return R(a,"OPTION")?!0:R(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):!1};var ja={"class":"className",readonly:"readOnly"},U="async autofocus autoplay checked compact complete controls declare defaultchecked defaultselected defer disabled draggable ended formnovalidate hidden indeterminate iscontenteditable ismap itemscope loop multiple muted nohref noresize noshade novalidate nowrap open paused pubdate readonly required reversed scoped seamless seeking selected spellcheck truespeed willvalidate".split(" ");function V(a,b){var e=null,c=b.toLowerCase();if("style"==c)return(e=a.style)&&!f(e)&&(e=e.cssText),e;if(("selected"==c||"checked"==c)&&T(a)){if(!T(a))throw new h(15,"Element is not selectable");b="selected";e=a.type&&a.type.toLowerCase();if("checkbox"==e||"radio"==e)b="checked";return S(a,b)?"true":null}var g=R(a,"A");if(R(a,"IMG")&&"src"==c||g&&"href"==c)return(e=Q(a,c))&&(e=S(a,c)),e;if("spellcheck"==c){e=Q(a,c);if(null!==e){if("false"==e.toLowerCase())return"false";if("true"==e.toLowerCase())return"true"}return S(a,
8
+ c)+""}g=ja[b]||b;a:if(f(U))c=f(c)&&1==c.length?U.indexOf(c,0):-1;else{for(var u=0;u<U.length;u++)if(u in U&&U[u]===c){c=u;break a}c=-1}if(0<=c)return(e=null!==Q(a,b)||S(a,g))?"true":null;try{var k=S(a,g)}catch(ka){}(c=null==k)||(c=typeof k,c="object"==c&&null!=k||"function"==c);c?e=Q(a,b):e=k;return null!=e?e.toString():null}var W=["_"],X=d;W[0]in X||!X.execScript||X.execScript("var "+W[0]);
9
+ for(var Y;W.length&&(Y=W.shift());){var Z;if(Z=!W.length)Z=void 0!==V;Z?X[Y]=V:X[Y]&&X[Y]!==Object.prototype[Y]?X=X[Y]:X=X[Y]={}};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null,document:typeof window!='undefined'?window.document:null}, arguments);};