selenium-webdriver 2.48.2 → 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 (524) hide show
  1. package/CHANGES.md +57 -0
  2. package/NOTICE +1 -1
  3. package/README.md +56 -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 +79 -87
  12. package/firefox/extension.js +10 -18
  13. package/firefox/index.js +173 -173
  14. package/firefox/profile.js +220 -240
  15. package/http/index.js +396 -79
  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} +88 -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 +5 -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/{webdriver/promise.js → promise.js} +688 -644
  34. package/lib/session.js +79 -0
  35. package/lib/{webdriver/serializable.js → symbols.js} +11 -16
  36. package/lib/test/build.js +4 -4
  37. package/lib/test/data/click_tests/html5_submit_buttons.html +2 -1
  38. package/lib/test/data/click_tests/overlapping_elements.html +15 -4
  39. package/lib/test/data/click_tests/partially_overlapping_elements.html +124 -0
  40. package/lib/test/data/click_tests/wrapped_overlapping_elements.html +13 -0
  41. package/lib/test/data/readOnlyPage.html +1 -1
  42. package/lib/test/data/selectPage.html +18 -2
  43. package/lib/test/fileserver.js +3 -4
  44. package/lib/test/index.js +7 -3
  45. package/lib/test/resources.js +1 -1
  46. package/lib/until.js +428 -0
  47. package/lib/webdriver.js +2351 -0
  48. package/net/portprober.js +15 -11
  49. package/opera.js +295 -314
  50. package/package.json +6 -5
  51. package/phantomjs.js +135 -140
  52. package/proxy.js +6 -4
  53. package/remote/index.js +229 -221
  54. package/safari.js +319 -310
  55. package/test/chrome/options_test.js +11 -9
  56. package/test/element_finding_test.js +51 -13
  57. package/test/error_test.js +163 -0
  58. package/test/execute_script_test.js +1 -1
  59. package/test/http/http_test.js +317 -55
  60. package/test/http/util_test.js +25 -23
  61. package/test/io_test.js +6 -1
  62. package/test/lib/by_test.js +127 -0
  63. package/test/lib/capabilities_test.js +84 -0
  64. package/test/lib/events_test.js +177 -0
  65. package/test/lib/logging_test.js +272 -0
  66. package/test/{promise_aplus_test.js → lib/promise_aplus_test.js} +4 -13
  67. package/test/lib/promise_error_test.js +808 -0
  68. package/test/lib/promise_flow_test.js +2282 -0
  69. package/test/lib/promise_generator_test.js +308 -0
  70. package/test/lib/promise_test.js +996 -0
  71. package/test/lib/testutil.js +90 -0
  72. package/test/lib/until_test.js +436 -0
  73. package/test/lib/webdriver_test.js +2207 -0
  74. package/test/page_loading_test.js +7 -9
  75. package/test/stale_element_test.js +2 -2
  76. package/test/testing/assert_test.js +374 -0
  77. package/test/testing/index_test.js +9 -11
  78. package/testing/assert.js +334 -17
  79. package/testing/index.js +10 -0
  80. package/_base.js +0 -200
  81. package/docs/Changes.html +0 -356
  82. package/docs/class_bot_Error.html +0 -15
  83. package/docs/class_webdriver_ActionSequence.html +0 -115
  84. package/docs/class_webdriver_Alert.html +0 -24
  85. package/docs/class_webdriver_AlertPromise.html +0 -92
  86. package/docs/class_webdriver_Capabilities.html +0 -60
  87. package/docs/class_webdriver_Command.html +0 -15
  88. package/docs/class_webdriver_EventEmitter.html +0 -35
  89. package/docs/class_webdriver_FileDetector.html +0 -21
  90. package/docs/class_webdriver_Locator.html +0 -12
  91. package/docs/class_webdriver_Serializable.html +0 -9
  92. package/docs/class_webdriver_Session.html +0 -13
  93. package/docs/class_webdriver_TouchSequence.html +0 -49
  94. package/docs/class_webdriver_UnhandledAlertError.html +0 -18
  95. package/docs/class_webdriver_WebDriver.html +0 -313
  96. package/docs/class_webdriver_WebDriver_Logs.html +0 -15
  97. package/docs/class_webdriver_WebDriver_Navigation.html +0 -16
  98. package/docs/class_webdriver_WebDriver_Options.html +0 -41
  99. package/docs/class_webdriver_WebDriver_TargetLocator.html +0 -38
  100. package/docs/class_webdriver_WebDriver_Timeouts.html +0 -29
  101. package/docs/class_webdriver_WebDriver_Window.html +0 -27
  102. package/docs/class_webdriver_WebElement.html +0 -223
  103. package/docs/class_webdriver_WebElementPromise.html +0 -274
  104. package/docs/class_webdriver_http_Executor.html +0 -22
  105. package/docs/class_webdriver_http_Request.html +0 -12
  106. package/docs/class_webdriver_http_Response.html +0 -13
  107. package/docs/class_webdriver_logging_Entry.html +0 -15
  108. package/docs/class_webdriver_logging_Level.html +0 -55
  109. package/docs/class_webdriver_logging_LogRecord.html +0 -45
  110. package/docs/class_webdriver_logging_Logger.html +0 -119
  111. package/docs/class_webdriver_logging_Preferences.html +0 -8
  112. package/docs/class_webdriver_promise_CancellationError.html +0 -17
  113. package/docs/class_webdriver_promise_ControlFlow.html +0 -153
  114. package/docs/class_webdriver_promise_Deferred.html +0 -84
  115. package/docs/class_webdriver_promise_MultipleUnhandledRejectionError.html +0 -14
  116. package/docs/class_webdriver_promise_Promise.html +0 -75
  117. package/docs/class_webdriver_stacktrace_Frame.html +0 -20
  118. package/docs/class_webdriver_stacktrace_Snapshot.html +0 -6
  119. package/docs/class_webdriver_testing_Assertion.html +0 -99
  120. package/docs/class_webdriver_testing_Assertion_DelegatingMatcher_.html +0 -13
  121. package/docs/class_webdriver_testing_ContainsMatcher.html +0 -11
  122. package/docs/class_webdriver_testing_NegatedAssertion.html +0 -97
  123. package/docs/class_webdriver_until_Condition.html +0 -7
  124. package/docs/dossier.css +0 -1
  125. package/docs/dossier.js +0 -86
  126. package/docs/enum_bot_ErrorCode.html +0 -3
  127. package/docs/enum_bot_Error_State.html +0 -2
  128. package/docs/enum_webdriver_Browser.html +0 -2
  129. package/docs/enum_webdriver_Button.html +0 -2
  130. package/docs/enum_webdriver_Capability.html +0 -33
  131. package/docs/enum_webdriver_CommandName.html +0 -3
  132. package/docs/enum_webdriver_Key.html +0 -12
  133. package/docs/enum_webdriver_logging_Type.html +0 -6
  134. package/docs/enum_webdriver_promise_ControlFlow_EventType.html +0 -9
  135. package/docs/index.html +0 -125
  136. package/docs/interface_webdriver_CommandExecutor.html +0 -9
  137. package/docs/interface_webdriver_http_Client.html +0 -10
  138. package/docs/interface_webdriver_promise_Thenable.html +0 -77
  139. package/docs/module_selenium-webdriver.html +0 -23
  140. package/docs/module_selenium-webdriver__base.html +0 -23
  141. package/docs/module_selenium-webdriver__base_class_Context.html +0 -5
  142. package/docs/module_selenium-webdriver_builder.html +0 -2
  143. package/docs/module_selenium-webdriver_builder_class_Builder.html +0 -138
  144. package/docs/module_selenium-webdriver_chrome.html +0 -90
  145. package/docs/module_selenium-webdriver_chrome_class_Driver.html +0 -280
  146. package/docs/module_selenium-webdriver_chrome_class_Options.html +0 -127
  147. package/docs/module_selenium-webdriver_chrome_class_ServiceBuilder.html +0 -46
  148. package/docs/module_selenium-webdriver_class_ActionSequence.html +0 -115
  149. package/docs/module_selenium-webdriver_class_Builder.html +0 -138
  150. package/docs/module_selenium-webdriver_class_Capabilities.html +0 -60
  151. package/docs/module_selenium-webdriver_class_Command.html +0 -15
  152. package/docs/module_selenium-webdriver_class_EventEmitter.html +0 -35
  153. package/docs/module_selenium-webdriver_class_FileDetector.html +0 -21
  154. package/docs/module_selenium-webdriver_class_Serializable.html +0 -9
  155. package/docs/module_selenium-webdriver_class_Session.html +0 -13
  156. package/docs/module_selenium-webdriver_class_WebDriver.html +0 -313
  157. package/docs/module_selenium-webdriver_class_WebElement.html +0 -223
  158. package/docs/module_selenium-webdriver_class_WebElementPromise.html +0 -274
  159. package/docs/module_selenium-webdriver_enum_Browser.html +0 -2
  160. package/docs/module_selenium-webdriver_enum_Button.html +0 -2
  161. package/docs/module_selenium-webdriver_enum_Capability.html +0 -33
  162. package/docs/module_selenium-webdriver_enum_CommandName.html +0 -3
  163. package/docs/module_selenium-webdriver_enum_Key.html +0 -12
  164. package/docs/module_selenium-webdriver_error.html +0 -4
  165. package/docs/module_selenium-webdriver_error_class_Error.html +0 -15
  166. package/docs/module_selenium-webdriver_error_enum_ErrorCode.html +0 -3
  167. package/docs/module_selenium-webdriver_executors.html +0 -10
  168. package/docs/module_selenium-webdriver_executors_class_DeferredExecutor.html +0 -12
  169. package/docs/module_selenium-webdriver_firefox.html +0 -68
  170. package/docs/module_selenium-webdriver_firefox_binary.html +0 -5
  171. package/docs/module_selenium-webdriver_firefox_binary_class_Binary.html +0 -20
  172. package/docs/module_selenium-webdriver_firefox_class_Binary.html +0 -20
  173. package/docs/module_selenium-webdriver_firefox_class_Driver.html +0 -276
  174. package/docs/module_selenium-webdriver_firefox_class_Options.html +0 -19
  175. package/docs/module_selenium-webdriver_firefox_class_Profile.html +0 -50
  176. package/docs/module_selenium-webdriver_firefox_extension.html +0 -8
  177. package/docs/module_selenium-webdriver_firefox_profile.html +0 -13
  178. package/docs/module_selenium-webdriver_firefox_profile_class_Profile.html +0 -50
  179. package/docs/module_selenium-webdriver_http.html +0 -9
  180. package/docs/module_selenium-webdriver_http_class_Executor.html +0 -22
  181. package/docs/module_selenium-webdriver_http_class_HttpClient.html +0 -16
  182. package/docs/module_selenium-webdriver_http_class_Request.html +0 -12
  183. package/docs/module_selenium-webdriver_http_class_Response.html +0 -13
  184. package/docs/module_selenium-webdriver_http_util.html +0 -17
  185. package/docs/module_selenium-webdriver_ie.html +0 -11
  186. package/docs/module_selenium-webdriver_ie_class_Driver.html +0 -274
  187. package/docs/module_selenium-webdriver_ie_class_Options.html +0 -89
  188. package/docs/module_selenium-webdriver_ie_enum_Level.html +0 -1
  189. package/docs/module_selenium-webdriver_io.html +0 -37
  190. package/docs/module_selenium-webdriver_io_exec.html +0 -6
  191. package/docs/module_selenium-webdriver_namespace_By.html +0 -56
  192. package/docs/module_selenium-webdriver_namespace_error.html +0 -4
  193. package/docs/module_selenium-webdriver_namespace_logging.html +0 -18
  194. package/docs/module_selenium-webdriver_namespace_promise.html +0 -163
  195. package/docs/module_selenium-webdriver_namespace_stacktrace.html +0 -17
  196. package/docs/module_selenium-webdriver_namespace_until.html +0 -82
  197. package/docs/module_selenium-webdriver_net.html +0 -7
  198. package/docs/module_selenium-webdriver_net_portprober.html +0 -12
  199. package/docs/module_selenium-webdriver_opera.html +0 -62
  200. package/docs/module_selenium-webdriver_opera_class_Driver.html +0 -276
  201. package/docs/module_selenium-webdriver_opera_class_Options.html +0 -44
  202. package/docs/module_selenium-webdriver_opera_class_ServiceBuilder.html +0 -35
  203. package/docs/module_selenium-webdriver_phantomjs.html +0 -2
  204. package/docs/module_selenium-webdriver_phantomjs_class_Driver.html +0 -299
  205. package/docs/module_selenium-webdriver_proxy.html +0 -28
  206. package/docs/module_selenium-webdriver_remote.html +0 -8
  207. package/docs/module_selenium-webdriver_remote_class_DriverService.html +0 -32
  208. package/docs/module_selenium-webdriver_remote_class_FileDetector.html +0 -22
  209. package/docs/module_selenium-webdriver_remote_class_SeleniumServer.html +0 -41
  210. package/docs/module_selenium-webdriver_safari.html +0 -9
  211. package/docs/module_selenium-webdriver_safari_class_Driver.html +0 -279
  212. package/docs/module_selenium-webdriver_safari_class_Options.html +0 -23
  213. package/docs/module_selenium-webdriver_testing.html +0 -74
  214. package/docs/module_selenium-webdriver_testing_assert.html +0 -9
  215. package/docs/namespace_bot.html +0 -4
  216. package/docs/namespace_bot_json.html +0 -20
  217. package/docs/namespace_bot_response.html +0 -18
  218. package/docs/namespace_bot_userAgent.html +0 -33
  219. package/docs/namespace_webdriver.html +0 -30
  220. package/docs/namespace_webdriver_By.html +0 -56
  221. package/docs/namespace_webdriver_http.html +0 -6
  222. package/docs/namespace_webdriver_logging.html +0 -70
  223. package/docs/namespace_webdriver_promise.html +0 -688
  224. package/docs/namespace_webdriver_stacktrace.html +0 -17
  225. package/docs/namespace_webdriver_testing.html +0 -7
  226. package/docs/namespace_webdriver_testing_assert.html +0 -9
  227. package/docs/namespace_webdriver_testing_asserts.html +0 -18
  228. package/docs/namespace_webdriver_until.html +0 -82
  229. package/docs/source/_base.js.src.html +0 -1
  230. package/docs/source/builder.js.src.html +0 -1
  231. package/docs/source/chrome.js.src.html +0 -1
  232. package/docs/source/error.js.src.html +0 -1
  233. package/docs/source/executors.js.src.html +0 -1
  234. package/docs/source/firefox/binary.js.src.html +0 -1
  235. package/docs/source/firefox/extension.js.src.html +0 -1
  236. package/docs/source/firefox/index.js.src.html +0 -1
  237. package/docs/source/firefox/profile.js.src.html +0 -1
  238. package/docs/source/http/index.js.src.html +0 -1
  239. package/docs/source/http/util.js.src.html +0 -1
  240. package/docs/source/ie.js.src.html +0 -1
  241. package/docs/source/index.js.src.html +0 -1
  242. package/docs/source/io/exec.js.src.html +0 -1
  243. package/docs/source/io/index.js.src.html +0 -1
  244. package/docs/source/lib/atoms/error.js.src.html +0 -1
  245. package/docs/source/lib/atoms/json.js.src.html +0 -1
  246. package/docs/source/lib/atoms/response.js.src.html +0 -1
  247. package/docs/source/lib/atoms/userAgent.js.src.html +0 -1
  248. package/docs/source/lib/goog/array/array.js.src.html +0 -1
  249. package/docs/source/lib/goog/asserts/asserts.js.src.html +0 -1
  250. package/docs/source/lib/goog/async/freelist.js.src.html +0 -1
  251. package/docs/source/lib/goog/async/nexttick.js.src.html +0 -1
  252. package/docs/source/lib/goog/async/run.js.src.html +0 -1
  253. package/docs/source/lib/goog/async/workqueue.js.src.html +0 -1
  254. package/docs/source/lib/goog/base.js.src.html +0 -1
  255. package/docs/source/lib/goog/debug/debug.js.src.html +0 -1
  256. package/docs/source/lib/goog/debug/entrypointregistry.js.src.html +0 -1
  257. package/docs/source/lib/goog/debug/error.js.src.html +0 -1
  258. package/docs/source/lib/goog/debug/logbuffer.js.src.html +0 -1
  259. package/docs/source/lib/goog/debug/logger.js.src.html +0 -1
  260. package/docs/source/lib/goog/debug/logrecord.js.src.html +0 -1
  261. package/docs/source/lib/goog/deps.js.src.html +0 -1
  262. package/docs/source/lib/goog/disposable/disposable.js.src.html +0 -1
  263. package/docs/source/lib/goog/disposable/idisposable.js.src.html +0 -1
  264. package/docs/source/lib/goog/dom/browserfeature.js.src.html +0 -1
  265. package/docs/source/lib/goog/dom/dom.js.src.html +0 -1
  266. package/docs/source/lib/goog/dom/nodetype.js.src.html +0 -1
  267. package/docs/source/lib/goog/dom/safe.js.src.html +0 -1
  268. package/docs/source/lib/goog/dom/tagname.js.src.html +0 -1
  269. package/docs/source/lib/goog/dom/tags.js.src.html +0 -1
  270. package/docs/source/lib/goog/dom/vendor.js.src.html +0 -1
  271. package/docs/source/lib/goog/events/browserevent.js.src.html +0 -1
  272. package/docs/source/lib/goog/events/browserfeature.js.src.html +0 -1
  273. package/docs/source/lib/goog/events/event.js.src.html +0 -1
  274. package/docs/source/lib/goog/events/eventid.js.src.html +0 -1
  275. package/docs/source/lib/goog/events/events.js.src.html +0 -1
  276. package/docs/source/lib/goog/events/eventtarget.js.src.html +0 -1
  277. package/docs/source/lib/goog/events/eventtype.js.src.html +0 -1
  278. package/docs/source/lib/goog/events/keycodes.js.src.html +0 -1
  279. package/docs/source/lib/goog/events/listenable.js.src.html +0 -1
  280. package/docs/source/lib/goog/events/listener.js.src.html +0 -1
  281. package/docs/source/lib/goog/events/listenermap.js.src.html +0 -1
  282. package/docs/source/lib/goog/fs/url.js.src.html +0 -1
  283. package/docs/source/lib/goog/functions/functions.js.src.html +0 -1
  284. package/docs/source/lib/goog/html/safehtml.js.src.html +0 -1
  285. package/docs/source/lib/goog/html/safescript.js.src.html +0 -1
  286. package/docs/source/lib/goog/html/safestyle.js.src.html +0 -1
  287. package/docs/source/lib/goog/html/safestylesheet.js.src.html +0 -1
  288. package/docs/source/lib/goog/html/safeurl.js.src.html +0 -1
  289. package/docs/source/lib/goog/html/trustedresourceurl.js.src.html +0 -1
  290. package/docs/source/lib/goog/html/uncheckedconversions.js.src.html +0 -1
  291. package/docs/source/lib/goog/i18n/bidi.js.src.html +0 -1
  292. package/docs/source/lib/goog/iter/iter.js.src.html +0 -1
  293. package/docs/source/lib/goog/json/json.js.src.html +0 -1
  294. package/docs/source/lib/goog/labs/testing/assertthat.js.src.html +0 -1
  295. package/docs/source/lib/goog/labs/testing/logicmatcher.js.src.html +0 -1
  296. package/docs/source/lib/goog/labs/testing/matcher.js.src.html +0 -1
  297. package/docs/source/lib/goog/labs/testing/numbermatcher.js.src.html +0 -1
  298. package/docs/source/lib/goog/labs/testing/objectmatcher.js.src.html +0 -1
  299. package/docs/source/lib/goog/labs/testing/stringmatcher.js.src.html +0 -1
  300. package/docs/source/lib/goog/labs/useragent/browser.js.src.html +0 -1
  301. package/docs/source/lib/goog/labs/useragent/engine.js.src.html +0 -1
  302. package/docs/source/lib/goog/labs/useragent/platform.js.src.html +0 -1
  303. package/docs/source/lib/goog/labs/useragent/util.js.src.html +0 -1
  304. package/docs/source/lib/goog/log/log.js.src.html +0 -1
  305. package/docs/source/lib/goog/math/box.js.src.html +0 -1
  306. package/docs/source/lib/goog/math/coordinate.js.src.html +0 -1
  307. package/docs/source/lib/goog/math/math.js.src.html +0 -1
  308. package/docs/source/lib/goog/math/rect.js.src.html +0 -1
  309. package/docs/source/lib/goog/math/size.js.src.html +0 -1
  310. package/docs/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html +0 -1
  311. package/docs/source/lib/goog/net/xhrlike.js.src.html +0 -1
  312. package/docs/source/lib/goog/net/xmlhttp.js.src.html +0 -1
  313. package/docs/source/lib/goog/net/xmlhttpfactory.js.src.html +0 -1
  314. package/docs/source/lib/goog/object/object.js.src.html +0 -1
  315. package/docs/source/lib/goog/promise/promise.js.src.html +0 -1
  316. package/docs/source/lib/goog/promise/resolver.js.src.html +0 -1
  317. package/docs/source/lib/goog/promise/thenable.js.src.html +0 -1
  318. package/docs/source/lib/goog/reflect/reflect.js.src.html +0 -1
  319. package/docs/source/lib/goog/string/const.js.src.html +0 -1
  320. package/docs/source/lib/goog/string/string.js.src.html +0 -1
  321. package/docs/source/lib/goog/string/typedstring.js.src.html +0 -1
  322. package/docs/source/lib/goog/structs/collection.js.src.html +0 -1
  323. package/docs/source/lib/goog/structs/map.js.src.html +0 -1
  324. package/docs/source/lib/goog/structs/set.js.src.html +0 -1
  325. package/docs/source/lib/goog/structs/structs.js.src.html +0 -1
  326. package/docs/source/lib/goog/style/style.js.src.html +0 -1
  327. package/docs/source/lib/goog/testing/asserts.js.src.html +0 -1
  328. package/docs/source/lib/goog/testing/events/events.js.src.html +0 -1
  329. package/docs/source/lib/goog/testing/functionmock.js.src.html +0 -1
  330. package/docs/source/lib/goog/testing/jsunit.js.src.html +0 -1
  331. package/docs/source/lib/goog/testing/loosemock.js.src.html +0 -1
  332. package/docs/source/lib/goog/testing/mock.js.src.html +0 -1
  333. package/docs/source/lib/goog/testing/mockclock.js.src.html +0 -1
  334. package/docs/source/lib/goog/testing/mockcontrol.js.src.html +0 -1
  335. package/docs/source/lib/goog/testing/mockinterface.js.src.html +0 -1
  336. package/docs/source/lib/goog/testing/mockmatchers.js.src.html +0 -1
  337. package/docs/source/lib/goog/testing/objectpropertystring.js.src.html +0 -1
  338. package/docs/source/lib/goog/testing/propertyreplacer.js.src.html +0 -1
  339. package/docs/source/lib/goog/testing/recordfunction.js.src.html +0 -1
  340. package/docs/source/lib/goog/testing/stacktrace.js.src.html +0 -1
  341. package/docs/source/lib/goog/testing/strictmock.js.src.html +0 -1
  342. package/docs/source/lib/goog/testing/testcase.js.src.html +0 -1
  343. package/docs/source/lib/goog/testing/testrunner.js.src.html +0 -1
  344. package/docs/source/lib/goog/uri/uri.js.src.html +0 -1
  345. package/docs/source/lib/goog/uri/utils.js.src.html +0 -1
  346. package/docs/source/lib/goog/useragent/product.js.src.html +0 -1
  347. package/docs/source/lib/goog/useragent/product_isversion.js.src.html +0 -1
  348. package/docs/source/lib/goog/useragent/useragent.js.src.html +0 -1
  349. package/docs/source/lib/webdriver/actionsequence.js.src.html +0 -1
  350. package/docs/source/lib/webdriver/button.js.src.html +0 -1
  351. package/docs/source/lib/webdriver/capabilities.js.src.html +0 -1
  352. package/docs/source/lib/webdriver/command.js.src.html +0 -1
  353. package/docs/source/lib/webdriver/events.js.src.html +0 -1
  354. package/docs/source/lib/webdriver/http/http.js.src.html +0 -1
  355. package/docs/source/lib/webdriver/key.js.src.html +0 -1
  356. package/docs/source/lib/webdriver/locators.js.src.html +0 -1
  357. package/docs/source/lib/webdriver/logging.js.src.html +0 -1
  358. package/docs/source/lib/webdriver/promise.js.src.html +0 -1
  359. package/docs/source/lib/webdriver/serializable.js.src.html +0 -1
  360. package/docs/source/lib/webdriver/session.js.src.html +0 -1
  361. package/docs/source/lib/webdriver/stacktrace.js.src.html +0 -1
  362. package/docs/source/lib/webdriver/testing/asserts.js.src.html +0 -1
  363. package/docs/source/lib/webdriver/touchsequence.js.src.html +0 -1
  364. package/docs/source/lib/webdriver/until.js.src.html +0 -1
  365. package/docs/source/lib/webdriver/webdriver.js.src.html +0 -1
  366. package/docs/source/net/index.js.src.html +0 -1
  367. package/docs/source/net/portprober.js.src.html +0 -1
  368. package/docs/source/opera.js.src.html +0 -1
  369. package/docs/source/phantomjs.js.src.html +0 -1
  370. package/docs/source/proxy.js.src.html +0 -1
  371. package/docs/source/remote/index.js.src.html +0 -1
  372. package/docs/source/safari.js.src.html +0 -1
  373. package/docs/source/testing/assert.js.src.html +0 -1
  374. package/docs/source/testing/index.js.src.html +0 -1
  375. package/docs/types.js +0 -1
  376. package/lib/atoms/error.js +0 -202
  377. package/lib/atoms/json.js +0 -80
  378. package/lib/atoms/response.js +0 -110
  379. package/lib/atoms/userAgent.js +0 -257
  380. package/lib/goog/LICENSE +0 -176
  381. package/lib/goog/array/array.js +0 -1654
  382. package/lib/goog/asserts/asserts.js +0 -365
  383. package/lib/goog/async/freelist.js +0 -88
  384. package/lib/goog/async/nexttick.js +0 -241
  385. package/lib/goog/async/run.js +0 -133
  386. package/lib/goog/async/workqueue.js +0 -139
  387. package/lib/goog/base.js +0 -2548
  388. package/lib/goog/debug/debug.js +0 -653
  389. package/lib/goog/debug/entrypointregistry.js +0 -158
  390. package/lib/goog/debug/error.js +0 -63
  391. package/lib/goog/debug/logbuffer.js +0 -148
  392. package/lib/goog/debug/logger.js +0 -873
  393. package/lib/goog/debug/logrecord.js +0 -242
  394. package/lib/goog/deps.js +0 -151
  395. package/lib/goog/disposable/disposable.js +0 -307
  396. package/lib/goog/disposable/idisposable.js +0 -45
  397. package/lib/goog/dom/browserfeature.js +0 -72
  398. package/lib/goog/dom/dom.js +0 -2991
  399. package/lib/goog/dom/nodetype.js +0 -48
  400. package/lib/goog/dom/safe.js +0 -347
  401. package/lib/goog/dom/tagname.js +0 -160
  402. package/lib/goog/dom/tags.js +0 -41
  403. package/lib/goog/dom/vendor.js +0 -96
  404. package/lib/goog/events/browserevent.js +0 -400
  405. package/lib/goog/events/browserfeature.js +0 -85
  406. package/lib/goog/events/event.js +0 -143
  407. package/lib/goog/events/eventid.js +0 -47
  408. package/lib/goog/events/events.js +0 -984
  409. package/lib/goog/events/eventtarget.js +0 -394
  410. package/lib/goog/events/eventtype.js +0 -237
  411. package/lib/goog/events/keycodes.js +0 -427
  412. package/lib/goog/events/listenable.js +0 -335
  413. package/lib/goog/events/listener.js +0 -131
  414. package/lib/goog/events/listenermap.js +0 -308
  415. package/lib/goog/fs/url.js +0 -109
  416. package/lib/goog/functions/functions.js +0 -442
  417. package/lib/goog/html/safehtml.js +0 -757
  418. package/lib/goog/html/safescript.js +0 -234
  419. package/lib/goog/html/safestyle.js +0 -442
  420. package/lib/goog/html/safestylesheet.js +0 -276
  421. package/lib/goog/html/safeurl.js +0 -398
  422. package/lib/goog/html/trustedresourceurl.js +0 -224
  423. package/lib/goog/html/uncheckedconversions.js +0 -232
  424. package/lib/goog/i18n/bidi.js +0 -908
  425. package/lib/goog/iter/iter.js +0 -1302
  426. package/lib/goog/json/json.js +0 -363
  427. package/lib/goog/labs/testing/assertthat.js +0 -58
  428. package/lib/goog/labs/testing/logicmatcher.js +0 -212
  429. package/lib/goog/labs/testing/matcher.js +0 -80
  430. package/lib/goog/labs/testing/numbermatcher.js +0 -346
  431. package/lib/goog/labs/testing/objectmatcher.js +0 -317
  432. package/lib/goog/labs/testing/stringmatcher.js +0 -415
  433. package/lib/goog/labs/useragent/browser.js +0 -341
  434. package/lib/goog/labs/useragent/engine.js +0 -160
  435. package/lib/goog/labs/useragent/platform.js +0 -160
  436. package/lib/goog/labs/useragent/util.js +0 -148
  437. package/lib/goog/log/log.js +0 -197
  438. package/lib/goog/math/box.js +0 -398
  439. package/lib/goog/math/coordinate.js +0 -268
  440. package/lib/goog/math/math.js +0 -451
  441. package/lib/goog/math/rect.js +0 -476
  442. package/lib/goog/math/size.js +0 -227
  443. package/lib/goog/net/wrapperxmlhttpfactory.js +0 -71
  444. package/lib/goog/net/xhrlike.js +0 -124
  445. package/lib/goog/net/xmlhttp.js +0 -246
  446. package/lib/goog/net/xmlhttpfactory.js +0 -67
  447. package/lib/goog/object/object.js +0 -686
  448. package/lib/goog/promise/promise.js +0 -1350
  449. package/lib/goog/promise/resolver.js +0 -48
  450. package/lib/goog/promise/thenable.js +0 -126
  451. package/lib/goog/reflect/reflect.js +0 -77
  452. package/lib/goog/string/const.js +0 -182
  453. package/lib/goog/string/string.js +0 -1599
  454. package/lib/goog/string/typedstring.js +0 -48
  455. package/lib/goog/structs/collection.js +0 -56
  456. package/lib/goog/structs/map.js +0 -457
  457. package/lib/goog/structs/set.js +0 -279
  458. package/lib/goog/structs/structs.js +0 -354
  459. package/lib/goog/style/style.js +0 -2037
  460. package/lib/goog/testing/asserts.js +0 -1278
  461. package/lib/goog/testing/events/events.js +0 -767
  462. package/lib/goog/testing/functionmock.js +0 -175
  463. package/lib/goog/testing/jsunit.js +0 -162
  464. package/lib/goog/testing/loosemock.js +0 -242
  465. package/lib/goog/testing/mock.js +0 -645
  466. package/lib/goog/testing/mockclock.js +0 -606
  467. package/lib/goog/testing/mockcontrol.js +0 -220
  468. package/lib/goog/testing/mockinterface.js +0 -45
  469. package/lib/goog/testing/mockmatchers.js +0 -400
  470. package/lib/goog/testing/objectpropertystring.js +0 -68
  471. package/lib/goog/testing/propertyreplacer.js +0 -262
  472. package/lib/goog/testing/recordfunction.js +0 -215
  473. package/lib/goog/testing/stacktrace.js +0 -594
  474. package/lib/goog/testing/strictmock.js +0 -130
  475. package/lib/goog/testing/testcase.js +0 -1629
  476. package/lib/goog/testing/testrunner.js +0 -440
  477. package/lib/goog/uri/uri.js +0 -1524
  478. package/lib/goog/uri/utils.js +0 -1064
  479. package/lib/goog/useragent/product.js +0 -183
  480. package/lib/goog/useragent/product_isversion.js +0 -144
  481. package/lib/goog/useragent/useragent.js +0 -572
  482. package/lib/webdriver/actionsequence.js +0 -356
  483. package/lib/webdriver/builder.js +0 -207
  484. package/lib/webdriver/capabilities.js +0 -412
  485. package/lib/webdriver/events.js +0 -179
  486. package/lib/webdriver/firefoxdomexecutor.js +0 -175
  487. package/lib/webdriver/http/corsclient.js +0 -133
  488. package/lib/webdriver/http/http.js +0 -525
  489. package/lib/webdriver/http/xhrclient.js +0 -67
  490. package/lib/webdriver/locators.js +0 -257
  491. package/lib/webdriver/logging.js +0 -347
  492. package/lib/webdriver/session.js +0 -74
  493. package/lib/webdriver/stacktrace.js +0 -619
  494. package/lib/webdriver/test/builder_test.js +0 -53
  495. package/lib/webdriver/test/capabilities_test.js +0 -72
  496. package/lib/webdriver/test/events_test.js +0 -203
  497. package/lib/webdriver/test/http/corsclient_test.js +0 -151
  498. package/lib/webdriver/test/http/http_test.js +0 -428
  499. package/lib/webdriver/test/http/xhrclient_test.js +0 -196
  500. package/lib/webdriver/test/locators_test.js +0 -59
  501. package/lib/webdriver/test/logging_test.js +0 -85
  502. package/lib/webdriver/test/promise_error_test.js +0 -892
  503. package/lib/webdriver/test/promise_flow_test.js +0 -2365
  504. package/lib/webdriver/test/promise_generator_test.js +0 -323
  505. package/lib/webdriver/test/promise_test.js +0 -2012
  506. package/lib/webdriver/test/stacktrace_test.js +0 -480
  507. package/lib/webdriver/test/test_bootstrap.js +0 -67
  508. package/lib/webdriver/test/testing/asserts_test.js +0 -117
  509. package/lib/webdriver/test/testing/client_test.js +0 -88
  510. package/lib/webdriver/test/testing/testcase_test.js +0 -229
  511. package/lib/webdriver/test/testutil.js +0 -209
  512. package/lib/webdriver/test/testutil_test.js +0 -104
  513. package/lib/webdriver/test/until_test.js +0 -411
  514. package/lib/webdriver/test/webdriver_generator_test.js +0 -92
  515. package/lib/webdriver/test/webdriver_test.js +0 -2369
  516. package/lib/webdriver/testing/asserts.js +0 -487
  517. package/lib/webdriver/testing/client.js +0 -179
  518. package/lib/webdriver/testing/jsunit.js +0 -363
  519. package/lib/webdriver/testing/testcase.js +0 -168
  520. package/lib/webdriver/testing/window.js +0 -244
  521. package/lib/webdriver/touchsequence.js +0 -248
  522. package/lib/webdriver/until.js +0 -412
  523. package/lib/webdriver/webdriver.js +0 -2511
  524. package/test/_base_test.js +0 -129
@@ -15,44 +15,15 @@
15
15
  // specific language governing permissions and limitations
16
16
  // under the License.
17
17
 
18
- /**
19
- * @license Portions of this code are from the Dojo toolkit, received under the
20
- * BSD License:
21
- * Redistribution and use in source and binary forms, with or without
22
- * modification, are permitted provided that the following conditions are met:
23
- *
24
- * * Redistributions of source code must retain the above copyright notice,
25
- * this list of conditions and the following disclaimer.
26
- * * Redistributions in binary form must reproduce the above copyright notice,
27
- * this list of conditions and the following disclaimer in the documentation
28
- * and/or other materials provided with the distribution.
29
- * * Neither the name of the Dojo Foundation nor the names of its contributors
30
- * may be used to endorse or promote products derived from this software
31
- * without specific prior written permission.
32
- *
33
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
37
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43
- * POSSIBILITY OF SUCH DAMAGE.
44
- */
45
-
46
18
  /**
47
19
  * @fileoverview
48
- * The promise module is centered around the
49
- * {@linkplain webdriver.promise.ControlFlow ControlFlow}, a class that
50
- * coordinates the execution of asynchronous tasks. The ControlFlow allows users
51
- * to focus on the imperative commands for their script without worrying about
52
- * chaining together every single asynchronous action, which can be tedious and
53
- * verbose. APIs may be layered on top of the control flow to read as if they
54
- * were synchronous. For instance, the core
55
- * {@linkplain webdriver.WebDriver WebDriver} API is built on top of the
20
+ * The promise module is centered around the {@linkplain ControlFlow}, a class
21
+ * that coordinates the execution of asynchronous tasks. The ControlFlow allows
22
+ * users to focus on the imperative commands for their script without worrying
23
+ * about chaining together every single asynchronous action, which can be
24
+ * tedious and verbose. APIs may be layered on top of the control flow to read
25
+ * as if they were synchronous. For instance, the core
26
+ * {@linkplain ./webdriver.WebDriver WebDriver} API is built on top of the
56
27
  * control flow, allowing users to write
57
28
  *
58
29
  * driver.get('http://www.google.com/ncr');
@@ -79,10 +50,9 @@
79
50
  *
80
51
  * The control flow is based on the concept of tasks and task queues. Tasks are
81
52
  * functions that define the basic unit of work for the control flow to execute.
82
- * Each task is scheduled via
83
- * {@link webdriver.promise.ControlFlow#execute() ControlFlow#execute()}, which
84
- * will return a {@link webdriver.promise.Promise Promise} that will be resolved
85
- * with the task's result.
53
+ * Each task is scheduled via {@link ControlFlow#execute()}, which will return
54
+ * a {@link ManagedPromise ManagedPromise} that will be resolved with the task's
55
+ * result.
86
56
  *
87
57
  * A task queue contains all of the tasks scheduled within a single turn of the
88
58
  * [JavaScript event loop][JSEL]. The control flow will create a new task queue
@@ -98,12 +68,12 @@
98
68
  * Whenever the control flow creates a new task queue, it will automatically
99
69
  * begin executing tasks in the next available turn of the event loop. This
100
70
  * execution is scheduled using a "micro-task" timer, such as a (native)
101
- * `Promise.then()` callback.
71
+ * `ManagedPromise.then()` callback.
102
72
  *
103
73
  * setTimeout(() => console.log('a'));
104
- * Promise.resolve().then(() => console.log('b')); // A native promise.
74
+ * ManagedPromise.resolve().then(() => console.log('b')); // A native promise.
105
75
  * flow.execute(() => console.log('c'));
106
- * Promise.resolve().then(() => console.log('d'));
76
+ * ManagedPromise.resolve().then(() => console.log('d'));
107
77
  * setTimeout(() => console.log('fin'));
108
78
  * // b
109
79
  * // c
@@ -127,14 +97,13 @@
127
97
  * There are several important events that may occur while executing a task
128
98
  * function:
129
99
  *
130
- * 1. A new task queue is created by a call to
131
- * {@link webdriver.promise.ControlFlow#execute ControlFlow#execute()}. Any
132
- * tasks scheduled within this task queue are considered subtasks of the
100
+ * 1. A new task queue is created by a call to {@link ControlFlow#execute()}.
101
+ * Any tasks scheduled within this task queue are considered subtasks of the
133
102
  * current task.
134
103
  * 2. The task function throws an error. Any scheduled tasks are immediately
135
104
  * discarded and the task's promised result (previously returned by
136
- * {@link webdriver.promise.ControlFlow#execute ControlFlow#execute()}) is
137
- * immediately rejected with the thrown error.
105
+ * {@link ControlFlow#execute()}) is immediately rejected with the thrown
106
+ * error.
138
107
  * 3. The task function returns sucessfully.
139
108
  *
140
109
  * If a task function created a new task queue, the control flow will wait for
@@ -153,13 +122,12 @@
153
122
  * // b
154
123
  * // c
155
124
  *
156
- * ## Promise Integration
125
+ * ## ManagedPromise Integration
157
126
  *
158
- * In addition to the {@link webdriver.promise.ControlFlow ControlFlow} class,
159
- * the promise module also exports a [Promise/A+]
160
- * {@linkplain webdriver.promise.Promise implementation} that is deeply
127
+ * In addition to the {@link ControlFlow} class, the promise module also exports
128
+ * a [ManagedPromise/A+] {@linkplain ManagedPromise implementation} that is deeply
161
129
  * integrated with the ControlFlow. First and foremost, each promise
162
- * {@linkplain webdriver.promise.Promise#then() callback} is scheduled with the
130
+ * {@linkplain ManagedPromise#then() callback} is scheduled with the
163
131
  * control flow as a task. As a result, each callback is invoked in its own turn
164
132
  * of the JavaScript event loop with its own task queue. If any tasks are
165
133
  * scheduled within a callback, the callback's promised result will not be
@@ -173,7 +141,7 @@
173
141
  * // b
174
142
  * // a
175
143
  *
176
- * ### Scheduling Promise Callbacks <a id="scheduling_callbacks"></a>
144
+ * ### Scheduling ManagedPromise Callbacks <a id="scheduling_callbacks"></a>
177
145
  *
178
146
  * How callbacks are scheduled in the control flow depends on when they are
179
147
  * attached to the promise. Callbacks attached to a _previously_ resolved
@@ -463,18 +431,17 @@
463
431
  *
464
432
  * ES6 promises do not require users to handle a promise rejections. This can
465
433
  * result in subtle bugs as the rejections are silently "swallowed" by the
466
- * Promise class.
434
+ * ManagedPromise class.
467
435
  *
468
- * Promise.reject(Error('boom'));
436
+ * ManagedPromise.reject(Error('boom'));
469
437
  * // ... *crickets* ...
470
438
  *
471
- * Selenium's {@link webdriver.promise promise} module, on the other hand,
472
- * requires that every rejection be explicitly handled. When a
473
- * {@linkplain webdriver.promise.Promise Promise} is rejected and no callbacks
474
- * are defined on that promise, it is considered an _unhandled rejection_ and
475
- * reproted to the active task queue. If the rejection remains unhandled after
476
- * a single turn of the [event loop][JSEL] (scheduled with a micro-task), it
477
- * will propagate up the stack.
439
+ * Selenium's promise module, on the other hand, requires that every rejection
440
+ * be explicitly handled. When a {@linkplain ManagedPromise ManagedPromise} is
441
+ * rejected and no callbacks are defined on that promise, it is considered an
442
+ * _unhandled rejection_ and reproted to the active task queue. If the rejection
443
+ * remains unhandled after a single turn of the [event loop][JSEL] (scheduled
444
+ * with a micro-task), it will propagate up the stack.
478
445
  *
479
446
  * ## Error Propagation
480
447
  *
@@ -485,7 +452,7 @@
485
452
  * // No callbacks registered on promise -> unhandled rejection
486
453
  * promise.rejected(Error('boom'));
487
454
  * flow.execute(function() { console.log('this will never run'); });
488
- * }).thenCatch(function(e) {
455
+ * }).catch(function(e) {
489
456
  * console.log(e.message);
490
457
  * });
491
458
  * // boom
@@ -497,7 +464,7 @@
497
464
  * promise.rejected(Error('boom'));
498
465
  * flow.execute(function() { console.log('a'); }).
499
466
  * then(function() { console.log('b'); });
500
- * }).thenCatch(function(e) {
467
+ * }).catch(function(e) {
501
468
  * console.log(e.message);
502
469
  * });
503
470
  * // boom
@@ -508,21 +475,20 @@
508
475
  * flow.execute(function() {
509
476
  * promise.rejected(Error('boom'));
510
477
  * return flow.execute(someOtherTask);
511
- * }).thenCatch(function(e) {
478
+ * }).catch(function(e) {
512
479
  * console.log(e.message);
513
480
  * });
514
481
  * // boom
515
482
  *
516
483
  * If there are multiple unhandled rejections within a task, they are packaged
517
- * in a {@link webdriver.promise.MultipleUnhandledRejectionError
518
- * MultipleUnhandledRejectionError}, which has an `errors` property that is a
519
- * `Set` of the recorded unhandled rejections:
484
+ * in a {@link MultipleUnhandledRejectionError}, which has an `errors` property
485
+ * that is a `Set` of the recorded unhandled rejections:
520
486
  *
521
487
  * flow.execute(function() {
522
488
  * promise.rejected(Error('boom1'));
523
489
  * promise.rejected(Error('boom2'));
524
- * }).thenCatch(function(ex) {
525
- * console.log(ex instanceof promise.MultipleUnhandledRejectionError);
490
+ * }).catch(function(ex) {
491
+ * console.log(ex instanceof MultipleUnhandledRejectionError);
526
492
  * for (var e of ex.errors) {
527
493
  * console.log(e.message);
528
494
  * }
@@ -542,7 +508,7 @@
542
508
  * flow.execute(function() {
543
509
  * promise.rejected(Error('boom'));
544
510
  * subTask = flow.execute(function() {});
545
- * }).thenCatch(function(e) {
511
+ * }).catch(function(e) {
546
512
  * console.log(e.message);
547
513
  * }).then(function() {
548
514
  * return subTask.then(
@@ -564,7 +530,7 @@
564
530
  * throw Error('fail!');
565
531
  * });
566
532
  * });
567
- * }).thenCatch(function(e) {
533
+ * }).catch(function(e) {
568
534
  * console.log(e.message);
569
535
  * });
570
536
  * // fail!
@@ -580,9 +546,9 @@
580
546
  *
581
547
  * Bottom line: you __*must*__ handle rejected promises.
582
548
  *
583
- * # Promise/A+ Compatibility
549
+ * # ManagedPromise/A+ Compatibility
584
550
  *
585
- * This `promise` module is compliant with the [Promise/A+][] specification
551
+ * This `promise` module is compliant with the [ManagedPromise/A+][] specification
586
552
  * except for sections `2.2.6.1` and `2.2.6.2`:
587
553
  *
588
554
  * >
@@ -596,7 +562,7 @@
596
562
  * Specifically, the conformance tests contains the following scenario (for
597
563
  * brevity, only the fulfillment version is shown):
598
564
  *
599
- * var p1 = Promise.resolve();
565
+ * var p1 = ManagedPromise.resolve();
600
566
  * p1.then(function() {
601
567
  * console.log('A');
602
568
  * p1.then(() => console.log('B'));
@@ -621,36 +587,73 @@
621
587
  *
622
588
  * [JSEL]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
623
589
  * [GF]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
624
- * [Promise/A+]: https://promisesaplus.com/
590
+ * [ManagedPromise/A+]: https://promisesaplus.com/
625
591
  */
626
592
 
627
- goog.module('webdriver.promise');
628
- goog.module.declareLegacyNamespace();
593
+ 'use strict';
594
+
595
+ const events = require('./events');
596
+ const logging = require('./logging');
629
597
 
630
- var Arrays = goog.require('goog.array');
631
- var asserts = goog.require('goog.asserts');
632
- var asyncRun = goog.require('goog.async.run');
633
- var throwException = goog.require('goog.async.throwException');
634
- var DebugError = goog.require('goog.debug.Error');
635
- var log = goog.require('goog.log');
636
- var Objects = goog.require('goog.object');
637
- var EventEmitter = goog.require('webdriver.EventEmitter');
638
- var stacktrace = goog.require('webdriver.stacktrace');
639
598
 
599
+ /**
600
+ * Alias to help with readability and differentiate types.
601
+ * @const
602
+ */
603
+ const NativePromise = Promise;
640
604
 
641
605
 
642
606
  /**
643
- * @define {boolean} Whether to append traces of {@code then} to rejection
644
- * errors.
607
+ * Whether to append traces of `then` to rejection errors.
608
+ * @type {boolean}
645
609
  */
646
- goog.define('webdriver.promise.LONG_STACK_TRACES', false);
610
+ exports.LONG_STACK_TRACES = false; // TODO: this should not be CONSTANT_CASE
611
+
647
612
 
648
613
  /** @const */
649
- var promise = exports;
614
+ const LOG = logging.getLogger('promise');
650
615
 
651
616
 
652
- /** @const */
653
- var LOG = log.getLogger('webdriver.promise');
617
+ const UNIQUE_IDS = new WeakMap;
618
+ let nextId = 1;
619
+
620
+
621
+ function getUid(obj) {
622
+ let id = UNIQUE_IDS.get(obj);
623
+ if (!id) {
624
+ id = nextId;
625
+ nextId += 1;
626
+ UNIQUE_IDS.set(obj, id);
627
+ }
628
+ return id;
629
+ }
630
+
631
+
632
+ /**
633
+ * Runs the given function after a micro-task yield.
634
+ * @param {function()} fn The function to run.
635
+ */
636
+ function asyncRun(fn) {
637
+ NativePromise.resolve().then(function() {
638
+ try {
639
+ fn();
640
+ } catch (ignored) {
641
+ // Do nothing.
642
+ }
643
+ });
644
+ }
645
+
646
+
647
+ /**
648
+ * Throws an error asynchronously so it is reported to the global error handler.
649
+ *
650
+ * @param {!Error} error The error to throw.
651
+ */
652
+ function asyncThrow(error) {
653
+ setTimeout(function() {
654
+ throw error;
655
+ }, 0);
656
+ }
654
657
 
655
658
 
656
659
  /**
@@ -661,18 +664,18 @@ var LOG = log.getLogger('webdriver.promise');
661
664
  * @template T
662
665
  */
663
666
  function vlog(level, loggable, opt_self) {
664
- var logLevel = log.Level.FINE;
667
+ var logLevel = logging.Level.FINE;
665
668
  if (level > 1) {
666
- logLevel = log.Level.FINEST;
669
+ logLevel = logging.Level.FINEST;
667
670
  } else if (level > 0) {
668
- logLevel = log.Level.FINER;
671
+ logLevel = logging.Level.FINER;
669
672
  }
670
673
 
671
674
  if (typeof loggable === 'function') {
672
675
  loggable = loggable.bind(opt_self);
673
676
  }
674
677
 
675
- log.log(LOG, logLevel, loggable);
678
+ LOG.log(logLevel, loggable);
676
679
  }
677
680
 
678
681
 
@@ -680,150 +683,134 @@ function vlog(level, loggable, opt_self) {
680
683
  * Generates an error to capture the current stack trace.
681
684
  * @param {string} name Error name for this stack trace.
682
685
  * @param {string} msg Message to record.
683
- * @param {!Function} topFn The function that should appear at the top of the
684
- * stack; only applicable in V8.
686
+ * @param {Function=} opt_topFn The function that should appear at the top of
687
+ * the stack; only applicable in V8.
685
688
  * @return {!Error} The generated error.
686
689
  */
687
- promise.captureStackTrace = function(name, msg, topFn) {
690
+ function captureStackTrace(name, msg, opt_topFn) {
688
691
  var e = Error(msg);
689
692
  e.name = name;
690
693
  if (Error.captureStackTrace) {
691
- Error.captureStackTrace(e, topFn);
694
+ Error.captureStackTrace(e, opt_topFn);
692
695
  } else {
693
- var stack = stacktrace.getStack(e);
694
- e.stack = e.toString();
696
+ var stack = Error().stack;
695
697
  if (stack) {
698
+ e.stack = e.toString();
696
699
  e.stack += '\n' + stack;
697
700
  }
698
701
  }
699
702
  return e;
700
- };
703
+ }
701
704
 
702
705
 
703
706
  /**
704
707
  * Error used when the computation of a promise is cancelled.
705
- *
706
- * @unrestricted
707
708
  */
708
- promise.CancellationError = goog.defineClass(DebugError, {
709
+ class CancellationError extends Error {
709
710
  /**
710
711
  * @param {string=} opt_msg The cancellation message.
711
712
  */
712
- constructor: function(opt_msg) {
713
- promise.CancellationError.base(this, 'constructor', opt_msg);
713
+ constructor(opt_msg) {
714
+ super(opt_msg);
714
715
 
715
716
  /** @override */
716
- this.name = 'CancellationError';
717
+ this.name = this.constructor.name;
717
718
 
718
719
  /** @private {boolean} */
719
720
  this.silent_ = false;
720
- },
721
+ }
721
722
 
722
- statics: {
723
- /**
724
- * Wraps the given error in a CancellationError.
725
- *
726
- * @param {*} error The error to wrap.
727
- * @param {string=} opt_msg The prefix message to use.
728
- * @return {!promise.CancellationError} A cancellation error.
729
- */
730
- wrap: function(error, opt_msg) {
731
- var message;
732
- if (error instanceof promise.CancellationError) {
733
- return new promise.CancellationError(
734
- opt_msg ? (opt_msg + ': ' + error.message) : error.message);
735
- } else if (opt_msg) {
736
- message = opt_msg;
737
- if (error) {
738
- message += ': ' + error;
739
- }
740
- return new promise.CancellationError(message);
741
- }
723
+ /**
724
+ * Wraps the given error in a CancellationError.
725
+ *
726
+ * @param {*} error The error to wrap.
727
+ * @param {string=} opt_msg The prefix message to use.
728
+ * @return {!CancellationError} A cancellation error.
729
+ */
730
+ static wrap(error, opt_msg) {
731
+ var message;
732
+ if (error instanceof CancellationError) {
733
+ return new CancellationError(
734
+ opt_msg ? (opt_msg + ': ' + error.message) : error.message);
735
+ } else if (opt_msg) {
736
+ message = opt_msg;
742
737
  if (error) {
743
- message = error + '';
738
+ message += ': ' + error;
744
739
  }
745
- return new promise.CancellationError(message);
740
+ return new CancellationError(message);
746
741
  }
742
+ if (error) {
743
+ message = error + '';
744
+ }
745
+ return new CancellationError(message);
747
746
  }
748
- });
747
+ }
749
748
 
750
749
 
751
750
  /**
752
751
  * Error used to cancel tasks when a control flow is reset.
753
- * @unrestricted
754
752
  * @final
755
753
  */
756
- var FlowResetError = goog.defineClass(promise.CancellationError, {
757
- constructor: function() {
758
- FlowResetError.base(this, 'constructor', 'ControlFlow was reset');
759
-
760
- /** @override */
761
- this.name = 'FlowResetError';
762
-
754
+ class FlowResetError extends CancellationError {
755
+ constructor() {
756
+ super('ControlFlow was reset');
763
757
  this.silent_ = true;
764
758
  }
765
- });
759
+ }
766
760
 
767
761
 
768
762
  /**
769
763
  * Error used to cancel tasks that have been discarded due to an uncaught error
770
764
  * reported earlier in the control flow.
771
- * @unrestricted
772
765
  * @final
773
766
  */
774
- var DiscardedTaskError = goog.defineClass(promise.CancellationError, {
767
+ class DiscardedTaskError extends CancellationError {
775
768
  /** @param {*} error The original error. */
776
- constructor: function(error) {
769
+ constructor(error) {
777
770
  if (error instanceof DiscardedTaskError) {
778
771
  return /** @type {!DiscardedTaskError} */(error);
779
772
  }
780
773
 
781
774
  var msg = '';
782
775
  if (error) {
783
- msg = ': ' + (typeof error.message === 'string' ? error.message : error);
776
+ msg = ': ' + (
777
+ typeof error.message === 'string' ? error.message : error);
784
778
  }
785
779
 
786
- DiscardedTaskError.base(this, 'constructor',
787
- 'Task was discarded due to a previous failure' + msg);
788
-
789
- /** @override */
790
- this.name = 'DiscardedTaskError';
780
+ super('Task was discarded due to a previous failure' + msg);
791
781
  this.silent_ = true;
792
782
  }
793
- });
783
+ }
794
784
 
795
785
 
796
786
  /**
797
787
  * Error used when there are multiple unhandled promise rejections detected
798
788
  * within a task or callback.
799
789
  *
800
- * @unrestricted
801
790
  * @final
802
791
  */
803
- promise.MultipleUnhandledRejectionError = goog.defineClass(DebugError, {
792
+ class MultipleUnhandledRejectionError extends Error {
804
793
  /**
805
794
  * @param {!(Set<*>)} errors The errors to report.
806
795
  */
807
- constructor: function(errors) {
808
- promise.MultipleUnhandledRejectionError.base(
809
- this, 'constructor', 'Multiple unhandled promise rejections reported');
796
+ constructor(errors) {
797
+ super('Multiple unhandled promise rejections reported');
810
798
 
811
799
  /** @override */
812
- this.name = 'MultipleUnhandledRejectionError';
800
+ this.name = this.constructor.name;
813
801
 
814
802
  /** @type {!Set<*>} */
815
803
  this.errors = errors;
816
804
  }
817
- });
805
+ }
818
806
 
819
807
 
820
808
  /**
821
809
  * Property used to flag constructor's as implementing the Thenable interface
822
810
  * for runtime type checking.
823
- * @type {string}
824
811
  * @const
825
812
  */
826
- var IMPLEMENTED_BY_PROP = '$webdriver_Thenable';
813
+ const IMPLEMENTED_BY_SYMBOL = Symbol('promise.Thenable');
827
814
 
828
815
 
829
816
  /**
@@ -834,64 +821,54 @@ var IMPLEMENTED_BY_PROP = '$webdriver_Thenable';
834
821
  * @extends {IThenable<T>}
835
822
  * @template T
836
823
  */
837
- promise.Thenable = goog.defineClass(null, {
838
- statics: {
839
- /**
840
- * Adds a property to a class prototype to allow runtime checks of whether
841
- * instances of that class implement the Thenable interface. This function
842
- * will also ensure the prototype's {@code then} function is exported from
843
- * compiled code.
844
- * @param {function(new: promise.Thenable, ...?)} ctor The
845
- * constructor whose prototype to modify.
846
- */
847
- addImplementation: function(ctor) {
848
- // Based on goog.promise.Thenable.isImplementation.
849
- ctor.prototype['then'] = ctor.prototype.then;
850
- try {
851
- // Old IE7 does not support defineProperty; IE8 only supports it for
852
- // DOM elements.
853
- Object.defineProperty(
854
- ctor.prototype,
855
- IMPLEMENTED_BY_PROP,
856
- {'value': true, 'enumerable': false});
857
- } catch (ex) {
858
- ctor.prototype[IMPLEMENTED_BY_PROP] = true;
859
- }
860
- },
824
+ class Thenable {
825
+ /**
826
+ * Adds a property to a class prototype to allow runtime checks of whether
827
+ * instances of that class implement the Thenable interface. This function
828
+ * will also ensure the prototype's {@code then} function is exported from
829
+ * compiled code.
830
+ * @param {function(new: Thenable, ...?)} ctor The
831
+ * constructor whose prototype to modify.
832
+ */
833
+ static addImplementation(ctor) {
834
+ ctor.prototype['then'] = ctor.prototype.then;
835
+ try {
836
+ ctor.prototype[IMPLEMENTED_BY_SYMBOL] = true;
837
+ } catch (ignored) {
838
+ // Property access denied?
839
+ }
840
+ }
861
841
 
862
- /**
863
- * Checks if an object has been tagged for implementing the Thenable
864
- * interface as defined by
865
- * {@link webdriver.promise.Thenable.addImplementation}.
866
- * @param {*} object The object to test.
867
- * @return {boolean} Whether the object is an implementation of the Thenable
868
- * interface.
869
- */
870
- isImplementation: function(object) {
871
- // Based on goog.promise.Thenable.isImplementation.
872
- if (!object) {
873
- return false;
874
- }
875
- try {
876
- return !!object[IMPLEMENTED_BY_PROP];
877
- } catch (e) {
878
- return false; // Property access seems to be forbidden.
879
- }
842
+ /**
843
+ * Checks if an object has been tagged for implementing the Thenable
844
+ * interface as defined by {@link Thenable.addImplementation}.
845
+ * @param {*} object The object to test.
846
+ * @return {boolean} Whether the object is an implementation of the Thenable
847
+ * interface.
848
+ */
849
+ static isImplementation(object) {
850
+ if (!object) {
851
+ return false;
880
852
  }
881
- },
853
+ try {
854
+ return !!object[IMPLEMENTED_BY_SYMBOL];
855
+ } catch (e) {
856
+ return false; // Property access seems to be forbidden.
857
+ }
858
+ }
882
859
 
883
860
  /**
884
861
  * Cancels the computation of this promise's value, rejecting the promise in
885
862
  * the process. This method is a no-op if the promise has already been
886
863
  * resolved.
887
864
  *
888
- * @param {(string|promise.CancellationError)=} opt_reason The reason this
889
- * promise is being cancelled.
865
+ * @param {(string|Error)=} opt_reason The reason this promise is being
866
+ * cancelled. This value will be wrapped in a {@link CancellationError}.
890
867
  */
891
- cancel: function(opt_reason) {},
868
+ cancel(opt_reason) {}
892
869
 
893
870
  /** @return {boolean} Whether this promise's value is still being computed. */
894
- isPending: function() {},
871
+ isPending() {}
895
872
 
896
873
  /**
897
874
  * Registers listeners for when this instance is resolved.
@@ -902,11 +879,11 @@ promise.Thenable = goog.defineClass(null, {
902
879
  * @param {?(function(*): (R|IThenable<R>))=} opt_errback
903
880
  * The function to call if this promise is rejected. The function should
904
881
  * expect a single argument: the rejection reason.
905
- * @return {!promise.Promise<R>} A new promise which will be
882
+ * @return {!ManagedPromise<R>} A new promise which will be
906
883
  * resolved with the result of the invoked callback.
907
884
  * @template R
908
885
  */
909
- then: function(opt_callback, opt_errback) {},
886
+ then(opt_callback, opt_errback) {}
910
887
 
911
888
  /**
912
889
  * Registers a listener for when this promise is rejected. This is synonymous
@@ -920,18 +897,30 @@ promise.Thenable = goog.defineClass(null, {
920
897
  * }
921
898
  *
922
899
  * // Asynchronous promise API:
923
- * doAsynchronousWork().thenCatch(function(ex) {
900
+ * doAsynchronousWork().catch(function(ex) {
924
901
  * console.error(ex);
925
902
  * });
926
903
  *
927
904
  * @param {function(*): (R|IThenable<R>)} errback The
928
905
  * function to call if this promise is rejected. The function should
929
906
  * expect a single argument: the rejection reason.
930
- * @return {!promise.Promise<R>} A new promise which will be
907
+ * @return {!ManagedPromise<R>} A new promise which will be
931
908
  * resolved with the result of the invoked callback.
932
909
  * @template R
933
910
  */
934
- thenCatch: function(errback) {},
911
+ catch(errback) {}
912
+
913
+ /**
914
+ * An alias for {@link #catch()}
915
+ *
916
+ * @param {function(*): (R|IThenable<R>)} errback The
917
+ * function to call if this promise is rejected. The function should
918
+ * expect a single argument: the rejection reason.
919
+ * @return {!ManagedPromise<R>} A new promise which will be
920
+ * resolved wdith the result of the invoked callback.
921
+ * @template R
922
+ */
923
+ thenCatch(errback) {}
935
924
 
936
925
  /**
937
926
  * Registers a listener to invoke when this promise is resolved, regardless
@@ -965,19 +954,18 @@ promise.Thenable = goog.defineClass(null, {
965
954
  *
966
955
  * @param {function(): (R|IThenable<R>)} callback The function
967
956
  * to call when this promise is resolved.
968
- * @return {!promise.Promise<R>} A promise that will be fulfilled
957
+ * @return {!ManagedPromise<R>} A promise that will be fulfilled
969
958
  * with the callback result.
970
959
  * @template R
971
960
  */
972
- thenFinally: function(callback) {}
973
- });
974
-
961
+ thenFinally(callback) {}
962
+ }
975
963
 
976
964
 
977
965
  /**
978
966
  * @enum {string}
979
967
  */
980
- var PromiseState = {
968
+ const PromiseState = {
981
969
  PENDING: 'pending',
982
970
  BLOCKED: 'blocked',
983
971
  REJECTED: 'rejected',
@@ -987,11 +975,11 @@ var PromiseState = {
987
975
 
988
976
  /**
989
977
  * Internal symbol used to store a cancellation handler for
990
- * {@link promise.Promise} objects. This is an internal implementation detail
978
+ * {@link ManagedPromise} objects. This is an internal implementation detail
991
979
  * used by the {@link TaskQueue} class to monitor for when a promise is
992
980
  * cancelled without generating an extra promise via then().
993
981
  */
994
- var CANCEL_HANDLER_SYMBOL = Symbol('on cancel');
982
+ const CANCEL_HANDLER_SYMBOL = Symbol('on cancel');
995
983
 
996
984
 
997
985
  /**
@@ -1001,12 +989,12 @@ var CANCEL_HANDLER_SYMBOL = Symbol('on cancel');
1001
989
  * fulfilled or rejected state, at which point the promise is considered
1002
990
  * resolved.
1003
991
  *
1004
- * @implements {promise.Thenable<T>}
992
+ * @implements {Thenable<T>}
993
+ * @unrestricted
1005
994
  * @template T
1006
995
  * @see http://promises-aplus.github.io/promises-spec/
1007
- * @unrestricted // For using CANCEL_HANDLER_SYMBOL.
1008
996
  */
1009
- promise.Promise = goog.defineClass(null, {
997
+ const ManagedPromise = class Promise {
1010
998
  /**
1011
999
  * @param {function(
1012
1000
  * function((T|IThenable<T>|Thenable)=),
@@ -1014,23 +1002,22 @@ promise.Promise = goog.defineClass(null, {
1014
1002
  * Function that is invoked immediately to begin computation of this
1015
1003
  * promise's value. The function should accept a pair of callback
1016
1004
  * functions, one for fulfilling the promise and another for rejecting it.
1017
- * @param {promise.ControlFlow=} opt_flow The control flow
1005
+ * @param {ControlFlow=} opt_flow The control flow
1018
1006
  * this instance was created under. Defaults to the currently active flow.
1019
1007
  */
1020
- constructor: function(resolver, opt_flow) {
1021
- goog.getUid(this);
1008
+ constructor(resolver, opt_flow) {
1009
+ getUid(this);
1022
1010
 
1023
- /** @private {!promise.ControlFlow} */
1024
- this.flow_ = opt_flow || promise.controlFlow();
1011
+ /** @private {!ControlFlow} */
1012
+ this.flow_ = opt_flow || controlFlow();
1025
1013
 
1026
1014
  /** @private {Error} */
1027
1015
  this.stack_ = null;
1028
- if (promise.LONG_STACK_TRACES) {
1029
- this.stack_ = promise.captureStackTrace(
1030
- 'Promise', 'new', promise.Promise);
1016
+ if (exports.LONG_STACK_TRACES) {
1017
+ this.stack_ = captureStackTrace('Promise', 'new', this.constructor);
1031
1018
  }
1032
1019
 
1033
- /** @private {promise.Promise<?>} */
1020
+ /** @private {ManagedPromise<?>} */
1034
1021
  this.parent_ = null;
1035
1022
 
1036
1023
  /** @private {Array<!Task>} */
@@ -1048,7 +1035,7 @@ promise.Promise = goog.defineClass(null, {
1048
1035
  /** @private {TaskQueue} */
1049
1036
  this.queue_ = null;
1050
1037
 
1051
- /** @private {(function(promise.CancellationError)|null)} */
1038
+ /** @private {(function(CancellationError)|null)} */
1052
1039
  this[CANCEL_HANDLER_SYMBOL] = null;
1053
1040
 
1054
1041
  try {
@@ -1061,13 +1048,13 @@ promise.Promise = goog.defineClass(null, {
1061
1048
  } catch (ex) {
1062
1049
  this.resolve_(PromiseState.REJECTED, ex);
1063
1050
  }
1064
- },
1051
+ }
1065
1052
 
1066
1053
  /** @override */
1067
- toString: function() {
1068
- return 'Promise::' + goog.getUid(this) +
1054
+ toString() {
1055
+ return 'ManagedPromise::' + getUid(this) +
1069
1056
  ' {[[PromiseStatus]]: "' + this.state_ + '"}';
1070
- },
1057
+ }
1071
1058
 
1072
1059
  /**
1073
1060
  * Resolves this promise. If the new value is itself a promise, this function
@@ -1077,7 +1064,7 @@ promise.Promise = goog.defineClass(null, {
1077
1064
  * @throws {TypeError} If {@code newValue === this}.
1078
1065
  * @private
1079
1066
  */
1080
- resolve_: function(newState, newValue) {
1067
+ resolve_(newState, newValue) {
1081
1068
  if (PromiseState.PENDING !== this.state_) {
1082
1069
  return;
1083
1070
  }
@@ -1093,15 +1080,16 @@ promise.Promise = goog.defineClass(null, {
1093
1080
  this.state_ = PromiseState.BLOCKED;
1094
1081
 
1095
1082
  if (newState !== PromiseState.REJECTED) {
1096
- if (promise.Thenable.isImplementation(newValue)) {
1083
+ if (Thenable.isImplementation(newValue)) {
1097
1084
  // 2.3.2
1098
- newValue = /** @type {!promise.Thenable} */(newValue);
1085
+ newValue = /** @type {!Thenable} */(newValue);
1099
1086
  newValue.then(
1100
1087
  this.unblockAndResolve_.bind(this, PromiseState.FULFILLED),
1101
1088
  this.unblockAndResolve_.bind(this, PromiseState.REJECTED));
1102
1089
  return;
1103
1090
 
1104
- } else if (goog.isObject(newValue)) {
1091
+ } else if (newValue
1092
+ && (typeof newValue === 'object' || typeof newValue === 'function')) {
1105
1093
  // 2.3.3
1106
1094
 
1107
1095
  try {
@@ -1115,10 +1103,9 @@ promise.Promise = goog.defineClass(null, {
1115
1103
  return;
1116
1104
  }
1117
1105
 
1118
- // NB: goog.isFunction is loose and will accept instanceof Function.
1119
1106
  if (typeof then === 'function') {
1120
1107
  // 2.3.3.3
1121
- this.invokeThen_(newValue, then);
1108
+ this.invokeThen_(/** @type {!Object} */(newValue), then);
1122
1109
  return;
1123
1110
  }
1124
1111
  }
@@ -1133,7 +1120,7 @@ promise.Promise = goog.defineClass(null, {
1133
1120
  this.state_ = newState;
1134
1121
  this.value_ = newValue;
1135
1122
  this.scheduleNotifications_();
1136
- },
1123
+ }
1137
1124
 
1138
1125
  /**
1139
1126
  * Invokes a thenable's "then" method according to 2.3.3.3 of the promise
@@ -1142,7 +1129,7 @@ promise.Promise = goog.defineClass(null, {
1142
1129
  * @param {!Function} then The "then" function to invoke.
1143
1130
  * @private
1144
1131
  */
1145
- invokeThen_: function(x, then) {
1132
+ invokeThen_(x, then) {
1146
1133
  var called = false;
1147
1134
  var self = this;
1148
1135
 
@@ -1169,28 +1156,28 @@ promise.Promise = goog.defineClass(null, {
1169
1156
  // 2.3.3.3.4.2
1170
1157
  rejectPromise(e);
1171
1158
  }
1172
- },
1159
+ }
1173
1160
 
1174
1161
  /**
1175
1162
  * @param {PromiseState} newState The promise's new state.
1176
1163
  * @param {*} newValue The promise's new value.
1177
1164
  * @private
1178
1165
  */
1179
- unblockAndResolve_: function(newState, newValue) {
1166
+ unblockAndResolve_(newState, newValue) {
1180
1167
  if (this.state_ === PromiseState.BLOCKED) {
1181
1168
  this.state_ = PromiseState.PENDING;
1182
1169
  this.resolve_(newState, newValue);
1183
1170
  }
1184
- },
1171
+ }
1185
1172
 
1186
1173
  /**
1187
1174
  * @private
1188
1175
  */
1189
- scheduleNotifications_: function() {
1176
+ scheduleNotifications_() {
1190
1177
  vlog(2, () => this + ' scheduling notifications', this);
1191
1178
 
1192
1179
  this[CANCEL_HANDLER_SYMBOL] = null;
1193
- if (this.value_ instanceof promise.CancellationError
1180
+ if (this.value_ instanceof CancellationError
1194
1181
  && this.value_.silent_) {
1195
1182
  this.callbacks_ = null;
1196
1183
  }
@@ -1201,14 +1188,14 @@ promise.Promise = goog.defineClass(null, {
1201
1188
 
1202
1189
  if (!this.handled_ &&
1203
1190
  this.state_ === PromiseState.REJECTED &&
1204
- !(this.value_ instanceof promise.CancellationError)) {
1191
+ !(this.value_ instanceof CancellationError)) {
1205
1192
  this.queue_.addUnhandledRejection(this);
1206
1193
  }
1207
1194
  this.queue_.scheduleCallbacks(this);
1208
- },
1195
+ }
1209
1196
 
1210
1197
  /** @override */
1211
- cancel: function(opt_reason) {
1198
+ cancel(opt_reason) {
1212
1199
  if (!canCancel(this)) {
1213
1200
  return;
1214
1201
  }
@@ -1216,7 +1203,7 @@ promise.Promise = goog.defineClass(null, {
1216
1203
  if (this.parent_ && canCancel(this.parent_)) {
1217
1204
  this.parent_.cancel(opt_reason);
1218
1205
  } else {
1219
- var reason = promise.CancellationError.wrap(opt_reason);
1206
+ var reason = CancellationError.wrap(opt_reason);
1220
1207
  if (this[CANCEL_HANDLER_SYMBOL]) {
1221
1208
  this[CANCEL_HANDLER_SYMBOL](reason);
1222
1209
  this[CANCEL_HANDLER_SYMBOL] = null;
@@ -1233,27 +1220,32 @@ promise.Promise = goog.defineClass(null, {
1233
1220
  return promise.state_ === PromiseState.PENDING
1234
1221
  || promise.state_ === PromiseState.BLOCKED;
1235
1222
  }
1236
- },
1223
+ }
1237
1224
 
1238
1225
  /** @override */
1239
- isPending: function() {
1226
+ isPending() {
1240
1227
  return this.state_ === PromiseState.PENDING;
1241
- },
1228
+ }
1242
1229
 
1243
1230
  /** @override */
1244
- then: function(opt_callback, opt_errback) {
1231
+ then(opt_callback, opt_errback) {
1245
1232
  return this.addCallback_(
1246
- opt_callback, opt_errback, 'then', promise.Promise.prototype.then);
1247
- },
1233
+ opt_callback, opt_errback, 'then', ManagedPromise.prototype.then);
1234
+ }
1248
1235
 
1249
1236
  /** @override */
1250
- thenCatch: function(errback) {
1237
+ catch(errback) {
1251
1238
  return this.addCallback_(
1252
- null, errback, 'thenCatch', promise.Promise.prototype.thenCatch);
1253
- },
1239
+ null, errback, 'catch', ManagedPromise.prototype.catch);
1240
+ }
1241
+
1242
+ /** @override */
1243
+ thenCatch(errback) {
1244
+ return this.catch(errback);
1245
+ }
1254
1246
 
1255
1247
  /** @override */
1256
- thenFinally: function(callback) {
1248
+ thenFinally(callback) {
1257
1249
  var error;
1258
1250
  var mustThrow = false;
1259
1251
  return this.then(function() {
@@ -1267,7 +1259,7 @@ promise.Promise = goog.defineClass(null, {
1267
1259
  throw error;
1268
1260
  }
1269
1261
  });
1270
- },
1262
+ }
1271
1263
 
1272
1264
  /**
1273
1265
  * Registers a new callback with this promise
@@ -1278,13 +1270,13 @@ promise.Promise = goog.defineClass(null, {
1278
1270
  * @param {string} name The callback name.
1279
1271
  * @param {!Function} fn The function to use as the top of the stack when
1280
1272
  * recording the callback's creation point.
1281
- * @return {!promise.Promise<R>} A new promise which will be resolved with the
1273
+ * @return {!ManagedPromise<R>} A new promise which will be resolved with the
1282
1274
  * esult of the invoked callback.
1283
1275
  * @template R
1284
1276
  * @private
1285
1277
  */
1286
- addCallback_: function(callback, errback, name, fn) {
1287
- if (!goog.isFunction(callback) && !goog.isFunction(errback)) {
1278
+ addCallback_(callback, errback, name, fn) {
1279
+ if (typeof callback !== 'function' && typeof errback !== 'function') {
1288
1280
  return this;
1289
1281
  }
1290
1282
 
@@ -1297,7 +1289,7 @@ promise.Promise = goog.defineClass(null, {
1297
1289
  this.flow_,
1298
1290
  this.invokeCallback_.bind(this, callback, errback),
1299
1291
  name,
1300
- promise.LONG_STACK_TRACES ? {name: 'Promise', top: fn} : undefined);
1292
+ exports.LONG_STACK_TRACES ? {name: 'Promise', top: fn} : undefined);
1301
1293
  cb.promise.parent_ = this;
1302
1294
 
1303
1295
  if (this.state_ !== PromiseState.PENDING &&
@@ -1313,7 +1305,7 @@ promise.Promise = goog.defineClass(null, {
1313
1305
  }
1314
1306
 
1315
1307
  return cb.promise;
1316
- },
1308
+ }
1317
1309
 
1318
1310
  /**
1319
1311
  * Invokes a callback function attached to this promise.
@@ -1324,15 +1316,15 @@ promise.Promise = goog.defineClass(null, {
1324
1316
  * @template R
1325
1317
  * @private
1326
1318
  */
1327
- invokeCallback_: function(callback, errback) {
1319
+ invokeCallback_(callback, errback) {
1328
1320
  var callbackFn = callback;
1329
1321
  if (this.state_ === PromiseState.REJECTED) {
1330
1322
  callbackFn = errback;
1331
1323
  }
1332
1324
 
1333
- if (goog.isFunction(callbackFn)) {
1334
- if (promise.isGenerator(callbackFn)) {
1335
- return promise.consume(callbackFn, null, this.value_);
1325
+ if (typeof callbackFn === 'function') {
1326
+ if (isGenerator(callbackFn)) {
1327
+ return consume(callbackFn, null, this.value_);
1336
1328
  }
1337
1329
  return callbackFn(this.value_);
1338
1330
  } else if (this.state_ === PromiseState.REJECTED) {
@@ -1341,34 +1333,34 @@ promise.Promise = goog.defineClass(null, {
1341
1333
  return this.value_;
1342
1334
  }
1343
1335
  }
1344
- });
1345
- promise.Thenable.addImplementation(promise.Promise);
1336
+ }
1337
+ Thenable.addImplementation(ManagedPromise);
1346
1338
 
1347
1339
 
1348
1340
  /**
1349
1341
  * Represents a value that will be resolved at some point in the future. This
1350
- * class represents the protected "producer" half of a Promise - each Deferred
1342
+ * class represents the protected "producer" half of a ManagedPromise - each Deferred
1351
1343
  * has a {@code promise} property that may be returned to consumers for
1352
1344
  * registering callbacks, reserving the ability to resolve the deferred to the
1353
1345
  * producer.
1354
1346
  *
1355
1347
  * If this Deferred is rejected and there are no listeners registered before
1356
1348
  * the next turn of the event loop, the rejection will be passed to the
1357
- * {@link webdriver.promise.ControlFlow} as an unhandled failure.
1349
+ * {@link ControlFlow} as an unhandled failure.
1358
1350
  *
1359
- * @implements {promise.Thenable<T>}
1351
+ * @implements {Thenable<T>}
1360
1352
  * @template T
1361
1353
  */
1362
- promise.Deferred = goog.defineClass(null, {
1354
+ class Deferred {
1363
1355
  /**
1364
- * @param {promise.ControlFlow=} opt_flow The control flow this instance was
1356
+ * @param {ControlFlow=} opt_flow The control flow this instance was
1365
1357
  * created under. This should only be provided during unit tests.
1366
1358
  */
1367
- constructor: function(opt_flow) {
1359
+ constructor(opt_flow) {
1368
1360
  var fulfill, reject;
1369
1361
 
1370
- /** @type {!promise.Promise<T>} */
1371
- this.promise = new promise.Promise(function(f, r) {
1362
+ /** @type {!ManagedPromise<T>} */
1363
+ this.promise = new ManagedPromise(function(f, r) {
1372
1364
  fulfill = f;
1373
1365
  reject = r;
1374
1366
  }, opt_flow);
@@ -1399,43 +1391,51 @@ promise.Deferred = goog.defineClass(null, {
1399
1391
  checkNotSelf(opt_reason);
1400
1392
  reject(opt_reason);
1401
1393
  };
1402
- },
1394
+ }
1403
1395
 
1404
1396
  /** @override */
1405
- isPending: function() {
1397
+ isPending() {
1406
1398
  return this.promise.isPending();
1407
- },
1399
+ }
1408
1400
 
1409
1401
  /** @override */
1410
- cancel: function(opt_reason) {
1402
+ cancel(opt_reason) {
1411
1403
  this.promise.cancel(opt_reason);
1412
- },
1404
+ }
1413
1405
 
1414
1406
  /**
1415
1407
  * @override
1416
1408
  * @deprecated Use {@code then} from the promise property directly.
1417
1409
  */
1418
- then: function(opt_cb, opt_eb) {
1410
+ then(opt_cb, opt_eb) {
1419
1411
  return this.promise.then(opt_cb, opt_eb);
1420
- },
1412
+ }
1413
+
1414
+ /**
1415
+ * @override
1416
+ * @deprecated Use {@lcode catch} from the promise property directly.
1417
+ */
1418
+ catch(opt_eb) {
1419
+ return this.promise.catch(opt_eb);
1420
+ }
1421
1421
 
1422
1422
  /**
1423
1423
  * @override
1424
1424
  * @deprecated Use {@code thenCatch} from the promise property directly.
1425
1425
  */
1426
- thenCatch: function(opt_eb) {
1426
+ thenCatch(opt_eb) {
1427
1427
  return this.promise.thenCatch(opt_eb);
1428
- },
1428
+ }
1429
1429
 
1430
1430
  /**
1431
1431
  * @override
1432
1432
  * @deprecated Use {@code thenFinally} from the promise property directly.
1433
1433
  */
1434
- thenFinally: function(opt_cb) {
1434
+ thenFinally(opt_cb) {
1435
1435
  return this.promise.thenFinally(opt_cb);
1436
1436
  }
1437
- });
1438
- promise.Thenable.addImplementation(promise.Deferred);
1437
+ }
1438
+ Thenable.addImplementation(Deferred);
1439
1439
 
1440
1440
 
1441
1441
  /**
@@ -1446,11 +1446,8 @@ promise.Thenable.addImplementation(promise.Deferred);
1446
1446
  */
1447
1447
  function isError(value) {
1448
1448
  return value instanceof Error ||
1449
- goog.isObject(value) &&
1450
- (goog.isString(value.message) ||
1451
- // A special test for goog.testing.JsUnitException.
1452
- value.isJsUnitException);
1453
-
1449
+ (!!value && typeof value === 'object'
1450
+ && typeof value.message === 'string');
1454
1451
  }
1455
1452
 
1456
1453
 
@@ -1458,97 +1455,101 @@ function isError(value) {
1458
1455
  * Determines whether a {@code value} should be treated as a promise.
1459
1456
  * Any object whose "then" property is a function will be considered a promise.
1460
1457
  *
1461
- * @param {*} value The value to test.
1458
+ * @param {?} value The value to test.
1462
1459
  * @return {boolean} Whether the value is a promise.
1463
1460
  */
1464
- promise.isPromise = function(value) {
1465
- return !!value && goog.isObject(value) &&
1466
- // Use array notation so the Closure compiler does not obfuscate away our
1467
- // contract. Use typeof rather than goog.isFunction because
1468
- // goog.isFunction accepts instanceof Function, which the promise spec
1469
- // does not.
1470
- typeof value['then'] === 'function';
1471
- };
1461
+ function isPromise(value) {
1462
+ try {
1463
+ // Use array notation so the Closure compiler does not obfuscate away our
1464
+ // contract.
1465
+ return value
1466
+ && (typeof value === 'object' || typeof value === 'function')
1467
+ && typeof value['then'] === 'function';
1468
+ } catch (ex) {
1469
+ return false;
1470
+ }
1471
+ }
1472
1472
 
1473
1473
 
1474
1474
  /**
1475
1475
  * Creates a promise that will be resolved at a set time in the future.
1476
1476
  * @param {number} ms The amount of time, in milliseconds, to wait before
1477
1477
  * resolving the promise.
1478
- * @return {!promise.Promise} The promise.
1478
+ * @return {!ManagedPromise} The promise.
1479
1479
  */
1480
- promise.delayed = function(ms) {
1480
+ function delayed(ms) {
1481
1481
  var key;
1482
- return new promise.Promise(function(fulfill) {
1482
+ return new ManagedPromise(function(fulfill) {
1483
1483
  key = setTimeout(function() {
1484
1484
  key = null;
1485
1485
  fulfill();
1486
1486
  }, ms);
1487
- }).thenCatch(function(e) {
1487
+ }).catch(function(e) {
1488
1488
  clearTimeout(key);
1489
1489
  key = null;
1490
1490
  throw e;
1491
1491
  });
1492
- };
1492
+ }
1493
1493
 
1494
1494
 
1495
1495
  /**
1496
1496
  * Creates a new deferred object.
1497
- * @return {!promise.Deferred<T>} The new deferred object.
1497
+ * @return {!Deferred<T>} The new deferred object.
1498
1498
  * @template T
1499
1499
  */
1500
- promise.defer = function() {
1501
- return new promise.Deferred();
1502
- };
1500
+ function defer() {
1501
+ return new Deferred();
1502
+ }
1503
1503
 
1504
1504
 
1505
1505
  /**
1506
1506
  * Creates a promise that has been resolved with the given value.
1507
1507
  * @param {T=} opt_value The resolved value.
1508
- * @return {!promise.Promise<T>} The resolved promise.
1508
+ * @return {!ManagedPromise<T>} The resolved promise.
1509
1509
  * @template T
1510
1510
  */
1511
- promise.fulfilled = function(opt_value) {
1512
- if (opt_value instanceof promise.Promise) {
1511
+ function fulfilled(opt_value) {
1512
+ if (opt_value instanceof ManagedPromise) {
1513
1513
  return opt_value;
1514
1514
  }
1515
- return new promise.Promise(function(fulfill) {
1515
+ return new ManagedPromise(function(fulfill) {
1516
1516
  fulfill(opt_value);
1517
1517
  });
1518
- };
1518
+ }
1519
1519
 
1520
1520
 
1521
1521
  /**
1522
1522
  * Creates a promise that has been rejected with the given reason.
1523
1523
  * @param {*=} opt_reason The rejection reason; may be any value, but is
1524
1524
  * usually an Error or a string.
1525
- * @return {!promise.Promise<T>} The rejected promise.
1525
+ * @return {!ManagedPromise<T>} The rejected promise.
1526
1526
  * @template T
1527
1527
  */
1528
- promise.rejected = function(opt_reason) {
1529
- if (opt_reason instanceof promise.Promise) {
1528
+ function rejected(opt_reason) {
1529
+ if (opt_reason instanceof ManagedPromise) {
1530
1530
  return opt_reason;
1531
1531
  }
1532
- return new promise.Promise(function(_, reject) {
1532
+ return new ManagedPromise(function(_, reject) {
1533
1533
  reject(opt_reason);
1534
1534
  });
1535
- };
1535
+ }
1536
1536
 
1537
1537
 
1538
1538
  /**
1539
1539
  * Wraps a function that expects a node-style callback as its final
1540
1540
  * argument. This callback expects two arguments: an error value (which will be
1541
1541
  * null if the call succeeded), and the success value as the second argument.
1542
- * The callback will the resolve or reject the returned promise, based on its arguments.
1542
+ * The callback will the resolve or reject the returned promise, based on its
1543
+ * arguments.
1543
1544
  * @param {!Function} fn The function to wrap.
1544
1545
  * @param {...?} var_args The arguments to apply to the function, excluding the
1545
1546
  * final callback.
1546
- * @return {!promise.Promise} A promise that will be resolved with the
1547
+ * @return {!ManagedPromise} A promise that will be resolved with the
1547
1548
  * result of the provided function's callback.
1548
1549
  */
1549
- promise.checkedNodeCall = function(fn, var_args) {
1550
- var args = Arrays.slice(arguments, 1);
1551
- return new promise.Promise(function(fulfill, reject) {
1550
+ function checkedNodeCall(fn, var_args) {
1551
+ let args = Array.prototype.slice.call(arguments, 1);
1552
+ return new ManagedPromise(function(fulfill, reject) {
1552
1553
  try {
1553
1554
  args.push(function(error, value) {
1554
1555
  error ? reject(error) : fulfill(value);
@@ -1558,7 +1559,7 @@ promise.checkedNodeCall = function(fn, var_args) {
1558
1559
  reject(ex);
1559
1560
  }
1560
1561
  });
1561
- };
1562
+ }
1562
1563
 
1563
1564
 
1564
1565
  /**
@@ -1570,43 +1571,37 @@ promise.checkedNodeCall = function(fn, var_args) {
1570
1571
  * resolved successfully.
1571
1572
  * @param {Function=} opt_errback The function to call when the value is
1572
1573
  * rejected.
1573
- * @return {!promise.Promise} A new promise.
1574
+ * @return {!ManagedPromise} A new promise.
1574
1575
  */
1575
- promise.when = function(value, opt_callback, opt_errback) {
1576
- if (promise.Thenable.isImplementation(value)) {
1576
+ function when(value, opt_callback, opt_errback) {
1577
+ if (Thenable.isImplementation(value)) {
1577
1578
  return value.then(opt_callback, opt_errback);
1578
1579
  }
1579
1580
 
1580
- return new promise.Promise(function(fulfill, reject) {
1581
- promise.asap(value, fulfill, reject);
1581
+ return new ManagedPromise(function(fulfill) {
1582
+ fulfill(value);
1582
1583
  }).then(opt_callback, opt_errback);
1583
- };
1584
+ }
1584
1585
 
1585
1586
 
1586
1587
  /**
1587
- * Invokes the appropriate callback function as soon as a promised
1588
- * {@code value} is resolved. This function is similar to
1589
- * {@link webdriver.promise.when}, except it does not return a new promise.
1588
+ * Invokes the appropriate callback function as soon as a promised `value` is
1589
+ * resolved. This function is similar to `when()`, except it does not return
1590
+ * a new promise.
1590
1591
  * @param {*} value The value to observe.
1591
1592
  * @param {Function} callback The function to call when the value is
1592
1593
  * resolved successfully.
1593
1594
  * @param {Function=} opt_errback The function to call when the value is
1594
1595
  * rejected.
1595
1596
  */
1596
- promise.asap = function(value, callback, opt_errback) {
1597
- if (promise.isPromise(value)) {
1597
+ function asap(value, callback, opt_errback) {
1598
+ if (isPromise(value)) {
1598
1599
  value.then(callback, opt_errback);
1599
1600
 
1600
- // Maybe a Dojo-like deferred object?
1601
- } else if (!!value && goog.isObject(value) &&
1602
- goog.isFunction(value.addCallbacks)) {
1603
- value.addCallbacks(callback, opt_errback);
1604
-
1605
- // A raw value, return a resolved promise.
1606
1601
  } else if (callback) {
1607
1602
  callback(value);
1608
1603
  }
1609
- };
1604
+ }
1610
1605
 
1611
1606
 
1612
1607
  /**
@@ -1615,16 +1610,16 @@ promise.asap = function(value, callback, opt_errback) {
1615
1610
  * input array's promises are rejected, the returned promise will be rejected
1616
1611
  * with the same reason.
1617
1612
  *
1618
- * @param {!Array<(T|!promise.Promise<T>)>} arr An array of
1613
+ * @param {!Array<(T|!ManagedPromise<T>)>} arr An array of
1619
1614
  * promises to wait on.
1620
- * @return {!promise.Promise<!Array<T>>} A promise that is
1615
+ * @return {!ManagedPromise<!Array<T>>} A promise that is
1621
1616
  * fulfilled with an array containing the fulfilled values of the
1622
1617
  * input array, or rejected with the same reason as the first
1623
1618
  * rejected value.
1624
1619
  * @template T
1625
1620
  */
1626
- promise.all = function(arr) {
1627
- return new promise.Promise(function(fulfill, reject) {
1621
+ function all(arr) {
1622
+ return new ManagedPromise(function(fulfill, reject) {
1628
1623
  var n = arr.length;
1629
1624
  var values = [];
1630
1625
 
@@ -1642,11 +1637,17 @@ promise.all = function(arr) {
1642
1637
  }
1643
1638
  };
1644
1639
 
1640
+ function processPromise(index) {
1641
+ asap(arr[index], function(value) {
1642
+ onFulfilled(index, value);
1643
+ }, reject);
1644
+ }
1645
+
1645
1646
  for (var i = 0; i < n; ++i) {
1646
- promise.asap(arr[i], goog.partial(onFulfilled, i), reject);
1647
+ processPromise(i);
1647
1648
  }
1648
1649
  });
1649
- };
1650
+ }
1650
1651
 
1651
1652
 
1652
1653
  /**
@@ -1662,7 +1663,7 @@ promise.all = function(arr) {
1662
1663
  * Only the first failure will be reported; all subsequent errors will be
1663
1664
  * silently ignored.
1664
1665
  *
1665
- * @param {!(Array<TYPE>|promise.Promise<!Array<TYPE>>)} arr The
1666
+ * @param {!(Array<TYPE>|ManagedPromise<!Array<TYPE>>)} arr The
1666
1667
  * array to iterator over, or a promise that will resolve to said array.
1667
1668
  * @param {function(this: SELF, TYPE, number, !Array<TYPE>): ?} fn The
1668
1669
  * function to call for each element in the array. This function should
@@ -1671,11 +1672,13 @@ promise.all = function(arr) {
1671
1672
  * {@code fn}.
1672
1673
  * @template TYPE, SELF
1673
1674
  */
1674
- promise.map = function(arr, fn, opt_self) {
1675
- return promise.fulfilled(arr).then(function(v) {
1676
- goog.asserts.assertNumber(v.length, 'not an array like value');
1675
+ function map(arr, fn, opt_self) {
1676
+ return fulfilled(arr).then(function(v) {
1677
+ if (!Array.isArray(v)) {
1678
+ throw TypeError('not an array');
1679
+ }
1677
1680
  var arr = /** @type {!Array} */(v);
1678
- return new promise.Promise(function(fulfill, reject) {
1681
+ return new ManagedPromise(function(fulfill, reject) {
1679
1682
  var n = arr.length;
1680
1683
  var values = new Array(n);
1681
1684
  (function processNext(i) {
@@ -1689,7 +1692,7 @@ promise.map = function(arr, fn, opt_self) {
1689
1692
  return;
1690
1693
  }
1691
1694
  try {
1692
- promise.asap(
1695
+ asap(
1693
1696
  fn.call(opt_self, arr[i], i, /** @type {!Array} */(arr)),
1694
1697
  function(value) {
1695
1698
  values[i] = value;
@@ -1702,7 +1705,7 @@ promise.map = function(arr, fn, opt_self) {
1702
1705
  })(0);
1703
1706
  });
1704
1707
  });
1705
- };
1708
+ }
1706
1709
 
1707
1710
 
1708
1711
  /**
@@ -1718,20 +1721,22 @@ promise.map = function(arr, fn, opt_self) {
1718
1721
  * first failure will be reported; all subsequent errors will be silently
1719
1722
  * ignored.
1720
1723
  *
1721
- * @param {!(Array<TYPE>|promise.Promise<!Array<TYPE>>)} arr The
1724
+ * @param {!(Array<TYPE>|ManagedPromise<!Array<TYPE>>)} arr The
1722
1725
  * array to iterator over, or a promise that will resolve to said array.
1723
1726
  * @param {function(this: SELF, TYPE, number, !Array<TYPE>): (
1724
- * boolean|promise.Promise<boolean>)} fn The function
1727
+ * boolean|ManagedPromise<boolean>)} fn The function
1725
1728
  * to call for each element in the array.
1726
1729
  * @param {SELF=} opt_self The object to be used as the value of 'this' within
1727
1730
  * {@code fn}.
1728
1731
  * @template TYPE, SELF
1729
1732
  */
1730
- promise.filter = function(arr, fn, opt_self) {
1731
- return promise.fulfilled(arr).then(function(v) {
1732
- goog.asserts.assertNumber(v.length, 'not an array like value');
1733
+ function filter(arr, fn, opt_self) {
1734
+ return fulfilled(arr).then(function(v) {
1735
+ if (!Array.isArray(v)) {
1736
+ throw TypeError('not an array');
1737
+ }
1733
1738
  var arr = /** @type {!Array} */(v);
1734
- return new promise.Promise(function(fulfill, reject) {
1739
+ return new ManagedPromise(function(fulfill, reject) {
1735
1740
  var n = arr.length;
1736
1741
  var values = [];
1737
1742
  var valuesLength = 0;
@@ -1748,7 +1753,7 @@ promise.filter = function(arr, fn, opt_self) {
1748
1753
  try {
1749
1754
  var value = arr[i];
1750
1755
  var include = fn.call(opt_self, value, i, /** @type {!Array} */(arr));
1751
- promise.asap(include, function(include) {
1756
+ asap(include, function(include) {
1752
1757
  if (include) {
1753
1758
  values[valuesLength++] = value;
1754
1759
  }
@@ -1760,7 +1765,7 @@ promise.filter = function(arr, fn, opt_self) {
1760
1765
  })(0);
1761
1766
  });
1762
1767
  });
1763
- };
1768
+ }
1764
1769
 
1765
1770
 
1766
1771
  /**
@@ -1779,90 +1784,91 @@ promise.filter = function(arr, fn, opt_self) {
1779
1784
  * promise.fullyResolved(value); // Stack overflow.
1780
1785
  *
1781
1786
  * @param {*} value The value to fully resolve.
1782
- * @return {!promise.Promise} A promise for a fully resolved version
1787
+ * @return {!ManagedPromise} A promise for a fully resolved version
1783
1788
  * of the input value.
1784
1789
  */
1785
- promise.fullyResolved = function(value) {
1786
- if (promise.isPromise(value)) {
1787
- return promise.when(value, fullyResolveValue);
1790
+ function fullyResolved(value) {
1791
+ if (isPromise(value)) {
1792
+ return when(value, fullyResolveValue);
1788
1793
  }
1789
1794
  return fullyResolveValue(value);
1790
- };
1795
+ }
1791
1796
 
1792
1797
 
1793
1798
  /**
1794
1799
  * @param {*} value The value to fully resolve. If a promise, assumed to
1795
1800
  * already be resolved.
1796
- * @return {!promise.Promise} A promise for a fully resolved version
1801
+ * @return {!ManagedPromise} A promise for a fully resolved version
1797
1802
  * of the input value.
1798
1803
  */
1799
- function fullyResolveValue(value) {
1800
- switch (goog.typeOf(value)) {
1801
- case 'array':
1802
- return fullyResolveKeys(/** @type {!Array} */ (value));
1803
-
1804
- case 'object':
1805
- if (promise.isPromise(value)) {
1806
- // We get here when the original input value is a promise that
1807
- // resolves to itself. When the user provides us with such a promise,
1808
- // trust that it counts as a "fully resolved" value and return it.
1809
- // Of course, since it's already a promise, we can just return it
1810
- // to the user instead of wrapping it in another promise.
1811
- return /** @type {!promise.Promise} */ (value);
1812
- }
1804
+ function fullyResolveValue(value) {
1805
+ if (Array.isArray(value)) {
1806
+ return fullyResolveKeys(/** @type {!Array} */ (value));
1807
+ }
1813
1808
 
1814
- if (goog.isNumber(value.nodeType) &&
1815
- goog.isObject(value.ownerDocument) &&
1816
- goog.isNumber(value.ownerDocument.nodeType)) {
1817
- // DOM node; return early to avoid infinite recursion. Should we
1818
- // only support objects with a certain level of nesting?
1819
- return promise.fulfilled(value);
1820
- }
1809
+ if (isPromise(value)) {
1810
+ if (isPromise(value)) {
1811
+ // We get here when the original input value is a promise that
1812
+ // resolves to itself. When the user provides us with such a promise,
1813
+ // trust that it counts as a "fully resolved" value and return it.
1814
+ // Of course, since it's already a promise, we can just return it
1815
+ // to the user instead of wrapping it in another promise.
1816
+ return /** @type {!ManagedPromise} */ (value);
1817
+ }
1818
+ }
1821
1819
 
1822
- return fullyResolveKeys(/** @type {!Object} */ (value));
1820
+ if (value && typeof value === 'object') {
1821
+ return fullyResolveKeys(/** @type {!Object} */ (value));
1822
+ }
1823
1823
 
1824
- default: // boolean, function, null, number, string, undefined
1825
- return promise.fulfilled(value);
1824
+ if (typeof value === 'function') {
1825
+ return fullyResolveKeys(/** @type {!Object} */ (value));
1826
1826
  }
1827
+
1828
+ return fulfilled(value);
1827
1829
  }
1828
1830
 
1829
1831
 
1830
1832
  /**
1831
1833
  * @param {!(Array|Object)} obj the object to resolve.
1832
- * @return {!promise.Promise} A promise that will be resolved with the
1834
+ * @return {!ManagedPromise} A promise that will be resolved with the
1833
1835
  * input object once all of its values have been fully resolved.
1834
1836
  */
1835
- function fullyResolveKeys(obj) {
1836
- var isArray = goog.isArray(obj);
1837
- var numKeys = isArray ? obj.length : Objects.getCount(obj);
1837
+ function fullyResolveKeys(obj) {
1838
+ var isArray = Array.isArray(obj);
1839
+ var numKeys = isArray ? obj.length : (function() {
1840
+ let n = 0;
1841
+ for (let key in obj) {
1842
+ n += 1;
1843
+ }
1844
+ return n;
1845
+ })();
1838
1846
  if (!numKeys) {
1839
- return promise.fulfilled(obj);
1847
+ return fulfilled(obj);
1848
+ }
1849
+
1850
+ function forEachProperty(obj, fn) {
1851
+ for (let key in obj) {
1852
+ fn.call(null, obj[key], key, obj);
1853
+ }
1854
+ }
1855
+
1856
+ function forEachElement(arr, fn) {
1857
+ arr.forEach(fn);
1840
1858
  }
1841
1859
 
1842
1860
  var numResolved = 0;
1843
- return new promise.Promise(function(fulfill, reject) {
1844
- // In pre-IE9, goog.array.forEach will not iterate properly over arrays
1845
- // containing undefined values because "index in array" returns false
1846
- // when array[index] === undefined (even for x = [undefined, 1]). To get
1847
- // around this, we need to use our own forEach implementation.
1848
- // DO NOT REMOVE THIS UNTIL WE NO LONGER SUPPORT IE8. This cannot be
1849
- // reproduced in IE9 by changing the browser/document modes, it requires an
1850
- // actual pre-IE9 browser. Yay, IE!
1851
- var forEachKey = !isArray ? Objects.forEach : function(arr, fn) {
1852
- var n = arr.length;
1853
- for (var i = 0; i < n; ++i) {
1854
- fn.call(null, arr[i], i, arr);
1855
- }
1856
- };
1861
+ return new ManagedPromise(function(fulfill, reject) {
1862
+ var forEachKey = isArray ? forEachElement: forEachProperty;
1857
1863
 
1858
1864
  forEachKey(obj, function(partialValue, key) {
1859
- var type = goog.typeOf(partialValue);
1860
- if (type != 'array' && type != 'object') {
1865
+ if (!Array.isArray(partialValue)
1866
+ && (!partialValue || typeof partialValue !== 'object')) {
1861
1867
  maybeResolveValue();
1862
1868
  return;
1863
1869
  }
1864
1870
 
1865
- promise.fullyResolved(partialValue).then(
1871
+ fullyResolved(partialValue).then(
1866
1872
  function(resolvedValue) {
1867
1873
  obj[key] = resolvedValue;
1868
1874
  maybeResolveValue();
@@ -1881,7 +1887,7 @@ promise.fullyResolved = function(value) {
1881
1887
 
1882
1888
  //////////////////////////////////////////////////////////////////////////////
1883
1889
  //
1884
- // promise.ControlFlow
1890
+ // ControlFlow
1885
1891
  //
1886
1892
  //////////////////////////////////////////////////////////////////////////////
1887
1893
 
@@ -1893,37 +1899,33 @@ promise.fullyResolved = function(value) {
1893
1899
  * the ordered scheduled, starting each task only once those before it have
1894
1900
  * completed.
1895
1901
  *
1896
- * Each task scheduled within this flow may return a
1897
- * {@link webdriver.promise.Promise} to indicate it is an asynchronous
1898
- * operation. The ControlFlow will wait for such promises to be resolved before
1899
- * marking the task as completed.
1902
+ * Each task scheduled within this flow may return a {@link ManagedPromise} to
1903
+ * indicate it is an asynchronous operation. The ControlFlow will wait for such
1904
+ * promises to be resolved before marking the task as completed.
1900
1905
  *
1901
- * Tasks and each callback registered on a {@link webdriver.promise.Promise}
1902
- * will be run in their own ControlFlow frame. Any tasks scheduled within a
1903
- * frame will take priority over previously scheduled tasks. Furthermore, if any
1904
- * of the tasks in the frame fail, the remainder of the tasks in that frame will
1905
- * be discarded and the failure will be propagated to the user through the
1906
- * callback/task's promised result.
1906
+ * Tasks and each callback registered on a {@link ManagedPromise} will be run
1907
+ * in their own ControlFlow frame. Any tasks scheduled within a frame will take
1908
+ * priority over previously scheduled tasks. Furthermore, if any of the tasks in
1909
+ * the frame fail, the remainder of the tasks in that frame will be discarded
1910
+ * and the failure will be propagated to the user through the callback/task's
1911
+ * promised result.
1907
1912
  *
1908
1913
  * Each time a ControlFlow empties its task queue, it will fire an
1909
- * {@link webdriver.promise.ControlFlow.EventType.IDLE IDLE} event. Conversely,
1914
+ * {@link ControlFlow.EventType.IDLE IDLE} event. Conversely,
1910
1915
  * whenever the flow terminates due to an unhandled error, it will remove all
1911
1916
  * remaining tasks in its queue and fire an
1912
- * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION
1913
- * UNCAUGHT_EXCEPTION} event. If there are no listeners registered with the
1914
- * flow, the error will be rethrown to the global error handler.
1917
+ * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION UNCAUGHT_EXCEPTION} event.
1918
+ * If there are no listeners registered with the flow, the error will be
1919
+ * rethrown to the global error handler.
1915
1920
  *
1916
- * Refer to the {@link webdriver.promise} module documentation for a detailed
1921
+ * Refer to the {@link ./promise} module documentation fora detailed
1917
1922
  * explanation of how the ControlFlow coordinates task execution.
1918
1923
  *
1919
1924
  * @final
1920
1925
  */
1921
- promise.ControlFlow = goog.defineClass(EventEmitter, {
1922
- // TODO: remove this empty comment when the compiler properly handles
1923
- // goog.defineClass with a missing constructor comment.
1924
- /** @constructor */
1925
- constructor: function() {
1926
- promise.ControlFlow.base(this, 'constructor');
1926
+ class ControlFlow extends events.EventEmitter {
1927
+ constructor() {
1928
+ super();
1927
1929
 
1928
1930
  /** @private {boolean} */
1929
1931
  this.propagateUnhandledRejections_ = true;
@@ -1937,7 +1939,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
1937
1939
  /**
1938
1940
  * Micro task that controls shutting down the control flow. Upon shut down,
1939
1941
  * the flow will emit an
1940
- * {@link webdriver.promise.ControlFlow.EventType.IDLE} event. Idle events
1942
+ * {@link ControlFlow.EventType.IDLE} event. Idle events
1941
1943
  * always follow a brief timeout in order to catch latent errors from the
1942
1944
  * last completed task. If this task had a callback registered, but no
1943
1945
  * errback, and the task fails, the unhandled failure would not be reported
@@ -1948,7 +1950,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
1948
1950
  * function() { return promise.rejected('failed'); });
1949
1951
  * // Set a callback on the result. This delays reporting the unhandled
1950
1952
  * // failure for 1 turn of the event loop.
1951
- * result.then(goog.nullFunction);
1953
+ * result.then(function() {});
1952
1954
  *
1953
1955
  * @private {MicroTask}
1954
1956
  */
@@ -1961,28 +1963,27 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
1961
1963
  * _actually_ something to run. When a control flow is waiting on a task,
1962
1964
  * there will be nothing in the JS event loop and the process would
1963
1965
  * terminate without this.
1964
- *
1965
- * @private {?number}
1966
+ * @private
1966
1967
  */
1967
1968
  this.hold_ = null;
1968
- },
1969
+ }
1969
1970
 
1970
1971
  /**
1971
1972
  * Returns a string representation of this control flow, which is its current
1972
- * {@link #getSchedule() schedule}, sans task stack traces.
1973
+ * {@linkplain #getSchedule() schedule}, sans task stack traces.
1973
1974
  * @return {string} The string representation of this contorl flow.
1974
1975
  * @override
1975
1976
  */
1976
- toString: function() {
1977
+ toString() {
1977
1978
  return this.getSchedule();
1978
- },
1979
+ }
1979
1980
 
1980
1981
  /**
1981
1982
  * Sets whether any unhandled rejections should propagate up through the
1982
1983
  * control flow stack and cause rejections within parent tasks. If error
1983
1984
  * propagation is disabled, tasks will not be aborted when an unhandled
1984
1985
  * promise rejection is detected, but the rejection _will_ trigger an
1985
- * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION}
1986
+ * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION}
1986
1987
  * event.
1987
1988
  *
1988
1989
  * The default behavior is to propagate all unhandled rejections. _The use
@@ -1990,26 +1991,26 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
1990
1991
  *
1991
1992
  * @param {boolean} propagate whether to propagate errors.
1992
1993
  */
1993
- setPropagateUnhandledRejections: function(propagate) {
1994
+ setPropagateUnhandledRejections(propagate) {
1994
1995
  this.propagateUnhandledRejections_ = propagate;
1995
- },
1996
+ }
1996
1997
 
1997
1998
  /**
1998
1999
  * @return {boolean} Whether this flow is currently idle.
1999
2000
  */
2000
- isIdle: function() {
2001
+ isIdle() {
2001
2002
  return !this.shutdownTask_ && (!this.taskQueues_ || !this.taskQueues_.size);
2002
- },
2003
+ }
2003
2004
 
2004
2005
  /**
2005
2006
  * Resets this instance, clearing its queue and removing all event listeners.
2006
2007
  */
2007
- reset: function() {
2008
+ reset() {
2008
2009
  this.cancelQueues_(new FlowResetError);
2009
- this.emit(promise.ControlFlow.EventType.RESET);
2010
+ this.emit(ControlFlow.EventType.RESET);
2010
2011
  this.removeAllListeners();
2011
2012
  this.cancelShutdown_();
2012
- },
2013
+ }
2013
2014
 
2014
2015
  /**
2015
2016
  * Generates an annotated string describing the internal state of this control
@@ -2020,8 +2021,8 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2020
2021
  * from when each task was scheduled. Defaults to false.
2021
2022
  * @return {string} String representation of this flow's internal state.
2022
2023
  */
2023
- getSchedule: function(opt_includeStackTraces) {
2024
- var ret = 'ControlFlow::' + goog.getUid(this);
2024
+ getSchedule(opt_includeStackTraces) {
2025
+ var ret = 'ControlFlow::' + getUid(this);
2025
2026
  var activeQueue = this.activeQueue_;
2026
2027
  if (!this.taskQueues_ || !this.taskQueues_.size) {
2027
2028
  return ret;
@@ -2066,7 +2067,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2066
2067
  }
2067
2068
  return ret;
2068
2069
  }
2069
- },
2070
+ }
2070
2071
 
2071
2072
  /**
2072
2073
  * Returns the currently actively task queue for this flow. If there is no
@@ -2074,7 +2075,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2074
2075
  * @return {!TaskQueue} the currently active task queue for this flow.
2075
2076
  * @private
2076
2077
  */
2077
- getActiveQueue_: function() {
2078
+ getActiveQueue_() {
2078
2079
  if (this.activeQueue_) {
2079
2080
  return this.activeQueue_;
2080
2081
  }
@@ -2088,45 +2089,46 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2088
2089
  .once('end', this.onQueueEnd_, this)
2089
2090
  .once('error', this.onQueueError_, this);
2090
2091
 
2091
- asyncRun(() => this.activeQueue_ = null, this);
2092
+ asyncRun(() => this.activeQueue_ = null);
2092
2093
  this.activeQueue_.start();
2093
2094
  return this.activeQueue_;
2094
- },
2095
+ }
2095
2096
 
2096
2097
  /**
2097
2098
  * Schedules a task for execution. If there is nothing currently in the
2098
2099
  * queue, the task will be executed in the next turn of the event loop. If
2099
2100
  * the task function is a generator, the task will be executed using
2100
- * {@link webdriver.promise.consume}.
2101
+ * {@link ./promise.consume consume()}.
2101
2102
  *
2102
- * @param {function(): (T|promise.Promise<T>)} fn The function to
2103
+ * @param {function(): (T|ManagedPromise<T>)} fn The function to
2103
2104
  * call to start the task. If the function returns a
2104
- * {@link webdriver.promise.Promise}, this instance will wait for it to be
2105
+ * {@link ManagedPromise}, this instance will wait for it to be
2105
2106
  * resolved before starting the next task.
2106
2107
  * @param {string=} opt_description A description of the task.
2107
- * @return {!promise.Promise<T>} A promise that will be resolved
2108
+ * @return {!ManagedPromise<T>} A promise that will be resolved
2108
2109
  * with the result of the action.
2109
2110
  * @template T
2110
2111
  */
2111
- execute: function(fn, opt_description) {
2112
- if (promise.isGenerator(fn)) {
2113
- fn = goog.partial(promise.consume, fn);
2112
+ execute(fn, opt_description) {
2113
+ if (isGenerator(fn)) {
2114
+ let original = fn;
2115
+ fn = () => consume(original);
2114
2116
  }
2115
2117
 
2116
2118
  if (!this.hold_) {
2117
2119
  var holdIntervalMs = 2147483647; // 2^31-1; max timer length for Node.js
2118
- this.hold_ = setInterval(goog.nullFunction, holdIntervalMs);
2120
+ this.hold_ = setInterval(function() {}, holdIntervalMs);
2119
2121
  }
2120
2122
 
2121
2123
  var task = new Task(
2122
2124
  this, fn, opt_description || '<anonymous>',
2123
- {name: 'Task', top: promise.ControlFlow.prototype.execute});
2125
+ {name: 'Task', top: ControlFlow.prototype.execute});
2124
2126
 
2125
2127
  var q = this.getActiveQueue_();
2126
2128
  q.enqueue(task);
2127
- this.emit(promise.ControlFlow.EventType.SCHEDULE_TASK, task.description);
2129
+ this.emit(ControlFlow.EventType.SCHEDULE_TASK, task.description);
2128
2130
  return task.promise;
2129
- },
2131
+ }
2130
2132
 
2131
2133
  /**
2132
2134
  * Inserts a {@code setTimeout} into the command queue. This is equivalent to
@@ -2134,14 +2136,14 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2134
2136
  *
2135
2137
  * @param {number} ms The timeout delay, in milliseconds.
2136
2138
  * @param {string=} opt_description A description to accompany the timeout.
2137
- * @return {!promise.Promise} A promise that will be resolved with
2139
+ * @return {!ManagedPromise} A promise that will be resolved with
2138
2140
  * the result of the action.
2139
2141
  */
2140
- timeout: function(ms, opt_description) {
2142
+ timeout(ms, opt_description) {
2141
2143
  return this.execute(function() {
2142
- return promise.delayed(ms);
2144
+ return delayed(ms);
2143
2145
  }, opt_description);
2144
- },
2146
+ }
2145
2147
 
2146
2148
  /**
2147
2149
  * Schedules a task that shall wait for a condition to hold. Each condition
@@ -2151,7 +2153,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2151
2153
  * Condition functions may schedule sub-tasks with this instance, however,
2152
2154
  * their execution time will be factored into whether a wait has timed out.
2153
2155
  *
2154
- * In the event a condition returns a Promise, the polling loop will wait for
2156
+ * In the event a condition returns a ManagedPromise, the polling loop will wait for
2155
2157
  * it to be resolved before evaluating whether the condition has been
2156
2158
  * satisfied. The resolution time for a promise is factored into whether a
2157
2159
  * wait has timed out.
@@ -2166,38 +2168,38 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2166
2168
  * If this function is invoked with `timeout === 0`, or the timeout is
2167
2169
  * omitted, the flow will wait indefinitely for the condition to be satisfied.
2168
2170
  *
2169
- * @param {(!promise.Promise<T>|function())} condition The condition to poll,
2171
+ * @param {(!ManagedPromise<T>|function())} condition The condition to poll,
2170
2172
  * or a promise to wait on.
2171
2173
  * @param {number=} opt_timeout How long to wait, in milliseconds, for the
2172
2174
  * condition to hold before timing out. If omitted, the flow will wait
2173
2175
  * indefinitely.
2174
2176
  * @param {string=} opt_message An optional error message to include if the
2175
2177
  * wait times out; defaults to the empty string.
2176
- * @return {!promise.Promise<T>} A promise that will be fulfilled
2178
+ * @return {!ManagedPromise<T>} A promise that will be fulfilled
2177
2179
  * when the condition has been satisified. The promise shall be rejected
2178
2180
  * if the wait times out waiting for the condition.
2179
2181
  * @throws {TypeError} If condition is not a function or promise or if timeout
2180
2182
  * is not a number >= 0.
2181
2183
  * @template T
2182
2184
  */
2183
- wait: function(condition, opt_timeout, opt_message) {
2185
+ wait(condition, opt_timeout, opt_message) {
2184
2186
  var timeout = opt_timeout || 0;
2185
- if (!goog.isNumber(timeout) || timeout < 0) {
2187
+ if (typeof timeout !== 'number' || timeout < 0) {
2186
2188
  throw TypeError('timeout must be a number >= 0: ' + timeout);
2187
2189
  }
2188
2190
 
2189
- if (promise.isPromise(condition)) {
2191
+ if (isPromise(condition)) {
2190
2192
  return this.execute(function() {
2191
2193
  if (!timeout) {
2192
2194
  return condition;
2193
2195
  }
2194
- return new promise.Promise(function(fulfill, reject) {
2195
- var start = goog.now();
2196
+ return new ManagedPromise(function(fulfill, reject) {
2197
+ var start = Date.now();
2196
2198
  var timer = setTimeout(function() {
2197
2199
  timer = null;
2198
2200
  reject(Error((opt_message ? opt_message + '\n' : '') +
2199
2201
  'Timed out waiting for promise to resolve after ' +
2200
- (goog.now() - start) + 'ms'));
2202
+ (Date.now() - start) + 'ms'));
2201
2203
  }, timeout);
2202
2204
 
2203
2205
  /** @type {Thenable} */(condition).then(
@@ -2213,25 +2215,26 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2213
2215
  }, opt_message || '<anonymous wait: promise resolution>');
2214
2216
  }
2215
2217
 
2216
- if (!goog.isFunction(condition)) {
2218
+ if (typeof condition !== 'function') {
2217
2219
  throw TypeError('Invalid condition; must be a function or promise: ' +
2218
- goog.typeOf(condition));
2220
+ typeof condition);
2219
2221
  }
2220
2222
 
2221
- if (promise.isGenerator(condition)) {
2222
- condition = goog.partial(promise.consume, condition);
2223
+ if (isGenerator(condition)) {
2224
+ let original = condition;
2225
+ condition = () => consume(original);
2223
2226
  }
2224
2227
 
2225
2228
  var self = this;
2226
2229
  return this.execute(function() {
2227
- var startTime = goog.now();
2228
- return new promise.Promise(function(fulfill, reject) {
2230
+ var startTime = Date.now();
2231
+ return new ManagedPromise(function(fulfill, reject) {
2229
2232
  pollCondition();
2230
2233
 
2231
2234
  function pollCondition() {
2232
2235
  var conditionFn = /** @type {function()} */(condition);
2233
2236
  self.execute(conditionFn).then(function(value) {
2234
- var elapsed = goog.now() - startTime;
2237
+ var elapsed = Date.now() - startTime;
2235
2238
  if (!!value) {
2236
2239
  fulfill(value);
2237
2240
  } else if (timeout && elapsed >= timeout) {
@@ -2247,7 +2250,7 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2247
2250
  }
2248
2251
  });
2249
2252
  }, opt_message || '<anonymous wait>');
2250
- },
2253
+ }
2251
2254
 
2252
2255
  /**
2253
2256
  * Executes a function in the next available turn of the JavaScript event
@@ -2285,36 +2288,36 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2285
2288
  * @param {Object=} opt_self The object in whose context to run the function.
2286
2289
  * @param {...*} var_args Any arguments to pass to the function.
2287
2290
  */
2288
- async: function(fn, opt_self, var_args) {
2289
- asyncRun(function() {
2291
+ async(fn, opt_self, var_args) {
2292
+ asyncRun(() => {
2290
2293
  // Clear any lingering queues, forces getActiveQueue_ to create a new one.
2291
2294
  this.activeQueue_ = null;
2292
2295
  var q = this.getActiveQueue_();
2293
2296
  try {
2294
2297
  q.execute_(fn.bind(opt_self, var_args));
2295
2298
  } catch (ex) {
2296
- var cancellationError = promise.CancellationError.wrap(ex,
2299
+ var cancellationError = CancellationError.wrap(ex,
2297
2300
  'Function passed to ControlFlow.async() threw');
2298
2301
  cancellationError.silent_ = true;
2299
2302
  q.abort_(cancellationError);
2300
2303
  } finally {
2301
2304
  this.activeQueue_ = null;
2302
2305
  }
2303
- }, this);
2304
- },
2306
+ });
2307
+ }
2305
2308
 
2306
2309
  /**
2307
2310
  * Event handler for when a task queue is exhausted. This starts the shutdown
2308
2311
  * sequence for this instance if there are no remaining task queues: after
2309
2312
  * one turn of the event loop, this object will emit the
2310
- * {@link webdriver.promise.ControlFlow.EventType.IDLE IDLE} event to signal
2313
+ * {@link ControlFlow.EventType.IDLE IDLE} event to signal
2311
2314
  * listeners that it has completed. During this wait, if another task is
2312
2315
  * scheduled, the shutdown will be aborted.
2313
2316
  *
2314
2317
  * @param {!TaskQueue} q the completed task queue.
2315
2318
  * @private
2316
2319
  */
2317
- onQueueEnd_: function(q) {
2320
+ onQueueEnd_(q) {
2318
2321
  if (!this.taskQueues_) {
2319
2322
  return;
2320
2323
  }
@@ -2324,15 +2327,18 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2324
2327
  vlog(1, () => this.taskQueues_.size + ' queues remain\n' + this, this);
2325
2328
 
2326
2329
  if (!this.taskQueues_.size) {
2327
- asserts.assert(!this.shutdownTask_, 'Already have a shutdown task??');
2328
- this.shutdownTask_ = new MicroTask(this.shutdown_, this);
2330
+ if (this.shutdownTask_) {
2331
+ throw Error('Already have a shutdown task??');
2332
+ }
2333
+ vlog(1, () => 'Scheduling shutdown\n' + this);
2334
+ this.shutdownTask_ = new MicroTask(() => this.shutdown_());
2329
2335
  }
2330
- },
2336
+ }
2331
2337
 
2332
2338
  /**
2333
2339
  * Event handler for when a task queue terminates with an error. This triggers
2334
2340
  * the cancellation of all other task queues and a
2335
- * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION} event.
2341
+ * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} event.
2336
2342
  * If there are no error event listeners registered with this instance, the
2337
2343
  * error will be rethrown to the global error handler.
2338
2344
  *
@@ -2340,30 +2346,30 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2340
2346
  * @param {!TaskQueue} q the task queue.
2341
2347
  * @private
2342
2348
  */
2343
- onQueueError_: function(error, q) {
2349
+ onQueueError_(error, q) {
2344
2350
  if (this.taskQueues_) {
2345
2351
  this.taskQueues_.delete(q);
2346
2352
  }
2347
- this.cancelQueues_(promise.CancellationError.wrap(
2353
+ this.cancelQueues_(CancellationError.wrap(
2348
2354
  error, 'There was an uncaught error in the control flow'));
2349
2355
  this.cancelShutdown_();
2350
2356
  this.cancelHold_();
2351
2357
 
2352
2358
  var listeners = this.listeners(
2353
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
2354
- if (!listeners.length) {
2355
- throwException(error);
2359
+ ControlFlow.EventType.UNCAUGHT_EXCEPTION);
2360
+ if (!listeners.size) {
2361
+ asyncThrow(/** @type {!Error} */(error));
2356
2362
  } else {
2357
2363
  this.reportUncaughtException_(error);
2358
2364
  }
2359
- },
2365
+ }
2360
2366
 
2361
2367
  /**
2362
2368
  * Cancels all remaining task queues.
2363
- * @param {!promise.CancellationError} reason The cancellation reason.
2369
+ * @param {!CancellationError} reason The cancellation reason.
2364
2370
  * @private
2365
2371
  */
2366
- cancelQueues_: function(reason) {
2372
+ cancelQueues_(reason) {
2367
2373
  reason.silent_ = true;
2368
2374
  if (this.taskQueues_) {
2369
2375
  for (var q of this.taskQueues_) {
@@ -2373,53 +2379,53 @@ promise.ControlFlow = goog.defineClass(EventEmitter, {
2373
2379
  this.taskQueues_.clear();
2374
2380
  this.taskQueues_ = null;
2375
2381
  }
2376
- },
2382
+ }
2377
2383
 
2378
2384
  /**
2379
2385
  * Reports an uncaught exception using a
2380
- * {@link webdriver.promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION} event.
2386
+ * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} event.
2381
2387
  *
2382
2388
  * @param {*} e the error to report.
2383
2389
  * @private
2384
2390
  */
2385
- reportUncaughtException_: function(e) {
2386
- this.emit(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, e);
2387
- },
2391
+ reportUncaughtException_(e) {
2392
+ this.emit(ControlFlow.EventType.UNCAUGHT_EXCEPTION, e);
2393
+ }
2388
2394
 
2389
2395
  /** @private */
2390
- cancelHold_: function() {
2396
+ cancelHold_() {
2391
2397
  if (this.hold_) {
2392
2398
  clearInterval(this.hold_);
2393
2399
  this.hold_ = null;
2394
2400
  }
2395
- },
2401
+ }
2396
2402
 
2397
2403
  /** @private */
2398
- shutdown_: function() {
2404
+ shutdown_() {
2399
2405
  vlog(1, () => 'Going idle: ' + this);
2400
2406
  this.cancelHold_();
2401
2407
  this.shutdownTask_ = null;
2402
- this.emit(promise.ControlFlow.EventType.IDLE);
2403
- },
2408
+ this.emit(ControlFlow.EventType.IDLE);
2409
+ }
2404
2410
 
2405
2411
  /**
2406
2412
  * Cancels the shutdown sequence if it is currently scheduled.
2407
2413
  * @private
2408
2414
  */
2409
- cancelShutdown_: function() {
2415
+ cancelShutdown_() {
2410
2416
  if (this.shutdownTask_) {
2411
2417
  this.shutdownTask_.cancel();
2412
2418
  this.shutdownTask_ = null;
2413
2419
  }
2414
2420
  }
2415
- });
2421
+ }
2416
2422
 
2417
2423
 
2418
2424
  /**
2419
- * Events that may be emitted by an {@link webdriver.promise.ControlFlow}.
2425
+ * Events that may be emitted by an {@link ControlFlow}.
2420
2426
  * @enum {string}
2421
2427
  */
2422
- promise.ControlFlow.EventType = {
2428
+ ControlFlow.EventType = {
2423
2429
 
2424
2430
  /** Emitted when all tasks have been successfully executed. */
2425
2431
  IDLE: 'idle',
@@ -2444,56 +2450,67 @@ promise.ControlFlow.EventType = {
2444
2450
  * Wraps a function to execute as a cancellable micro task.
2445
2451
  * @final
2446
2452
  */
2447
- var MicroTask = goog.defineClass(null, {
2453
+ class MicroTask {
2448
2454
  /**
2449
- * @param {function(this: THIS)} fn The function to run as a micro task.
2450
- * @param {THIS=} opt_scope The scope to run the function in.
2451
- * @template THIS
2455
+ * @param {function()} fn The function to run as a micro task.
2452
2456
  */
2453
- constructor: function(fn, opt_scope) {
2457
+ constructor(fn) {
2454
2458
  /** @private {boolean} */
2455
2459
  this.cancelled_ = false;
2456
- asyncRun(function() {
2460
+ asyncRun(() => {
2457
2461
  if (!this.cancelled_) {
2458
- fn.call(opt_scope);
2462
+ fn();
2459
2463
  }
2460
- }, this);
2461
- },
2464
+ });
2465
+ }
2466
+
2467
+ /**
2468
+ * Runs the given function after a micro-task yield.
2469
+ * @param {function()} fn The function to run.
2470
+ */
2471
+ static run(fn) {
2472
+ NativePromise.resolve().then(function() {
2473
+ try {
2474
+ fn();
2475
+ } catch (ignored) {
2476
+ // Do nothing.
2477
+ }
2478
+ });
2479
+ }
2462
2480
 
2463
2481
  /**
2464
2482
  * Cancels the execution of this task. Note: this will not prevent the task
2465
2483
  * timer from firing, just the invocation of the wrapped function.
2466
2484
  */
2467
- cancel: function() {
2485
+ cancel() {
2468
2486
  this.cancelled_ = true;
2469
2487
  }
2470
- });
2488
+ }
2471
2489
 
2472
2490
 
2473
2491
  /**
2474
- * A task to be executed by a {@link webdriver.promise.ControlFlow}.
2492
+ * A task to be executed by a {@link ControlFlow}.
2475
2493
  *
2494
+ * @template T
2476
2495
  * @final
2477
2496
  */
2478
- var Task = goog.defineClass(promise.Deferred, {
2497
+ class Task extends Deferred {
2479
2498
  /**
2480
- * @param {!promise.ControlFlow} flow The flow this instances belongs
2499
+ * @param {!ControlFlow} flow The flow this instances belongs
2481
2500
  * to.
2482
- * @param {function(): (T|!promise.Promise<T>)} fn The function to
2501
+ * @param {function(): (T|!ManagedPromise<T>)} fn The function to
2483
2502
  * call when the task executes. If it returns a
2484
- * {@link webdriver.promise.Promise}, the flow will wait for it to be
2503
+ * {@link ManagedPromise}, the flow will wait for it to be
2485
2504
  * resolved before starting the next task.
2486
2505
  * @param {string} description A description of the task for debugging.
2487
2506
  * @param {{name: string, top: !Function}=} opt_stackOptions Options to use
2488
2507
  * when capturing the stacktrace for when this task was created.
2489
- * @constructor
2490
- * @extends {promise.Deferred<T>}
2491
- * @template T
2492
2508
  */
2493
- constructor: function(flow, fn, description, opt_stackOptions) {
2494
- Task.base(this, 'constructor', flow);
2509
+ constructor(flow, fn, description, opt_stackOptions) {
2510
+ super(flow);
2511
+ getUid(this);
2495
2512
 
2496
- /** @type {function(): (T|!promise.Promise<T>)} */
2513
+ /** @type {function(): (T|!ManagedPromise<T>)} */
2497
2514
  this.execute = fn;
2498
2515
 
2499
2516
  /** @type {string} */
@@ -2519,20 +2536,20 @@ var Task = goog.defineClass(promise.Deferred, {
2519
2536
  this.blocked = false;
2520
2537
 
2521
2538
  if (opt_stackOptions) {
2522
- this.promise.stack_ = promise.captureStackTrace(
2539
+ this.promise.stack_ = captureStackTrace(
2523
2540
  opt_stackOptions.name, this.description, opt_stackOptions.top);
2524
2541
  }
2525
- },
2542
+ }
2526
2543
 
2527
2544
  /** @override */
2528
- toString: function() {
2529
- return 'Task::' + goog.getUid(this) + '<' + this.description + '>';
2545
+ toString() {
2546
+ return 'Task::' + getUid(this) + '<' + this.description + '>';
2530
2547
  }
2531
- });
2548
+ }
2532
2549
 
2533
2550
 
2534
2551
  /** @enum {string} */
2535
- var TaskQueueState = {
2552
+ const TaskQueueState = {
2536
2553
  NEW: 'new',
2537
2554
  STARTED: 'started',
2538
2555
  FINISHED: 'finished'
@@ -2542,16 +2559,15 @@ var TaskQueueState = {
2542
2559
  /**
2543
2560
  * @final
2544
2561
  */
2545
- var TaskQueue = goog.defineClass(EventEmitter, {
2546
- /** @param {!promise.ControlFlow} flow . */
2547
- constructor: function(flow) {
2548
- TaskQueue.base(this, 'constructor');
2549
- goog.getUid(this);
2562
+ class TaskQueue extends events.EventEmitter {
2563
+ /** @param {!ControlFlow} flow . */
2564
+ constructor(flow) {
2565
+ super();
2550
2566
 
2551
2567
  /** @private {string} */
2552
- this.name_ = 'TaskQueue::' + goog.getUid(this);
2568
+ this.name_ = 'TaskQueue::' + getUid(this);
2553
2569
 
2554
- /** @private {!promise.ControlFlow} */
2570
+ /** @private {!ControlFlow} */
2555
2571
  this.flow_ = flow;
2556
2572
 
2557
2573
  /** @private {!Array<!Task>} */
@@ -2566,41 +2582,41 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2566
2582
  /** @private {TaskQueueState} */
2567
2583
  this.state_ = TaskQueueState.NEW;
2568
2584
 
2569
- /** @private {!Set<!webdriver.promise.Promise>} */
2585
+ /** @private {!Set<!ManagedPromise>} */
2570
2586
  this.unhandledRejections_ = new Set();
2571
- },
2587
+ }
2572
2588
 
2573
2589
  /** @override */
2574
- toString: function() {
2575
- return 'TaskQueue::' + goog.getUid(this);
2576
- },
2590
+ toString() {
2591
+ return 'TaskQueue::' + getUid(this);
2592
+ }
2577
2593
 
2578
2594
  /**
2579
- * @param {!webdriver.promise.Promise} promise .
2595
+ * @param {!ManagedPromise} promise .
2580
2596
  */
2581
- addUnhandledRejection: function(promise) {
2597
+ addUnhandledRejection(promise) {
2582
2598
  // TODO: node 4.0.0+
2583
2599
  vlog(2, () => this + ' registering unhandled rejection: ' + promise, this);
2584
2600
  this.unhandledRejections_.add(promise);
2585
- },
2601
+ }
2586
2602
 
2587
2603
  /**
2588
- * @param {!webdriver.promise.Promise} promise .
2604
+ * @param {!ManagedPromise} promise .
2589
2605
  */
2590
- clearUnhandledRejection: function(promise) {
2606
+ clearUnhandledRejection(promise) {
2591
2607
  var deleted = this.unhandledRejections_.delete(promise);
2592
2608
  if (deleted) {
2593
2609
  // TODO: node 4.0.0+
2594
2610
  vlog(2, () => this + ' clearing unhandled rejection: ' + promise, this);
2595
2611
  }
2596
- },
2612
+ }
2597
2613
 
2598
2614
  /**
2599
2615
  * Enqueues a new task for execution.
2600
2616
  * @param {!Task} task The task to enqueue.
2601
2617
  * @throws {Error} If this instance has already started execution.
2602
2618
  */
2603
- enqueue: function(task) {
2619
+ enqueue(task) {
2604
2620
  if (this.state_ !== TaskQueueState.NEW) {
2605
2621
  throw Error('TaskQueue has started: ' + this);
2606
2622
  }
@@ -2616,16 +2632,16 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2616
2632
 
2617
2633
  vlog(1, () => this + '.enqueue(' + task + ')', this);
2618
2634
  vlog(2, () => this.flow_.toString(), this);
2619
- },
2635
+ }
2620
2636
 
2621
2637
  /**
2622
2638
  * Schedules the callbacks registered on the given promise in this queue.
2623
2639
  *
2624
- * @param {!promise.Promise} promise the promise whose callbacks should be
2640
+ * @param {!ManagedPromise} promise the promise whose callbacks should be
2625
2641
  * registered as interrupts in this task queue.
2626
2642
  * @throws {Error} if this queue has already finished.
2627
2643
  */
2628
- scheduleCallbacks: function(promise) {
2644
+ scheduleCallbacks(promise) {
2629
2645
  if (this.state_ === TaskQueueState.FINISHED) {
2630
2646
  throw new Error('cannot interrupt a finished q(' + this + ')');
2631
2647
  }
@@ -2633,7 +2649,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2633
2649
  if (this.pending_ && this.pending_.task.promise === promise) {
2634
2650
  this.pending_.task.promise.queue_ = null;
2635
2651
  this.pending_ = null;
2636
- asyncRun(this.executeNext_, this);
2652
+ asyncRun(() => this.executeNext_());
2637
2653
  }
2638
2654
 
2639
2655
  if (!promise.callbacks_) {
@@ -2663,7 +2679,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2663
2679
  }, this);
2664
2680
  promise.callbacks_ = null;
2665
2681
  vlog(2, () => this + ' interrupted\n' + this.flow_, this);
2666
- },
2682
+ }
2667
2683
 
2668
2684
  /**
2669
2685
  * Starts executing tasks in this queue. Once called, no further tasks may
@@ -2671,15 +2687,15 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2671
2687
  *
2672
2688
  * @throws {Error} if this queue has already been started.
2673
2689
  */
2674
- start: function() {
2690
+ start() {
2675
2691
  if (this.state_ !== TaskQueueState.NEW) {
2676
2692
  throw new Error('TaskQueue has already started');
2677
2693
  }
2678
2694
  // Always asynchronously execute next, even if there doesn't look like
2679
2695
  // there is anything in the queue. This will catch pending unhandled
2680
2696
  // rejections that were registered before start was called.
2681
- asyncRun(this.executeNext_, this);
2682
- },
2697
+ asyncRun(() => this.executeNext_());
2698
+ }
2683
2699
 
2684
2700
  /**
2685
2701
  * Aborts this task queue. If there are any scheduled tasks, they are silently
@@ -2690,7 +2706,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2690
2706
  * @param {*} error The abortion reason.
2691
2707
  * @private
2692
2708
  */
2693
- abort_: function(error) {
2709
+ abort_(error) {
2694
2710
  var cancellation;
2695
2711
 
2696
2712
  if (error instanceof FlowResetError) {
@@ -2711,17 +2727,16 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2711
2727
 
2712
2728
  if (this.pending_) {
2713
2729
  vlog(2, () => this + '.abort(); cancelling pending task', this);
2714
- this.pending_.task.cancel(
2715
- /** @type {!webdriver.promise.CancellationError} */(error));
2730
+ this.pending_.task.cancel(/** @type {!CancellationError} */(error));
2716
2731
 
2717
2732
  } else {
2718
2733
  vlog(2, () => this + '.abort(); emitting error event', this);
2719
2734
  this.emit('error', error, this);
2720
2735
  }
2721
- },
2736
+ }
2722
2737
 
2723
2738
  /** @private */
2724
- executeNext_: function() {
2739
+ executeNext_() {
2725
2740
  if (this.state_ === TaskQueueState.FINISHED) {
2726
2741
  return;
2727
2742
  }
@@ -2760,8 +2775,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2760
2775
  } catch (ex) {
2761
2776
  subQ.abort_(ex);
2762
2777
  }
2763
- },
2764
-
2778
+ }
2765
2779
 
2766
2780
  /**
2767
2781
  * @param {!Function} fn .
@@ -2769,7 +2783,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2769
2783
  * @template T
2770
2784
  * @private
2771
2785
  */
2772
- execute_: function(fn) {
2786
+ execute_(fn) {
2773
2787
  try {
2774
2788
  activeFlows.push(this.flow_);
2775
2789
  this.flow_.activeQueue_ = this;
@@ -2778,17 +2792,17 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2778
2792
  this.flow_.activeQueue_ = null;
2779
2793
  activeFlows.pop();
2780
2794
  }
2781
- },
2795
+ }
2782
2796
 
2783
2797
  /**
2784
2798
  * Process any unhandled rejections registered with this task queue. If there
2785
2799
  * is a rejection, this queue will be aborted with the rejection error. If
2786
2800
  * there are multiple rejections registered, this queue will be aborted with
2787
- * a {@link promise.MultipleUnhandledRejectionError}.
2801
+ * a {@link MultipleUnhandledRejectionError}.
2788
2802
  * @return {boolean} whether there was an unhandled rejection.
2789
2803
  * @private
2790
2804
  */
2791
- processUnhandledRejections_: function() {
2805
+ processUnhandledRejections_() {
2792
2806
  if (!this.unhandledRejections_.size) {
2793
2807
  return false;
2794
2808
  }
@@ -2801,7 +2815,7 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2801
2815
 
2802
2816
  var errorToReport = errors.size === 1
2803
2817
  ? errors.values().next().value
2804
- : new promise.MultipleUnhandledRejectionError(errors);
2818
+ : new MultipleUnhandledRejectionError(errors);
2805
2819
 
2806
2820
  vlog(1, () => this + ' aborting due to unhandled rejections', this);
2807
2821
  if (this.flow_.propagateUnhandledRejections_) {
@@ -2812,13 +2826,13 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2812
2826
  this.flow_.reportUncaughtException_(errorToReport);
2813
2827
  return false;
2814
2828
  }
2815
- },
2829
+ }
2816
2830
 
2817
2831
  /**
2818
2832
  * @param {!Task} task The task to drop.
2819
2833
  * @private
2820
2834
  */
2821
- dropTask_: function(task) {
2835
+ dropTask_(task) {
2822
2836
  var index;
2823
2837
  if (this.interrupts_) {
2824
2838
  index = this.interrupts_.indexOf(task);
@@ -2834,49 +2848,49 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2834
2848
  task.queue = null;
2835
2849
  this.tasks_.splice(index, 1);
2836
2850
  }
2837
- },
2851
+ }
2838
2852
 
2839
2853
  /**
2840
2854
  * @param {!Task} task The task that was cancelled.
2841
- * @param {!promise.CancellationError} reason The cancellation reason.
2855
+ * @param {!CancellationError} reason The cancellation reason.
2842
2856
  * @private
2843
2857
  */
2844
- onTaskCancelled_: function(task, reason) {
2858
+ onTaskCancelled_(task, reason) {
2845
2859
  if (this.pending_ && this.pending_.task === task) {
2846
2860
  this.pending_.q.abort_(reason);
2847
2861
  } else {
2848
2862
  this.dropTask_(task);
2849
2863
  }
2850
- },
2864
+ }
2851
2865
 
2852
2866
  /**
2853
2867
  * @param {*} value the value originally returned by the task function.
2854
2868
  * @private
2855
2869
  */
2856
- onTaskComplete_: function(value) {
2870
+ onTaskComplete_(value) {
2857
2871
  if (this.pending_) {
2858
2872
  this.pending_.task.fulfill(value);
2859
2873
  }
2860
- },
2874
+ }
2861
2875
 
2862
2876
  /**
2863
2877
  * @param {*} taskFnResult the value originally returned by the task function.
2864
2878
  * @param {*} error the error that caused the task function to terminate.
2865
2879
  * @private
2866
2880
  */
2867
- onTaskFailure_: function(taskFnResult, error) {
2868
- if (promise.Thenable.isImplementation(taskFnResult)) {
2869
- taskFnResult.cancel(promise.CancellationError.wrap(error));
2881
+ onTaskFailure_(taskFnResult, error) {
2882
+ if (Thenable.isImplementation(taskFnResult)) {
2883
+ taskFnResult.cancel(CancellationError.wrap(error));
2870
2884
  }
2871
2885
  this.pending_.task.reject(error);
2872
- },
2886
+ }
2873
2887
 
2874
2888
  /**
2875
2889
  * @return {(Task|undefined)} the next task scheduled within this queue,
2876
2890
  * if any.
2877
2891
  * @private
2878
2892
  */
2879
- getNextTask_: function() {
2893
+ getNextTask_() {
2880
2894
  var task = undefined;
2881
2895
  while (true) {
2882
2896
  if (this.interrupts_) {
@@ -2896,15 +2910,15 @@ var TaskQueue = goog.defineClass(EventEmitter, {
2896
2910
  }
2897
2911
  return task;
2898
2912
  }
2899
- });
2913
+ };
2900
2914
 
2901
2915
 
2902
2916
 
2903
2917
  /**
2904
2918
  * The default flow to use if no others are active.
2905
- * @type {!promise.ControlFlow}
2919
+ * @type {!ControlFlow}
2906
2920
  */
2907
- var defaultFlow = new promise.ControlFlow();
2921
+ var defaultFlow = new ControlFlow();
2908
2922
 
2909
2923
 
2910
2924
  /**
@@ -2912,48 +2926,48 @@ var defaultFlow = new promise.ControlFlow();
2912
2926
  * commands. When there are multiple flows on the stack, the flow at index N
2913
2927
  * represents a callback triggered within a task owned by the flow at index
2914
2928
  * N-1.
2915
- * @type {!Array<!promise.ControlFlow>}
2929
+ * @type {!Array<!ControlFlow>}
2916
2930
  */
2917
2931
  var activeFlows = [];
2918
2932
 
2919
2933
 
2920
2934
  /**
2921
2935
  * Changes the default flow to use when no others are active.
2922
- * @param {!promise.ControlFlow} flow The new default flow.
2936
+ * @param {!ControlFlow} flow The new default flow.
2923
2937
  * @throws {Error} If the default flow is not currently active.
2924
2938
  */
2925
- promise.setDefaultFlow = function(flow) {
2939
+ function setDefaultFlow(flow) {
2926
2940
  if (activeFlows.length) {
2927
2941
  throw Error('You may only change the default flow while it is active');
2928
2942
  }
2929
2943
  defaultFlow = flow;
2930
- };
2944
+ }
2931
2945
 
2932
2946
 
2933
2947
  /**
2934
- * @return {!promise.ControlFlow} The currently active control flow.
2948
+ * @return {!ControlFlow} The currently active control flow.
2935
2949
  */
2936
- promise.controlFlow = function() {
2937
- return /** @type {!promise.ControlFlow} */ (
2938
- Arrays.peek(activeFlows) || defaultFlow);
2939
- };
2950
+ function controlFlow() {
2951
+ return /** @type {!ControlFlow} */ (
2952
+ activeFlows.length ? activeFlows[activeFlows.length - 1] : defaultFlow);
2953
+ }
2940
2954
 
2941
2955
 
2942
2956
  /**
2943
2957
  * Creates a new control flow. The provided callback will be invoked as the
2944
2958
  * first task within the new flow, with the flow as its sole argument. Returns
2945
2959
  * a promise that resolves to the callback result.
2946
- * @param {function(!promise.ControlFlow)} callback The entry point
2960
+ * @param {function(!ControlFlow)} callback The entry point
2947
2961
  * to the newly created flow.
2948
- * @return {!promise.Promise} A promise that resolves to the callback
2962
+ * @return {!ManagedPromise} A promise that resolves to the callback
2949
2963
  * result.
2950
2964
  */
2951
- promise.createFlow = function(callback) {
2952
- var flow = new promise.ControlFlow;
2965
+ function createFlow(callback) {
2966
+ var flow = new ControlFlow;
2953
2967
  return flow.execute(function() {
2954
2968
  return callback(flow);
2955
2969
  });
2956
- };
2970
+ }
2957
2971
 
2958
2972
 
2959
2973
  /**
@@ -2961,9 +2975,9 @@ promise.createFlow = function(callback) {
2961
2975
  * @param {!Function} fn The function to test.
2962
2976
  * @return {boolean} Whether the function is a generator.
2963
2977
  */
2964
- promise.isGenerator = function(fn) {
2978
+ function isGenerator(fn) {
2965
2979
  return fn.constructor.name === 'GeneratorFunction';
2966
- };
2980
+ }
2967
2981
 
2968
2982
 
2969
2983
  /**
@@ -2992,7 +3006,7 @@ promise.isGenerator = function(fn) {
2992
3006
  * yield promise.delayed(250).then(function() {
2993
3007
  * throw Error('boom');
2994
3008
  * });
2995
- * }).thenCatch(function(e) {
3009
+ * }).catch(function(e) {
2996
3010
  * console.log(e.toString()); // Error: boom
2997
3011
  * });
2998
3012
  *
@@ -3000,18 +3014,19 @@ promise.isGenerator = function(fn) {
3000
3014
  * @param {Object=} opt_self The object to use as "this" when invoking the
3001
3015
  * initial generator.
3002
3016
  * @param {...*} var_args Any arguments to pass to the initial generator.
3003
- * @return {!promise.Promise<?>} A promise that will resolve to the
3017
+ * @return {!ManagedPromise<?>} A promise that will resolve to the
3004
3018
  * generator's final result.
3005
3019
  * @throws {TypeError} If the given function is not a generator.
3006
3020
  */
3007
- promise.consume = function(generatorFn, opt_self, var_args) {
3008
- if (!promise.isGenerator(generatorFn)) {
3021
+ function consume(generatorFn, opt_self, var_args) {
3022
+ if (!isGenerator(generatorFn)) {
3009
3023
  throw new TypeError('Input is not a GeneratorFunction: ' +
3010
3024
  generatorFn.constructor.name);
3011
3025
  }
3012
3026
 
3013
- var deferred = promise.defer();
3014
- var generator = generatorFn.apply(opt_self, Arrays.slice(arguments, 2));
3027
+ var deferred = defer();
3028
+ var generator = generatorFn.apply(
3029
+ opt_self, Array.prototype.slice.call(arguments, 2));
3015
3030
  callNext();
3016
3031
  return deferred.promise;
3017
3032
 
@@ -3044,6 +3059,35 @@ promise.consume = function(generatorFn, opt_self, var_args) {
3044
3059
  return;
3045
3060
  }
3046
3061
 
3047
- promise.asap(result.value, callNext, callThrow);
3062
+ asap(result.value, callNext, callThrow);
3048
3063
  }
3049
- };
3064
+ }
3065
+
3066
+
3067
+ // PUBLIC API
3068
+
3069
+
3070
+ exports.CancellationError = CancellationError;
3071
+ exports.ControlFlow = ControlFlow;
3072
+ exports.Deferred = Deferred;
3073
+ exports.MultipleUnhandledRejectionError = MultipleUnhandledRejectionError;
3074
+ exports.Thenable = Thenable;
3075
+ exports.Promise = ManagedPromise;
3076
+ exports.all = all;
3077
+ exports.asap = asap;
3078
+ exports.captureStackTrace = captureStackTrace;
3079
+ exports.checkedNodeCall = checkedNodeCall;
3080
+ exports.consume = consume;
3081
+ exports.controlFlow = controlFlow;
3082
+ exports.createFlow = createFlow;
3083
+ exports.defer = defer;
3084
+ exports.delayed = delayed;
3085
+ exports.filter = filter;
3086
+ exports.fulfilled = fulfilled;
3087
+ exports.fullyResolved = fullyResolved;
3088
+ exports.isGenerator = isGenerator;
3089
+ exports.isPromise = isPromise;
3090
+ exports.map = map;
3091
+ exports.rejected = rejected;
3092
+ exports.setDefaultFlow = setDefaultFlow;
3093
+ exports.when = when;