selenium-webdriver 4.0.0 → 4.1.2

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.
package/http/util.js CHANGED
@@ -21,12 +21,12 @@
21
21
 
22
22
  'use strict'
23
23
 
24
- const Executor = require('./index').Executor,
25
- HttpClient = require('./index').HttpClient,
26
- HttpRequest = require('./index').Request,
27
- Command = require('../lib/command').Command,
28
- CommandName = require('../lib/command').Name,
29
- error = require('../lib/error')
24
+ const Executor = require('./index').Executor
25
+ const HttpClient = require('./index').HttpClient
26
+ const HttpRequest = require('./index').Request
27
+ const Command = require('../lib/command').Command
28
+ const CommandName = require('../lib/command').Name
29
+ const error = require('../lib/error')
30
30
 
31
31
  /**
32
32
  * Queries a WebDriver server for its current status.
@@ -43,18 +43,6 @@ function getStatus(url) {
43
43
 
44
44
  class CancellationError {}
45
45
 
46
- // PUBLIC API
47
-
48
- /**
49
- * Queries a WebDriver server for its current status.
50
- * @param {string} url Base URL of the server to query.
51
- * @return {!Promise<!Object>} A promise that resolves with
52
- * a hash of the server status.
53
- */
54
- exports.getStatus = getStatus
55
-
56
- exports.CancellationError = CancellationError
57
-
58
46
  /**
59
47
  * Waits for a WebDriver server to be healthy and accepting requests.
60
48
  * @param {string} url Base URL of the server to query.
@@ -65,7 +53,7 @@ exports.CancellationError = CancellationError
65
53
  * @return {!Promise} A promise that will resolve when the server is ready, or
66
54
  * if the wait is cancelled.
67
55
  */
68
- exports.waitForServer = function (url, timeout, opt_cancelToken) {
56
+ function waitForServer(url, timeout, opt_cancelToken) {
69
57
  return new Promise((onResolve, onReject) => {
70
58
  let start = Date.now()
71
59
 
@@ -120,7 +108,7 @@ exports.waitForServer = function (url, timeout, opt_cancelToken) {
120
108
  * @return {!Promise} A promise that will resolve when a 2xx is received from
121
109
  * the given URL, or if the wait is cancelled.
122
110
  */
123
- exports.waitForUrl = function (url, timeout, opt_cancelToken) {
111
+ function waitForUrl(url, timeout, opt_cancelToken) {
124
112
  return new Promise((onResolve, onReject) => {
125
113
  let client = new HttpClient(url)
126
114
  let request = new HttpRequest('GET', '')
@@ -170,3 +158,9 @@ exports.waitForUrl = function (url, timeout, opt_cancelToken) {
170
158
  }
171
159
  })
172
160
  }
161
+
162
+ // PUBLIC API
163
+ module.exports.getStatus = getStatus
164
+ module.exports.CancellationError = CancellationError
165
+ module.exports.waitForServer = waitForServer
166
+ module.exports.waitForUrl = waitForUrl
package/index.js CHANGED
@@ -45,7 +45,7 @@ const Capabilities = capabilities.Capabilities
45
45
  const Capability = capabilities.Capability
46
46
  const WebDriver = webdriver.WebDriver
47
47
 
48
- var seleniumServer
48
+ let seleniumServer
49
49
 
50
50
  /**
51
51
  * Starts an instance of the Selenium server if not yet running.
@@ -76,13 +76,12 @@ function startSeleniumServer(jar) {
76
76
  * @return {function(new: webdriver.WebDriver, ...?)}
77
77
  */
78
78
  function ensureFileDetectorsAreEnabled(ctor) {
79
- const mixin = class extends ctor {
79
+ return class extends ctor {
80
80
  /** @param {input.FileDetector} detector */
81
- setFileDetector(detector) {
81
+ setFileDetector (detector) {
82
82
  webdriver.WebDriver.prototype.setFileDetector.call(this, detector)
83
83
  }
84
84
  }
85
- return mixin
86
85
  }
87
86
 
88
87
  /**
@@ -103,7 +102,7 @@ function ensureFileDetectorsAreEnabled(ctor) {
103
102
  */
104
103
  class ThenableWebDriver {
105
104
  /** @param {...?} args */
106
- static createSession(...args) { } // eslint-disable-line
105
+ static createSession(...args) {} // eslint-disable-line
107
106
  }
108
107
 
109
108
  /**
@@ -339,10 +338,10 @@ class Builder {
339
338
  getCapabilities() {
340
339
  return this.capabilities_
341
340
  }
342
-
341
+
343
342
  /**
344
- * Sets the desired capability when requesting a new session.
345
- * If there is already a capability named key, its value will be overwritten with value.
343
+ * Sets the desired capability when requesting a new session.
344
+ * If there is already a capability named key, its value will be overwritten with value.
346
345
  * This is a convenience wrapper around builder.getCapabilities().set(key, value) to support Builder method chaining.
347
346
  * @param {string} key The capability key.
348
347
  * @param {*} value The capability value.
@@ -630,7 +629,7 @@ class Builder {
630
629
  if (typeof browser !== 'string') {
631
630
  throw TypeError(
632
631
  `Target browser must be a string, but is <${typeof browser}>;` +
633
- ' did you forget to call forBrowser()?'
632
+ ' did you forget to call forBrowser()?'
634
633
  )
635
634
  }
636
635
 
@@ -751,8 +750,8 @@ class Builder {
751
750
  default:
752
751
  throw new Error(
753
752
  'Do not know how to build driver: ' +
754
- browser +
755
- '; did you forget to call usingServer(url)?'
753
+ browser +
754
+ '; did you forget to call usingServer(url)?'
756
755
  )
757
756
  }
758
757
  }
@@ -808,9 +807,9 @@ function checkOptions(caps, key, optionType, setMethod) {
808
807
  if (val instanceof optionType) {
809
808
  throw new error.InvalidArgumentError(
810
809
  'Options class extends Capabilities and should not be set as key ' +
811
- `"${key}"; set browser-specific options with ` +
812
- `Builder.${setMethod}(). For more information, see the ` +
813
- 'documentation attached to the function that threw this error'
810
+ `"${key}"; set browser-specific options with ` +
811
+ `Builder.${setMethod}(). For more information, see the ` +
812
+ 'documentation attached to the function that threw this error'
814
813
  )
815
814
  }
816
815
  }
@@ -821,8 +820,9 @@ exports.Browser = capabilities.Browser
821
820
  exports.Builder = Builder
822
821
  exports.Button = input.Button
823
822
  exports.By = by.By
823
+ exports.RelativeBy = by.RelativeBy
824
824
  exports.withTagName = by.withTagName
825
- exports.withLocator = by.withLocator
825
+ exports.locateWith = by.locateWith
826
826
  exports.Capabilities = capabilities.Capabilities
827
827
  exports.Capability = capabilities.Capability
828
828
  exports.Condition = webdriver.Condition
package/io/index.js CHANGED
@@ -19,7 +19,6 @@
19
19
 
20
20
  const fs = require('fs')
21
21
  const path = require('path')
22
- const rimraf = require('rimraf')
23
22
  const tmp = require('tmp')
24
23
 
25
24
  /**
@@ -43,8 +42,6 @@ function checkedCall(fn) {
43
42
  })
44
43
  }
45
44
 
46
- // PUBLIC API
47
-
48
45
  /**
49
46
  * Recursively removes a directory and all of its contents. This is equivalent
50
47
  * to {@code rm -rf} on a POSIX system.
@@ -52,24 +49,16 @@ function checkedCall(fn) {
52
49
  * @return {!Promise} A promise to be resolved when the operation has
53
50
  * completed.
54
51
  */
55
- exports.rmDir = function (dirPath) {
52
+ function rmDir(dirPath) {
56
53
  return new Promise(function (fulfill, reject) {
57
- var numAttempts = 0
58
- attemptRm()
59
- function attemptRm() {
60
- numAttempts += 1
61
- rimraf(dirPath, function (err) {
62
- if (err) {
63
- if (err.code && err.code === 'ENOTEMPTY' && numAttempts < 2) {
64
- attemptRm()
65
- return
66
- }
67
- reject(err)
68
- } else {
69
- fulfill()
70
- }
71
- })
72
- }
54
+ fs.rm(dirPath, { recursive: true, maxRetries: 2 }, function (err) {
55
+ if (err && err.code === 'ENOENT') {
56
+ fulfill()
57
+ } else if (err) {
58
+ reject(err)
59
+ }
60
+ fulfill()
61
+ })
73
62
  })
74
63
  }
75
64
 
@@ -79,12 +68,12 @@ exports.rmDir = function (dirPath) {
79
68
  * @param {string} dst The destination file.
80
69
  * @return {!Promise<string>} A promise for the copied file's path.
81
70
  */
82
- exports.copy = function (src, dst) {
71
+ function copy(src, dst) {
83
72
  return new Promise(function (fulfill, reject) {
84
- var rs = fs.createReadStream(src)
73
+ const rs = fs.createReadStream(src)
85
74
  rs.on('error', reject)
86
75
 
87
- var ws = fs.createWriteStream(dst)
76
+ const ws = fs.createWriteStream(dst)
88
77
  ws.on('error', reject)
89
78
  ws.on('close', () => fulfill(dst))
90
79
 
@@ -102,20 +91,19 @@ exports.copy = function (src, dst) {
102
91
  * @return {!Promise<string>} A promise for the destination
103
92
  * directory's path once all files have been copied.
104
93
  */
105
- exports.copyDir = function (src, dst, opt_exclude) {
106
- var predicate = opt_exclude
94
+ function copyDir(src, dst, opt_exclude) {
95
+ let predicate = opt_exclude
107
96
  if (opt_exclude && typeof opt_exclude !== 'function') {
108
97
  predicate = function (p) {
109
98
  return !opt_exclude.test(p)
110
99
  }
111
100
  }
112
101
 
113
- // TODO(jleyba): Make this function completely async.
114
102
  if (!fs.existsSync(dst)) {
115
103
  fs.mkdirSync(dst)
116
104
  }
117
105
 
118
- var files = fs.readdirSync(src)
106
+ let files = fs.readdirSync(src)
119
107
  files = files.map(function (file) {
120
108
  return path.join(src, file)
121
109
  })
@@ -124,18 +112,18 @@ exports.copyDir = function (src, dst, opt_exclude) {
124
112
  files = files.filter(/** @type {function(string): boolean} */ (predicate))
125
113
  }
126
114
 
127
- var results = []
115
+ const results = []
128
116
  files.forEach(function (file) {
129
- var stats = fs.statSync(file)
130
- var target = path.join(dst, path.basename(file))
117
+ const stats = fs.statSync(file)
118
+ const target = path.join(dst, path.basename(file))
131
119
 
132
120
  if (stats.isDirectory()) {
133
121
  if (!fs.existsSync(target)) {
134
122
  fs.mkdirSync(target, stats.mode)
135
123
  }
136
- results.push(exports.copyDir(file, target, predicate))
124
+ results.push(copyDir(file, target, predicate))
137
125
  } else {
138
- results.push(exports.copy(file, target))
126
+ results.push(copy(file, target))
139
127
  }
140
128
  })
141
129
 
@@ -147,14 +135,13 @@ exports.copyDir = function (src, dst, opt_exclude) {
147
135
  * @param {string} aPath The path to test.
148
136
  * @return {!Promise<boolean>} A promise for whether the file exists.
149
137
  */
150
- exports.exists = function (aPath) {
138
+ function exists(aPath) {
151
139
  return new Promise(function (fulfill, reject) {
152
140
  let type = typeof aPath
153
141
  if (type !== 'string') {
154
142
  reject(TypeError(`expected string path, but got ${type}`))
155
143
  } else {
156
- // eslint-disable-next-line node/no-deprecated-api
157
- fs.exists(aPath, fulfill)
144
+ fulfill(fs.existsSync(aPath))
158
145
  }
159
146
  })
160
147
  }
@@ -164,7 +151,7 @@ exports.exists = function (aPath) {
164
151
  * @param {string} aPath The path to stat.
165
152
  * @return {!Promise<!fs.Stats>} A promise for the file stats.
166
153
  */
167
- exports.stat = function stat(aPath) {
154
+ function stat(aPath) {
168
155
  return checkedCall((callback) => fs.stat(aPath, callback))
169
156
  }
170
157
 
@@ -174,18 +161,16 @@ exports.stat = function stat(aPath) {
174
161
  * @param {string} aPath The path to remove.
175
162
  * @return {!Promise} A promise for when the file has been removed.
176
163
  */
177
- exports.unlink = function (aPath) {
164
+ function unlink(aPath) {
178
165
  return new Promise(function (fulfill, reject) {
179
- // eslint-disable-next-line node/no-deprecated-api
180
- fs.exists(aPath, function (exists) {
181
- if (exists) {
182
- fs.unlink(aPath, function (err) {
183
- ;(err && reject(err)) || fulfill()
184
- })
185
- } else {
186
- fulfill()
187
- }
188
- })
166
+ const exists = fs.existsSync(aPath)
167
+ if (exists) {
168
+ fs.unlink(aPath, function (err) {
169
+ ;(err && reject(err)) || fulfill()
170
+ })
171
+ } else {
172
+ fulfill()
173
+ }
189
174
  })
190
175
  }
191
176
 
@@ -193,7 +178,7 @@ exports.unlink = function (aPath) {
193
178
  * @return {!Promise<string>} A promise for the path to a temporary directory.
194
179
  * @see https://www.npmjs.org/package/tmp
195
180
  */
196
- exports.tmpDir = function () {
181
+ function tmpDir() {
197
182
  return checkedCall((callback) => tmp.dir({ unsafeCleanup: true }, callback))
198
183
  }
199
184
 
@@ -202,7 +187,7 @@ exports.tmpDir = function () {
202
187
  * @return {!Promise<string>} A promise for the path to a temporary file.
203
188
  * @see https://www.npmjs.org/package/tmp
204
189
  */
205
- exports.tmpFile = function (opt_options) {
190
+ function tmpFile(opt_options) {
206
191
  return checkedCall((callback) => {
207
192
  /** check fixed in v > 0.2.1 if
208
193
  * (typeof options === 'function') {
@@ -222,7 +207,7 @@ exports.tmpFile = function (opt_options) {
222
207
  * @return {?string} Path to the located file, or {@code null} if it could
223
208
  * not be found.
224
209
  */
225
- exports.findInPath = function (file, opt_checkCwd) {
210
+ function findInPath(file, opt_checkCwd) {
226
211
  const dirs = []
227
212
  if (opt_checkCwd) {
228
213
  dirs.push(process.cwd())
@@ -249,7 +234,7 @@ exports.findInPath = function (file, opt_checkCwd) {
249
234
  * @return {!Promise<!Buffer>} A promise that will resolve with a buffer of the
250
235
  * file contents.
251
236
  */
252
- exports.read = function (aPath) {
237
+ function read(aPath) {
253
238
  return checkedCall((callback) => fs.readFile(aPath, callback))
254
239
  }
255
240
 
@@ -261,7 +246,7 @@ exports.read = function (aPath) {
261
246
  * @return {!Promise} A promise that will resolve when the operation has
262
247
  * completed.
263
248
  */
264
- exports.write = function (aPath, data) {
249
+ function write(aPath, data) {
265
250
  return checkedCall((callback) => fs.writeFile(aPath, data, callback))
266
251
  }
267
252
 
@@ -272,7 +257,7 @@ exports.write = function (aPath, data) {
272
257
  * @return {!Promise<string>} A promise that will resolve with the path of the
273
258
  * created directory.
274
259
  */
275
- exports.mkdir = function (aPath) {
260
+ function mkdir(aPath) {
276
261
  return checkedCall((callback) => {
277
262
  fs.mkdir(aPath, undefined, (err) => {
278
263
  if (err && err.code !== 'EEXIST') {
@@ -291,7 +276,7 @@ exports.mkdir = function (aPath) {
291
276
  * @return {!Promise<string>} A promise that will resolve with the path of the
292
277
  * created directory.
293
278
  */
294
- exports.mkdirp = function mkdirp(dir) {
279
+ function mkdirp(dir) {
295
280
  return checkedCall((callback) => {
296
281
  fs.mkdir(dir, undefined, (err) => {
297
282
  if (!err) {
@@ -327,7 +312,7 @@ exports.mkdirp = function mkdirp(dir) {
327
312
  * resolve with a list of entries seen. For each entry, the recorded path
328
313
  * will be relative to `rootPath`.
329
314
  */
330
- exports.walkDir = function (rootPath) {
315
+ function walkDir(rootPath) {
331
316
  const seen = []
332
317
  return (function walk(dir) {
333
318
  return checkedCall((callback) => fs.readdir(dir, callback)).then((files) =>
@@ -346,3 +331,21 @@ exports.walkDir = function (rootPath) {
346
331
  )
347
332
  })(rootPath).then(() => seen)
348
333
  }
334
+
335
+ // PUBLIC API
336
+ module.exports = {
337
+ walkDir,
338
+ rmDir,
339
+ mkdirp,
340
+ mkdir,
341
+ write,
342
+ read,
343
+ findInPath,
344
+ tmpFile,
345
+ tmpDir,
346
+ unlink,
347
+ copy,
348
+ copyDir,
349
+ exists,
350
+ stat,
351
+ }
package/io/zip.js CHANGED
@@ -218,6 +218,4 @@ function unzip(src, dst) {
218
218
  }
219
219
 
220
220
  // PUBLIC API
221
- module.exports.Zip = Zip
222
- module.exports.load = load
223
- module.exports.unzip = unzip
221
+ module.exports = { Zip, load, unzip }
@@ -109,8 +109,8 @@ function gd(a){var b=a.shape.toLowerCase();a=a.coords.split(",");if("rect"==b&&4
109
109
  function hd(a){return a.replace(/^[^\S\xa0]+|[^\S\xa0]+$/g,"")}function id(a){var b=[];Yc?jd(a,b):kd(a,b);a=qa(b,hd);return hd(a.join("\n")).replace(/\xa0/g," ")}
110
110
  function ld(a,b,c){if(S(a,"BR"))b.push("");else{var d=S(a,"TD"),e=V(a,"display"),f=!d&&!(0<=oa(md,e)),g=void 0!==a.previousElementSibling?a.previousElementSibling:gb(a.previousSibling);g=g?V(g,"display"):"";var h=V(a,"float")||V(a,"cssFloat")||V(a,"styleFloat");!f||"run-in"==g&&"none"==h||/^[\s\xa0]*$/.test(b[b.length-1]||"")||b.push("");var n=ed(a),u=null,p=null;n&&(u=V(a,"white-space"),p=V(a,"text-transform"));l(a.childNodes,function(G){c(G,b,n,u,p)});a=b[b.length-1]||"";!d&&"table-cell"!=e||!a||
111
111
  za(a)||(b[b.length-1]+=" ");f&&"run-in"!=e&&!/^[\s\xa0]*$/.test(a)&&b.push("")}}function kd(a,b){ld(a,b,function(c,d,e,f,g){3==c.nodeType&&e?nd(c,d,f,g):S(c)&&kd(c,d)})}var md="inline inline-block inline-table none table-cell table-column table-column-group".split(" ");
112
- function nd(a,b,c,d){a=a.nodeValue.replace(/[\u200b\u200e\u200f]/g,"");a=a.replace(/(\r\n|\r|\n)/g,"\n");if("normal"==c||"nowrap"==c)a=a.replace(/\n/g," ");a="pre"==c||"pre-wrap"==c?a.replace(/[ \f\t\v\u2028\u2029]/g,"\u00a0"):a.replace(/[ \f\t\v\u2028\u2029]+/g," ");"capitalize"==d?a=a.replace(/(^|[^\d\p{L}\p{S}])([\p{Ll}|\p{S}])/gu,function(e,f,g){return f+g.toUpperCase()}):"uppercase"==d?a=a.toUpperCase():"lowercase"==d&&(a=a.toLowerCase());c=b.pop()||"";za(c)&&0==a.lastIndexOf(" ",0)&&(a=a.substr(1));
113
- b.push(c+a)}function dd(a){if(Mc){if("relative"==V(a,"position"))return 1;a=V(a,"filter");return(a=a.match(/^alpha\(opacity=(\d*)\)/)||a.match(/^progid:DXImageTransform.Microsoft.Alpha\(Opacity=(\d*)\)/))?Number(a[1])/100:1}return od(a)}function od(a){var b=1,c=V(a,"opacity");c&&(b=Number(c));(a=Zc(a))&&(b*=od(a));return b}
112
+ function nd(a,b,c,d){a=a.nodeValue.replace(/[\u200b\u200e\u200f]/g,"");a=a.replace(/(\r\n|\r|\n)/g,"\n");if("normal"==c||"nowrap"==c)a=a.replace(/\n/g," ");a="pre"==c||"pre-wrap"==c?a.replace(/[ \f\t\v\u2028\u2029]/g,"\u00a0"):a.replace(/[ \f\t\v\u2028\u2029]+/g," ");"capitalize"==d?a=a.replace(t?/(^|\s|\b)(\S)/g:/(^|[^\d\p{L}\p{S}])([\p{Ll}|\p{S}])/gu,function(e,f,g){return f+g.toUpperCase()}):"uppercase"==d?a=a.toUpperCase():"lowercase"==d&&(a=a.toLowerCase());c=b.pop()||"";za(c)&&0==a.lastIndexOf(" ",
113
+ 0)&&(a=a.substr(1));b.push(c+a)}function dd(a){if(Mc){if("relative"==V(a,"position"))return 1;a=V(a,"filter");return(a=a.match(/^alpha\(opacity=(\d*)\)/)||a.match(/^progid:DXImageTransform.Microsoft.Alpha\(Opacity=(\d*)\)/))?Number(a[1])/100:1}return od(a)}function od(a){var b=1,c=V(a,"opacity");c&&(b=Number(c));(a=Zc(a))&&(b*=od(a));return b}
114
114
  function pd(a,b,c,d,e){if(3==a.nodeType&&c)nd(a,b,d,e);else if(S(a))if(S(a,"CONTENT")||S(a,"SLOT")){for(var f=a;f.parentNode;)f=f.parentNode;f instanceof ShadowRoot?(a=S(a,"CONTENT")?a.getDistributedNodes():a.assignedNodes(),l(a,function(g){pd(g,b,c,d,e)})):jd(a,b)}else if(S(a,"SHADOW")){for(f=a;f.parentNode;)f=f.parentNode;if(f instanceof ShadowRoot&&(a=f))for(a=a.olderShadowRoot;a;)l(a.childNodes,function(g){pd(g,b,c,d,e)}),a=a.olderShadowRoot}else jd(a,b)}
115
115
  function jd(a,b){a.shadowRoot&&l(a.shadowRoot.childNodes,function(c){pd(c,b,!0,null,null)});ld(a,b,function(c,d,e,f,g){var h=null;1==c.nodeType?h=c:3==c.nodeType&&(h=c);null!=h&&(null!=h.assignedSlot||h.getDestinationInsertionPoints&&0<h.getDestinationInsertionPoints().length)||pd(c,d,e,f,g)})};var qd={C:function(a,b){return!(!a.querySelectorAll||!a.querySelector)&&!/^\d.*/.test(b)},o:function(a,b){var c=eb(b),d="string"===typeof a?c.a.getElementById(a):a;return d?Uc(d,"id")==a&&b!=d&&hb(b,d)?d:ua(mb(c,"*"),function(e){return Uc(e,"id")==a&&b!=e&&hb(b,e)}):null},j:function(a,b){if(!a)return[];if(qd.C(b,a))try{return b.querySelectorAll("#"+qd.T(a))}catch(c){return[]}b=mb(eb(b),"*",null,b);return pa(b,function(c){return Uc(c,"id")==a})},T:function(a){return a.replace(/([\s'"\\#.:;,!?+<>=~*^$|%&@`{}\-\/\[\]\(\)])/g,
116
116
  "\\$1")}};var Y={},rd={};Y.N=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return ua(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.K=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return pa(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.o=function(a,b){return Y.N(a,b,!1)};Y.j=function(a,b){return Y.K(a,b,!1)};rd.o=function(a,b){return Y.N(a,b,!0)};
package/lib/by.js CHANGED
@@ -190,11 +190,9 @@ class By {
190
190
  * @return {function(!./webdriver.WebDriver): !Promise}
191
191
  * A new JavaScript-based locator function.
192
192
  */
193
- static js(script, var_args) { // eslint-disable-line
194
- // eslint-disable-line
195
- let args = Array.prototype.slice.call(arguments, 0)
193
+ static js(script, ...var_args) {
196
194
  return function (driver) {
197
- return driver.executeScript.apply(driver, args)
195
+ return driver.executeScript.call(driver, script, ...var_args)
198
196
  }
199
197
  }
200
198
 
@@ -227,7 +225,7 @@ class By {
227
225
  * @return {!By} The new locator.
228
226
  */
229
227
  static tagName(name) {
230
- return By.css(name)
228
+ return new By('tag name', name)
231
229
  }
232
230
 
233
231
  /**
@@ -277,7 +275,7 @@ function withTagName(tagName) {
277
275
  * @returns {RelativeBy}
278
276
  */
279
277
  function locateWith(by) {
280
- return new RelativeBy(getLocator(by));
278
+ return new RelativeBy(getLocator(by))
281
279
  }
282
280
 
283
281
  function getLocator(locatorOrElement) {
@@ -426,9 +424,10 @@ function check(locator) {
426
424
  // PUBLIC API
427
425
 
428
426
  module.exports = {
429
- By: By,
430
- RelativeBy: RelativeBy,
431
- withTagName: withTagName,
432
- locateWith: locateWith,
427
+ By,
428
+ RelativeBy,
429
+ withTagName,
430
+ locateWith,
431
+ escapeCss,
433
432
  checkedLocator: check,
434
433
  }
@@ -83,7 +83,7 @@ const Platform = {
83
83
  *
84
84
  * @record
85
85
  */
86
- function Timeouts() { }
86
+ function Timeouts() {}
87
87
 
88
88
  /**
89
89
  * Defines when, in milliseconds, to interrupt a script that is being
package/lib/command.js CHANGED
@@ -83,7 +83,6 @@ class Command {
83
83
  * will support.
84
84
  * @enum {string}
85
85
  */
86
- // TODO: Delete obsolete command names.
87
86
  const Name = {
88
87
  GET_SERVER_STATUS: 'getStatus',
89
88
 
@@ -115,14 +114,9 @@ const Name = {
115
114
  CLEAR_ELEMENT: 'clearElement',
116
115
  CLICK_ELEMENT: 'clickElement',
117
116
  SEND_KEYS_TO_ELEMENT: 'sendKeysToElement',
118
- SUBMIT_ELEMENT: 'submitElement',
119
117
 
120
118
  GET_CURRENT_WINDOW_HANDLE: 'getCurrentWindowHandle',
121
119
  GET_WINDOW_HANDLES: 'getWindowHandles',
122
- GET_WINDOW_POSITION: 'getWindowPosition',
123
- SET_WINDOW_POSITION: 'setWindowPosition',
124
- GET_WINDOW_SIZE: 'getWindowSize',
125
- SET_WINDOW_SIZE: 'setWindowSize',
126
120
  GET_WINDOW_RECT: 'getWindowRect',
127
121
  SET_WINDOW_RECT: 'setWindowRect',
128
122
  MAXIMIZE_WINDOW: 'maximizeWindow',
@@ -146,17 +140,14 @@ const Name = {
146
140
  IS_ELEMENT_SELECTED: 'isElementSelected',
147
141
  IS_ELEMENT_ENABLED: 'isElementEnabled',
148
142
  IS_ELEMENT_DISPLAYED: 'isElementDisplayed',
149
- GET_ELEMENT_LOCATION: 'getElementLocation',
150
- GET_ELEMENT_LOCATION_IN_VIEW: 'getElementLocationOnceScrolledIntoView',
151
143
  GET_ELEMENT_RECT: 'getElementRect',
152
- GET_ELEMENT_SIZE: 'getElementSize',
153
144
  GET_ELEMENT_ATTRIBUTE: 'getElementAttribute',
145
+ GET_DOM_ATTRIBUTE: 'getDomAttribute',
154
146
  GET_ELEMENT_VALUE_OF_CSS_PROPERTY: 'getElementValueOfCssProperty',
155
147
  GET_ELEMENT_PROPERTY: 'getElementProperty',
156
148
 
157
149
  SCREENSHOT: 'screenshot',
158
150
  TAKE_ELEMENT_SCREENSHOT: 'takeElementScreenshot',
159
- SET_SCRIPT_TIMEOUT: 'setScriptTimeout',
160
151
 
161
152
  PRINT_PAGE: 'printPage',
162
153
 
@@ -168,9 +159,13 @@ const Name = {
168
159
  GET_ALERT_TEXT: 'getAlertText',
169
160
  SET_ALERT_TEXT: 'setAlertValue',
170
161
 
162
+ // Shadow DOM Commands
163
+ GET_SHADOW_ROOT: 'getShadowRoot',
164
+ FIND_ELEMENT_FROM_SHADOWROOT: 'findElementFromShadowRoot',
165
+ FIND_ELEMENTS_FROM_SHADOWROOT: 'findElementsFromShadowRoot',
166
+
171
167
  GET_AVAILABLE_LOG_TYPES: 'getAvailableLogTypes',
172
168
  GET_LOG: 'getLog',
173
- GET_SESSION_LOGS: 'getSessionLogs',
174
169
 
175
170
  // Non-standard commands used by the standalone Selenium server.
176
171
  UPLOAD_FILE: 'uploadFile',
package/lib/error.js CHANGED
@@ -39,6 +39,16 @@ class WebDriverError extends Error {
39
39
  }
40
40
  }
41
41
 
42
+ /**
43
+ * Indicates the shadow root is no longer attached to the DOM
44
+ */
45
+ class DetachedShadowRootError extends WebDriverError {
46
+ /** @param {string=} opt_error the error message, if any. */
47
+ constructor(opt_error) {
48
+ super(opt_error)
49
+ }
50
+ }
51
+
42
52
  /**
43
53
  * Indicates a {@linkplain ./webdriver.WebElement#click click command} could not
44
54
  * completed because the click target is obscured by other elements on the
@@ -201,6 +211,16 @@ class NoSuchElementError extends WebDriverError {
201
211
  }
202
212
  }
203
213
 
214
+ /**
215
+ * A ShadowRoot could not be located on the element
216
+ */
217
+ class NoSuchShadowRootError extends WebDriverError {
218
+ /** @param {string=} opt_error the error message, if any. */
219
+ constructor(opt_error) {
220
+ super(opt_error)
221
+ }
222
+ }
223
+
204
224
  /**
205
225
  * A request to switch to a frame could not be satisfied because the frame
206
226
  * could not be found.
@@ -420,6 +440,7 @@ const LEGACY_ERROR_CODE_TO_TYPE = new Map([
420
440
 
421
441
  const ERROR_CODE_TO_TYPE = new Map([
422
442
  ['unknown error', WebDriverError],
443
+ ['detached shadow root', DetachedShadowRootError],
423
444
  ['element click intercepted', ElementClickInterceptedError],
424
445
  ['element not interactable', ElementNotInteractableError],
425
446
  ['element not selectable', ElementNotSelectableError],
@@ -436,6 +457,7 @@ const ERROR_CODE_TO_TYPE = new Map([
436
457
  ['no such cookie', NoSuchCookieError],
437
458
  ['no such element', NoSuchElementError],
438
459
  ['no such frame', NoSuchFrameError],
460
+ ['no such shadow root', NoSuchShadowRootError],
439
461
  ['no such window', NoSuchWindowError],
440
462
  ['script timeout', ScriptTimeoutError],
441
463
  ['session not created', SessionNotCreatedError],
@@ -473,23 +495,6 @@ function encodeError(err) {
473
495
  return { error: code, message: message }
474
496
  }
475
497
 
476
- /**
477
- * Checks a response object from a server that adheres to the W3C WebDriver
478
- * protocol.
479
- * @param {*} data The response data to check.
480
- * @return {*} The response data if it was not an encoded error.
481
- * @throws {WebDriverError} the decoded error, if present in the data object.
482
- * @deprecated Use {@link #throwDecodedError(data)} instead.
483
- * @see https://w3c.github.io/webdriver/webdriver-spec.html#protocol
484
- */
485
- function checkResponse(data) {
486
- if (data && typeof data.error === 'string') {
487
- let ctor = ERROR_CODE_TO_TYPE.get(data.error) || WebDriverError
488
- throw new ctor(data.message)
489
- }
490
- return data
491
- }
492
-
493
498
  /**
494
499
  * Tests if the given value is a valid error response object according to the
495
500
  * W3C WebDriver spec.
@@ -569,6 +574,7 @@ module.exports = {
569
574
  ErrorCode,
570
575
 
571
576
  WebDriverError,
577
+ DetachedShadowRootError,
572
578
  ElementClickInterceptedError,
573
579
  ElementNotInteractableError,
574
580
  ElementNotSelectableError,
@@ -584,6 +590,7 @@ module.exports = {
584
590
  NoSuchCookieError,
585
591
  NoSuchElementError,
586
592
  NoSuchFrameError,
593
+ NoSuchShadowRootError,
587
594
  NoSuchSessionError,
588
595
  NoSuchWindowError,
589
596
  ScriptTimeoutError,
@@ -596,8 +603,6 @@ module.exports = {
596
603
  UnknownCommandError,
597
604
  UnknownMethodError,
598
605
  UnsupportedOperationError,
599
-
600
- checkResponse,
601
606
  checkLegacyResponse,
602
607
  encodeError,
603
608
  isErrorResponse,