selenium-webdriver 4.0.0-alpha.8 → 4.0.0-beta.4

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 (53) hide show
  1. package/CHANGES.md +41 -1
  2. package/LICENSE +202 -0
  3. package/NOTICE +2 -0
  4. package/README.md +0 -0
  5. package/chrome.js +0 -0
  6. package/chromium.js +23 -202
  7. package/devtools/CDPConnection.js +16 -18
  8. package/edge.js +89 -130
  9. package/example/chrome_android.js +45 -0
  10. package/{lib/atoms/make-atoms-module.js → example/chrome_mobile_emulation.js} +26 -15
  11. package/example/firefox_channels.js +84 -0
  12. package/example/google_search.js +50 -0
  13. package/example/google_search_test.js +70 -0
  14. package/example/headless.js +63 -0
  15. package/example/logging.js +64 -0
  16. package/firefox.js +10 -9
  17. package/http/index.js +0 -0
  18. package/http/util.js +3 -3
  19. package/ie.js +0 -0
  20. package/index.js +2 -2
  21. package/io/exec.js +3 -3
  22. package/io/index.js +12 -13
  23. package/io/zip.js +5 -6
  24. package/lib/atoms/find-elements.js +78 -78
  25. package/lib/atoms/get-attribute.js +64 -68
  26. package/lib/atoms/is-displayed.js +27 -27
  27. package/lib/atoms/mutation-listener.js +55 -0
  28. package/lib/by.js +1 -1
  29. package/lib/capabilities.js +2 -3
  30. package/lib/command.js +2 -15
  31. package/lib/error.js +0 -0
  32. package/lib/http.js +17 -30
  33. package/lib/input.js +2 -286
  34. package/lib/logging.js +0 -0
  35. package/lib/promise.js +4 -16
  36. package/lib/proxy.js +0 -0
  37. package/lib/session.js +0 -0
  38. package/lib/symbols.js +0 -0
  39. package/lib/until.js +17 -15
  40. package/lib/webdriver.js +336 -16
  41. package/net/index.js +0 -0
  42. package/net/portprober.js +8 -8
  43. package/opera.js +0 -0
  44. package/package.json +13 -13
  45. package/proxy.js +0 -0
  46. package/remote/index.js +6 -7
  47. package/safari.js +0 -0
  48. package/testing/index.js +504 -0
  49. package/.eslintrc.js +0 -27
  50. package/.prettierrc +0 -4
  51. package/devtools/generator/protocol-dts-generator.js +0 -429
  52. package/lib/README +0 -5
  53. package/lib/actions.js +0 -626
@@ -0,0 +1,55 @@
1
+ // Licensed to the Software Freedom Conservancy (SFC) under one
2
+ // or more contributor license agreements. See the NOTICE file
3
+ // distributed with this work for additional information
4
+ // regarding copyright ownership. The SFC licenses this file
5
+ // to you under the Apache License, Version 2.0 (the
6
+ // "License"); you may not use this file except in compliance
7
+ // with the License. You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing,
12
+ // software distributed under the License is distributed on an
13
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ // KIND, either express or implied. See the License for the
15
+ // specific language governing permissions and limitations
16
+ // under the License.
17
+
18
+ (function () {
19
+ const observer = new MutationObserver((mutations) => {
20
+ for (const mutation of mutations) {
21
+ switch (mutation.type) {
22
+ case 'attributes':
23
+ // Don't report our own attribute has changed.
24
+ if (mutation.attributeName === "data-__webdriver_id") {
25
+ break;
26
+ }
27
+ const curr = mutation.target.getAttribute(mutation.attributeName);
28
+ var id = mutation.target.dataset.__webdriver_id
29
+ if (!id) {
30
+ id = Math.random().toString(36).substring(2) + Date.now().toString(36);
31
+ mutation.target.dataset.__webdriver_id = id;
32
+ }
33
+ const json = JSON.stringify({
34
+ 'target': id,
35
+ 'name': mutation.attributeName,
36
+ 'value': curr,
37
+ 'oldValue': mutation.oldValue
38
+ });
39
+ __webdriver_attribute(json);
40
+ break;
41
+ default:
42
+ break;
43
+ }
44
+ }
45
+ });
46
+
47
+ observer.observe(document, {
48
+ 'attributes': true,
49
+ 'attributeOldValue': true,
50
+ 'characterData': true,
51
+ 'characterDataOldValue': true,
52
+ 'childList': true,
53
+ 'subtree': true
54
+ });
55
+ })();
package/lib/by.js CHANGED
@@ -252,7 +252,7 @@ class By {
252
252
  }
253
253
 
254
254
  toObject() {
255
- var tmp = {}
255
+ const tmp = {}
256
256
  tmp[this.using] = this.value
257
257
  return tmp
258
258
  }
@@ -32,7 +32,6 @@ const Browser = {
32
32
  CHROME: 'chrome',
33
33
  EDGE: 'MicrosoftEdge',
34
34
  FIREFOX: 'firefox',
35
- IE: 'internet explorer',
36
35
  INTERNET_EXPLORER: 'internet explorer',
37
36
  SAFARI: 'safari',
38
37
  OPERA: 'opera',
@@ -84,7 +83,7 @@ const Platform = {
84
83
  *
85
84
  * @record
86
85
  */
87
- function Timeouts() {}
86
+ function Timeouts() { }
88
87
 
89
88
  /**
90
89
  * Defines when, in milliseconds, to interrupt a script that is being
@@ -264,7 +263,7 @@ class Capabilities {
264
263
  * @return {!Capabilities} A basic set of capabilities for Firefox.
265
264
  */
266
265
  static firefox() {
267
- return new Capabilities().setBrowserName(Browser.FIREFOX)
266
+ return new Capabilities().setBrowserName(Browser.FIREFOX).set("moz:debuggerAddress", true)
268
267
  }
269
268
 
270
269
  /**
package/lib/command.js CHANGED
@@ -140,6 +140,8 @@ const Name = {
140
140
  EXECUTE_ASYNC_SCRIPT: 'executeAsyncScript',
141
141
 
142
142
  GET_ELEMENT_TEXT: 'getElementText',
143
+ GET_COMPUTED_ROLE: 'getAriaRole',
144
+ GET_COMPUTED_LABEL: 'getAccessibleName',
143
145
  GET_ELEMENT_TAG_NAME: 'getElementTagName',
144
146
  IS_ELEMENT_SELECTED: 'isElementSelected',
145
147
  IS_ELEMENT_ENABLED: 'isElementEnabled',
@@ -175,21 +177,6 @@ const Name = {
175
177
 
176
178
  ACTIONS: 'actions',
177
179
  CLEAR_ACTIONS: 'clearActions',
178
-
179
- LEGACY_ACTION_CLICK: 'legacyAction:click',
180
- LEGACY_ACTION_DOUBLE_CLICK: 'legacyAction:doubleclick',
181
- LEGACY_ACTION_MOUSE_DOWN: 'legacyAction:mouseDown',
182
- LEGACY_ACTION_MOUSE_UP: 'legacyAction:mouseUp',
183
- LEGACY_ACTION_MOUSE_MOVE: 'legacyAction:mouseMove',
184
- LEGACY_ACTION_SEND_KEYS: 'legacyAction:sendKeys',
185
- LEGACY_ACTION_TOUCH_DOWN: 'legacyAction:touchDown',
186
- LEGACY_ACTION_TOUCH_UP: 'legacyAction:touchUp',
187
- LEGACY_ACTION_TOUCH_MOVE: 'legacyAction:touchMove',
188
- LEGACY_ACTION_TOUCH_SCROLL: 'legacyAction:touchScroll',
189
- LEGACY_ACTION_TOUCH_LONG_PRESS: 'legacyAction:touchLongPress',
190
- LEGACY_ACTION_TOUCH_FLICK: 'legacyAction:touchFlick',
191
- LEGACY_ACTION_TOUCH_SINGLE_TAP: 'legacyAction:singleTap',
192
- LEGACY_ACTION_TOUCH_DOUBLE_TAP: 'legacyAction:doubleTap',
193
180
  }
194
181
 
195
182
  /**
package/lib/error.js CHANGED
File without changes
package/lib/http.js CHANGED
@@ -76,7 +76,7 @@ function requireAtom(module, bazelTarget) {
76
76
  * @return {string} The headers as a string.
77
77
  */
78
78
  function headersToString(headers) {
79
- let ret = []
79
+ const ret = []
80
80
  headers.forEach(function (value, name) {
81
81
  ret.push(`${name.toLowerCase()}: ${value}`)
82
82
  })
@@ -234,6 +234,14 @@ const COMMAND_MAP = new Map([
234
234
  ],
235
235
  [cmd.Name.SUBMIT_ELEMENT, post('/session/:sessionId/element/:id/submit')],
236
236
  [cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')],
237
+ [
238
+ cmd.Name.GET_COMPUTED_ROLE,
239
+ get('/session/:sessionId/element/:id/computedrole'),
240
+ ],
241
+ [
242
+ cmd.Name.GET_COMPUTED_LABEL,
243
+ get('/session/:sessionId/element/:id/computedlabel'),
244
+ ],
237
245
  [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
238
246
  [
239
247
  cmd.Name.IS_ELEMENT_SELECTED,
@@ -297,35 +305,6 @@ const COMMAND_MAP = new Map([
297
305
  [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/log/types')],
298
306
  [cmd.Name.GET_SESSION_LOGS, post('/logs')],
299
307
  [cmd.Name.UPLOAD_FILE, post('/session/:sessionId/se/file')],
300
- [cmd.Name.LEGACY_ACTION_CLICK, post('/session/:sessionId/click')],
301
- [
302
- cmd.Name.LEGACY_ACTION_DOUBLE_CLICK,
303
- post('/session/:sessionId/doubleclick'),
304
- ],
305
- [cmd.Name.LEGACY_ACTION_MOUSE_DOWN, post('/session/:sessionId/buttondown')],
306
- [cmd.Name.LEGACY_ACTION_MOUSE_UP, post('/session/:sessionId/buttonup')],
307
- [cmd.Name.LEGACY_ACTION_MOUSE_MOVE, post('/session/:sessionId/moveto')],
308
- [cmd.Name.LEGACY_ACTION_SEND_KEYS, post('/session/:sessionId/keys')],
309
- [cmd.Name.LEGACY_ACTION_TOUCH_DOWN, post('/session/:sessionId/touch/down')],
310
- [cmd.Name.LEGACY_ACTION_TOUCH_UP, post('/session/:sessionId/touch/up')],
311
- [cmd.Name.LEGACY_ACTION_TOUCH_MOVE, post('/session/:sessionId/touch/move')],
312
- [
313
- cmd.Name.LEGACY_ACTION_TOUCH_SCROLL,
314
- post('/session/:sessionId/touch/scroll'),
315
- ],
316
- [
317
- cmd.Name.LEGACY_ACTION_TOUCH_LONG_PRESS,
318
- post('/session/:sessionId/touch/longclick'),
319
- ],
320
- [cmd.Name.LEGACY_ACTION_TOUCH_FLICK, post('/session/:sessionId/touch/flick')],
321
- [
322
- cmd.Name.LEGACY_ACTION_TOUCH_SINGLE_TAP,
323
- post('/session/:sessionId/touch/click'),
324
- ],
325
- [
326
- cmd.Name.LEGACY_ACTION_TOUCH_DOUBLE_TAP,
327
- post('/session/:sessionId/touch/doubleclick'),
328
- ],
329
308
  ])
330
309
 
331
310
  /** @const {!Map<string, (CommandSpec|CommandTransformer)>} */
@@ -402,6 +381,14 @@ const W3C_COMMAND_MAP = new Map([
402
381
  post('/session/:sessionId/element/:id/value'),
403
382
  ],
404
383
  [cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')],
384
+ [
385
+ cmd.Name.GET_COMPUTED_ROLE,
386
+ get('/session/:sessionId/element/:id/computedrole'),
387
+ ],
388
+ [
389
+ cmd.Name.GET_COMPUTED_LABEL,
390
+ get('/session/:sessionId/element/:id/computedlabel'),
391
+ ],
405
392
  [cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
406
393
  [
407
394
  cmd.Name.GET_ELEMENT_ATTRIBUTE,
package/lib/input.js CHANGED
@@ -489,67 +489,6 @@ Pointer.Type = {
489
489
  * | Keyboard | pause(100) | keyDown(SHIFT) |
490
490
  * | Mouse | move({duration: 300}) | |
491
491
  *
492
- *
493
- * #### Bridge Mode
494
- *
495
- * As of January 2018, only Firefox natively supports this API. For other
496
- * browsers, you may either use the
497
- * {@link ./actions.LegacyActionSequence LegacyActionSequence} class, _or_ you
498
- * can put the Actions class into bridge mode by passing `{bridge: true}` on
499
- * creation:
500
- *
501
- * const actions = driver.actions({bridge: true});
502
- * await actions.click(element).sendKeys('abc').perform();
503
- *
504
- * In bridge mode, {@link #perform perform()} will first attempt to execute the
505
- * configured action sequence using the W3C action protocol. If this is rejected
506
- * by the remote end, the sequence will be translated to and executed against
507
- * the legacy protocol.
508
- *
509
- * Bridge mode __is not enabled by default__ as there are several notable
510
- * differences between W3C-specified and legacy protocols. Care must be
511
- * taken to configure your action sequences to account for these differences:
512
- *
513
- * 1. For W3C actions, the entire action sequence is executed in a single
514
- * call to the remote end. For legacy sequences, multiple calls must be
515
- * made for each step in the sequence. This introduces additional latency
516
- * which may impact how the browser responds to the emulated user actions.
517
- *
518
- * 2. For the legacy actions, {@linkplain #pause pauses} are handled _locally_.
519
- *
520
- * 3. For legacy actions, a {@linkplain #keyDown keyDown()} for a
521
- * _non-modifier key_ **must** be followed by a {@linkplain #keyUP keyUp()}
522
- * for the same key. This will be handled for you if you use the
523
- * {@linkplain #sendKeys sendKeys()} method.
524
- *
525
- * 4. Mouse movements may not be specified relative to
526
- * {@linkplain ./input.Origin.VIEWPORT Origin.VIEWPORT}.
527
- * All movements must be relative to an element or the mouse's current
528
- * position ({@linkplain ./input.Origin.POINTER Origin.POINTER}).
529
- * The {@linkplain #move move()} method defaults to viewport relative
530
- * offsets, so you must always specify an appropriate origin in bridge mode:
531
- *
532
- * driver.actions({bridge: true})
533
- * .move({x: 0, y: 0, origin: Origin.POINTER})
534
- * .perform();
535
- * driver.actions({bridge: true})
536
- * .move({x: 0, y: 0, origin: someWebElement})
537
- * .perform();
538
- *
539
- * 5. The legacy protocol does not support specifying the duration of a
540
- * {@linkplain #move mouse movement}; any specified duration _is ignored_
541
- * when translating actions to the legacy protocol.
542
- *
543
- * 6. For W3C actions, move offsets relative to a
544
- * {@linkplain ./webdriver.WebElement WebElement} are interpreted relative
545
- * to the center of an element's _first_ [client rect] in the viewport. For
546
- * legacy actions, element offsets are relative to the top-left corner of
547
- * the element's [bounding client rect]. When translating actions to the
548
- * legacy protocol in bridge mode, an extra command must be inserted to
549
- * translate move offsets from one frame of reference to the other. This
550
- * extra command contributes to the overall latency issue outlined in
551
- * point 1.
552
- *
553
492
  * [client rect]: https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects
554
493
  * [bounding client rect]: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
555
494
  *
@@ -560,16 +499,10 @@ class Actions {
560
499
  /**
561
500
  * @param {!Executor} executor The object to execute the configured
562
501
  * actions with.
563
- * @param {{async: (boolean|undefined),
564
- * bridge: (boolean|undefined)}} options Options for this action
502
+ * @param {{async: (boolean|undefined)}} options Options for this action
565
503
  * sequence (see class description for details).
566
504
  */
567
- constructor(executor, { async = false, bridge = false } = {}) {
568
- if (async && bridge) {
569
- throw new InvalidArgumentError(
570
- 'Async sequences not supported with bridge mode'
571
- )
572
- }
505
+ constructor(executor, { async = false } = {}) {
573
506
 
574
507
  /** @private @const */
575
508
  this.executor_ = executor
@@ -577,9 +510,6 @@ class Actions {
577
510
  /** @private @const */
578
511
  this.sync_ = !async
579
512
 
580
- /** @private @const */
581
- this.bridge_ = !!bridge
582
-
583
513
  /** @private @const */
584
514
  this.keyboard_ = new Keyboard('default keyboard')
585
515
 
@@ -957,13 +887,6 @@ class Actions {
957
887
  new Command(Name.ACTIONS).setParameter('actions', _actions)
958
888
  )
959
889
  } catch (ex) {
960
- if (
961
- this.bridge_ &&
962
- (ex instanceof UnknownCommandError ||
963
- ex instanceof UnsupportedOperationError)
964
- ) {
965
- return executeLegacy(this.executor_, this.sequences_)
966
- }
967
890
  throw ex
968
891
  }
969
892
  }
@@ -980,213 +903,6 @@ function isIdle(actions) {
980
903
  )
981
904
  }
982
905
 
983
- const MODIFIER_KEYS = new Set([Key.ALT, Key.CONTROL, Key.SHIFT, Key.COMMAND])
984
-
985
- /**
986
- * @param {!Executor} executor
987
- * @param {!Map<!Device, !Array<!Action>>} sequences
988
- * @return {!Promise<void>}
989
- * @suppress {deprecated} Ignore warnings about using LegacyActionSequence.
990
- */
991
- async function executeLegacy(executor, sequences) {
992
- let maxLength = 0
993
- sequences.forEach((seq) => (maxLength = Math.max(maxLength, seq.length)))
994
-
995
- const actions = []
996
- for (let i = 0; i < maxLength; i++) {
997
- let next
998
- for (const device of sequences.keys()) {
999
- const seq = sequences.get(device)
1000
-
1001
- if (
1002
- device instanceof Pointer &&
1003
- device.pointerType_ !== Pointer.Type.MOUSE
1004
- ) {
1005
- throw new UnsupportedOperationError(
1006
- `${device.pointerType_} pointer not supported in bridge mode`
1007
- )
1008
- }
1009
-
1010
- const action = seq[i]
1011
- if (!action || (action.type === Action.Type.PAUSE && !action.duration)) {
1012
- continue
1013
- }
1014
-
1015
- // - If we've already found an action for this tick:
1016
- // - If we have two pauses, use the one with a longer duration
1017
- // - If one is a pause and the other isn't, use the non-pause
1018
- // - Otherwise, two non-pauses is an error.
1019
- // - Otherwise, we haven't selected an action yet.
1020
- if (next) {
1021
- if (next.type === Action.Type.PAUSE) {
1022
- if (action.type === Action.Type.PAUSE) {
1023
- next = next.duration > action.duration ? next : action
1024
- } else {
1025
- next = action
1026
- }
1027
- } else if (action.type !== Action.Type.PAUSE) {
1028
- throw new UnsupportedOperationError(
1029
- 'parallel actions not supported in bridge mode'
1030
- )
1031
- }
1032
- } else {
1033
- next = action
1034
- }
1035
-
1036
- if (action.type === Action.Type.KEY_DOWN) {
1037
- // If this action is a keydown for a non-modifier key, the next action
1038
- // must be a keyup for the same key, otherwise it cannot be translated
1039
- // to the legacy action API.
1040
- if (!MODIFIER_KEYS.has(action.value)) {
1041
- const nextAction = seq[i + 1]
1042
- if (
1043
- !nextAction ||
1044
- nextAction.type !== Action.Type.KEY_UP ||
1045
- nextAction.value !== action.value
1046
- ) {
1047
- throw new UnsupportedOperationError(
1048
- `in bridge mode, keydown for <${action.value}> must be followed` +
1049
- ' by a keyup for the same key'
1050
- )
1051
- }
1052
- }
1053
- } else if (
1054
- action.type === Action.Type.KEY_UP &&
1055
- !MODIFIER_KEYS.has(action.value)
1056
- ) {
1057
- next = null
1058
- }
1059
- }
1060
-
1061
- if (next) {
1062
- actions.push(next)
1063
- }
1064
- }
1065
-
1066
- for (let i = 0; i < actions.length; i++) {
1067
- const action = actions[i]
1068
- switch (action.type) {
1069
- case Action.Type.PAUSE: {
1070
- await promise.delayed(action.duration || 0)
1071
- break
1072
- }
1073
- case Action.Type.KEY_DOWN: {
1074
- const keys = [action.value]
1075
- if (!MODIFIER_KEYS.has(action.value)) {
1076
- // eslint-disable-next-line no-inner-declarations
1077
- function nextIsKeyDown() {
1078
- const next = actions[i + 1]
1079
- return (
1080
- !!next &&
1081
- next.type === Action.Type.KEY_DOWN &&
1082
- !MODIFIER_KEYS.has(next.value)
1083
- )
1084
- }
1085
- for (; nextIsKeyDown(); i++) {
1086
- keys.push(actions[i + 1].value)
1087
- }
1088
- }
1089
- await executor.execute(
1090
- new Command(Name.LEGACY_ACTION_SEND_KEYS).setParameter('value', keys)
1091
- )
1092
- break
1093
- }
1094
- case Action.Type.KEY_UP: {
1095
- await executor.execute(
1096
- new Command(Name.LEGACY_ACTION_SEND_KEYS).setParameter('value', [
1097
- action.value,
1098
- ])
1099
- )
1100
- break
1101
- }
1102
- case Action.Type.POINTER_DOWN: {
1103
- // eslint-disable-next-line no-inner-declarations
1104
- function isClick(startAt) {
1105
- const first = actions[startAt]
1106
- const second = actions[startAt + 1]
1107
- return (
1108
- !!first &&
1109
- !!second &&
1110
- first.type === Action.Type.POINTER_DOWN &&
1111
- second.type === Action.Type.POINTER_UP &&
1112
- first.button === second.button
1113
- )
1114
- }
1115
-
1116
- // eslint-disable-next-line no-inner-declarations
1117
- function isDoubleClick(startAt) {
1118
- return (
1119
- isClick(startAt) &&
1120
- isClick(startAt + 2) &&
1121
- actions[startAt].button === actions[(startAt = 2)].button
1122
- )
1123
- }
1124
-
1125
- let cmd
1126
- if (isDoubleClick(i)) {
1127
- i += 3 // Consume the pointer up/down/up.
1128
- cmd = Name.LEGACY_ACTION_DOUBLE_CLICK
1129
- } else if (isClick(i)) {
1130
- i++ // Consume the pointer-up.
1131
- cmd = Name.LEGACY_ACTION_CLICK
1132
- } else {
1133
- cmd = Name.LEGACY_ACTION_MOUSE_DOWN
1134
- }
1135
- await executor.execute(
1136
- new Command(cmd).setParameter('button', action.button)
1137
- )
1138
- break
1139
- }
1140
- case Action.Type.POINTER_UP: {
1141
- await executor.execute(
1142
- new Command(Name.LEGACY_ACTION_MOUSE_UP).setParameter(
1143
- 'button',
1144
- action.button
1145
- )
1146
- )
1147
- break
1148
- }
1149
- case Action.Type.POINTER_MOVE: {
1150
- if (action.origin === Origin.VIEWPORT) {
1151
- throw new UnsupportedOperationError(
1152
- `pointer movements relative to ${Origin.VIEWPORT} are not` +
1153
- ' supported in bridge mode'
1154
- )
1155
- }
1156
-
1157
- let x = action.x
1158
- let y = action.y
1159
- const cmd = new Command(Name.LEGACY_ACTION_MOUSE_MOVE)
1160
- if (action.origin && action.origin !== Origin.POINTER) {
1161
- const el = /** @type {!./webdriver.WebElement} */ (action.origin)
1162
-
1163
- // Need to translate frame of reference from center of element's first
1164
- // client rect to the top-left of its bounding client rect. See:
1165
- // https://w3c.github.io/webdriver/webdriver-spec.html#dfn-center-point
1166
- let diff = await executor.execute(
1167
- new Command(Name.EXECUTE_SCRIPT)
1168
- .setParameter('script', INTERNAL_COMPUTE_OFFSET_SCRIPT)
1169
- .setParameter('args', [el])
1170
- )
1171
- x += diff[0]
1172
- y += diff[1]
1173
-
1174
- const id = await el.getId()
1175
- cmd.setParameter('element', id)
1176
- }
1177
- cmd.setParameter('xoffset', x).setParameter('yoffset', y)
1178
- await executor.execute(cmd)
1179
- break
1180
- }
1181
- default: {
1182
- throw new UnsupportedOperationError(
1183
- `${action.type} actions not supported in bridge mode`
1184
- )
1185
- }
1186
- }
1187
- }
1188
- }
1189
-
1190
906
  /**
1191
907
  * Script used to compute the offset from the center of a DOM element's first
1192
908
  * client rect from the top-left corner of the element's bounding client rect.
package/lib/logging.js CHANGED
File without changes
package/lib/promise.js CHANGED
@@ -30,17 +30,7 @@
30
30
  * @return {boolean} Whether the value is a promise.
31
31
  */
32
32
  function isPromise(value) {
33
- try {
34
- // Use array notation so the Closure compiler does not obfuscate away our
35
- // contract.
36
- return (
37
- value &&
38
- (typeof value === 'object' || typeof value === 'function') &&
39
- typeof value['then'] === 'function'
40
- )
41
- } catch (ex) {
42
- return false
43
- }
33
+ return Object.prototype.toString.call(value) === '[object Promise]'
44
34
  }
45
35
 
46
36
  /**
@@ -50,9 +40,7 @@ function isPromise(value) {
50
40
  * @return {!Promise<void>} The promise.
51
41
  */
52
42
  function delayed(ms) {
53
- return new Promise((resolve) => {
54
- setTimeout(() => resolve(), ms)
55
- })
43
+ return new Promise((resolve) => setTimeout(resolve, ms))
56
44
  }
57
45
 
58
46
  /**
@@ -199,8 +187,8 @@ async function filter(array, fn, self = undefined) {
199
187
 
200
188
  for (let i = 0; i < n; i++) {
201
189
  if (i in arr) {
202
- let value = arr[i]
203
- let include = await fn.call(self, value, i, arr)
190
+ const value = arr[i]
191
+ const include = await fn.call(self, value, i, arr)
204
192
  if (include) {
205
193
  values[valuesLength++] = value
206
194
  }
package/lib/proxy.js CHANGED
File without changes
package/lib/session.js CHANGED
File without changes
package/lib/symbols.js CHANGED
File without changes
package/lib/until.js CHANGED
@@ -68,7 +68,7 @@ const webdriver = require('./webdriver'),
68
68
  * @return {!Condition<boolean>} A new condition.
69
69
  */
70
70
  exports.ableToSwitchToFrame = function ableToSwitchToFrame(frame) {
71
- var condition
71
+ let condition
72
72
  if (typeof frame === 'number' || frame instanceof webdriver.WebElement) {
73
73
  condition = (driver) => attemptToSwitchFrames(driver, frame)
74
74
  } else {
@@ -137,13 +137,14 @@ exports.alertIsPresent = function alertIsPresent() {
137
137
  * @return {!Condition<boolean>} The new condition.
138
138
  */
139
139
  exports.titleIs = function titleIs(title) {
140
- return new Condition('for title to be ' + JSON.stringify(title), function (
141
- driver
142
- ) {
143
- return driver.getTitle().then(function (t) {
144
- return t === title
145
- })
146
- })
140
+ return new Condition(
141
+ 'for title to be ' + JSON.stringify(title),
142
+ function (driver) {
143
+ return driver.getTitle().then(function (t) {
144
+ return t === title
145
+ })
146
+ }
147
+ )
147
148
  }
148
149
 
149
150
  /**
@@ -188,13 +189,14 @@ exports.titleMatches = function titleMatches(regex) {
188
189
  * @return {!Condition<boolean>} The new condition.
189
190
  */
190
191
  exports.urlIs = function urlIs(url) {
191
- return new Condition('for URL to be ' + JSON.stringify(url), function (
192
- driver
193
- ) {
194
- return driver.getCurrentUrl().then(function (u) {
195
- return u === url
196
- })
197
- })
192
+ return new Condition(
193
+ 'for URL to be ' + JSON.stringify(url),
194
+ function (driver) {
195
+ return driver.getCurrentUrl().then(function (u) {
196
+ return u === url
197
+ })
198
+ }
199
+ )
198
200
  }
199
201
 
200
202
  /**