selenium-webdriver 4.0.0-alpha.5 → 4.0.0-beta.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 (49) hide show
  1. package/CHANGES.md +35 -1
  2. package/LICENSE +1 -1
  3. package/NOTICE +1 -1
  4. package/README.md +4 -4
  5. package/chrome.js +72 -592
  6. package/chromium.js +829 -0
  7. package/devtools/CDPConnection.js +37 -0
  8. package/edge.js +124 -86
  9. package/example/chrome_android.js +16 -13
  10. package/example/chrome_mobile_emulation.js +18 -14
  11. package/example/firefox_channels.js +35 -28
  12. package/example/google_search.js +9 -9
  13. package/example/google_search_test.js +20 -22
  14. package/example/headless.js +27 -19
  15. package/example/logging.js +34 -38
  16. package/firefox.js +200 -200
  17. package/http/index.js +131 -115
  18. package/http/util.js +56 -64
  19. package/ie.js +180 -104
  20. package/index.js +246 -199
  21. package/io/exec.js +34 -39
  22. package/io/index.js +142 -152
  23. package/io/zip.js +75 -65
  24. package/lib/actions.js +140 -122
  25. package/lib/atoms/find-elements.js +124 -0
  26. package/lib/atoms/get-attribute.js +79 -59
  27. package/lib/atoms/is-displayed.js +72 -73
  28. package/lib/atoms/mutation-listener.js +38 -0
  29. package/lib/by.js +192 -65
  30. package/lib/capabilities.js +82 -78
  31. package/lib/command.js +20 -20
  32. package/lib/error.js +134 -168
  33. package/lib/http.js +337 -230
  34. package/lib/input.js +325 -302
  35. package/lib/logging.js +127 -138
  36. package/lib/promise.js +60 -66
  37. package/lib/proxy.js +31 -41
  38. package/lib/session.js +12 -15
  39. package/lib/symbols.js +3 -4
  40. package/lib/until.js +162 -160
  41. package/lib/webdriver.js +1024 -541
  42. package/net/index.js +30 -36
  43. package/net/portprober.js +31 -144
  44. package/opera.js +406 -0
  45. package/package.json +19 -12
  46. package/proxy.js +2 -2
  47. package/remote/index.js +190 -187
  48. package/safari.js +40 -49
  49. package/testing/index.js +166 -155
package/io/exec.js CHANGED
@@ -15,10 +15,9 @@
15
15
  // specific language governing permissions and limitations
16
16
  // under the License.
17
17
 
18
- 'use strict';
19
-
20
- const childProcess = require('child_process');
18
+ 'use strict'
21
19
 
20
+ const childProcess = require('child_process')
22
21
 
23
22
  /**
24
23
  * Options for configuring an executed command.
@@ -31,7 +30,7 @@ class Options {
31
30
  * Command line arguments for the child process, if any.
32
31
  * @type (!Array<string>|undefined)
33
32
  */
34
- this.args;
33
+ this.args
35
34
 
36
35
  /**
37
36
  * Environment variables for the spawned process. If unspecified, the
@@ -39,7 +38,7 @@ class Options {
39
38
  *
40
39
  * @type {(!Object<string, string>|undefined)}
41
40
  */
42
- this.env;
41
+ this.env
43
42
 
44
43
  /**
45
44
  * IO conifguration for the spawned server child process. If unspecified,
@@ -49,11 +48,10 @@ class Options {
49
48
  * undefined)}
50
49
  * @see <https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_options_stdio>
51
50
  */
52
- this.stdio;
51
+ this.stdio
53
52
  }
54
53
  }
55
54
 
56
-
57
55
  /**
58
56
  * Describes a command's termination conditions.
59
57
  */
@@ -66,21 +64,20 @@ class Result {
66
64
  */
67
65
  constructor(code, signal) {
68
66
  /** @type {?number} */
69
- this.code = code;
67
+ this.code = code
70
68
 
71
69
  /** @type {?string} */
72
- this.signal = signal;
70
+ this.signal = signal
73
71
  }
74
72
 
75
73
  /** @override */
76
74
  toString() {
77
- return `Result(code=${this.code}, signal=${this.signal})`;
75
+ return `Result(code=${this.code}, signal=${this.signal})`
78
76
  }
79
77
  }
80
78
 
81
-
82
- const COMMAND_RESULT = /** !WeakMap<!Command, !Promise<!Result>> */new WeakMap;
83
- const KILL_HOOK = /** !WeakMap<!Command, function(string)> */new WeakMap;
79
+ const COMMAND_RESULT = /** !WeakMap<!Command, !Promise<!Result>> */ new WeakMap()
80
+ const KILL_HOOK = /** !WeakMap<!Command, function(string)> */ new WeakMap()
84
81
 
85
82
  /**
86
83
  * Represents a command running in a sub-process.
@@ -92,8 +89,8 @@ class Command {
92
89
  * is called.
93
90
  */
94
91
  constructor(result, onKill) {
95
- COMMAND_RESULT.set(this, result);
96
- KILL_HOOK.set(this, onKill);
92
+ COMMAND_RESULT.set(this, result)
93
+ KILL_HOOK.set(this, onKill)
97
94
  }
98
95
 
99
96
  /**
@@ -101,7 +98,7 @@ class Command {
101
98
  * command.
102
99
  */
103
100
  result() {
104
- return /** @type {!Promise<!Result>} */(COMMAND_RESULT.get(this));
101
+ return /** @type {!Promise<!Result>} */ (COMMAND_RESULT.get(this))
105
102
  }
106
103
 
107
104
  /**
@@ -109,14 +106,12 @@ class Command {
109
106
  * @param {string=} opt_signal The signal to send; defaults to `SIGTERM`.
110
107
  */
111
108
  kill(opt_signal) {
112
- KILL_HOOK.get(this)(opt_signal || 'SIGTERM');
109
+ KILL_HOOK.get(this)(opt_signal || 'SIGTERM')
113
110
  }
114
111
  }
115
112
 
116
-
117
113
  // PUBLIC API
118
114
 
119
-
120
115
  /**
121
116
  * Spawns a child process. The returned {@link Command} may be used to wait
122
117
  * for the process result or to send signals to the process.
@@ -126,42 +121,42 @@ class Command {
126
121
  * @return {!Command} The launched command.
127
122
  */
128
123
  module.exports = function exec(command, opt_options) {
129
- var options = opt_options || {};
124
+ var options = opt_options || {}
130
125
 
131
126
  var proc = childProcess.spawn(command, options.args || [], {
132
127
  env: options.env || process.env,
133
- stdio: options.stdio || 'ignore'
134
- });
128
+ stdio: options.stdio || 'ignore',
129
+ })
135
130
 
136
131
  // This process should not wait on the spawned child, however, we do
137
132
  // want to ensure the child is killed when this process exits.
138
- proc.unref();
139
- process.once('exit', onProcessExit);
133
+ proc.unref()
134
+ process.once('exit', onProcessExit)
140
135
 
141
- let result = new Promise(resolve => {
136
+ let result = new Promise((resolve) => {
142
137
  proc.once('exit', (code, signal) => {
143
- proc = null;
144
- process.removeListener('exit', onProcessExit);
145
- resolve(new Result(code, signal));
146
- });
147
- });
148
- return new Command(result, killCommand);
138
+ proc = null
139
+ process.removeListener('exit', onProcessExit)
140
+ resolve(new Result(code, signal))
141
+ })
142
+ })
143
+ return new Command(result, killCommand)
149
144
 
150
145
  function onProcessExit() {
151
- killCommand('SIGTERM');
146
+ killCommand('SIGTERM')
152
147
  }
153
148
 
154
149
  function killCommand(signal) {
155
- process.removeListener('exit', onProcessExit);
150
+ process.removeListener('exit', onProcessExit)
156
151
  if (proc) {
157
- proc.kill(signal);
158
- proc = null;
152
+ proc.kill(signal)
153
+ proc = null
159
154
  }
160
155
  }
161
- };
156
+ }
162
157
 
163
158
  // Exported to improve generated API documentation.
164
159
 
165
- module.exports.Command = Command;
166
- module.exports.Options = Options;
167
- module.exports.Result = Result;
160
+ module.exports.Command = Command
161
+ module.exports.Options = Options
162
+ module.exports.Result = Result
package/io/index.js CHANGED
@@ -15,13 +15,12 @@
15
15
  // specific language governing permissions and limitations
16
16
  // under the License.
17
17
 
18
- 'use strict';
19
-
20
- var fs = require('fs'),
21
- path = require('path'),
22
- rimraf = require('rimraf'),
23
- tmp = require('tmp');
18
+ 'use strict'
24
19
 
20
+ const fs = require('fs')
21
+ const path = require('path')
22
+ const rimraf = require('rimraf')
23
+ const tmp = require('tmp')
25
24
 
26
25
  /**
27
26
  * @param {!Function} fn .
@@ -33,23 +32,19 @@ function checkedCall(fn) {
33
32
  try {
34
33
  fn((err, value) => {
35
34
  if (err) {
36
- reject(err);
35
+ reject(err)
37
36
  } else {
38
- resolve(value);
37
+ resolve(value)
39
38
  }
40
- });
39
+ })
41
40
  } catch (e) {
42
- reject(e);
41
+ reject(e)
43
42
  }
44
- });
43
+ })
45
44
  }
46
45
 
47
-
48
-
49
46
  // PUBLIC API
50
47
 
51
-
52
-
53
48
  /**
54
49
  * Recursively removes a directory and all of its contents. This is equivalent
55
50
  * to {@code rm -rf} on a POSIX system.
@@ -57,27 +52,26 @@ function checkedCall(fn) {
57
52
  * @return {!Promise} A promise to be resolved when the operation has
58
53
  * completed.
59
54
  */
60
- exports.rmDir = function(dirPath) {
61
- return new Promise(function(fulfill, reject) {
62
- var numAttempts = 0;
63
- attemptRm();
55
+ exports.rmDir = function (dirPath) {
56
+ return new Promise(function (fulfill, reject) {
57
+ var numAttempts = 0
58
+ attemptRm()
64
59
  function attemptRm() {
65
- numAttempts += 1;
66
- rimraf(dirPath, function(err) {
60
+ numAttempts += 1
61
+ rimraf(dirPath, function (err) {
67
62
  if (err) {
68
63
  if (err.code && err.code === 'ENOTEMPTY' && numAttempts < 2) {
69
- attemptRm();
70
- return;
64
+ attemptRm()
65
+ return
71
66
  }
72
- reject(err);
67
+ reject(err)
73
68
  } else {
74
- fulfill();
69
+ fulfill()
75
70
  }
76
- });
71
+ })
77
72
  }
78
- });
79
- };
80
-
73
+ })
74
+ }
81
75
 
82
76
  /**
83
77
  * Copies one file to another.
@@ -85,19 +79,18 @@ exports.rmDir = function(dirPath) {
85
79
  * @param {string} dst The destination file.
86
80
  * @return {!Promise<string>} A promise for the copied file's path.
87
81
  */
88
- exports.copy = function(src, dst) {
89
- return new Promise(function(fulfill, reject) {
90
- var rs = fs.createReadStream(src);
91
- rs.on('error', reject);
82
+ exports.copy = function (src, dst) {
83
+ return new Promise(function (fulfill, reject) {
84
+ var rs = fs.createReadStream(src)
85
+ rs.on('error', reject)
92
86
 
93
- var ws = fs.createWriteStream(dst);
94
- ws.on('error', reject);
95
- ws.on('close', () => fulfill(dst));
96
-
97
- rs.pipe(ws);
98
- });
99
- };
87
+ var ws = fs.createWriteStream(dst)
88
+ ws.on('error', reject)
89
+ ws.on('close', () => fulfill(dst))
100
90
 
91
+ rs.pipe(ws)
92
+ })
93
+ }
101
94
 
102
95
  /**
103
96
  * Recursively copies the contents of one directory to another.
@@ -109,63 +102,62 @@ exports.copy = function(src, dst) {
109
102
  * @return {!Promise<string>} A promise for the destination
110
103
  * directory's path once all files have been copied.
111
104
  */
112
- exports.copyDir = function(src, dst, opt_exclude) {
113
- var predicate = opt_exclude;
105
+ exports.copyDir = function (src, dst, opt_exclude) {
106
+ var predicate = opt_exclude
114
107
  if (opt_exclude && typeof opt_exclude !== 'function') {
115
- predicate = function(p) {
116
- return !opt_exclude.test(p);
117
- };
108
+ predicate = function (p) {
109
+ return !opt_exclude.test(p)
110
+ }
118
111
  }
119
112
 
120
113
  // TODO(jleyba): Make this function completely async.
121
114
  if (!fs.existsSync(dst)) {
122
- fs.mkdirSync(dst);
115
+ fs.mkdirSync(dst)
123
116
  }
124
117
 
125
- var files = fs.readdirSync(src);
126
- files = files.map(function(file) {
127
- return path.join(src, file);
128
- });
118
+ var files = fs.readdirSync(src)
119
+ files = files.map(function (file) {
120
+ return path.join(src, file)
121
+ })
129
122
 
130
123
  if (predicate) {
131
- files = files.filter(/** @type {function(string): boolean} */(predicate));
124
+ files = files.filter(/** @type {function(string): boolean} */ (predicate))
132
125
  }
133
126
 
134
- var results = [];
135
- files.forEach(function(file) {
136
- var stats = fs.statSync(file);
137
- var target = path.join(dst, path.basename(file));
127
+ var results = []
128
+ files.forEach(function (file) {
129
+ var stats = fs.statSync(file)
130
+ var target = path.join(dst, path.basename(file))
138
131
 
139
132
  if (stats.isDirectory()) {
140
133
  if (!fs.existsSync(target)) {
141
- fs.mkdirSync(target, stats.mode);
134
+ fs.mkdirSync(target, stats.mode)
142
135
  }
143
- results.push(exports.copyDir(file, target, predicate));
136
+ results.push(exports.copyDir(file, target, predicate))
144
137
  } else {
145
- results.push(exports.copy(file, target));
138
+ results.push(exports.copy(file, target))
146
139
  }
147
- });
148
-
149
- return Promise.all(results).then(() => dst);
150
- };
140
+ })
151
141
 
142
+ return Promise.all(results).then(() => dst)
143
+ }
152
144
 
153
145
  /**
154
146
  * Tests if a file path exists.
155
147
  * @param {string} aPath The path to test.
156
148
  * @return {!Promise<boolean>} A promise for whether the file exists.
157
149
  */
158
- exports.exists = function(aPath) {
159
- return new Promise(function(fulfill, reject) {
160
- let type = typeof aPath;
150
+ exports.exists = function (aPath) {
151
+ return new Promise(function (fulfill, reject) {
152
+ let type = typeof aPath
161
153
  if (type !== 'string') {
162
- reject(TypeError(`expected string path, but got ${type}`));
154
+ reject(TypeError(`expected string path, but got ${type}`))
163
155
  } else {
164
- fs.exists(aPath, fulfill);
156
+ // eslint-disable-next-line node/no-deprecated-api
157
+ fs.exists(aPath, fulfill)
165
158
  }
166
- });
167
- };
168
-
159
+ })
160
+ }
169
161
 
170
162
  /**
171
163
  * Calls `stat(2)`.
@@ -173,9 +165,8 @@ exports.exists = function(aPath) {
173
165
  * @return {!Promise<!fs.Stats>} A promise for the file stats.
174
166
  */
175
167
  exports.stat = function stat(aPath) {
176
- return checkedCall(callback => fs.stat(aPath, callback));
177
- };
178
-
168
+ return checkedCall((callback) => fs.stat(aPath, callback))
169
+ }
179
170
 
180
171
  /**
181
172
  * Deletes a name from the filesystem and possibly the file it refers to. Has
@@ -183,47 +174,45 @@ exports.stat = function stat(aPath) {
183
174
  * @param {string} aPath The path to remove.
184
175
  * @return {!Promise} A promise for when the file has been removed.
185
176
  */
186
- exports.unlink = function(aPath) {
187
- return new Promise(function(fulfill, reject) {
188
- fs.exists(aPath, function(exists) {
177
+ exports.unlink = function (aPath) {
178
+ return new Promise(function (fulfill, reject) {
179
+ // eslint-disable-next-line node/no-deprecated-api
180
+ fs.exists(aPath, function (exists) {
189
181
  if (exists) {
190
- fs.unlink(aPath, function(err) {
191
- err && reject(err) || fulfill();
192
- });
182
+ fs.unlink(aPath, function (err) {
183
+ ;(err && reject(err)) || fulfill()
184
+ })
193
185
  } else {
194
- fulfill();
186
+ fulfill()
195
187
  }
196
- });
197
- });
198
- };
199
-
188
+ })
189
+ })
190
+ }
200
191
 
201
192
  /**
202
193
  * @return {!Promise<string>} A promise for the path to a temporary directory.
203
194
  * @see https://www.npmjs.org/package/tmp
204
195
  */
205
- exports.tmpDir = function() {
206
- return checkedCall(tmp.dir);
207
- };
208
-
196
+ exports.tmpDir = function () {
197
+ return checkedCall((callback) => tmp.dir({ unsafeCleanup: true }, callback))
198
+ }
209
199
 
210
200
  /**
211
201
  * @param {{postfix: string}=} opt_options Temporary file options.
212
202
  * @return {!Promise<string>} A promise for the path to a temporary file.
213
203
  * @see https://www.npmjs.org/package/tmp
214
204
  */
215
- exports.tmpFile = function(opt_options) {
216
- return checkedCall(callback => {
205
+ exports.tmpFile = function (opt_options) {
206
+ return checkedCall((callback) => {
217
207
  // |tmp.file| checks arguments length to detect options rather than doing a
218
208
  // truthy check, so we must only pass options if there are some to pass.
219
209
  if (opt_options) {
220
- tmp.file(opt_options, callback);
210
+ tmp.file(opt_options, callback)
221
211
  } else {
222
- tmp.file(callback);
212
+ tmp.file(callback)
223
213
  }
224
- });
225
- };
226
-
214
+ })
215
+ }
227
216
 
228
217
  /**
229
218
  * Searches the {@code PATH} environment variable for the given file.
@@ -234,26 +223,25 @@ exports.tmpFile = function(opt_options) {
234
223
  * @return {?string} Path to the located file, or {@code null} if it could
235
224
  * not be found.
236
225
  */
237
- exports.findInPath = function(file, opt_checkCwd) {
238
- let dirs = [];
226
+ exports.findInPath = function (file, opt_checkCwd) {
227
+ let dirs = []
239
228
  if (opt_checkCwd) {
240
- dirs.push(process.cwd());
229
+ dirs.push(process.cwd())
241
230
  }
242
- dirs.push.apply(dirs, process.env['PATH'].split(path.delimiter));
231
+ dirs.push.apply(dirs, process.env['PATH'].split(path.delimiter))
243
232
 
244
- let foundInDir = dirs.find(dir => {
245
- let tmp = path.join(dir, file);
233
+ let foundInDir = dirs.find((dir) => {
234
+ let tmp = path.join(dir, file)
246
235
  try {
247
- let stats = fs.statSync(tmp);
248
- return stats.isFile() && !stats.isDirectory();
236
+ let stats = fs.statSync(tmp)
237
+ return stats.isFile() && !stats.isDirectory()
249
238
  } catch (ex) {
250
- return false;
239
+ return false
251
240
  }
252
- });
253
-
254
- return foundInDir ? path.join(foundInDir, file) : null;
255
- };
241
+ })
256
242
 
243
+ return foundInDir ? path.join(foundInDir, file) : null
244
+ }
257
245
 
258
246
  /**
259
247
  * Reads the contents of the given file.
@@ -262,10 +250,9 @@ exports.findInPath = function(file, opt_checkCwd) {
262
250
  * @return {!Promise<!Buffer>} A promise that will resolve with a buffer of the
263
251
  * file contents.
264
252
  */
265
- exports.read = function(aPath) {
266
- return checkedCall(callback => fs.readFile(aPath, callback));
267
- };
268
-
253
+ exports.read = function (aPath) {
254
+ return checkedCall((callback) => fs.readFile(aPath, callback))
255
+ }
269
256
 
270
257
  /**
271
258
  * Writes to a file.
@@ -275,10 +262,9 @@ exports.read = function(aPath) {
275
262
  * @return {!Promise} A promise that will resolve when the operation has
276
263
  * completed.
277
264
  */
278
- exports.write = function(aPath, data) {
279
- return checkedCall(callback => fs.writeFile(aPath, data, callback));
280
- };
281
-
265
+ exports.write = function (aPath, data) {
266
+ return checkedCall((callback) => fs.writeFile(aPath, data, callback))
267
+ }
282
268
 
283
269
  /**
284
270
  * Creates a directory.
@@ -287,18 +273,17 @@ exports.write = function(aPath, data) {
287
273
  * @return {!Promise<string>} A promise that will resolve with the path of the
288
274
  * created directory.
289
275
  */
290
- exports.mkdir = function(aPath) {
291
- return checkedCall(callback => {
292
- fs.mkdir(aPath, undefined, err => {
276
+ exports.mkdir = function (aPath) {
277
+ return checkedCall((callback) => {
278
+ fs.mkdir(aPath, undefined, (err) => {
293
279
  if (err && err.code !== 'EEXIST') {
294
- callback(err);
280
+ callback(err)
295
281
  } else {
296
- callback(null, aPath);
282
+ callback(null, aPath)
297
283
  }
298
- });
299
- });
300
- };
301
-
284
+ })
285
+ })
286
+ }
302
287
 
303
288
  /**
304
289
  * Recursively creates a directory and any ancestors that do not yet exist.
@@ -308,29 +293,31 @@ exports.mkdir = function(aPath) {
308
293
  * created directory.
309
294
  */
310
295
  exports.mkdirp = function mkdirp(dir) {
311
- return checkedCall(callback => {
312
- fs.mkdir(dir, undefined, err => {
296
+ return checkedCall((callback) => {
297
+ fs.mkdir(dir, undefined, (err) => {
313
298
  if (!err) {
314
- callback(null, dir);
315
- return;
299
+ callback(null, dir)
300
+ return
316
301
  }
317
302
 
318
303
  switch (err.code) {
319
304
  case 'EEXIST':
320
- callback(null, dir);
321
- return;
305
+ callback(null, dir)
306
+ return
322
307
  case 'ENOENT':
323
308
  return mkdirp(path.dirname(dir))
324
- .then(() => mkdirp(dir))
325
- .then(() => callback(null, dir), err => callback(err));
309
+ .then(() => mkdirp(dir))
310
+ .then(
311
+ () => callback(null, dir),
312
+ (err) => callback(err)
313
+ )
326
314
  default:
327
- callback(err);
328
- return;
315
+ callback(err)
316
+ return
329
317
  }
330
- });
331
- });
332
- };
333
-
318
+ })
319
+ })
320
+ }
334
321
 
335
322
  /**
336
323
  * Recursively walks a directory, returning a promise that will resolve with
@@ -341,19 +328,22 @@ exports.mkdirp = function mkdirp(dir) {
341
328
  * resolve with a list of entries seen. For each entry, the recorded path
342
329
  * will be relative to `rootPath`.
343
330
  */
344
- exports.walkDir = function(rootPath) {
345
- let seen = [];
331
+ exports.walkDir = function (rootPath) {
332
+ let seen = []
346
333
  return (function walk(dir) {
347
- return checkedCall(callback => fs.readdir(dir, callback))
348
- .then(files => Promise.all(files.map(file => {
349
- file = path.join(dir, file);
350
- return checkedCall(cb => fs.stat(file, cb)).then(stats => {
334
+ return checkedCall((callback) => fs.readdir(dir, callback)).then((files) =>
335
+ Promise.all(
336
+ files.map((file) => {
337
+ file = path.join(dir, file)
338
+ return checkedCall((cb) => fs.stat(file, cb)).then((stats) => {
351
339
  seen.push({
352
340
  path: path.relative(rootPath, file),
353
- dir: stats.isDirectory()
354
- });
355
- return stats.isDirectory() && walk(file);
356
- });
357
- })));
358
- })(rootPath).then(() => seen);
359
- };
341
+ dir: stats.isDirectory(),
342
+ })
343
+ return stats.isDirectory() && walk(file)
344
+ })
345
+ })
346
+ )
347
+ )
348
+ })(rootPath).then(() => seen)
349
+ }