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/lib/by.js CHANGED
@@ -15,7 +15,7 @@
15
15
  // specific language governing permissions and limitations
16
16
  // under the License.
17
17
 
18
- 'use strict';
18
+ 'use strict'
19
19
 
20
20
  /**
21
21
  * @fileoverview Factory methods for the supported locator strategies.
@@ -43,8 +43,7 @@
43
43
  * {tagName: string}|
44
44
  * {xpath: string})}
45
45
  */
46
- var ByHash;
47
-
46
+ var ByHash // eslint-disable-line
48
47
 
49
48
  /**
50
49
  * Error thrown if an invalid character is encountered while escaping a CSS
@@ -53,12 +52,11 @@ var ByHash;
53
52
  */
54
53
  class InvalidCharacterError extends Error {
55
54
  constructor() {
56
- super();
57
- this.name = this.constructor.name;
55
+ super()
56
+ this.name = this.constructor.name
58
57
  }
59
58
  }
60
59
 
61
-
62
60
  /**
63
61
  * Escapes a CSS string.
64
62
  * @param {string} css the string to escape.
@@ -69,46 +67,49 @@ class InvalidCharacterError extends Error {
69
67
  */
70
68
  function escapeCss(css) {
71
69
  if (typeof css !== 'string') {
72
- throw new TypeError('input must be a string');
70
+ throw new TypeError('input must be a string')
73
71
  }
74
- let ret = '';
75
- const n = css.length;
76
- for (let i = 0; i < n; i++) {
77
- const c = css.charCodeAt(i);
72
+ let ret = ''
73
+ const n = css.length
74
+ for (let i = 0; i < n; i++) {
75
+ const c = css.charCodeAt(i)
78
76
  if (c == 0x0) {
79
- throw new InvalidCharacterError();
77
+ throw new InvalidCharacterError()
80
78
  }
81
79
 
82
- if ((c >= 0x0001 && c <= 0x001F)
83
- || c == 0x007F
84
- || (i == 0 && c >= 0x0030 && c <= 0x0039)
85
- || (i == 1 && c >= 0x0030 && c <= 0x0039
86
- && css.charCodeAt(0) == 0x002D)) {
87
- ret += '\\' + c.toString(16) + ' ';
88
- continue;
80
+ if (
81
+ (c >= 0x0001 && c <= 0x001f) ||
82
+ c == 0x007f ||
83
+ (i == 0 && c >= 0x0030 && c <= 0x0039) ||
84
+ (i == 1 && c >= 0x0030 && c <= 0x0039 && css.charCodeAt(0) == 0x002d)
85
+ ) {
86
+ ret += '\\' + c.toString(16) + ' '
87
+ continue
89
88
  }
90
89
 
91
- if (i == 0 && c == 0x002D && n == 1) {
92
- ret += '\\' + css.charAt(i);
93
- continue;
90
+ if (i == 0 && c == 0x002d && n == 1) {
91
+ ret += '\\' + css.charAt(i)
92
+ continue
94
93
  }
95
94
 
96
- if (c >= 0x0080
97
- || c == 0x002D // -
98
- || c == 0x005F // _
99
- || (c >= 0x0030 && c <= 0x0039) // [0-9]
100
- || (c >= 0x0041 && c <= 0x005A) // [A-Z]
101
- || (c >= 0x0061 && c <= 0x007A)) { // [a-z]
102
- ret += css.charAt(i);
103
- continue;
95
+ if (
96
+ c >= 0x0080 ||
97
+ c == 0x002d || // -
98
+ c == 0x005f || // _
99
+ (c >= 0x0030 && c <= 0x0039) || // [0-9]
100
+ (c >= 0x0041 && c <= 0x005a) || // [A-Z]
101
+ (c >= 0x0061 && c <= 0x007a)
102
+ ) {
103
+ // [a-z]
104
+ ret += css.charAt(i)
105
+ continue
104
106
  }
105
107
 
106
- ret += '\\' + css.charAt(i);
108
+ ret += '\\' + css.charAt(i)
107
109
  }
108
- return ret;
110
+ return ret
109
111
  }
110
112
 
111
-
112
113
  /**
113
114
  * Describes a mechanism for locating an element on the page.
114
115
  * @final
@@ -120,10 +121,10 @@ class By {
120
121
  */
121
122
  constructor(using, value) {
122
123
  /** @type {string} */
123
- this.using = using;
124
+ this.using = using
124
125
 
125
126
  /** @type {string} */
126
- this.value = value;
127
+ this.value = value
127
128
  }
128
129
 
129
130
  /**
@@ -135,10 +136,11 @@ class By {
135
136
  * @see http://www.w3.org/TR/CSS2/selector.html#class-html
136
137
  */
137
138
  static className(name) {
138
- let names = name.split(/\s+/g)
139
- .filter(s => s.length > 0)
140
- .map(s => escapeCss(s));
141
- return By.css('.' + names.join('.'));
139
+ let names = name
140
+ .split(/\s+/g)
141
+ .filter((s) => s.length > 0)
142
+ .map((s) => escapeCss(s))
143
+ return By.css('.' + names.join('.'))
142
144
  }
143
145
 
144
146
  /**
@@ -149,7 +151,7 @@ class By {
149
151
  * @see http://www.w3.org/TR/CSS2/selector.html
150
152
  */
151
153
  static css(selector) {
152
- return new By('css selector', selector);
154
+ return new By('css selector', selector)
153
155
  }
154
156
 
155
157
  /**
@@ -160,7 +162,7 @@ class By {
160
162
  * @return {!By} The new locator.
161
163
  */
162
164
  static id(id) {
163
- return By.css('*[id="' + escapeCss(id) + '"]');
165
+ return By.css('*[id="' + escapeCss(id) + '"]')
164
166
  }
165
167
 
166
168
  /**
@@ -172,7 +174,7 @@ class By {
172
174
  * @return {!By} The new locator.
173
175
  */
174
176
  static linkText(text) {
175
- return new By('link text', text);
177
+ return new By('link text', text)
176
178
  }
177
179
 
178
180
  /**
@@ -188,11 +190,12 @@ class By {
188
190
  * @return {function(!./webdriver.WebDriver): !Promise}
189
191
  * A new JavaScript-based locator function.
190
192
  */
191
- static js(script, var_args) {
192
- let args = Array.prototype.slice.call(arguments, 0);
193
- return function(driver) {
194
- return driver.executeScript.apply(driver, args);
195
- };
193
+ static js(script, var_args) { // eslint-disable-line
194
+ // eslint-disable-line
195
+ let args = Array.prototype.slice.call(arguments, 0)
196
+ return function (driver) {
197
+ return driver.executeScript.apply(driver, args)
198
+ }
196
199
  }
197
200
 
198
201
  /**
@@ -202,7 +205,7 @@ class By {
202
205
  * @return {!By} The new locator.
203
206
  */
204
207
  static name(name) {
205
- return By.css('*[name="' + escapeCss(name) + '"]');
208
+ return By.css('*[name="' + escapeCss(name) + '"]')
206
209
  }
207
210
 
208
211
  /**
@@ -214,7 +217,7 @@ class By {
214
217
  * @return {!By} The new locator.
215
218
  */
216
219
  static partialLinkText(text) {
217
- return new By('partial link text', text);
220
+ return new By('partial link text', text)
218
221
  }
219
222
 
220
223
  /**
@@ -222,10 +225,9 @@ class By {
222
225
  *
223
226
  * @param {string} name The tag name to search for.
224
227
  * @return {!By} The new locator.
225
- * @deprecated Use {@link By.css() By.css(tagName)} instead.
226
228
  */
227
229
  static tagName(name) {
228
- return By.css(name);
230
+ return By.css(name)
229
231
  }
230
232
 
231
233
  /**
@@ -240,16 +242,136 @@ class By {
240
242
  * @see http://www.w3.org/TR/xpath/
241
243
  */
242
244
  static xpath(xpath) {
243
- return new By('xpath', xpath);
245
+ return new By('xpath', xpath)
244
246
  }
245
247
 
246
248
  /** @override */
247
249
  toString() {
248
250
  // The static By.name() overrides this.constructor.name. Shame...
249
- return `By(${this.using}, ${this.value})`;
251
+ return `By(${this.using}, ${this.value})`
252
+ }
253
+
254
+ toObject() {
255
+ const tmp = {}
256
+ tmp[this.using] = this.value
257
+ return tmp
250
258
  }
251
259
  }
252
260
 
261
+ function withTagName(tagName) {
262
+ return new RelativeBy(tagName)
263
+ }
264
+
265
+ /**
266
+ * Describes a mechanism for locating an element relative to others
267
+ * on the page.
268
+ * @final
269
+ */
270
+ class RelativeBy {
271
+ /**
272
+ * @param {string} tagName
273
+ * @param {Array<Object>} filters
274
+ */
275
+ constructor(tagName, filters = null) {
276
+ this.root = tagName
277
+ this.filters = filters || []
278
+ }
279
+
280
+ /**
281
+ * Look for elements above the root element passed in
282
+ * @param {string|WebElement} locatorOrElement
283
+ * @return {!RelativeBy} Return this object
284
+ */
285
+ above(locatorOrElement) {
286
+ this.filters.push({
287
+ kind: 'above',
288
+ args: [this.getLocator(locatorOrElement)],
289
+ })
290
+ return this
291
+ }
292
+
293
+ /**
294
+ * Look for elements below the root element passed in
295
+ * @param {string|WebElement} locatorOrElement
296
+ * @return {!RelativeBy} Return this object
297
+ */
298
+ below(locatorOrElement) {
299
+ this.filters.push({
300
+ kind: 'below',
301
+ args: [this.getLocator(locatorOrElement)],
302
+ })
303
+ return this
304
+ }
305
+
306
+ /**
307
+ * Look for elements left the root element passed in
308
+ * @param {string|WebElement} locatorOrElement
309
+ * @return {!RelativeBy} Return this object
310
+ */
311
+ toLeftOf(locatorOrElement) {
312
+ this.filters.push({
313
+ kind: 'left',
314
+ args: [this.getLocator(locatorOrElement)],
315
+ })
316
+ return this
317
+ }
318
+
319
+ /**
320
+ * Look for elements right the root element passed in
321
+ * @param {string|WebElement} locatorOrElement
322
+ * @return {!RelativeBy} Return this object
323
+ */
324
+ toRightOf(locatorOrElement) {
325
+ this.filters.push({
326
+ kind: 'right',
327
+ args: [this.getLocator(locatorOrElement)],
328
+ })
329
+ return this
330
+ }
331
+
332
+ /**
333
+ * Look for elements near the root element passed in
334
+ * @param {string|WebElement} locatorOrElement
335
+ * @return {!RelativeBy} Return this object
336
+ */
337
+ near(locatorOrElement) {
338
+ this.filters.push({
339
+ kind: 'near',
340
+ args: [this.getLocator(locatorOrElement)],
341
+ })
342
+ return this
343
+ }
344
+
345
+ /**
346
+ * Returns a marshalled version of the {@link RelativeBy}
347
+ * @return {!Object} Object representation of a {@link WebElement}
348
+ * that will be used in {@link #findElements}.
349
+ */
350
+ marshall() {
351
+ return {
352
+ relative: {
353
+ root: { 'css selector': this.root },
354
+ filters: this.filters,
355
+ },
356
+ }
357
+ }
358
+
359
+ getLocator(locatorOrElement) {
360
+ let toFind
361
+ if (locatorOrElement instanceof By) {
362
+ toFind = locatorOrElement.toObject()
363
+ } else {
364
+ toFind = locatorOrElement
365
+ }
366
+ return toFind
367
+ }
368
+
369
+ /** @override */
370
+ toString() {
371
+ // The static By.name() overrides this.constructor.name. Shame...
372
+ return `RelativeBy(${JSON.stringify(this.marshall())})`
373
+ }
374
+ }
253
375
 
254
376
  /**
255
377
  * Checks if a value is a valid locator.
@@ -260,29 +382,34 @@ class By {
260
382
  */
261
383
  function check(locator) {
262
384
  if (locator instanceof By || typeof locator === 'function') {
263
- return locator;
385
+ return locator
264
386
  }
265
387
 
266
- if (locator
267
- && typeof locator === 'object'
268
- && typeof locator.using === 'string'
269
- && typeof locator.value === 'string') {
270
- return new By(locator.using, locator.value);
388
+ if (
389
+ locator &&
390
+ typeof locator === 'object' &&
391
+ typeof locator.using === 'string' &&
392
+ typeof locator.value === 'string'
393
+ ) {
394
+ return new By(locator.using, locator.value)
271
395
  }
272
396
 
273
397
  for (let key in locator) {
274
- if (locator.hasOwnProperty(key) && By.hasOwnProperty(key)) {
275
- return By[key](locator[key]);
398
+ if (
399
+ Object.prototype.hasOwnProperty.call(locator, key) &&
400
+ Object.prototype.hasOwnProperty.call(By, key)
401
+ ) {
402
+ return By[key](locator[key])
276
403
  }
277
404
  }
278
- throw new TypeError('Invalid locator');
405
+ throw new TypeError('Invalid locator')
279
406
  }
280
407
 
281
-
282
-
283
408
  // PUBLIC API
284
409
 
285
410
  module.exports = {
286
411
  By: By,
412
+ RelativeBy: RelativeBy,
413
+ withTagName: withTagName,
287
414
  checkedLocator: check,
288
- };
415
+ }