selenium-webdriver 2.47.0 → 2.52.0

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 (529) hide show
  1. package/CHANGES.md +96 -0
  2. package/NOTICE +1 -1
  3. package/README.md +57 -6
  4. package/builder.js +375 -358
  5. package/chrome.js +549 -586
  6. package/edge.js +378 -0
  7. package/error.js +597 -5
  8. package/example/google_search_generator.js +2 -4
  9. package/example/logging.js +6 -2
  10. package/executors.js +11 -27
  11. package/firefox/binary.js +80 -114
  12. package/firefox/extension.js +10 -19
  13. package/firefox/index.js +175 -171
  14. package/firefox/profile.js +221 -239
  15. package/http/index.js +396 -77
  16. package/http/util.js +35 -35
  17. package/ie.js +288 -309
  18. package/index.js +34 -125
  19. package/io/exec.js +58 -39
  20. package/io/index.js +54 -48
  21. package/lib/actions.js +594 -0
  22. package/lib/by.js +276 -0
  23. package/lib/capabilities.js +404 -0
  24. package/lib/{webdriver/command.js → command.js} +89 -72
  25. package/lib/{webdriver/button.js → devmode.js} +13 -8
  26. package/lib/events.js +210 -0
  27. package/lib/firefox/amd64/libnoblur64.so +0 -0
  28. package/lib/firefox/i386/libnoblur.so +0 -0
  29. package/lib/firefox/webdriver.json +6 -1
  30. package/lib/firefox/webdriver.xpi +0 -0
  31. package/lib/{webdriver/key.js → input.js} +82 -2
  32. package/lib/logging.js +668 -0
  33. package/lib/promise.js +3093 -0
  34. package/lib/safari/client.js +697 -659
  35. package/lib/session.js +79 -0
  36. package/{test/promise_aplus_test.js → lib/symbols.js} +15 -25
  37. package/lib/test/build.js +4 -4
  38. package/lib/test/data/click_tests/disappearing_element.html +62 -0
  39. package/lib/test/data/click_tests/html5_submit_buttons.html +2 -1
  40. package/lib/test/data/click_tests/overlapping_elements.html +70 -0
  41. package/lib/test/data/click_tests/partially_overlapping_elements.html +124 -0
  42. package/lib/test/data/click_tests/wrapped_overlapping_elements.html +13 -0
  43. package/lib/test/data/readOnlyPage.html +3 -1
  44. package/lib/test/data/selectPage.html +18 -2
  45. package/lib/test/data/simpleTest.html +1 -0
  46. package/lib/test/fileserver.js +3 -4
  47. package/lib/test/index.js +13 -4
  48. package/lib/test/resources.js +1 -1
  49. package/lib/until.js +428 -0
  50. package/lib/webdriver.js +2351 -0
  51. package/net/portprober.js +15 -11
  52. package/opera.js +295 -314
  53. package/package.json +6 -5
  54. package/phantomjs.js +135 -140
  55. package/proxy.js +6 -4
  56. package/remote/index.js +234 -219
  57. package/safari.js +319 -310
  58. package/test/chrome/options_test.js +11 -9
  59. package/test/element_finding_test.js +51 -13
  60. package/test/error_test.js +163 -0
  61. package/test/execute_script_test.js +1 -1
  62. package/test/firefox/firefox_test.js +24 -0
  63. package/test/http/http_test.js +354 -43
  64. package/test/http/util_test.js +25 -23
  65. package/test/io_test.js +6 -1
  66. package/test/lib/by_test.js +127 -0
  67. package/test/lib/capabilities_test.js +84 -0
  68. package/test/lib/events_test.js +177 -0
  69. package/test/lib/logging_test.js +272 -0
  70. package/test/lib/promise_aplus_test.js +74 -0
  71. package/test/lib/promise_error_test.js +808 -0
  72. package/test/lib/promise_flow_test.js +2282 -0
  73. package/test/lib/promise_generator_test.js +308 -0
  74. package/test/lib/promise_test.js +996 -0
  75. package/test/lib/testutil.js +90 -0
  76. package/test/lib/until_test.js +436 -0
  77. package/test/lib/webdriver_test.js +2207 -0
  78. package/test/page_loading_test.js +7 -9
  79. package/test/stale_element_test.js +2 -2
  80. package/test/testing/assert_test.js +374 -0
  81. package/test/testing/index_test.js +9 -11
  82. package/testing/assert.js +334 -17
  83. package/testing/index.js +10 -0
  84. package/_base.js +0 -200
  85. package/docs/Changes.html +0 -317
  86. package/docs/class_bot_Error.html +0 -15
  87. package/docs/class_webdriver_ActionSequence.html +0 -115
  88. package/docs/class_webdriver_Alert.html +0 -24
  89. package/docs/class_webdriver_AlertPromise.html +0 -91
  90. package/docs/class_webdriver_Capabilities.html +0 -60
  91. package/docs/class_webdriver_Command.html +0 -15
  92. package/docs/class_webdriver_EventEmitter.html +0 -35
  93. package/docs/class_webdriver_FileDetector.html +0 -21
  94. package/docs/class_webdriver_Locator.html +0 -12
  95. package/docs/class_webdriver_Serializable.html +0 -9
  96. package/docs/class_webdriver_Session.html +0 -13
  97. package/docs/class_webdriver_TouchSequence.html +0 -49
  98. package/docs/class_webdriver_UnhandledAlertError.html +0 -18
  99. package/docs/class_webdriver_WebDriver.html +0 -313
  100. package/docs/class_webdriver_WebDriver_Logs.html +0 -15
  101. package/docs/class_webdriver_WebDriver_Navigation.html +0 -16
  102. package/docs/class_webdriver_WebDriver_Options.html +0 -41
  103. package/docs/class_webdriver_WebDriver_TargetLocator.html +0 -38
  104. package/docs/class_webdriver_WebDriver_Timeouts.html +0 -29
  105. package/docs/class_webdriver_WebDriver_Window.html +0 -27
  106. package/docs/class_webdriver_WebElement.html +0 -216
  107. package/docs/class_webdriver_WebElementPromise.html +0 -266
  108. package/docs/class_webdriver_http_Executor.html +0 -22
  109. package/docs/class_webdriver_http_Request.html +0 -12
  110. package/docs/class_webdriver_http_Response.html +0 -13
  111. package/docs/class_webdriver_logging_Entry.html +0 -15
  112. package/docs/class_webdriver_logging_Level.html +0 -55
  113. package/docs/class_webdriver_logging_LogRecord.html +0 -45
  114. package/docs/class_webdriver_logging_Logger.html +0 -119
  115. package/docs/class_webdriver_logging_Preferences.html +0 -8
  116. package/docs/class_webdriver_promise_CancellationError.html +0 -18
  117. package/docs/class_webdriver_promise_ControlFlow.html +0 -109
  118. package/docs/class_webdriver_promise_Deferred.html +0 -84
  119. package/docs/class_webdriver_promise_Promise.html +0 -74
  120. package/docs/class_webdriver_stacktrace_Frame.html +0 -20
  121. package/docs/class_webdriver_stacktrace_Snapshot.html +0 -6
  122. package/docs/class_webdriver_testing_Assertion.html +0 -99
  123. package/docs/class_webdriver_testing_Assertion_DelegatingMatcher_.html +0 -13
  124. package/docs/class_webdriver_testing_ContainsMatcher.html +0 -11
  125. package/docs/class_webdriver_testing_NegatedAssertion.html +0 -97
  126. package/docs/class_webdriver_until_Condition.html +0 -7
  127. package/docs/dossier.css +0 -1
  128. package/docs/dossier.js +0 -86
  129. package/docs/enum_bot_ErrorCode.html +0 -3
  130. package/docs/enum_bot_Error_State.html +0 -2
  131. package/docs/enum_webdriver_Browser.html +0 -2
  132. package/docs/enum_webdriver_Button.html +0 -2
  133. package/docs/enum_webdriver_Capability.html +0 -33
  134. package/docs/enum_webdriver_CommandName.html +0 -3
  135. package/docs/enum_webdriver_Key.html +0 -12
  136. package/docs/enum_webdriver_logging_Type.html +0 -6
  137. package/docs/enum_webdriver_promise_ControlFlow_EventType.html +0 -9
  138. package/docs/index.html +0 -123
  139. package/docs/interface_webdriver_CommandExecutor.html +0 -9
  140. package/docs/interface_webdriver_http_Client.html +0 -10
  141. package/docs/interface_webdriver_promise_Thenable.html +0 -77
  142. package/docs/module_selenium-webdriver.html +0 -23
  143. package/docs/module_selenium-webdriver__base.html +0 -23
  144. package/docs/module_selenium-webdriver__base_class_Context.html +0 -5
  145. package/docs/module_selenium-webdriver_builder.html +0 -2
  146. package/docs/module_selenium-webdriver_builder_class_Builder.html +0 -138
  147. package/docs/module_selenium-webdriver_chrome.html +0 -90
  148. package/docs/module_selenium-webdriver_chrome_class_Driver.html +0 -280
  149. package/docs/module_selenium-webdriver_chrome_class_Options.html +0 -127
  150. package/docs/module_selenium-webdriver_chrome_class_ServiceBuilder.html +0 -46
  151. package/docs/module_selenium-webdriver_class_ActionSequence.html +0 -115
  152. package/docs/module_selenium-webdriver_class_Builder.html +0 -138
  153. package/docs/module_selenium-webdriver_class_Capabilities.html +0 -60
  154. package/docs/module_selenium-webdriver_class_Command.html +0 -15
  155. package/docs/module_selenium-webdriver_class_EventEmitter.html +0 -35
  156. package/docs/module_selenium-webdriver_class_FileDetector.html +0 -21
  157. package/docs/module_selenium-webdriver_class_Serializable.html +0 -9
  158. package/docs/module_selenium-webdriver_class_Session.html +0 -13
  159. package/docs/module_selenium-webdriver_class_WebDriver.html +0 -313
  160. package/docs/module_selenium-webdriver_class_WebElement.html +0 -216
  161. package/docs/module_selenium-webdriver_class_WebElementPromise.html +0 -266
  162. package/docs/module_selenium-webdriver_enum_Browser.html +0 -2
  163. package/docs/module_selenium-webdriver_enum_Button.html +0 -2
  164. package/docs/module_selenium-webdriver_enum_Capability.html +0 -33
  165. package/docs/module_selenium-webdriver_enum_CommandName.html +0 -3
  166. package/docs/module_selenium-webdriver_enum_Key.html +0 -12
  167. package/docs/module_selenium-webdriver_error.html +0 -4
  168. package/docs/module_selenium-webdriver_error_class_Error.html +0 -15
  169. package/docs/module_selenium-webdriver_error_enum_ErrorCode.html +0 -3
  170. package/docs/module_selenium-webdriver_executors.html +0 -10
  171. package/docs/module_selenium-webdriver_executors_class_DeferredExecutor.html +0 -12
  172. package/docs/module_selenium-webdriver_firefox.html +0 -67
  173. package/docs/module_selenium-webdriver_firefox_binary.html +0 -4
  174. package/docs/module_selenium-webdriver_firefox_binary_class_Binary.html +0 -21
  175. package/docs/module_selenium-webdriver_firefox_class_Binary.html +0 -21
  176. package/docs/module_selenium-webdriver_firefox_class_Driver.html +0 -276
  177. package/docs/module_selenium-webdriver_firefox_class_Options.html +0 -19
  178. package/docs/module_selenium-webdriver_firefox_class_Profile.html +0 -50
  179. package/docs/module_selenium-webdriver_firefox_extension.html +0 -8
  180. package/docs/module_selenium-webdriver_firefox_profile.html +0 -13
  181. package/docs/module_selenium-webdriver_firefox_profile_class_Profile.html +0 -50
  182. package/docs/module_selenium-webdriver_http.html +0 -9
  183. package/docs/module_selenium-webdriver_http_class_Executor.html +0 -22
  184. package/docs/module_selenium-webdriver_http_class_HttpClient.html +0 -16
  185. package/docs/module_selenium-webdriver_http_class_Request.html +0 -12
  186. package/docs/module_selenium-webdriver_http_class_Response.html +0 -13
  187. package/docs/module_selenium-webdriver_http_util.html +0 -17
  188. package/docs/module_selenium-webdriver_ie.html +0 -11
  189. package/docs/module_selenium-webdriver_ie_class_Driver.html +0 -274
  190. package/docs/module_selenium-webdriver_ie_class_Options.html +0 -89
  191. package/docs/module_selenium-webdriver_ie_enum_Level.html +0 -1
  192. package/docs/module_selenium-webdriver_io.html +0 -37
  193. package/docs/module_selenium-webdriver_io_exec.html +0 -6
  194. package/docs/module_selenium-webdriver_namespace_By.html +0 -56
  195. package/docs/module_selenium-webdriver_namespace_error.html +0 -4
  196. package/docs/module_selenium-webdriver_namespace_logging.html +0 -18
  197. package/docs/module_selenium-webdriver_namespace_promise.html +0 -162
  198. package/docs/module_selenium-webdriver_namespace_stacktrace.html +0 -17
  199. package/docs/module_selenium-webdriver_namespace_until.html +0 -82
  200. package/docs/module_selenium-webdriver_net.html +0 -7
  201. package/docs/module_selenium-webdriver_net_portprober.html +0 -12
  202. package/docs/module_selenium-webdriver_opera.html +0 -62
  203. package/docs/module_selenium-webdriver_opera_class_Driver.html +0 -276
  204. package/docs/module_selenium-webdriver_opera_class_Options.html +0 -44
  205. package/docs/module_selenium-webdriver_opera_class_ServiceBuilder.html +0 -35
  206. package/docs/module_selenium-webdriver_phantomjs.html +0 -2
  207. package/docs/module_selenium-webdriver_phantomjs_class_Driver.html +0 -299
  208. package/docs/module_selenium-webdriver_proxy.html +0 -28
  209. package/docs/module_selenium-webdriver_remote.html +0 -8
  210. package/docs/module_selenium-webdriver_remote_class_DriverService.html +0 -32
  211. package/docs/module_selenium-webdriver_remote_class_FileDetector.html +0 -22
  212. package/docs/module_selenium-webdriver_remote_class_SeleniumServer.html +0 -40
  213. package/docs/module_selenium-webdriver_safari.html +0 -9
  214. package/docs/module_selenium-webdriver_safari_class_Driver.html +0 -279
  215. package/docs/module_selenium-webdriver_safari_class_Options.html +0 -23
  216. package/docs/module_selenium-webdriver_testing.html +0 -74
  217. package/docs/module_selenium-webdriver_testing_assert.html +0 -9
  218. package/docs/namespace_bot.html +0 -4
  219. package/docs/namespace_bot_json.html +0 -20
  220. package/docs/namespace_bot_response.html +0 -18
  221. package/docs/namespace_bot_userAgent.html +0 -33
  222. package/docs/namespace_webdriver.html +0 -30
  223. package/docs/namespace_webdriver_By.html +0 -56
  224. package/docs/namespace_webdriver_http.html +0 -6
  225. package/docs/namespace_webdriver_logging.html +0 -70
  226. package/docs/namespace_webdriver_promise.html +0 -165
  227. package/docs/namespace_webdriver_stacktrace.html +0 -17
  228. package/docs/namespace_webdriver_testing.html +0 -7
  229. package/docs/namespace_webdriver_testing_assert.html +0 -9
  230. package/docs/namespace_webdriver_testing_asserts.html +0 -18
  231. package/docs/namespace_webdriver_until.html +0 -82
  232. package/docs/source/_base.js.src.html +0 -1
  233. package/docs/source/builder.js.src.html +0 -1
  234. package/docs/source/chrome.js.src.html +0 -1
  235. package/docs/source/error.js.src.html +0 -1
  236. package/docs/source/executors.js.src.html +0 -1
  237. package/docs/source/firefox/binary.js.src.html +0 -1
  238. package/docs/source/firefox/extension.js.src.html +0 -1
  239. package/docs/source/firefox/index.js.src.html +0 -1
  240. package/docs/source/firefox/profile.js.src.html +0 -1
  241. package/docs/source/http/index.js.src.html +0 -1
  242. package/docs/source/http/util.js.src.html +0 -1
  243. package/docs/source/ie.js.src.html +0 -1
  244. package/docs/source/index.js.src.html +0 -1
  245. package/docs/source/io/exec.js.src.html +0 -1
  246. package/docs/source/io/index.js.src.html +0 -1
  247. package/docs/source/lib/atoms/error.js.src.html +0 -1
  248. package/docs/source/lib/atoms/json.js.src.html +0 -1
  249. package/docs/source/lib/atoms/response.js.src.html +0 -1
  250. package/docs/source/lib/atoms/userAgent.js.src.html +0 -1
  251. package/docs/source/lib/goog/array/array.js.src.html +0 -1
  252. package/docs/source/lib/goog/asserts/asserts.js.src.html +0 -1
  253. package/docs/source/lib/goog/async/freelist.js.src.html +0 -1
  254. package/docs/source/lib/goog/async/nexttick.js.src.html +0 -1
  255. package/docs/source/lib/goog/async/run.js.src.html +0 -1
  256. package/docs/source/lib/goog/async/workqueue.js.src.html +0 -1
  257. package/docs/source/lib/goog/base.js.src.html +0 -1
  258. package/docs/source/lib/goog/debug/debug.js.src.html +0 -1
  259. package/docs/source/lib/goog/debug/entrypointregistry.js.src.html +0 -1
  260. package/docs/source/lib/goog/debug/error.js.src.html +0 -1
  261. package/docs/source/lib/goog/debug/logbuffer.js.src.html +0 -1
  262. package/docs/source/lib/goog/debug/logger.js.src.html +0 -1
  263. package/docs/source/lib/goog/debug/logrecord.js.src.html +0 -1
  264. package/docs/source/lib/goog/deps.js.src.html +0 -1
  265. package/docs/source/lib/goog/disposable/disposable.js.src.html +0 -1
  266. package/docs/source/lib/goog/disposable/idisposable.js.src.html +0 -1
  267. package/docs/source/lib/goog/dom/browserfeature.js.src.html +0 -1
  268. package/docs/source/lib/goog/dom/dom.js.src.html +0 -1
  269. package/docs/source/lib/goog/dom/nodetype.js.src.html +0 -1
  270. package/docs/source/lib/goog/dom/safe.js.src.html +0 -1
  271. package/docs/source/lib/goog/dom/tagname.js.src.html +0 -1
  272. package/docs/source/lib/goog/dom/tags.js.src.html +0 -1
  273. package/docs/source/lib/goog/dom/vendor.js.src.html +0 -1
  274. package/docs/source/lib/goog/events/browserevent.js.src.html +0 -1
  275. package/docs/source/lib/goog/events/browserfeature.js.src.html +0 -1
  276. package/docs/source/lib/goog/events/event.js.src.html +0 -1
  277. package/docs/source/lib/goog/events/eventid.js.src.html +0 -1
  278. package/docs/source/lib/goog/events/events.js.src.html +0 -1
  279. package/docs/source/lib/goog/events/eventtarget.js.src.html +0 -1
  280. package/docs/source/lib/goog/events/eventtype.js.src.html +0 -1
  281. package/docs/source/lib/goog/events/keycodes.js.src.html +0 -1
  282. package/docs/source/lib/goog/events/listenable.js.src.html +0 -1
  283. package/docs/source/lib/goog/events/listener.js.src.html +0 -1
  284. package/docs/source/lib/goog/events/listenermap.js.src.html +0 -1
  285. package/docs/source/lib/goog/fs/url.js.src.html +0 -1
  286. package/docs/source/lib/goog/functions/functions.js.src.html +0 -1
  287. package/docs/source/lib/goog/html/safehtml.js.src.html +0 -1
  288. package/docs/source/lib/goog/html/safescript.js.src.html +0 -1
  289. package/docs/source/lib/goog/html/safestyle.js.src.html +0 -1
  290. package/docs/source/lib/goog/html/safestylesheet.js.src.html +0 -1
  291. package/docs/source/lib/goog/html/safeurl.js.src.html +0 -1
  292. package/docs/source/lib/goog/html/trustedresourceurl.js.src.html +0 -1
  293. package/docs/source/lib/goog/html/uncheckedconversions.js.src.html +0 -1
  294. package/docs/source/lib/goog/i18n/bidi.js.src.html +0 -1
  295. package/docs/source/lib/goog/iter/iter.js.src.html +0 -1
  296. package/docs/source/lib/goog/json/json.js.src.html +0 -1
  297. package/docs/source/lib/goog/labs/testing/assertthat.js.src.html +0 -1
  298. package/docs/source/lib/goog/labs/testing/logicmatcher.js.src.html +0 -1
  299. package/docs/source/lib/goog/labs/testing/matcher.js.src.html +0 -1
  300. package/docs/source/lib/goog/labs/testing/numbermatcher.js.src.html +0 -1
  301. package/docs/source/lib/goog/labs/testing/objectmatcher.js.src.html +0 -1
  302. package/docs/source/lib/goog/labs/testing/stringmatcher.js.src.html +0 -1
  303. package/docs/source/lib/goog/labs/useragent/browser.js.src.html +0 -1
  304. package/docs/source/lib/goog/labs/useragent/engine.js.src.html +0 -1
  305. package/docs/source/lib/goog/labs/useragent/platform.js.src.html +0 -1
  306. package/docs/source/lib/goog/labs/useragent/util.js.src.html +0 -1
  307. package/docs/source/lib/goog/math/box.js.src.html +0 -1
  308. package/docs/source/lib/goog/math/coordinate.js.src.html +0 -1
  309. package/docs/source/lib/goog/math/math.js.src.html +0 -1
  310. package/docs/source/lib/goog/math/rect.js.src.html +0 -1
  311. package/docs/source/lib/goog/math/size.js.src.html +0 -1
  312. package/docs/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html +0 -1
  313. package/docs/source/lib/goog/net/xhrlike.js.src.html +0 -1
  314. package/docs/source/lib/goog/net/xmlhttp.js.src.html +0 -1
  315. package/docs/source/lib/goog/net/xmlhttpfactory.js.src.html +0 -1
  316. package/docs/source/lib/goog/object/object.js.src.html +0 -1
  317. package/docs/source/lib/goog/promise/promise.js.src.html +0 -1
  318. package/docs/source/lib/goog/promise/resolver.js.src.html +0 -1
  319. package/docs/source/lib/goog/promise/thenable.js.src.html +0 -1
  320. package/docs/source/lib/goog/reflect/reflect.js.src.html +0 -1
  321. package/docs/source/lib/goog/string/const.js.src.html +0 -1
  322. package/docs/source/lib/goog/string/string.js.src.html +0 -1
  323. package/docs/source/lib/goog/string/typedstring.js.src.html +0 -1
  324. package/docs/source/lib/goog/structs/collection.js.src.html +0 -1
  325. package/docs/source/lib/goog/structs/map.js.src.html +0 -1
  326. package/docs/source/lib/goog/structs/set.js.src.html +0 -1
  327. package/docs/source/lib/goog/structs/structs.js.src.html +0 -1
  328. package/docs/source/lib/goog/style/style.js.src.html +0 -1
  329. package/docs/source/lib/goog/testing/asserts.js.src.html +0 -1
  330. package/docs/source/lib/goog/testing/events/events.js.src.html +0 -1
  331. package/docs/source/lib/goog/testing/functionmock.js.src.html +0 -1
  332. package/docs/source/lib/goog/testing/jsunit.js.src.html +0 -1
  333. package/docs/source/lib/goog/testing/loosemock.js.src.html +0 -1
  334. package/docs/source/lib/goog/testing/mock.js.src.html +0 -1
  335. package/docs/source/lib/goog/testing/mockclock.js.src.html +0 -1
  336. package/docs/source/lib/goog/testing/mockcontrol.js.src.html +0 -1
  337. package/docs/source/lib/goog/testing/mockinterface.js.src.html +0 -1
  338. package/docs/source/lib/goog/testing/mockmatchers.js.src.html +0 -1
  339. package/docs/source/lib/goog/testing/objectpropertystring.js.src.html +0 -1
  340. package/docs/source/lib/goog/testing/propertyreplacer.js.src.html +0 -1
  341. package/docs/source/lib/goog/testing/recordfunction.js.src.html +0 -1
  342. package/docs/source/lib/goog/testing/stacktrace.js.src.html +0 -1
  343. package/docs/source/lib/goog/testing/strictmock.js.src.html +0 -1
  344. package/docs/source/lib/goog/testing/testcase.js.src.html +0 -1
  345. package/docs/source/lib/goog/testing/testrunner.js.src.html +0 -1
  346. package/docs/source/lib/goog/testing/watchers.js.src.html +0 -1
  347. package/docs/source/lib/goog/uri/uri.js.src.html +0 -1
  348. package/docs/source/lib/goog/uri/utils.js.src.html +0 -1
  349. package/docs/source/lib/goog/useragent/product.js.src.html +0 -1
  350. package/docs/source/lib/goog/useragent/product_isversion.js.src.html +0 -1
  351. package/docs/source/lib/goog/useragent/useragent.js.src.html +0 -1
  352. package/docs/source/lib/webdriver/actionsequence.js.src.html +0 -1
  353. package/docs/source/lib/webdriver/button.js.src.html +0 -1
  354. package/docs/source/lib/webdriver/capabilities.js.src.html +0 -1
  355. package/docs/source/lib/webdriver/command.js.src.html +0 -1
  356. package/docs/source/lib/webdriver/events.js.src.html +0 -1
  357. package/docs/source/lib/webdriver/http/http.js.src.html +0 -1
  358. package/docs/source/lib/webdriver/key.js.src.html +0 -1
  359. package/docs/source/lib/webdriver/locators.js.src.html +0 -1
  360. package/docs/source/lib/webdriver/logging.js.src.html +0 -1
  361. package/docs/source/lib/webdriver/promise.js.src.html +0 -1
  362. package/docs/source/lib/webdriver/serializable.js.src.html +0 -1
  363. package/docs/source/lib/webdriver/session.js.src.html +0 -1
  364. package/docs/source/lib/webdriver/stacktrace.js.src.html +0 -1
  365. package/docs/source/lib/webdriver/testing/asserts.js.src.html +0 -1
  366. package/docs/source/lib/webdriver/touchsequence.js.src.html +0 -1
  367. package/docs/source/lib/webdriver/until.js.src.html +0 -1
  368. package/docs/source/lib/webdriver/webdriver.js.src.html +0 -1
  369. package/docs/source/net/index.js.src.html +0 -1
  370. package/docs/source/net/portprober.js.src.html +0 -1
  371. package/docs/source/opera.js.src.html +0 -1
  372. package/docs/source/phantomjs.js.src.html +0 -1
  373. package/docs/source/proxy.js.src.html +0 -1
  374. package/docs/source/remote/index.js.src.html +0 -1
  375. package/docs/source/safari.js.src.html +0 -1
  376. package/docs/source/testing/assert.js.src.html +0 -1
  377. package/docs/source/testing/index.js.src.html +0 -1
  378. package/docs/types.js +0 -1
  379. package/lib/atoms/error.js +0 -202
  380. package/lib/atoms/json.js +0 -80
  381. package/lib/atoms/response.js +0 -110
  382. package/lib/atoms/userAgent.js +0 -257
  383. package/lib/goog/LICENSE +0 -176
  384. package/lib/goog/array/array.js +0 -1655
  385. package/lib/goog/asserts/asserts.js +0 -365
  386. package/lib/goog/async/freelist.js +0 -88
  387. package/lib/goog/async/nexttick.js +0 -241
  388. package/lib/goog/async/run.js +0 -139
  389. package/lib/goog/async/workqueue.js +0 -139
  390. package/lib/goog/base.js +0 -2547
  391. package/lib/goog/debug/debug.js +0 -653
  392. package/lib/goog/debug/entrypointregistry.js +0 -158
  393. package/lib/goog/debug/error.js +0 -63
  394. package/lib/goog/debug/logbuffer.js +0 -148
  395. package/lib/goog/debug/logger.js +0 -873
  396. package/lib/goog/debug/logrecord.js +0 -242
  397. package/lib/goog/deps.js +0 -151
  398. package/lib/goog/disposable/disposable.js +0 -307
  399. package/lib/goog/disposable/idisposable.js +0 -45
  400. package/lib/goog/dom/browserfeature.js +0 -72
  401. package/lib/goog/dom/dom.js +0 -2995
  402. package/lib/goog/dom/nodetype.js +0 -48
  403. package/lib/goog/dom/safe.js +0 -347
  404. package/lib/goog/dom/tagname.js +0 -160
  405. package/lib/goog/dom/tags.js +0 -42
  406. package/lib/goog/dom/vendor.js +0 -96
  407. package/lib/goog/events/browserevent.js +0 -386
  408. package/lib/goog/events/browserfeature.js +0 -85
  409. package/lib/goog/events/event.js +0 -143
  410. package/lib/goog/events/eventid.js +0 -47
  411. package/lib/goog/events/events.js +0 -984
  412. package/lib/goog/events/eventtarget.js +0 -394
  413. package/lib/goog/events/eventtype.js +0 -233
  414. package/lib/goog/events/keycodes.js +0 -420
  415. package/lib/goog/events/listenable.js +0 -335
  416. package/lib/goog/events/listener.js +0 -131
  417. package/lib/goog/events/listenermap.js +0 -308
  418. package/lib/goog/fs/url.js +0 -105
  419. package/lib/goog/functions/functions.js +0 -332
  420. package/lib/goog/html/safehtml.js +0 -756
  421. package/lib/goog/html/safescript.js +0 -234
  422. package/lib/goog/html/safestyle.js +0 -442
  423. package/lib/goog/html/safestylesheet.js +0 -276
  424. package/lib/goog/html/safeurl.js +0 -431
  425. package/lib/goog/html/trustedresourceurl.js +0 -224
  426. package/lib/goog/html/uncheckedconversions.js +0 -231
  427. package/lib/goog/i18n/bidi.js +0 -908
  428. package/lib/goog/iter/iter.js +0 -1305
  429. package/lib/goog/json/json.js +0 -365
  430. package/lib/goog/labs/testing/assertthat.js +0 -58
  431. package/lib/goog/labs/testing/logicmatcher.js +0 -212
  432. package/lib/goog/labs/testing/matcher.js +0 -80
  433. package/lib/goog/labs/testing/numbermatcher.js +0 -346
  434. package/lib/goog/labs/testing/objectmatcher.js +0 -317
  435. package/lib/goog/labs/testing/stringmatcher.js +0 -415
  436. package/lib/goog/labs/useragent/browser.js +0 -327
  437. package/lib/goog/labs/useragent/engine.js +0 -160
  438. package/lib/goog/labs/useragent/platform.js +0 -160
  439. package/lib/goog/labs/useragent/util.js +0 -148
  440. package/lib/goog/math/box.js +0 -389
  441. package/lib/goog/math/coordinate.js +0 -268
  442. package/lib/goog/math/math.js +0 -451
  443. package/lib/goog/math/rect.js +0 -476
  444. package/lib/goog/math/size.js +0 -227
  445. package/lib/goog/net/wrapperxmlhttpfactory.js +0 -71
  446. package/lib/goog/net/xhrlike.js +0 -124
  447. package/lib/goog/net/xmlhttp.js +0 -246
  448. package/lib/goog/net/xmlhttpfactory.js +0 -67
  449. package/lib/goog/object/object.js +0 -686
  450. package/lib/goog/promise/promise.js +0 -1310
  451. package/lib/goog/promise/resolver.js +0 -48
  452. package/lib/goog/promise/thenable.js +0 -126
  453. package/lib/goog/reflect/reflect.js +0 -78
  454. package/lib/goog/string/const.js +0 -182
  455. package/lib/goog/string/string.js +0 -1565
  456. package/lib/goog/string/typedstring.js +0 -48
  457. package/lib/goog/structs/collection.js +0 -56
  458. package/lib/goog/structs/map.js +0 -456
  459. package/lib/goog/structs/set.js +0 -279
  460. package/lib/goog/structs/structs.js +0 -354
  461. package/lib/goog/style/style.js +0 -2054
  462. package/lib/goog/testing/asserts.js +0 -1265
  463. package/lib/goog/testing/events/events.js +0 -727
  464. package/lib/goog/testing/functionmock.js +0 -176
  465. package/lib/goog/testing/jsunit.js +0 -162
  466. package/lib/goog/testing/loosemock.js +0 -242
  467. package/lib/goog/testing/mock.js +0 -645
  468. package/lib/goog/testing/mockclock.js +0 -617
  469. package/lib/goog/testing/mockcontrol.js +0 -220
  470. package/lib/goog/testing/mockinterface.js +0 -45
  471. package/lib/goog/testing/mockmatchers.js +0 -400
  472. package/lib/goog/testing/objectpropertystring.js +0 -68
  473. package/lib/goog/testing/propertyreplacer.js +0 -245
  474. package/lib/goog/testing/recordfunction.js +0 -215
  475. package/lib/goog/testing/stacktrace.js +0 -594
  476. package/lib/goog/testing/strictmock.js +0 -130
  477. package/lib/goog/testing/testcase.js +0 -1569
  478. package/lib/goog/testing/testrunner.js +0 -440
  479. package/lib/goog/testing/watchers.js +0 -46
  480. package/lib/goog/uri/uri.js +0 -1507
  481. package/lib/goog/uri/utils.js +0 -1116
  482. package/lib/goog/useragent/product.js +0 -175
  483. package/lib/goog/useragent/product_isversion.js +0 -143
  484. package/lib/goog/useragent/useragent.js +0 -538
  485. package/lib/webdriver/actionsequence.js +0 -356
  486. package/lib/webdriver/builder.js +0 -208
  487. package/lib/webdriver/capabilities.js +0 -411
  488. package/lib/webdriver/events.js +0 -179
  489. package/lib/webdriver/firefoxdomexecutor.js +0 -175
  490. package/lib/webdriver/http/corsclient.js +0 -133
  491. package/lib/webdriver/http/http.js +0 -523
  492. package/lib/webdriver/http/xhrclient.js +0 -67
  493. package/lib/webdriver/locators.js +0 -257
  494. package/lib/webdriver/logging.js +0 -347
  495. package/lib/webdriver/promise.js +0 -2609
  496. package/lib/webdriver/serializable.js +0 -41
  497. package/lib/webdriver/session.js +0 -74
  498. package/lib/webdriver/stacktrace.js +0 -619
  499. package/lib/webdriver/test/builder_test.js +0 -53
  500. package/lib/webdriver/test/capabilities_test.js +0 -72
  501. package/lib/webdriver/test/events_test.js +0 -203
  502. package/lib/webdriver/test/http/corsclient_test.js +0 -151
  503. package/lib/webdriver/test/http/http_test.js +0 -428
  504. package/lib/webdriver/test/http/xhrclient_test.js +0 -196
  505. package/lib/webdriver/test/locators_test.js +0 -59
  506. package/lib/webdriver/test/logging_test.js +0 -85
  507. package/lib/webdriver/test/promise_error_test.js +0 -719
  508. package/lib/webdriver/test/promise_flow_test.js +0 -1957
  509. package/lib/webdriver/test/promise_generator_test.js +0 -251
  510. package/lib/webdriver/test/promise_test.js +0 -1981
  511. package/lib/webdriver/test/stacktrace_test.js +0 -480
  512. package/lib/webdriver/test/test_bootstrap.js +0 -67
  513. package/lib/webdriver/test/testing/asserts_test.js +0 -117
  514. package/lib/webdriver/test/testing/client_test.js +0 -88
  515. package/lib/webdriver/test/testing/testcase_test.js +0 -229
  516. package/lib/webdriver/test/testutil.js +0 -209
  517. package/lib/webdriver/test/testutil_test.js +0 -104
  518. package/lib/webdriver/test/until_test.js +0 -411
  519. package/lib/webdriver/test/webdriver_generator_test.js +0 -92
  520. package/lib/webdriver/test/webdriver_test.js +0 -2369
  521. package/lib/webdriver/testing/asserts.js +0 -487
  522. package/lib/webdriver/testing/client.js +0 -179
  523. package/lib/webdriver/testing/jsunit.js +0 -363
  524. package/lib/webdriver/testing/testcase.js +0 -168
  525. package/lib/webdriver/testing/window.js +0 -244
  526. package/lib/webdriver/touchsequence.js +0 -248
  527. package/lib/webdriver/until.js +0 -412
  528. package/lib/webdriver/webdriver.js +0 -2492
  529. package/test/_base_test.js +0 -129
package/http/index.js CHANGED
@@ -16,94 +16,285 @@
16
16
  // under the License.
17
17
 
18
18
  /**
19
- * @fileoverview Defines the {@code webdriver.http.Client} for use with
20
- * NodeJS.
19
+ * @fileoverview Defines an {@linkplain cmd.Executor command executor} that
20
+ * communicates with a remote end using HTTP + JSON.
21
21
  */
22
22
 
23
- var http = require('http'),
24
- url = require('url');
23
+ 'use strict';
24
+
25
+ const http = require('http');
26
+ const url = require('url');
27
+
28
+ const error = require('../error');
29
+ const cmd = require('../lib/command');
30
+ const logging = require('../lib/logging');
31
+ const promise = require('../lib/promise');
25
32
 
26
- var base = require('../_base'),
27
- HttpResponse = base.require('webdriver.http.Response');
28
33
 
29
34
 
30
35
  /**
31
- * A {@link webdriver.http.Client} implementation using Node's built-in http
32
- * module.
33
- * @param {string} serverUrl URL for the WebDriver server to send commands to.
34
- * @param {http.Agent=} opt_agent The agent to use for each request.
35
- * Defaults to {@code http.globalAgent}.
36
- * @param {string=} opt_proxy The proxy to use for the connection to the server.
37
- * Default is to use no proxy.
38
- * @constructor
39
- * @implements {webdriver.http.Client}
36
+ * Converts a headers map to a HTTP header block string.
37
+ * @param {!Map<string, string>} headers The map to convert.
38
+ * @return {string} The headers as a string.
40
39
  */
41
- var HttpClient = function(serverUrl, opt_agent, opt_proxy) {
42
- var parsedUrl = url.parse(serverUrl);
43
- if (!parsedUrl.hostname) {
44
- throw new Error('Invalid server URL: ' + serverUrl);
45
- }
46
-
47
- /** @private {http.Agent} */
48
- this.agent_ = opt_agent;
40
+ function headersToString(headers) {
41
+ let ret = [];
42
+ headers.forEach(function(value, name) {
43
+ ret.push(`${name.toLowerCase()}: ${value}`);
44
+ });
45
+ return ret.join('\n');
46
+ }
49
47
 
50
- /** @private {string} */
51
- this.proxy_ = opt_proxy;
52
48
 
49
+ /**
50
+ * Represents a HTTP request message. This class is a "partial" request and only
51
+ * defines the path on the server to send a request to. It is each client's
52
+ * responsibility to build the full URL for the final request.
53
+ * @final
54
+ */
55
+ class HttpRequest {
53
56
  /**
54
- * Base options for each request.
55
- * @private {!Object}
57
+ * @param {string} method The HTTP method to use for the request.
58
+ * @param {string} path The path on the server to send the request to.
59
+ * @param {Object=} opt_data This request's non-serialized JSON payload data.
56
60
  */
57
- this.options_ = {
58
- host: parsedUrl.hostname,
59
- path: parsedUrl.pathname,
60
- port: parsedUrl.port
61
- };
62
- };
61
+ constructor(method, path, opt_data) {
62
+ this.method = /** string */method;
63
+ this.path = /** string */path;
64
+ this.data = /** Object */opt_data;
65
+ this.headers = /** !Map<string, string> */new Map(
66
+ [['Accept', 'application/json; charset=utf-8']]);
67
+ }
68
+
69
+ /** @override */
70
+ toString() {
71
+ let ret = `${this.method} ${this.path} HTTP/1.1\n`;
72
+ ret += headersToString(this.headers) + '\n\n';
73
+ if (this.data) {
74
+ ret += JSON.stringify(this.data);
75
+ }
76
+ return ret;
77
+ }
78
+ }
63
79
 
64
80
 
65
- /** @override */
66
- HttpClient.prototype.send = function(httpRequest, callback) {
67
- var data;
68
- httpRequest.headers['Content-Length'] = 0;
69
- if (httpRequest.method == 'POST' || httpRequest.method == 'PUT') {
70
- data = JSON.stringify(httpRequest.data);
71
- httpRequest.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
72
- httpRequest.headers['Content-Type'] = 'application/json;charset=UTF-8';
81
+ /**
82
+ * Represents a HTTP response message.
83
+ * @final
84
+ */
85
+ class HttpResponse {
86
+ /**
87
+ * @param {number} status The response code.
88
+ * @param {!Object<string>} headers The response headers. All header names
89
+ * will be converted to lowercase strings for consistent lookups.
90
+ * @param {string} body The response body.
91
+ */
92
+ constructor(status, headers, body) {
93
+ this.status = /** number */status;
94
+ this.body = /** string */body;
95
+ this.headers = /** !Map<string, string>*/new Map;
96
+ for (let header in headers) {
97
+ this.headers.set(header.toLowerCase(), headers[header]);
98
+ }
73
99
  }
74
100
 
75
- var path = this.options_.path;
76
- if (path[path.length - 1] === '/' && httpRequest.path[0] === '/') {
77
- path += httpRequest.path.substring(1);
78
- } else {
79
- path += httpRequest.path;
101
+ /** @override */
102
+ toString() {
103
+ let ret = `HTTP/1.1 ${this.status}\n${headersToString(this.headers)}\n\n`;
104
+ if (this.body) {
105
+ ret += this.body;
106
+ }
107
+ return ret;
80
108
  }
109
+ }
110
+
111
+
112
+ function post(path) { return resource('POST', path); }
113
+ function del(path) { return resource('DELETE', path); }
114
+ function get(path) { return resource('GET', path); }
115
+ function resource(method, path) { return {method: method, path: path}; }
116
+
117
+
118
+ /** @const {!Map<string, {method: string, path: string}>} */
119
+ const COMMAND_MAP = new Map([
120
+ [cmd.Name.GET_SERVER_STATUS, get('/status')],
121
+ [cmd.Name.NEW_SESSION, post('/session')],
122
+ [cmd.Name.GET_SESSIONS, get('/sessions')],
123
+ [cmd.Name.DESCRIBE_SESSION, get('/session/:sessionId')],
124
+ [cmd.Name.QUIT, del('/session/:sessionId')],
125
+ [cmd.Name.CLOSE, del('/session/:sessionId/window')],
126
+ [cmd.Name.GET_CURRENT_WINDOW_HANDLE, get('/session/:sessionId/window_handle')],
127
+ [cmd.Name.GET_WINDOW_HANDLES, get('/session/:sessionId/window_handles')],
128
+ [cmd.Name.GET_CURRENT_URL, get('/session/:sessionId/url')],
129
+ [cmd.Name.GET, post('/session/:sessionId/url')],
130
+ [cmd.Name.GO_BACK, post('/session/:sessionId/back')],
131
+ [cmd.Name.GO_FORWARD, post('/session/:sessionId/forward')],
132
+ [cmd.Name.REFRESH, post('/session/:sessionId/refresh')],
133
+ [cmd.Name.ADD_COOKIE, post('/session/:sessionId/cookie')],
134
+ [cmd.Name.GET_ALL_COOKIES, get('/session/:sessionId/cookie')],
135
+ [cmd.Name.DELETE_ALL_COOKIES, del('/session/:sessionId/cookie')],
136
+ [cmd.Name.DELETE_COOKIE, del('/session/:sessionId/cookie/:name')],
137
+ [cmd.Name.FIND_ELEMENT, post('/session/:sessionId/element')],
138
+ [cmd.Name.FIND_ELEMENTS, post('/session/:sessionId/elements')],
139
+ [cmd.Name.GET_ACTIVE_ELEMENT, post('/session/:sessionId/element/active')],
140
+ [cmd.Name.FIND_CHILD_ELEMENT, post('/session/:sessionId/element/:id/element')],
141
+ [cmd.Name.FIND_CHILD_ELEMENTS, post('/session/:sessionId/element/:id/elements')],
142
+ [cmd.Name.CLEAR_ELEMENT, post('/session/:sessionId/element/:id/clear')],
143
+ [cmd.Name.CLICK_ELEMENT, post('/session/:sessionId/element/:id/click')],
144
+ [cmd.Name.SEND_KEYS_TO_ELEMENT, post('/session/:sessionId/element/:id/value')],
145
+ [cmd.Name.SUBMIT_ELEMENT, post('/session/:sessionId/element/:id/submit')],
146
+ [cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')],
147
+ [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
148
+ [cmd.Name.IS_ELEMENT_SELECTED, get('/session/:sessionId/element/:id/selected')],
149
+ [cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
150
+ [cmd.Name.IS_ELEMENT_DISPLAYED, get('/session/:sessionId/element/:id/displayed')],
151
+ [cmd.Name.GET_ELEMENT_LOCATION, get('/session/:sessionId/element/:id/location')],
152
+ [cmd.Name.GET_ELEMENT_SIZE, get('/session/:sessionId/element/:id/size')],
153
+ [cmd.Name.GET_ELEMENT_ATTRIBUTE, get('/session/:sessionId/element/:id/attribute/:name')],
154
+ [cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, get('/session/:sessionId/element/:id/css/:propertyName')],
155
+ [cmd.Name.ELEMENT_EQUALS, get('/session/:sessionId/element/:id/equals/:other')],
156
+ [cmd.Name.TAKE_ELEMENT_SCREENSHOT, get('/session/:sessionId/element/:id/screenshot')],
157
+ [cmd.Name.SWITCH_TO_WINDOW, post('/session/:sessionId/window')],
158
+ [cmd.Name.MAXIMIZE_WINDOW, post('/session/:sessionId/window/:windowHandle/maximize')],
159
+ [cmd.Name.GET_WINDOW_POSITION, get('/session/:sessionId/window/:windowHandle/position')],
160
+ [cmd.Name.SET_WINDOW_POSITION, post('/session/:sessionId/window/:windowHandle/position')],
161
+ [cmd.Name.GET_WINDOW_SIZE, get('/session/:sessionId/window/:windowHandle/size')],
162
+ [cmd.Name.SET_WINDOW_SIZE, post('/session/:sessionId/window/:windowHandle/size')],
163
+ [cmd.Name.SWITCH_TO_FRAME, post('/session/:sessionId/frame')],
164
+ [cmd.Name.GET_PAGE_SOURCE, get('/session/:sessionId/source')],
165
+ [cmd.Name.GET_TITLE, get('/session/:sessionId/title')],
166
+ [cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute')],
167
+ [cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute_async')],
168
+ [cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
169
+ [cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')],
170
+ [cmd.Name.SET_SCRIPT_TIMEOUT, post('/session/:sessionId/timeouts/async_script')],
171
+ [cmd.Name.IMPLICITLY_WAIT, post('/session/:sessionId/timeouts/implicit_wait')],
172
+ [cmd.Name.MOVE_TO, post('/session/:sessionId/moveto')],
173
+ [cmd.Name.CLICK, post('/session/:sessionId/click')],
174
+ [cmd.Name.DOUBLE_CLICK, post('/session/:sessionId/doubleclick')],
175
+ [cmd.Name.MOUSE_DOWN, post('/session/:sessionId/buttondown')],
176
+ [cmd.Name.MOUSE_UP, post('/session/:sessionId/buttonup')],
177
+ [cmd.Name.MOVE_TO, post('/session/:sessionId/moveto')],
178
+ [cmd.Name.SEND_KEYS_TO_ACTIVE_ELEMENT, post('/session/:sessionId/keys')],
179
+ [cmd.Name.TOUCH_SINGLE_TAP, post('/session/:sessionId/touch/click')],
180
+ [cmd.Name.TOUCH_DOUBLE_TAP, post('/session/:sessionId/touch/doubleclick')],
181
+ [cmd.Name.TOUCH_DOWN, post('/session/:sessionId/touch/down')],
182
+ [cmd.Name.TOUCH_UP, post('/session/:sessionId/touch/up')],
183
+ [cmd.Name.TOUCH_MOVE, post('/session/:sessionId/touch/move')],
184
+ [cmd.Name.TOUCH_SCROLL, post('/session/:sessionId/touch/scroll')],
185
+ [cmd.Name.TOUCH_LONG_PRESS, post('/session/:sessionId/touch/longclick')],
186
+ [cmd.Name.TOUCH_FLICK, post('/session/:sessionId/touch/flick')],
187
+ [cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/accept_alert')],
188
+ [cmd.Name.DISMISS_ALERT, post('/session/:sessionId/dismiss_alert')],
189
+ [cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert_text')],
190
+ [cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert_text')],
191
+ [cmd.Name.GET_LOG, post('/session/:sessionId/log')],
192
+ [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/log/types')],
193
+ [cmd.Name.GET_SESSION_LOGS, post('/logs')],
194
+ [cmd.Name.UPLOAD_FILE, post('/session/:sessionId/file')],
195
+ ]);
81
196
 
82
- var options = {
83
- method: httpRequest.method,
84
- host: this.options_.host,
85
- port: this.options_.port,
86
- path: path,
87
- headers: httpRequest.headers
88
- };
89
197
 
90
- if (this.agent_) {
91
- options.agent = this.agent_;
198
+ /**
199
+ * A basic HTTP client used to send messages to a remote end.
200
+ */
201
+ class HttpClient {
202
+ /**
203
+ * @param {string} serverUrl URL for the WebDriver server to send commands to.
204
+ * @param {http.Agent=} opt_agent The agent to use for each request.
205
+ * Defaults to `http.globalAgent`.
206
+ * @param {?string=} opt_proxy The proxy to use for the connection to the
207
+ * server. Default is to use no proxy.
208
+ */
209
+ constructor(serverUrl, opt_agent, opt_proxy) {
210
+ let parsedUrl = url.parse(serverUrl);
211
+ if (!parsedUrl.hostname) {
212
+ throw new Error('Invalid server URL: ' + serverUrl);
213
+ }
214
+
215
+ /** @private {http.Agent} */
216
+ this.agent_ = opt_agent || null;
217
+
218
+ /** @private {?string} */
219
+ this.proxy_ = opt_proxy || null;
220
+
221
+ /**
222
+ * Base options for each request.
223
+ * @private {{auth: (?string|undefined),
224
+ * host: string,
225
+ * path: (?string|undefined),
226
+ * port: (?string|undefined)}}
227
+ */
228
+ this.options_ = {
229
+ auth: parsedUrl.auth,
230
+ host: parsedUrl.hostname,
231
+ path: parsedUrl.pathname,
232
+ port: parsedUrl.port
233
+ };
92
234
  }
93
235
 
94
- sendRequest(options, callback, data, this.proxy_);
95
- };
236
+ /**
237
+ * Sends a request to the server. The client will automatically follow any
238
+ * redirects returned by the server, fulfilling the returned promise with the
239
+ * final response.
240
+ *
241
+ * @param {!HttpRequest} httpRequest The request to send.
242
+ * @return {!promise.Promise<HttpResponse>} A promise that will be fulfilled
243
+ * with the server's response.
244
+ */
245
+ send(httpRequest) {
246
+ var data;
247
+
248
+ let headers = {};
249
+ httpRequest.headers.forEach(function(value, name) {
250
+ headers[name] = value;
251
+ });
252
+
253
+ headers['Content-Length'] = 0;
254
+ if (httpRequest.method == 'POST' || httpRequest.method == 'PUT') {
255
+ data = JSON.stringify(httpRequest.data);
256
+ headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
257
+ headers['Content-Type'] = 'application/json;charset=UTF-8';
258
+ }
259
+
260
+ var path = this.options_.path;
261
+ if (path[path.length - 1] === '/' && httpRequest.path[0] === '/') {
262
+ path += httpRequest.path.substring(1);
263
+ } else {
264
+ path += httpRequest.path;
265
+ }
266
+
267
+ var options = {
268
+ method: httpRequest.method,
269
+ auth: this.options_.auth,
270
+ host: this.options_.host,
271
+ port: this.options_.port,
272
+ path: path,
273
+ headers: headers
274
+ };
275
+
276
+ if (this.agent_) {
277
+ options.agent = this.agent_;
278
+ }
279
+
280
+ var proxy = this.proxy_;
281
+ return new promise.Promise(function(fulfill, reject) {
282
+ sendRequest(options, fulfill, reject, data, proxy);
283
+ });
284
+ }
285
+ }
96
286
 
97
287
 
98
288
  /**
99
289
  * Sends a single HTTP request.
100
290
  * @param {!Object} options The request options.
101
- * @param {function(Error, !webdriver.http.Response=)} callback The function to
102
- * invoke with the server's response.
103
- * @param {string=} opt_data The data to send with the request.
104
- * @param {string=} opt_proxy The proxy server to use for the request.
291
+ * @param {function(!HttpResponse)} onOk The function to call if the
292
+ * request succeeds.
293
+ * @param {function(!Error)} onError The function to call if the request fails.
294
+ * @param {?string=} opt_data The data to send with the request.
295
+ * @param {?string=} opt_proxy The proxy server to use for the request.
105
296
  */
106
- var sendRequest = function(options, callback, opt_data, opt_proxy) {
297
+ function sendRequest(options, onOk, onError, opt_data, opt_proxy) {
107
298
  var host = options.host;
108
299
  var port = options.port;
109
300
 
@@ -125,7 +316,7 @@ var sendRequest = function(options, callback, opt_data, opt_proxy) {
125
316
  try {
126
317
  var location = url.parse(response.headers['location']);
127
318
  } catch (ex) {
128
- callback(Error(
319
+ onError(Error(
129
320
  'Failed to parse "Location" header for server redirect: ' +
130
321
  ex.message + '\nResponse was: \n' +
131
322
  new HttpResponse(response.statusCode, response.headers, '')));
@@ -146,30 +337,32 @@ var sendRequest = function(options, callback, opt_data, opt_proxy) {
146
337
  headers: {
147
338
  'Accept': 'application/json; charset=utf-8'
148
339
  }
149
- }, callback, undefined, opt_proxy);
340
+ }, onOk, onError, undefined, opt_proxy);
150
341
  return;
151
342
  }
152
343
 
153
344
  var body = [];
154
345
  response.on('data', body.push.bind(body));
155
346
  response.on('end', function() {
156
- var resp = new HttpResponse(response.statusCode,
157
- response.headers, body.join('').replace(/\0/g, ''));
158
- callback(null, resp);
347
+ var resp = new HttpResponse(
348
+ /** @type {number} */(response.statusCode),
349
+ /** @type {!Object<string>} */(response.headers),
350
+ body.join('').replace(/\0/g, ''));
351
+ onOk(resp);
159
352
  });
160
353
  });
161
354
 
162
355
  request.on('error', function(e) {
163
356
  if (e.code === 'ECONNRESET') {
164
357
  setTimeout(function() {
165
- sendRequest(options, callback, opt_data, opt_proxy);
358
+ sendRequest(options, onOk, onError, opt_data, opt_proxy);
166
359
  }, 15);
167
360
  } else {
168
361
  var message = e.message;
169
362
  if (e.code) {
170
363
  message = e.code + ' ' + message;
171
364
  }
172
- callback(new Error(message));
365
+ onError(new Error(message));
173
366
  }
174
367
  });
175
368
 
@@ -178,18 +371,144 @@ var sendRequest = function(options, callback, opt_data, opt_proxy) {
178
371
  }
179
372
 
180
373
  request.end();
181
- };
374
+ }
182
375
 
183
376
 
184
- // PUBLIC API
377
+ /**
378
+ * A command executor that communicates with the server using HTTP + JSON.
379
+ * @implements {cmd.Executor}
380
+ */
381
+ class Executor {
382
+ /**
383
+ * @param {!HttpClient} client The client to use for sending requests to the
384
+ * server.
385
+ */
386
+ constructor(client) {
387
+ /** @private {!HttpClient} */
388
+ this.client_ = client;
389
+
390
+ /** @private {Map<string, {method: string, path: string}>} */
391
+ this.customCommands_ = null;
392
+
393
+ /** @private {!logging.Logger} */
394
+ this.log_ = logging.getLogger('webdriver.http.Executor');
395
+ }
396
+
397
+ /**
398
+ * Defines a new command for use with this executor. When a command is sent,
399
+ * the {@code path} will be preprocessed using the command's parameters; any
400
+ * path segments prefixed with ":" will be replaced by the parameter of the
401
+ * same name. For example, given "/person/:name" and the parameters
402
+ * "{name: 'Bob'}", the final command path will be "/person/Bob".
403
+ *
404
+ * @param {string} name The command name.
405
+ * @param {string} method The HTTP method to use when sending this command.
406
+ * @param {string} path The path to send the command to, relative to
407
+ * the WebDriver server's command root and of the form
408
+ * "/path/:variable/segment".
409
+ */
410
+ defineCommand(name, method, path) {
411
+ if (!this.customCommands_) {
412
+ this.customCommands_ = new Map;
413
+ }
414
+ this.customCommands_.set(name, {method, path});
415
+ }
416
+
417
+ /** @override */
418
+ execute(command) {
419
+ let resource =
420
+ (this.customCommands_ && this.customCommands_.get(command.getName()))
421
+ || COMMAND_MAP.get(command.getName());
422
+ if (!resource) {
423
+ throw new error.UnknownCommandError(
424
+ 'Unrecognized command: ' + command.getName());
425
+ }
426
+
427
+ let parameters = command.getParameters();
428
+ let path = buildPath(resource.path, parameters);
429
+ let request = new HttpRequest(resource.method, path, parameters);
430
+
431
+ let log = this.log_;
432
+ log.finer(() => '>>>\n' + request);
433
+ return this.client_.send(request).then(function(response) {
434
+ log.finer(() => '<<<\n' + response);
435
+ return parseHttpResponse(/** @type {!HttpResponse} */ (response));
436
+ });
437
+ }
438
+ }
439
+
440
+
441
+ /**
442
+ * Callback used to parse {@link HttpResponse} objects from a
443
+ * {@link HttpClient}.
444
+ * @param {!HttpResponse} httpResponse The HTTP response to parse.
445
+ * @return {!Object} The parsed response.
446
+ */
447
+ function parseHttpResponse(httpResponse) {
448
+ try {
449
+ return /** @type {!Object} */ (JSON.parse(httpResponse.body));
450
+ } catch (ignored) {
451
+ // Whoops, looks like the server sent us a malformed response. We'll need
452
+ // to manually build a response object based on the response code.
453
+ }
454
+
455
+ let response = {
456
+ 'status': error.ErrorCode.SUCCESS,
457
+ 'value': httpResponse.body.replace(/\r\n/g, '\n')
458
+ };
459
+
460
+ if (httpResponse.status >= 400) {
461
+ // 404 represents an unknown command; anything else is a generic unknown
462
+ // error.
463
+ response['status'] = httpResponse.status == 404 ?
464
+ error.ErrorCode.UNKNOWN_COMMAND :
465
+ error.ErrorCode.UNKNOWN_ERROR;
466
+ }
185
467
 
186
- /** @type {webdriver.http.Executor.} */
187
- exports.Executor = base.require('webdriver.http.Executor');
468
+ return response;
469
+ }
188
470
 
189
- /** @type {webdriver.http.Request.} */
190
- exports.Request = base.require('webdriver.http.Request');
191
471
 
192
- /** @type {webdriver.http.Response.} */
193
- exports.Response = base.require('webdriver.http.Response');
472
+ /**
473
+ * Builds a fully qualified path using the given set of command parameters. Each
474
+ * path segment prefixed with ':' will be replaced by the value of the
475
+ * corresponding parameter. All parameters spliced into the path will be
476
+ * removed from the parameter map.
477
+ * @param {string} path The original resource path.
478
+ * @param {!Object<*>} parameters The parameters object to splice into the path.
479
+ * @return {string} The modified path.
480
+ */
481
+ function buildPath(path, parameters) {
482
+ let pathParameters = path.match(/\/:(\w+)\b/g);
483
+ if (pathParameters) {
484
+ for (let i = 0; i < pathParameters.length; ++i) {
485
+ let key = pathParameters[i].substring(2); // Trim the /:
486
+ if (key in parameters) {
487
+ let value = parameters[key];
488
+ // TODO: move webdriver.WebElement.ELEMENT definition to a
489
+ // common file so we can reference it here without pulling in all of
490
+ // webdriver.WebElement's dependencies.
491
+ if (value && value['ELEMENT']) {
492
+ // When inserting a WebElement into the URL, only use its ID value,
493
+ // not the full JSON.
494
+ value = value['ELEMENT'];
495
+ }
496
+ path = path.replace(pathParameters[i], '/' + value);
497
+ delete parameters[key];
498
+ } else {
499
+ throw new error.InvalidArgumentError(
500
+ 'Missing required parameter: ' + key);
501
+ }
502
+ }
503
+ }
504
+ return path;
505
+ }
506
+
507
+
508
+ // PUBLIC API
194
509
 
510
+ exports.Executor = Executor;
195
511
  exports.HttpClient = HttpClient;
512
+ exports.Request = HttpRequest;
513
+ exports.Response = HttpResponse;
514
+ exports.buildPath = buildPath; // Exported for testing.
package/http/util.js CHANGED
@@ -19,35 +19,31 @@
19
19
  * @fileoverview Various HTTP utilities.
20
20
  */
21
21
 
22
- var base = require('../_base'),
22
+ 'use strict';
23
+
24
+ const error = require('../error'),
25
+ Executor = require('./index').Executor,
23
26
  HttpClient = require('./index').HttpClient,
24
- checkResponse = base.require('bot.response').checkResponse,
25
- Executor = base.require('webdriver.http.Executor'),
26
- HttpRequest = base.require('webdriver.http.Request'),
27
- Command = base.require('webdriver.Command'),
28
- CommandName = base.require('webdriver.CommandName'),
29
- promise = base.require('webdriver.promise');
27
+ HttpRequest = require('./index').Request,
28
+ Command = require('../lib/command').Command,
29
+ CommandName = require('../lib/command').Name,
30
+ promise = require('../lib/promise');
30
31
 
31
32
 
32
33
 
33
34
  /**
34
35
  * Queries a WebDriver server for its current status.
35
36
  * @param {string} url Base URL of the server to query.
36
- * @param {function(Error, *=)} callback The function to call with the
37
- * response.
37
+ * @return {!promise.Promise.<!Object>} A promise that resolves with
38
+ * a hash of the server status.
38
39
  */
39
- function getStatus(url, callback) {
40
+ function getStatus(url) {
40
41
  var client = new HttpClient(url);
41
42
  var executor = new Executor(client);
42
43
  var command = new Command(CommandName.GET_SERVER_STATUS);
43
- executor.execute(command, function(err, responseObj) {
44
- if (err) return callback(err);
45
- try {
46
- checkResponse(responseObj);
47
- } catch (ex) {
48
- return callback(ex);
49
- }
50
- callback(null, responseObj['value']);
44
+ return executor.execute(command).then(function(responseObj) {
45
+ error.checkLegacyResponse(responseObj);
46
+ return responseObj['value'];
51
47
  });
52
48
  }
53
49
 
@@ -58,32 +54,30 @@ function getStatus(url, callback) {
58
54
  /**
59
55
  * Queries a WebDriver server for its current status.
60
56
  * @param {string} url Base URL of the server to query.
61
- * @return {!webdriver.promise.Promise.<!Object>} A promise that resolves with
57
+ * @return {!promise.Promise.<!Object>} A promise that resolves with
62
58
  * a hash of the server status.
63
59
  */
64
- exports.getStatus = function(url) {
65
- return promise.checkedNodeCall(getStatus.bind(null, url));
66
- };
60
+ exports.getStatus = getStatus;
67
61
 
68
62
 
69
63
  /**
70
64
  * Waits for a WebDriver server to be healthy and accepting requests.
71
65
  * @param {string} url Base URL of the server to query.
72
66
  * @param {number} timeout How long to wait for the server.
73
- * @return {!webdriver.promise.Promise} A promise that will resolve when the
67
+ * @return {!promise.Promise} A promise that will resolve when the
74
68
  * server is ready.
75
69
  */
76
70
  exports.waitForServer = function(url, timeout) {
77
71
  var ready = promise.defer(),
78
- start = Date.now(),
79
- checkServerStatus = getStatus.bind(null, url, onResponse);
72
+ start = Date.now();
80
73
  checkServerStatus();
81
74
  return ready.promise;
82
75
 
83
- function onResponse(err) {
84
- if (!ready.isPending()) return;
85
- if (!err) return ready.fulfill();
76
+ function checkServerStatus() {
77
+ return getStatus(url).then(ready.fulfill, onError);
78
+ }
86
79
 
80
+ function onError() {
87
81
  if (Date.now() - start > timeout) {
88
82
  ready.reject(
89
83
  Error('Timed out waiting for the WebDriver server at ' + url));
@@ -103,24 +97,22 @@ exports.waitForServer = function(url, timeout) {
103
97
  * timeout expires.
104
98
  * @param {string} url The URL to poll.
105
99
  * @param {number} timeout How long to wait, in milliseconds.
106
- * @return {!webdriver.promise.Promise} A promise that will resolve when the
100
+ * @return {!promise.Promise} A promise that will resolve when the
107
101
  * URL responds with 2xx.
108
102
  */
109
103
  exports.waitForUrl = function(url, timeout) {
110
104
  var client = new HttpClient(url),
111
105
  request = new HttpRequest('GET', ''),
112
- testUrl = client.send.bind(client, request, onResponse),
113
106
  ready = promise.defer(),
114
107
  start = Date.now();
115
108
  testUrl();
116
109
  return ready.promise;
117
110
 
118
- function onResponse(err, response) {
119
- if (!ready.isPending()) return;
120
- if (!err && response.status > 199 && response.status < 300) {
121
- return ready.fulfill();
122
- }
111
+ function testUrl() {
112
+ client.send(request).then(onResponse, onError);
113
+ }
123
114
 
115
+ function onError() {
124
116
  if (Date.now() - start > timeout) {
125
117
  ready.reject(Error(
126
118
  'Timed out waiting for the URL to return 2xx: ' + url));
@@ -132,4 +124,12 @@ exports.waitForUrl = function(url, timeout) {
132
124
  }, 50);
133
125
  }
134
126
  }
127
+
128
+ function onResponse(response) {
129
+ if (!ready.isPending()) return;
130
+ if (response.status > 199 && response.status < 300) {
131
+ return ready.fulfill();
132
+ }
133
+ onError();
134
+ }
135
135
  };