UrgentcareCLI 0.1.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (318) hide show
  1. checksums.yaml +4 -4
  2. data/lib/UrgentCare/CLI.rb +57 -22
  3. data/lib/UrgentCare/Office.rb +1 -5
  4. data/lib/UrgentCare/Scraper.rb +71 -0
  5. data/lib/UrgentCare/version.rb +2 -2
  6. data/lib/UrgentCare.rb +2 -1
  7. metadata +27 -321
  8. data/.gitignore +0 -11
  9. data/.rspec +0 -3
  10. data/.travis.yml +0 -5
  11. data/CODE_OF_CONDUCT.md +0 -74
  12. data/Gemfile +0 -12
  13. data/Gemfile.lock +0 -84
  14. data/LICENSE.txt +0 -21
  15. data/Notes +0 -41
  16. data/README.md +0 -41
  17. data/Rakefile +0 -8
  18. data/UrgentCare.gemspec +0 -39
  19. data/background.jpg +0 -0
  20. data/data.txt +0 -4
  21. data/lib/Urgentcare/Scraper.rb +0 -78
  22. data/node_modules/.bin/rimraf +0 -1
  23. data/node_modules/.package-lock.json +0 -250
  24. data/node_modules/balanced-match/.github/FUNDING.yml +0 -2
  25. data/node_modules/balanced-match/LICENSE.md +0 -21
  26. data/node_modules/balanced-match/README.md +0 -97
  27. data/node_modules/balanced-match/index.js +0 -62
  28. data/node_modules/balanced-match/package.json +0 -48
  29. data/node_modules/brace-expansion/LICENSE +0 -21
  30. data/node_modules/brace-expansion/README.md +0 -129
  31. data/node_modules/brace-expansion/index.js +0 -201
  32. data/node_modules/brace-expansion/package.json +0 -47
  33. data/node_modules/concat-map/.travis.yml +0 -4
  34. data/node_modules/concat-map/LICENSE +0 -18
  35. data/node_modules/concat-map/README.markdown +0 -62
  36. data/node_modules/concat-map/example/map.js +0 -6
  37. data/node_modules/concat-map/index.js +0 -13
  38. data/node_modules/concat-map/package.json +0 -43
  39. data/node_modules/concat-map/test/map.js +0 -39
  40. data/node_modules/core-util-is/LICENSE +0 -19
  41. data/node_modules/core-util-is/README.md +0 -3
  42. data/node_modules/core-util-is/float.patch +0 -604
  43. data/node_modules/core-util-is/lib/util.js +0 -107
  44. data/node_modules/core-util-is/package.json +0 -32
  45. data/node_modules/core-util-is/test.js +0 -68
  46. data/node_modules/fs.realpath/LICENSE +0 -43
  47. data/node_modules/fs.realpath/README.md +0 -33
  48. data/node_modules/fs.realpath/index.js +0 -66
  49. data/node_modules/fs.realpath/old.js +0 -303
  50. data/node_modules/fs.realpath/package.json +0 -26
  51. data/node_modules/glob/LICENSE +0 -21
  52. data/node_modules/glob/README.md +0 -375
  53. data/node_modules/glob/changelog.md +0 -67
  54. data/node_modules/glob/common.js +0 -234
  55. data/node_modules/glob/glob.js +0 -788
  56. data/node_modules/glob/package.json +0 -51
  57. data/node_modules/glob/sync.js +0 -484
  58. data/node_modules/immediate/LICENSE.txt +0 -20
  59. data/node_modules/immediate/README.md +0 -93
  60. data/node_modules/immediate/dist/immediate.js +0 -75
  61. data/node_modules/immediate/dist/immediate.min.js +0 -1
  62. data/node_modules/immediate/lib/browser.js +0 -69
  63. data/node_modules/immediate/lib/index.js +0 -73
  64. data/node_modules/immediate/package.json +0 -42
  65. data/node_modules/inflight/LICENSE +0 -15
  66. data/node_modules/inflight/README.md +0 -37
  67. data/node_modules/inflight/inflight.js +0 -54
  68. data/node_modules/inflight/package.json +0 -29
  69. data/node_modules/inherits/LICENSE +0 -16
  70. data/node_modules/inherits/README.md +0 -42
  71. data/node_modules/inherits/inherits.js +0 -9
  72. data/node_modules/inherits/inherits_browser.js +0 -27
  73. data/node_modules/inherits/package.json +0 -29
  74. data/node_modules/isarray/.npmignore +0 -1
  75. data/node_modules/isarray/.travis.yml +0 -4
  76. data/node_modules/isarray/Makefile +0 -6
  77. data/node_modules/isarray/README.md +0 -60
  78. data/node_modules/isarray/component.json +0 -19
  79. data/node_modules/isarray/index.js +0 -5
  80. data/node_modules/isarray/package.json +0 -45
  81. data/node_modules/isarray/test.js +0 -20
  82. data/node_modules/jszip/.codeclimate.yml +0 -16
  83. data/node_modules/jszip/.editorconfig +0 -8
  84. data/node_modules/jszip/.jshintignore +0 -1
  85. data/node_modules/jszip/.jshintrc +0 -21
  86. data/node_modules/jszip/.travis.yml +0 -17
  87. data/node_modules/jszip/CHANGES.md +0 -163
  88. data/node_modules/jszip/LICENSE.markdown +0 -651
  89. data/node_modules/jszip/README.markdown +0 -35
  90. data/node_modules/jszip/dist/jszip.js +0 -30
  91. data/node_modules/jszip/dist/jszip.min.js +0 -13
  92. data/node_modules/jszip/index.d.ts +0 -270
  93. data/node_modules/jszip/lib/base64.js +0 -106
  94. data/node_modules/jszip/lib/compressedObject.js +0 -74
  95. data/node_modules/jszip/lib/compressions.js +0 -14
  96. data/node_modules/jszip/lib/crc32.js +0 -77
  97. data/node_modules/jszip/lib/defaults.js +0 -11
  98. data/node_modules/jszip/lib/external.js +0 -19
  99. data/node_modules/jszip/lib/flate.js +0 -85
  100. data/node_modules/jszip/lib/generate/ZipFileWorker.js +0 -540
  101. data/node_modules/jszip/lib/generate/index.js +0 -57
  102. data/node_modules/jszip/lib/index.js +0 -52
  103. data/node_modules/jszip/lib/license_header.js +0 -11
  104. data/node_modules/jszip/lib/load.js +0 -81
  105. data/node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js +0 -74
  106. data/node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js +0 -42
  107. data/node_modules/jszip/lib/nodejsUtils.js +0 -57
  108. data/node_modules/jszip/lib/object.js +0 -389
  109. data/node_modules/jszip/lib/readable-stream-browser.js +0 -9
  110. data/node_modules/jszip/lib/reader/ArrayReader.js +0 -57
  111. data/node_modules/jszip/lib/reader/DataReader.js +0 -116
  112. data/node_modules/jszip/lib/reader/NodeBufferReader.js +0 -19
  113. data/node_modules/jszip/lib/reader/StringReader.js +0 -38
  114. data/node_modules/jszip/lib/reader/Uint8ArrayReader.js +0 -22
  115. data/node_modules/jszip/lib/reader/readerFor.js +0 -28
  116. data/node_modules/jszip/lib/signature.js +0 -7
  117. data/node_modules/jszip/lib/stream/ConvertWorker.js +0 -26
  118. data/node_modules/jszip/lib/stream/Crc32Probe.js +0 -24
  119. data/node_modules/jszip/lib/stream/DataLengthProbe.js +0 -29
  120. data/node_modules/jszip/lib/stream/DataWorker.js +0 -116
  121. data/node_modules/jszip/lib/stream/GenericWorker.js +0 -263
  122. data/node_modules/jszip/lib/stream/StreamHelper.js +0 -212
  123. data/node_modules/jszip/lib/support.js +0 -38
  124. data/node_modules/jszip/lib/utf8.js +0 -275
  125. data/node_modules/jszip/lib/utils.js +0 -476
  126. data/node_modules/jszip/lib/zipEntries.js +0 -262
  127. data/node_modules/jszip/lib/zipEntry.js +0 -294
  128. data/node_modules/jszip/lib/zipObject.js +0 -133
  129. data/node_modules/jszip/package.json +0 -63
  130. data/node_modules/jszip/vendor/FileSaver.js +0 -247
  131. data/node_modules/lie/README.md +0 -62
  132. data/node_modules/lie/dist/lie.js +0 -350
  133. data/node_modules/lie/dist/lie.min.js +0 -1
  134. data/node_modules/lie/dist/lie.polyfill.js +0 -358
  135. data/node_modules/lie/dist/lie.polyfill.min.js +0 -1
  136. data/node_modules/lie/lib/browser.js +0 -273
  137. data/node_modules/lie/lib/index.js +0 -298
  138. data/node_modules/lie/license.md +0 -7
  139. data/node_modules/lie/lie.d.ts +0 -244
  140. data/node_modules/lie/package.json +0 -69
  141. data/node_modules/lie/polyfill.js +0 -4
  142. data/node_modules/minimatch/LICENSE +0 -15
  143. data/node_modules/minimatch/README.md +0 -209
  144. data/node_modules/minimatch/minimatch.js +0 -923
  145. data/node_modules/minimatch/package.json +0 -30
  146. data/node_modules/once/LICENSE +0 -15
  147. data/node_modules/once/README.md +0 -79
  148. data/node_modules/once/once.js +0 -42
  149. data/node_modules/once/package.json +0 -33
  150. data/node_modules/pako/CHANGELOG.md +0 -164
  151. data/node_modules/pako/LICENSE +0 -21
  152. data/node_modules/pako/README.md +0 -191
  153. data/node_modules/pako/dist/pako.js +0 -6818
  154. data/node_modules/pako/dist/pako.min.js +0 -1
  155. data/node_modules/pako/dist/pako_deflate.js +0 -3997
  156. data/node_modules/pako/dist/pako_deflate.min.js +0 -1
  157. data/node_modules/pako/dist/pako_inflate.js +0 -3300
  158. data/node_modules/pako/dist/pako_inflate.min.js +0 -1
  159. data/node_modules/pako/index.js +0 -14
  160. data/node_modules/pako/lib/deflate.js +0 -400
  161. data/node_modules/pako/lib/inflate.js +0 -423
  162. data/node_modules/pako/lib/utils/common.js +0 -105
  163. data/node_modules/pako/lib/utils/strings.js +0 -187
  164. data/node_modules/pako/lib/zlib/README +0 -59
  165. data/node_modules/pako/lib/zlib/adler32.js +0 -51
  166. data/node_modules/pako/lib/zlib/constants.js +0 -68
  167. data/node_modules/pako/lib/zlib/crc32.js +0 -59
  168. data/node_modules/pako/lib/zlib/deflate.js +0 -1874
  169. data/node_modules/pako/lib/zlib/gzheader.js +0 -58
  170. data/node_modules/pako/lib/zlib/inffast.js +0 -345
  171. data/node_modules/pako/lib/zlib/inflate.js +0 -1556
  172. data/node_modules/pako/lib/zlib/inftrees.js +0 -343
  173. data/node_modules/pako/lib/zlib/messages.js +0 -32
  174. data/node_modules/pako/lib/zlib/trees.js +0 -1222
  175. data/node_modules/pako/lib/zlib/zstream.js +0 -47
  176. data/node_modules/pako/package.json +0 -44
  177. data/node_modules/path-is-absolute/index.js +0 -20
  178. data/node_modules/path-is-absolute/license +0 -21
  179. data/node_modules/path-is-absolute/package.json +0 -43
  180. data/node_modules/path-is-absolute/readme.md +0 -59
  181. data/node_modules/process-nextick-args/index.js +0 -45
  182. data/node_modules/process-nextick-args/license.md +0 -19
  183. data/node_modules/process-nextick-args/package.json +0 -25
  184. data/node_modules/process-nextick-args/readme.md +0 -18
  185. data/node_modules/readable-stream/.travis.yml +0 -34
  186. data/node_modules/readable-stream/CONTRIBUTING.md +0 -38
  187. data/node_modules/readable-stream/GOVERNANCE.md +0 -136
  188. data/node_modules/readable-stream/LICENSE +0 -47
  189. data/node_modules/readable-stream/README.md +0 -58
  190. data/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +0 -60
  191. data/node_modules/readable-stream/duplex-browser.js +0 -1
  192. data/node_modules/readable-stream/duplex.js +0 -1
  193. data/node_modules/readable-stream/lib/_stream_duplex.js +0 -131
  194. data/node_modules/readable-stream/lib/_stream_passthrough.js +0 -47
  195. data/node_modules/readable-stream/lib/_stream_readable.js +0 -1019
  196. data/node_modules/readable-stream/lib/_stream_transform.js +0 -214
  197. data/node_modules/readable-stream/lib/_stream_writable.js +0 -687
  198. data/node_modules/readable-stream/lib/internal/streams/BufferList.js +0 -79
  199. data/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -74
  200. data/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
  201. data/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
  202. data/node_modules/readable-stream/package.json +0 -52
  203. data/node_modules/readable-stream/passthrough.js +0 -1
  204. data/node_modules/readable-stream/readable-browser.js +0 -7
  205. data/node_modules/readable-stream/readable.js +0 -19
  206. data/node_modules/readable-stream/transform.js +0 -1
  207. data/node_modules/readable-stream/writable-browser.js +0 -1
  208. data/node_modules/readable-stream/writable.js +0 -8
  209. data/node_modules/rimraf/LICENSE +0 -15
  210. data/node_modules/rimraf/README.md +0 -101
  211. data/node_modules/rimraf/bin.js +0 -50
  212. data/node_modules/rimraf/package.json +0 -29
  213. data/node_modules/rimraf/rimraf.js +0 -372
  214. data/node_modules/safe-buffer/LICENSE +0 -21
  215. data/node_modules/safe-buffer/README.md +0 -584
  216. data/node_modules/safe-buffer/index.d.ts +0 -187
  217. data/node_modules/safe-buffer/index.js +0 -62
  218. data/node_modules/safe-buffer/package.json +0 -37
  219. data/node_modules/selenium-webdriver/CHANGES.md +0 -1114
  220. data/node_modules/selenium-webdriver/LICENSE +0 -202
  221. data/node_modules/selenium-webdriver/NOTICE +0 -2
  222. data/node_modules/selenium-webdriver/README.md +0 -229
  223. data/node_modules/selenium-webdriver/chrome.js +0 -295
  224. data/node_modules/selenium-webdriver/chromium.js +0 -829
  225. data/node_modules/selenium-webdriver/devtools/CDPConnection.js +0 -35
  226. data/node_modules/selenium-webdriver/edge.js +0 -224
  227. data/node_modules/selenium-webdriver/example/chrome_android.js +0 -45
  228. data/node_modules/selenium-webdriver/example/chrome_mobile_emulation.js +0 -46
  229. data/node_modules/selenium-webdriver/example/firefox_channels.js +0 -84
  230. data/node_modules/selenium-webdriver/example/google_search.js +0 -50
  231. data/node_modules/selenium-webdriver/example/google_search_test.js +0 -70
  232. data/node_modules/selenium-webdriver/example/headless.js +0 -63
  233. data/node_modules/selenium-webdriver/example/logging.js +0 -64
  234. data/node_modules/selenium-webdriver/firefox.js +0 -789
  235. data/node_modules/selenium-webdriver/http/index.js +0 -324
  236. data/node_modules/selenium-webdriver/http/util.js +0 -172
  237. data/node_modules/selenium-webdriver/ie.js +0 -503
  238. data/node_modules/selenium-webdriver/index.js +0 -825
  239. data/node_modules/selenium-webdriver/io/exec.js +0 -162
  240. data/node_modules/selenium-webdriver/io/index.js +0 -348
  241. data/node_modules/selenium-webdriver/io/zip.js +0 -223
  242. data/node_modules/selenium-webdriver/lib/atoms/find-elements.js +0 -123
  243. data/node_modules/selenium-webdriver/lib/atoms/get-attribute.js +0 -101
  244. data/node_modules/selenium-webdriver/lib/atoms/is-displayed.js +0 -101
  245. data/node_modules/selenium-webdriver/lib/atoms/mutation-listener.js +0 -55
  246. data/node_modules/selenium-webdriver/lib/by.js +0 -415
  247. data/node_modules/selenium-webdriver/lib/capabilities.js +0 -553
  248. data/node_modules/selenium-webdriver/lib/command.js +0 -206
  249. data/node_modules/selenium-webdriver/lib/error.js +0 -605
  250. data/node_modules/selenium-webdriver/lib/http.js +0 -704
  251. data/node_modules/selenium-webdriver/lib/input.js +0 -946
  252. data/node_modules/selenium-webdriver/lib/logging.js +0 -661
  253. data/node_modules/selenium-webdriver/lib/promise.js +0 -285
  254. data/node_modules/selenium-webdriver/lib/proxy.js +0 -212
  255. data/node_modules/selenium-webdriver/lib/session.js +0 -77
  256. data/node_modules/selenium-webdriver/lib/symbols.js +0 -37
  257. data/node_modules/selenium-webdriver/lib/until.js +0 -429
  258. data/node_modules/selenium-webdriver/lib/webdriver.js +0 -2919
  259. data/node_modules/selenium-webdriver/net/index.js +0 -107
  260. data/node_modules/selenium-webdriver/net/portprober.js +0 -75
  261. data/node_modules/selenium-webdriver/opera.js +0 -406
  262. data/node_modules/selenium-webdriver/package.json +0 -54
  263. data/node_modules/selenium-webdriver/proxy.js +0 -32
  264. data/node_modules/selenium-webdriver/remote/index.js +0 -624
  265. data/node_modules/selenium-webdriver/safari.js +0 -168
  266. data/node_modules/selenium-webdriver/testing/index.js +0 -504
  267. data/node_modules/set-immediate-shim/index.js +0 -7
  268. data/node_modules/set-immediate-shim/package.json +0 -34
  269. data/node_modules/set-immediate-shim/readme.md +0 -31
  270. data/node_modules/string_decoder/.travis.yml +0 -50
  271. data/node_modules/string_decoder/LICENSE +0 -48
  272. data/node_modules/string_decoder/README.md +0 -47
  273. data/node_modules/string_decoder/lib/string_decoder.js +0 -296
  274. data/node_modules/string_decoder/package.json +0 -31
  275. data/node_modules/tmp/CHANGELOG.md +0 -288
  276. data/node_modules/tmp/LICENSE +0 -21
  277. data/node_modules/tmp/README.md +0 -365
  278. data/node_modules/tmp/lib/tmp.js +0 -780
  279. data/node_modules/tmp/node_modules/.bin/rimraf +0 -1
  280. data/node_modules/tmp/node_modules/rimraf/CHANGELOG.md +0 -65
  281. data/node_modules/tmp/node_modules/rimraf/LICENSE +0 -15
  282. data/node_modules/tmp/node_modules/rimraf/README.md +0 -101
  283. data/node_modules/tmp/node_modules/rimraf/bin.js +0 -68
  284. data/node_modules/tmp/node_modules/rimraf/package.json +0 -32
  285. data/node_modules/tmp/node_modules/rimraf/rimraf.js +0 -360
  286. data/node_modules/tmp/package.json +0 -58
  287. data/node_modules/util-deprecate/History.md +0 -16
  288. data/node_modules/util-deprecate/LICENSE +0 -24
  289. data/node_modules/util-deprecate/README.md +0 -53
  290. data/node_modules/util-deprecate/browser.js +0 -67
  291. data/node_modules/util-deprecate/node.js +0 -6
  292. data/node_modules/util-deprecate/package.json +0 -27
  293. data/node_modules/wrappy/LICENSE +0 -15
  294. data/node_modules/wrappy/README.md +0 -36
  295. data/node_modules/wrappy/package.json +0 -29
  296. data/node_modules/wrappy/wrappy.js +0 -33
  297. data/node_modules/ws/LICENSE +0 -21
  298. data/node_modules/ws/README.md +0 -496
  299. data/node_modules/ws/browser.js +0 -8
  300. data/node_modules/ws/index.js +0 -10
  301. data/node_modules/ws/lib/buffer-util.js +0 -129
  302. data/node_modules/ws/lib/constants.js +0 -10
  303. data/node_modules/ws/lib/event-target.js +0 -184
  304. data/node_modules/ws/lib/extension.js +0 -223
  305. data/node_modules/ws/lib/limiter.js +0 -55
  306. data/node_modules/ws/lib/permessage-deflate.js +0 -517
  307. data/node_modules/ws/lib/receiver.js +0 -507
  308. data/node_modules/ws/lib/sender.js +0 -405
  309. data/node_modules/ws/lib/stream.js +0 -165
  310. data/node_modules/ws/lib/validation.js +0 -104
  311. data/node_modules/ws/lib/websocket-server.js +0 -418
  312. data/node_modules/ws/lib/websocket.js +0 -942
  313. data/node_modules/ws/package.json +0 -56
  314. data/package-lock.json +0 -458
  315. data/package.json +0 -5
  316. data/selenium.log +0 -1
  317. data/spec.md +0 -6
  318. data/test.data +0 -2110
@@ -1,946 +0,0 @@
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
- /**
21
- * @fileoverview Defines types related to user input with the WebDriver API.
22
- */
23
-
24
- const promise = require('./promise')
25
- const { Command, Name } = require('./command')
26
- const {
27
- InvalidArgumentError,
28
- UnknownCommandError,
29
- UnsupportedOperationError,
30
- } = require('./error')
31
-
32
- /**
33
- * Enumeration of the buttons used in the advanced interactions API.
34
- * @enum {number}
35
- */
36
- const Button = {
37
- LEFT: 0,
38
- MIDDLE: 1,
39
- RIGHT: 2,
40
- }
41
-
42
- /**
43
- * Representations of pressable keys that aren't text. These are stored in
44
- * the Unicode PUA (Private Use Area) code points, 0xE000-0xF8FF. Refer to
45
- * http://www.google.com.au/search?&q=unicode+pua&btnK=Search
46
- *
47
- * @enum {string}
48
- * @see <https://www.w3.org/TR/webdriver/#keyboard-actions>
49
- */
50
- const Key = {
51
- NULL: '\uE000',
52
- CANCEL: '\uE001', // ^break
53
- HELP: '\uE002',
54
- BACK_SPACE: '\uE003',
55
- TAB: '\uE004',
56
- CLEAR: '\uE005',
57
- RETURN: '\uE006',
58
- ENTER: '\uE007',
59
- SHIFT: '\uE008',
60
- CONTROL: '\uE009',
61
- ALT: '\uE00A',
62
- PAUSE: '\uE00B',
63
- ESCAPE: '\uE00C',
64
- SPACE: '\uE00D',
65
- PAGE_UP: '\uE00E',
66
- PAGE_DOWN: '\uE00F',
67
- END: '\uE010',
68
- HOME: '\uE011',
69
- ARROW_LEFT: '\uE012',
70
- LEFT: '\uE012',
71
- ARROW_UP: '\uE013',
72
- UP: '\uE013',
73
- ARROW_RIGHT: '\uE014',
74
- RIGHT: '\uE014',
75
- ARROW_DOWN: '\uE015',
76
- DOWN: '\uE015',
77
- INSERT: '\uE016',
78
- DELETE: '\uE017',
79
- SEMICOLON: '\uE018',
80
- EQUALS: '\uE019',
81
-
82
- NUMPAD0: '\uE01A', // number pad keys
83
- NUMPAD1: '\uE01B',
84
- NUMPAD2: '\uE01C',
85
- NUMPAD3: '\uE01D',
86
- NUMPAD4: '\uE01E',
87
- NUMPAD5: '\uE01F',
88
- NUMPAD6: '\uE020',
89
- NUMPAD7: '\uE021',
90
- NUMPAD8: '\uE022',
91
- NUMPAD9: '\uE023',
92
- MULTIPLY: '\uE024',
93
- ADD: '\uE025',
94
- SEPARATOR: '\uE026',
95
- SUBTRACT: '\uE027',
96
- DECIMAL: '\uE028',
97
- DIVIDE: '\uE029',
98
-
99
- F1: '\uE031', // function keys
100
- F2: '\uE032',
101
- F3: '\uE033',
102
- F4: '\uE034',
103
- F5: '\uE035',
104
- F6: '\uE036',
105
- F7: '\uE037',
106
- F8: '\uE038',
107
- F9: '\uE039',
108
- F10: '\uE03A',
109
- F11: '\uE03B',
110
- F12: '\uE03C',
111
-
112
- COMMAND: '\uE03D', // Apple command key
113
- META: '\uE03D', // alias for Windows key
114
-
115
- /**
116
- * Japanese modifier key for switching between full- and half-width
117
- * characters.
118
- * @see <https://en.wikipedia.org/wiki/Language_input_keys>
119
- */
120
- ZENKAKU_HANKAKU: '\uE040',
121
- }
122
-
123
- /**
124
- * Simulate pressing many keys at once in a "chord". Takes a sequence of
125
- * {@linkplain Key keys} or strings, appends each of the values to a string,
126
- * adds the chord termination key ({@link Key.NULL}) and returns the resulting
127
- * string.
128
- *
129
- * Note: when the low-level webdriver key handlers see Keys.NULL, active
130
- * modifier keys (CTRL/ALT/SHIFT/etc) release via a keyup event.
131
- *
132
- * @param {...string} keys The key sequence to concatenate.
133
- * @return {string} The null-terminated key sequence.
134
- */
135
- Key.chord = function (...keys) {
136
- return keys.join('') + Key.NULL
137
- }
138
-
139
- /**
140
- * Used with {@link ./webelement.WebElement#sendKeys WebElement#sendKeys} on
141
- * file input elements (`<input type="file">`) to detect when the entered key
142
- * sequence defines the path to a file.
143
- *
144
- * By default, {@linkplain ./webelement.WebElement WebElement's} will enter all
145
- * key sequences exactly as entered. You may set a
146
- * {@linkplain ./webdriver.WebDriver#setFileDetector file detector} on the
147
- * parent WebDriver instance to define custom behavior for handling file
148
- * elements. Of particular note is the
149
- * {@link selenium-webdriver/remote.FileDetector}, which should be used when
150
- * running against a remote
151
- * [Selenium Server](https://selenium.dev/downloads/).
152
- */
153
- class FileDetector {
154
- /**
155
- * Handles the file specified by the given path, preparing it for use with
156
- * the current browser. If the path does not refer to a valid file, it will
157
- * be returned unchanged, otherwise a path suitable for use with the current
158
- * browser will be returned.
159
- *
160
- * This default implementation is a no-op. Subtypes may override this function
161
- * for custom tailored file handling.
162
- *
163
- * @param {!./webdriver.WebDriver} driver The driver for the current browser.
164
- * @param {string} path The path to process.
165
- * @return {!Promise<string>} A promise for the processed file path.
166
- * @package
167
- */
168
- handleFile(driver, path) { // eslint-disable-line
169
- return Promise.resolve(path)
170
- }
171
- }
172
-
173
- /**
174
- * Generic description of a single action to send to the remote end.
175
- *
176
- * @record
177
- * @package
178
- */
179
- class Action {
180
- constructor() {
181
- /** @type {!Action.Type} */
182
- this.type
183
- /** @type {(number|undefined)} */
184
- this.duration
185
- /** @type {(string|undefined)} */
186
- this.value
187
- /** @type {(Button|undefined)} */
188
- this.button
189
- /** @type {(number|undefined)} */
190
- this.x
191
- /** @type {(number|undefined)} */
192
- this.y
193
- }
194
- }
195
-
196
- /**
197
- * @enum {string}
198
- * @package
199
- * @see <https://w3c.github.io/webdriver/webdriver-spec.html#terminology-0>
200
- */
201
- Action.Type = {
202
- KEY_DOWN: 'keyDown',
203
- KEY_UP: 'keyUp',
204
- PAUSE: 'pause',
205
- POINTER_DOWN: 'pointerDown',
206
- POINTER_UP: 'pointerUp',
207
- POINTER_MOVE: 'pointerMove',
208
- POINTER_CANCEL: 'pointerCancel',
209
- }
210
-
211
- /**
212
- * Represents a user input device.
213
- *
214
- * @abstract
215
- */
216
- class Device {
217
- /**
218
- * @param {Device.Type} type the input type.
219
- * @param {string} id a unique ID for this device.
220
- */
221
- constructor(type, id) {
222
- /** @private @const */ this.type_ = type
223
- /** @private @const */ this.id_ = id
224
- }
225
-
226
- /** @return {!Object} the JSON encoding for this device. */
227
- toJSON() {
228
- return { type: this.type_, id: this.id_ }
229
- }
230
- }
231
-
232
- /**
233
- * Device types supported by the WebDriver protocol.
234
- *
235
- * @enum {string}
236
- * @see <https://w3c.github.io/webdriver/webdriver-spec.html#input-source-state>
237
- */
238
- Device.Type = {
239
- KEY: 'key',
240
- NONE: 'none',
241
- POINTER: 'pointer',
242
- }
243
-
244
- /**
245
- * @param {(string|Key|number)} key
246
- * @return {string}
247
- * @throws {!(InvalidArgumentError|RangeError)}
248
- */
249
- function checkCodePoint(key) {
250
- if (typeof key === 'number') {
251
- return String.fromCodePoint(key)
252
- }
253
-
254
- if (typeof key !== 'string') {
255
- throw new InvalidArgumentError(`key is not a string: ${key}`)
256
- }
257
-
258
- key = key.normalize()
259
- if (Array.from(key).length != 1) {
260
- throw new InvalidArgumentError(
261
- `key input is not a single code point: ${key}`
262
- )
263
- }
264
- return key
265
- }
266
-
267
- /**
268
- * Keyboard input device.
269
- *
270
- * @final
271
- * @see <https://www.w3.org/TR/webdriver/#dfn-key-input-source>
272
- */
273
- class Keyboard extends Device {
274
- /** @param {string} id the device ID. */
275
- constructor(id) {
276
- super(Device.Type.KEY, id)
277
- }
278
-
279
- /**
280
- * Generates a key down action.
281
- *
282
- * @param {(Key|string|number)} key the key to press. This key may be
283
- * specified as a {@link Key} value, a specific unicode code point,
284
- * or a string containing a single unicode code point.
285
- * @return {!Action} a new key down action.
286
- * @package
287
- */
288
- keyDown(key) {
289
- return { type: Action.Type.KEY_DOWN, value: checkCodePoint(key) }
290
- }
291
-
292
- /**
293
- * Generates a key up action.
294
- *
295
- * @param {(Key|string|number)} key the key to press. This key may be
296
- * specified as a {@link Key} value, a specific unicode code point,
297
- * or a string containing a single unicode code point.
298
- * @return {!Action} a new key up action.
299
- * @package
300
- */
301
- keyUp(key) {
302
- return { type: Action.Type.KEY_UP, value: checkCodePoint(key) }
303
- }
304
- }
305
-
306
- /**
307
- * Defines the reference point from which to compute offsets for
308
- * {@linkplain ./input.Pointer#move pointer move} actions.
309
- *
310
- * @enum {string}
311
- */
312
- const Origin = {
313
- /** Compute offsets relative to the pointer's current position. */
314
- POINTER: 'pointer',
315
- /** Compute offsets relative to the viewport. */
316
- VIEWPORT: 'viewport',
317
- }
318
-
319
- /**
320
- * Pointer input device.
321
- *
322
- * @final
323
- * @see <https://www.w3.org/TR/webdriver/#dfn-pointer-input-source>
324
- */
325
- class Pointer extends Device {
326
- /**
327
- * @param {string} id the device ID.
328
- * @param {Pointer.Type} type the pointer type.
329
- */
330
- constructor(id, type) {
331
- super(Device.Type.POINTER, id)
332
- /** @private @const */ this.pointerType_ = type
333
- }
334
-
335
- /** @override */
336
- toJSON() {
337
- return Object.assign(
338
- { parameters: { pointerType: this.pointerType_ } },
339
- super.toJSON()
340
- )
341
- }
342
-
343
- /**
344
- * @return {!Action} An action that cancels this pointer's current input.
345
- * @package
346
- */
347
- cancel() {
348
- return { type: Action.Type.POINTER_CANCEL }
349
- }
350
-
351
- /**
352
- * @param {!Button=} button The button to press.
353
- * @return {!Action} An action to press the specified button with this device.
354
- * @package
355
- */
356
- press(button = Button.LEFT) {
357
- return { type: Action.Type.POINTER_DOWN, button }
358
- }
359
-
360
- /**
361
- * @param {!Button=} button The button to release.
362
- * @return {!Action} An action to release the specified button with this
363
- * device.
364
- * @package
365
- */
366
- release(button = Button.LEFT) {
367
- return { type: Action.Type.POINTER_UP, button }
368
- }
369
-
370
- /**
371
- * Creates an action for moving the pointer `x` and `y` pixels from the
372
- * specified `origin`. The `origin` may be defined as the pointer's
373
- * {@linkplain Origin.POINTER current position}, the
374
- * {@linkplain Origin.VIEWPORT viewport}, or the center of a specific
375
- * {@linkplain ./webdriver.WebElement WebElement}.
376
- *
377
- * @param {{
378
- * x: (number|undefined),
379
- * y: (number|undefined),
380
- * duration: (number|undefined),
381
- * origin: (!Origin|!./webdriver.WebElement|undefined),
382
- * }=} options the move options.
383
- * @return {!Action} The new action.
384
- * @package
385
- */
386
- move({ x = 0, y = 0, duration = 100, origin = Origin.VIEWPORT }) {
387
- return { type: Action.Type.POINTER_MOVE, origin, duration, x, y }
388
- }
389
- }
390
-
391
- /**
392
- * The supported types of pointers.
393
- * @enum {string}
394
- */
395
- Pointer.Type = {
396
- MOUSE: 'mouse',
397
- PEN: 'pen',
398
- TOUCH: 'touch',
399
- }
400
-
401
- /**
402
- * User facing API for generating complex user gestures. This class should not
403
- * be instantiated directly. Instead, users should create new instances by
404
- * calling {@link ./webdriver.WebDriver#actions WebDriver.actions()}.
405
- *
406
- * ### Action Ticks
407
- *
408
- * Action sequences are divided into a series of "ticks". At each tick, the
409
- * WebDriver remote end will perform a single action for each device included
410
- * in the action sequence. At tick 0, the driver will perform the first action
411
- * defined for each device, at tick 1 the second action for each device, and
412
- * so on until all actions have been executed. If an individual device does
413
- * not have an action defined at a particular tick, it will automatically
414
- * pause.
415
- *
416
- * By default, action sequences will be synchronized so only one device has a
417
- * define action in each tick. Consider the following code sample:
418
- *
419
- * const actions = driver.actions();
420
- *
421
- * await actions
422
- * .keyDown(SHIFT)
423
- * .move({origin: el})
424
- * .press()
425
- * .release()
426
- * .keyUp(SHIFT)
427
- * .perform();
428
- *
429
- * This sample produces the following sequence of ticks:
430
- *
431
- * | Device | Tick 1 | Tick 2 | Tick 3 | Tick 4 | Tick 5 |
432
- * | -------- | -------------- | ------------------ | ------- | --------- | ------------ |
433
- * | Keyboard | keyDown(SHIFT) | pause() | pause() | pause() | keyUp(SHIFT) |
434
- * | Mouse | pause() | move({origin: el}) | press() | release() | pause() |
435
- *
436
- * If you'd like the remote end to execute actions with multiple devices
437
- * simultaneously, you may pass `{async: true}` when creating the actions
438
- * builder. With synchronization disabled (`{async: true}`), the ticks from our
439
- * previous example become:
440
- *
441
- * | Device | Tick 1 | Tick 2 | Tick 3 |
442
- * | -------- | ------------------ | ------------ | --------- |
443
- * | Keyboard | keyDown(SHIFT) | keyUp(SHIFT) | |
444
- * | Mouse | move({origin: el}) | press() | release() |
445
- *
446
- * When synchronization is disabled, it is your responsibility to insert
447
- * {@linkplain #pause() pauses} for each device, as needed:
448
- *
449
- * const actions = driver.actions({async: true});
450
- * const kb = actions.keyboard();
451
- * const mouse = actions.mouse();
452
- *
453
- * actions.keyDown(SHIFT).pause(kb).pause(kb).key(SHIFT);
454
- * actions.pause(mouse).move({origin: el}).press().release();
455
- * actions.perform();
456
- *
457
- * With pauses insert for individual devices, we're back to:
458
- *
459
- * | Device | Tick 1 | Tick 2 | Tick 3 | Tick 4 |
460
- * | -------- | -------------- | ------------------ | ------- | ------------ |
461
- * | Keyboard | keyDown(SHIFT) | pause() | pause() | keyUp(SHIFT) |
462
- * | Mouse | pause() | move({origin: el}) | press() | release() |
463
- *
464
- * #### Tick Durations
465
- *
466
- * The length of each action tick is however long it takes the remote end to
467
- * execute the actions for every device in that tick. Most actions are
468
- * "instantaneous", however, {@linkplain #pause pause} and
469
- * {@linkplain #move pointer move} actions allow you to specify a duration for
470
- * how long that action should take. The remote end will always wait for all
471
- * actions within a tick to finish before starting the next tick, so a device
472
- * may implicitly pause while waiting for other devices to finish.
473
- *
474
- * | Device | Tick 1 | Tick 2 |
475
- * | --------- | --------------------- | ------- |
476
- * | Pointer 1 | move({duration: 200}) | press() |
477
- * | Pointer 2 | move({duration: 300}) | press() |
478
- *
479
- * In table above, the move for Pointer 1 should only take 200 ms, but the
480
- * remote end will wait for the move for Pointer 2 to finish
481
- * (an additional 100 ms) before proceeding to Tick 2.
482
- *
483
- * This implicit waiting also applies to pauses. In the table below, even though
484
- * the keyboard only defines a pause of 100 ms, the remote end will wait an
485
- * additional 200 ms for the mouse move to finish before moving to Tick 2.
486
- *
487
- * | Device | Tick 1 | Tick 2 |
488
- * | -------- | --------------------- | -------------- |
489
- * | Keyboard | pause(100) | keyDown(SHIFT) |
490
- * | Mouse | move({duration: 300}) | |
491
- *
492
- * [client rect]: https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects
493
- * [bounding client rect]: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
494
- *
495
- * @final
496
- * @see <https://www.w3.org/TR/webdriver/#actions>
497
- */
498
- class Actions {
499
- /**
500
- * @param {!Executor} executor The object to execute the configured
501
- * actions with.
502
- * @param {{async: (boolean|undefined)}} options Options for this action
503
- * sequence (see class description for details).
504
- */
505
- constructor(executor, { async = false } = {}) {
506
-
507
- /** @private @const */
508
- this.executor_ = executor
509
-
510
- /** @private @const */
511
- this.sync_ = !async
512
-
513
- /** @private @const */
514
- this.keyboard_ = new Keyboard('default keyboard')
515
-
516
- /** @private @const */
517
- this.mouse_ = new Pointer('default mouse', Pointer.Type.MOUSE)
518
-
519
- /** @private @const {!Map<!Device, !Array<!Action>>} */
520
- this.sequences_ = new Map([
521
- [this.keyboard_, []],
522
- [this.mouse_, []],
523
- ])
524
- }
525
-
526
- /** @return {!Keyboard} the keyboard device handle. */
527
- keyboard() {
528
- return this.keyboard_
529
- }
530
-
531
- /** @return {!Pointer} the mouse pointer device handle. */
532
- mouse() {
533
- return this.mouse_
534
- }
535
-
536
- /**
537
- * @param {!Device} device
538
- * @return {!Array<!Action>}
539
- * @private
540
- */
541
- sequence_(device) {
542
- let sequence = this.sequences_.get(device)
543
- if (!sequence) {
544
- sequence = []
545
- this.sequences_.set(device, sequence)
546
- }
547
- return sequence
548
- }
549
-
550
- /**
551
- * Appends `actions` to the end of the current sequence for the given
552
- * `device`. If device synchronization is enabled, after inserting the
553
- * actions, pauses will be inserted for all other devices to ensure all action
554
- * sequences are the same length.
555
- *
556
- * @param {!Device} device the device to update.
557
- * @param {...!Action} actions the actions to insert.
558
- * @return {!Actions} a self reference.
559
- */
560
- insert(device, ...actions) {
561
- this.sequence_(device).push(...actions)
562
- return this.sync_ ? this.synchronize() : this
563
- }
564
-
565
- /**
566
- * Ensures the action sequence for every device referenced in this action
567
- * sequence is the same length. For devices whose sequence is too short,
568
- * this will insert {@linkplain #pause pauses} so that every device has an
569
- * explicit action defined at each tick.
570
- *
571
- * @param {...!Device} devices The specific devices to synchronize.
572
- * If unspecified, the action sequences for every device will be
573
- * synchronized.
574
- * @return {!Actions} a self reference.
575
- */
576
- synchronize(...devices) {
577
- let sequences
578
- let max = 0
579
- if (devices.length === 0) {
580
- for (const s of this.sequences_.values()) {
581
- max = Math.max(max, s.length)
582
- }
583
- sequences = this.sequences_.values()
584
- } else {
585
- sequences = []
586
- for (const device of devices) {
587
- const seq = this.sequence_(device)
588
- max = Math.max(max, seq.length)
589
- sequences.push(seq)
590
- }
591
- }
592
-
593
- const pause = { type: Action.Type.PAUSE, duration: 0 }
594
- for (const seq of sequences) {
595
- while (seq.length < max) {
596
- seq.push(pause)
597
- }
598
- }
599
-
600
- return this
601
- }
602
-
603
- /**
604
- * Inserts a pause action for the specified devices, ensuring each device is
605
- * idle for a tick. The length of the pause (in milliseconds) may be specified
606
- * as the first parameter to this method (defaults to 0). Otherwise, you may
607
- * just specify the individual devices that should pause.
608
- *
609
- * If no devices are specified, a pause action will be created (using the same
610
- * duration) for every device.
611
- *
612
- * When device synchronization is enabled (the default for new {@link Actions}
613
- * objects), there is no need to specify devices as pausing one automatically
614
- * pauses the others for the same duration. In other words, the following are
615
- * all equivalent:
616
- *
617
- * let a1 = driver.actions();
618
- * a1.pause(100).perform();
619
- *
620
- * let a2 = driver.actions();
621
- * a2.pause(100, a2.keyboard()).perform();
622
- * // Synchronization ensures a2.mouse() is automatically paused too.
623
- *
624
- * let a3 = driver.actions();
625
- * a3.pause(100, a3.keyboard(), a3.mouse()).perform();
626
- *
627
- * When device synchronization is _disabled_, you can cause individual devices
628
- * to pause during a tick. For example, to hold the SHIFT key down while
629
- * moving the mouse:
630
- *
631
- * let actions = driver.actions({async: true});
632
- *
633
- * actions.keyDown(Key.SHIFT);
634
- * actions.pause(actions.mouse()) // Pause for shift down
635
- * .press(Button.LEFT)
636
- * .move({x: 10, y: 10})
637
- * .release(Button.LEFT);
638
- * actions
639
- * .pause(
640
- * actions.keyboard(), // Pause for press left
641
- * actions.keyboard(), // Pause for move
642
- * actions.keyboard()) // Pause for release left
643
- * .keyUp(Key.SHIFT);
644
- * await actions.perform();
645
- *
646
- * @param {(number|!Device)=} duration The length of the pause to insert, in
647
- * milliseconds. Alternatively, the duration may be omitted (yielding a
648
- * default 0 ms pause), and the first device to pause may be specified.
649
- * @param {...!Device} devices The devices to insert the pause for. If no
650
- * devices are specified, the pause will be inserted for _all_ devices.
651
- * @return {!Actions} a self reference.
652
- */
653
- pause(duration, ...devices) {
654
- if (duration instanceof Device) {
655
- devices.push(duration)
656
- duration = 0
657
- } else if (!duration) {
658
- duration = 0
659
- }
660
-
661
- const action = { type: Action.Type.PAUSE, duration }
662
-
663
- // NB: need a properly typed variable for type checking.
664
- /** @type {!Iterable<!Device>} */
665
- const iterable = devices.length === 0 ? this.sequences_.keys() : devices
666
- for (const device of iterable) {
667
- this.sequence_(device).push(action)
668
- }
669
- return this.sync_ ? this.synchronize() : this
670
- }
671
-
672
- /**
673
- * Inserts an action to press a single key.
674
- *
675
- * @param {(Key|string|number)} key the key to press. This key may be
676
- * specified as a {@link Key} value, a specific unicode code point,
677
- * or a string containing a single unicode code point.
678
- * @return {!Actions} a self reference.
679
- */
680
- keyDown(key) {
681
- return this.insert(this.keyboard_, this.keyboard_.keyDown(key))
682
- }
683
-
684
- /**
685
- * Inserts an action to release a single key.
686
- *
687
- * @param {(Key|string|number)} key the key to release. This key may be
688
- * specified as a {@link Key} value, a specific unicode code point,
689
- * or a string containing a single unicode code point.
690
- * @return {!Actions} a self reference.
691
- */
692
- keyUp(key) {
693
- return this.insert(this.keyboard_, this.keyboard_.keyUp(key))
694
- }
695
-
696
- /**
697
- * Inserts a sequence of actions to type the provided key sequence.
698
- * For each key, this will record a pair of {@linkplain #keyDown keyDown}
699
- * and {@linkplain #keyUp keyUp} actions. An implication of this pairing
700
- * is that modifier keys (e.g. {@link ./input.Key.SHIFT Key.SHIFT}) will
701
- * always be immediately released. In other words, `sendKeys(Key.SHIFT, 'a')`
702
- * is the same as typing `sendKeys('a')`, _not_ `sendKeys('A')`.
703
- *
704
- * @param {...(Key|string|number)} keys the keys to type.
705
- * @return {!Actions} a self reference.
706
- */
707
- sendKeys(...keys) {
708
- const actions = []
709
- for (const key of keys) {
710
- if (typeof key === 'string') {
711
- for (const symbol of key) {
712
- actions.push(
713
- this.keyboard_.keyDown(symbol),
714
- this.keyboard_.keyUp(symbol)
715
- )
716
- }
717
- } else {
718
- actions.push(this.keyboard_.keyDown(key), this.keyboard_.keyUp(key))
719
- }
720
- }
721
- return this.insert(this.keyboard_, ...actions)
722
- }
723
-
724
- /**
725
- * Inserts an action to press a mouse button at the mouse's current location.
726
- *
727
- * @param {!Button=} button The button to press; defaults to `LEFT`.
728
- * @return {!Actions} a self reference.
729
- */
730
- press(button = Button.LEFT) {
731
- return this.insert(this.mouse_, this.mouse_.press(button))
732
- }
733
-
734
- /**
735
- * Inserts an action to release a mouse button at the mouse's current
736
- * location.
737
- *
738
- * @param {!Button=} button The button to release; defaults to `LEFT`.
739
- * @return {!Actions} a self reference.
740
- */
741
- release(button = Button.LEFT) {
742
- return this.insert(this.mouse_, this.mouse_.release(button))
743
- }
744
-
745
- /**
746
- * Inserts an action for moving the mouse `x` and `y` pixels relative to the
747
- * specified `origin`. The `origin` may be defined as the mouse's
748
- * {@linkplain ./input.Origin.POINTER current position}, the
749
- * {@linkplain ./input.Origin.VIEWPORT viewport}, or the center of a specific
750
- * {@linkplain ./webdriver.WebElement WebElement}.
751
- *
752
- * You may adjust how long the remote end should take, in milliseconds, to
753
- * perform the move using the `duration` parameter (defaults to 100 ms).
754
- * The number of incremental move events generated over this duration is an
755
- * implementation detail for the remote end.
756
- *
757
- * @param {{
758
- * x: (number|undefined),
759
- * y: (number|undefined),
760
- * duration: (number|undefined),
761
- * origin: (!Origin|!./webdriver.WebElement|undefined),
762
- * }=} options The move options. Defaults to moving the mouse to the top-left
763
- * corner of the viewport over 100ms.
764
- * @return {!Actions} a self reference.
765
- */
766
- move({ x = 0, y = 0, duration = 100, origin = Origin.VIEWPORT } = {}) {
767
- return this.insert(
768
- this.mouse_,
769
- this.mouse_.move({ x, y, duration, origin })
770
- )
771
- }
772
-
773
- /**
774
- * Short-hand for performing a simple left-click (down/up) with the mouse.
775
- *
776
- * @param {./webdriver.WebElement=} element If specified, the mouse will
777
- * first be moved to the center of the element before performing the
778
- * click.
779
- * @return {!Actions} a self reference.
780
- */
781
- click(element) {
782
- if (element) {
783
- this.move({ origin: element })
784
- }
785
- return this.press().release()
786
- }
787
-
788
- /**
789
- * Short-hand for performing a simple right-click (down/up) with the mouse.
790
- *
791
- * @param {./webdriver.WebElement=} element If specified, the mouse will
792
- * first be moved to the center of the element before performing the
793
- * click.
794
- * @return {!Actions} a self reference.
795
- */
796
- contextClick(element) {
797
- if (element) {
798
- this.move({ origin: element })
799
- }
800
- return this.press(Button.RIGHT).release(Button.RIGHT)
801
- }
802
-
803
- /**
804
- * Short-hand for performing a double left-click with the mouse.
805
- *
806
- * @param {./webdriver.WebElement=} element If specified, the mouse will
807
- * first be moved to the center of the element before performing the
808
- * click.
809
- * @return {!Actions} a self reference.
810
- */
811
- doubleClick(element) {
812
- return this.click(element).press().release()
813
- }
814
-
815
- /**
816
- * Configures a drag-and-drop action consisting of the following steps:
817
- *
818
- * 1. Move to the center of the `from` element (element to be dragged).
819
- * 2. Press the left mouse button.
820
- * 3. If the `to` target is a {@linkplain ./webdriver.WebElement WebElement},
821
- * move the mouse to its center. Otherwise, move the mouse by the
822
- * specified offset.
823
- * 4. Release the left mouse button.
824
- *
825
- * @param {!./webdriver.WebElement} from The element to press the left mouse
826
- * button on to start the drag.
827
- * @param {(!./webdriver.WebElement|{x: number, y: number})} to Either another
828
- * element to drag to (will drag to the center of the element), or an
829
- * object specifying the offset to drag by, in pixels.
830
- * @return {!Actions} a self reference.
831
- */
832
- dragAndDrop(from, to) {
833
- // Do not require up top to avoid a cycle that breaks static analysis.
834
- const { WebElement } = require('./webdriver')
835
- if (
836
- !(to instanceof WebElement) &&
837
- (!to || typeof to.x !== 'number' || typeof to.y !== 'number')
838
- ) {
839
- throw new InvalidArgumentError(
840
- 'Invalid drag target; must specify a WebElement or {x, y} offset'
841
- )
842
- }
843
-
844
- this.move({ origin: from }).press()
845
- if (to instanceof WebElement) {
846
- this.move({ origin: to })
847
- } else {
848
- this.move({ x: to.x, y: to.y, origin: Origin.POINTER })
849
- }
850
- return this.release()
851
- }
852
-
853
- /**
854
- * Releases all keys, pointers, and clears internal state.
855
- *
856
- * @return {!Promise<void>} a promise that will resolve when finished
857
- * clearing all action state.
858
- */
859
- clear() {
860
- for (const s of this.sequences_.values()) {
861
- s.length = 0
862
- }
863
- return this.executor_.execute(new Command(Name.CLEAR_ACTIONS))
864
- }
865
-
866
- /**
867
- * Performs the configured action sequence.
868
- *
869
- * @return {!Promise<void>} a promise that will resolve when all actions have
870
- * been completed.
871
- */
872
- async perform() {
873
- const _actions = []
874
- this.sequences_.forEach((actions, device) => {
875
- if (!isIdle(actions)) {
876
- actions = actions.concat() // Defensive copy.
877
- _actions.push(Object.assign({ actions }, device.toJSON()))
878
- }
879
- })
880
-
881
- if (_actions.length === 0) {
882
- return Promise.resolve()
883
- }
884
-
885
- try {
886
- await this.executor_.execute(
887
- new Command(Name.ACTIONS).setParameter('actions', _actions)
888
- )
889
- } catch (ex) {
890
- throw ex
891
- }
892
- }
893
- }
894
-
895
- /**
896
- * @param {!Array<!Action>} actions
897
- * @return {boolean}
898
- */
899
- function isIdle(actions) {
900
- return (
901
- actions.length === 0 ||
902
- actions.every((a) => a.type === Action.Type.PAUSE && !a.duration)
903
- )
904
- }
905
-
906
- /**
907
- * Script used to compute the offset from the center of a DOM element's first
908
- * client rect from the top-left corner of the element's bounding client rect.
909
- * The element's center point is computed using the algorithm defined here:
910
- * <https://w3c.github.io/webdriver/webdriver-spec.html#dfn-center-point>.
911
- *
912
- * __This is only exported for use in internal unit tests. DO NOT USE.__
913
- *
914
- * @package
915
- */
916
- const INTERNAL_COMPUTE_OFFSET_SCRIPT = `
917
- function computeOffset(el) {
918
- var rect = el.getClientRects()[0];
919
- var left = Math.max(0, Math.min(rect.x, rect.x + rect.width));
920
- var right =
921
- Math.min(window.innerWidth, Math.max(rect.x, rect.x + rect.width));
922
- var top = Math.max(0, Math.min(rect.y, rect.y + rect.height));
923
- var bot =
924
- Math.min(window.innerHeight, Math.max(rect.y, rect.y + rect.height));
925
- var x = Math.floor(0.5 * (left + right));
926
- var y = Math.floor(0.5 * (top + bot));
927
-
928
- var bbox = el.getBoundingClientRect();
929
- return [x - bbox.left, y - bbox.top];
930
- }
931
- return computeOffset(arguments[0]);`
932
-
933
- // PUBLIC API
934
-
935
- module.exports = {
936
- Action, // For documentation only.
937
- Actions,
938
- Button,
939
- Device,
940
- Key,
941
- Keyboard,
942
- FileDetector,
943
- Origin,
944
- Pointer,
945
- INTERNAL_COMPUTE_OFFSET_SCRIPT,
946
- }