selenium-webdriver 2.43.5 → 2.44.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 (219) hide show
  1. package/CHANGES.md +20 -0
  2. package/README.md +8 -13
  3. package/builder.js +4 -3
  4. package/docs/class_webdriver_Alert.html +6 -6
  5. package/docs/class_webdriver_AlertPromise.html +6 -6
  6. package/docs/class_webdriver_UnhandledAlertError.html +4 -4
  7. package/docs/class_webdriver_WebDriver.html +39 -37
  8. package/docs/class_webdriver_WebDriver_Logs.html +3 -3
  9. package/docs/class_webdriver_WebDriver_Navigation.html +5 -5
  10. package/docs/class_webdriver_WebDriver_Options.html +9 -9
  11. package/docs/class_webdriver_WebDriver_TargetLocator.html +6 -6
  12. package/docs/class_webdriver_WebDriver_Timeouts.html +4 -4
  13. package/docs/class_webdriver_WebDriver_Window.html +6 -6
  14. package/docs/class_webdriver_WebElement.html +23 -23
  15. package/docs/class_webdriver_WebElementPromise.html +22 -22
  16. package/docs/class_webdriver_promise_CancellationError.html +3 -0
  17. package/docs/class_webdriver_promise_ControlFlow.html +32 -32
  18. package/docs/class_webdriver_promise_Deferred.html +7 -8
  19. package/docs/class_webdriver_promise_Frame_.html +14 -30
  20. package/docs/class_webdriver_promise_Promise.html +2 -2
  21. package/docs/class_webdriver_promise_Task_.html +12 -12
  22. package/docs/class_webdriver_until_Condition.html +3 -0
  23. package/docs/enum_webdriver_Key.html +1 -1
  24. package/docs/enum_webdriver_promise_ControlFlow_EventType.html +1 -1
  25. package/docs/enum_webdriver_promise_Deferred_State_.html +1 -1
  26. package/docs/index.html +8 -13
  27. package/docs/interface_webdriver_promise_Thenable.html +8 -10
  28. package/docs/license.html +1 -1
  29. package/docs/module_selenium-webdriver.html +2 -2
  30. package/docs/module_selenium-webdriver__base.html +1 -1
  31. package/docs/module_selenium-webdriver__base_class_Context.html +1 -1
  32. package/docs/module_selenium-webdriver_builder.html +1 -1
  33. package/docs/module_selenium-webdriver_builder_class_Builder.html +1 -1
  34. package/docs/module_selenium-webdriver_chrome.html +1 -1
  35. package/docs/module_selenium-webdriver_chrome_class_Driver.html +2 -2
  36. package/docs/module_selenium-webdriver_chrome_class_Options.html +2 -2
  37. package/docs/module_selenium-webdriver_chrome_class_ServiceBuilder.html +1 -1
  38. package/docs/module_selenium-webdriver_error.html +1 -1
  39. package/docs/module_selenium-webdriver_executors.html +1 -1
  40. package/docs/module_selenium-webdriver_firefox.html +1 -1
  41. package/docs/module_selenium-webdriver_firefox_binary.html +1 -1
  42. package/docs/module_selenium-webdriver_firefox_binary_class_Binary.html +1 -1
  43. package/docs/module_selenium-webdriver_firefox_class_Driver.html +2 -2
  44. package/docs/module_selenium-webdriver_firefox_class_Options.html +1 -1
  45. package/docs/module_selenium-webdriver_firefox_extension.html +1 -1
  46. package/docs/module_selenium-webdriver_firefox_profile.html +1 -1
  47. package/docs/module_selenium-webdriver_firefox_profile_class_Profile.html +1 -1
  48. package/docs/module_selenium-webdriver_http.html +1 -1
  49. package/docs/module_selenium-webdriver_http_class_HttpClient.html +1 -1
  50. package/docs/module_selenium-webdriver_http_util.html +1 -1
  51. package/docs/module_selenium-webdriver_io.html +1 -1
  52. package/docs/module_selenium-webdriver_io_exec.html +1 -1
  53. package/docs/module_selenium-webdriver_net.html +1 -1
  54. package/docs/module_selenium-webdriver_net_portprober.html +1 -1
  55. package/docs/module_selenium-webdriver_phantomjs.html +1 -1
  56. package/docs/module_selenium-webdriver_phantomjs_class_Driver.html +2 -2
  57. package/docs/module_selenium-webdriver_proxy.html +1 -1
  58. package/docs/module_selenium-webdriver_remote.html +1 -1
  59. package/docs/module_selenium-webdriver_remote_class_DriverService.html +2 -2
  60. package/docs/module_selenium-webdriver_remote_class_SeleniumServer.html +2 -2
  61. package/docs/module_selenium-webdriver_testing.html +16 -29
  62. package/docs/module_selenium-webdriver_testing_assert.html +1 -1
  63. package/docs/namespace_webdriver_promise.html +18 -20
  64. package/docs/namespace_webdriver_stacktrace.html +15 -15
  65. package/docs/namespace_webdriver_until.html +32 -0
  66. package/docs/source/_base.js.src.html +1 -1
  67. package/docs/source/builder.js.src.html +1 -1
  68. package/docs/source/chrome.js.src.html +1 -1
  69. package/docs/source/error.js.src.html +1 -1
  70. package/docs/source/executors.js.src.html +1 -1
  71. package/docs/source/firefox/binary.js.src.html +1 -1
  72. package/docs/source/firefox/extension.js.src.html +1 -1
  73. package/docs/source/firefox/index.js.src.html +1 -1
  74. package/docs/source/firefox/profile.js.src.html +1 -1
  75. package/docs/source/http/index.js.src.html +1 -1
  76. package/docs/source/http/util.js.src.html +1 -1
  77. package/docs/source/index.js.src.html +1 -1
  78. package/docs/source/io/exec.js.src.html +1 -1
  79. package/docs/source/io/index.js.src.html +1 -1
  80. package/docs/source/lib/atoms/error.js.src.html +1 -1
  81. package/docs/source/lib/atoms/json.js.src.html +1 -1
  82. package/docs/source/lib/atoms/response.js.src.html +1 -1
  83. package/docs/source/lib/atoms/userAgent.js.src.html +1 -1
  84. package/docs/source/lib/goog/array/array.js.src.html +1 -1
  85. package/docs/source/lib/goog/asserts/asserts.js.src.html +1 -1
  86. package/docs/source/lib/goog/async/nexttick.js.src.html +1 -1
  87. package/docs/source/lib/goog/async/run.js.src.html +1 -1
  88. package/docs/source/lib/goog/base.js.src.html +1 -1
  89. package/docs/source/lib/goog/debug/debug.js.src.html +1 -1
  90. package/docs/source/lib/goog/debug/entrypointregistry.js.src.html +1 -1
  91. package/docs/source/lib/goog/debug/error.js.src.html +1 -1
  92. package/docs/source/lib/goog/debug/logbuffer.js.src.html +1 -1
  93. package/docs/source/lib/goog/debug/logger.js.src.html +1 -1
  94. package/docs/source/lib/goog/debug/logrecord.js.src.html +1 -1
  95. package/docs/source/lib/goog/deps.js.src.html +1 -1
  96. package/docs/source/lib/goog/disposable/disposable.js.src.html +1 -1
  97. package/docs/source/lib/goog/disposable/idisposable.js.src.html +1 -1
  98. package/docs/source/lib/goog/dom/browserfeature.js.src.html +1 -1
  99. package/docs/source/lib/goog/dom/dom.js.src.html +1 -1
  100. package/docs/source/lib/goog/dom/nodetype.js.src.html +1 -1
  101. package/docs/source/lib/goog/dom/tagname.js.src.html +1 -1
  102. package/docs/source/lib/goog/dom/vendor.js.src.html +1 -1
  103. package/docs/source/lib/goog/events/browserevent.js.src.html +1 -1
  104. package/docs/source/lib/goog/events/browserfeature.js.src.html +1 -1
  105. package/docs/source/lib/goog/events/event.js.src.html +1 -1
  106. package/docs/source/lib/goog/events/eventid.js.src.html +1 -1
  107. package/docs/source/lib/goog/events/events.js.src.html +1 -1
  108. package/docs/source/lib/goog/events/eventtarget.js.src.html +1 -1
  109. package/docs/source/lib/goog/events/eventtype.js.src.html +1 -1
  110. package/docs/source/lib/goog/events/keycodes.js.src.html +1 -1
  111. package/docs/source/lib/goog/events/listenable.js.src.html +1 -1
  112. package/docs/source/lib/goog/events/listener.js.src.html +1 -1
  113. package/docs/source/lib/goog/events/listenermap.js.src.html +1 -1
  114. package/docs/source/lib/goog/functions/functions.js.src.html +1 -1
  115. package/docs/source/lib/goog/iter/iter.js.src.html +1 -1
  116. package/docs/source/lib/goog/json/json.js.src.html +1 -1
  117. package/docs/source/lib/goog/labs/testing/assertthat.js.src.html +1 -1
  118. package/docs/source/lib/goog/labs/testing/logicmatcher.js.src.html +1 -1
  119. package/docs/source/lib/goog/labs/testing/matcher.js.src.html +1 -1
  120. package/docs/source/lib/goog/labs/testing/numbermatcher.js.src.html +1 -1
  121. package/docs/source/lib/goog/labs/testing/objectmatcher.js.src.html +1 -1
  122. package/docs/source/lib/goog/labs/testing/stringmatcher.js.src.html +1 -1
  123. package/docs/source/lib/goog/labs/useragent/browser.js.src.html +1 -1
  124. package/docs/source/lib/goog/labs/useragent/engine.js.src.html +1 -1
  125. package/docs/source/lib/goog/labs/useragent/util.js.src.html +1 -1
  126. package/docs/source/lib/goog/math/box.js.src.html +1 -1
  127. package/docs/source/lib/goog/math/coordinate.js.src.html +1 -1
  128. package/docs/source/lib/goog/math/math.js.src.html +1 -1
  129. package/docs/source/lib/goog/math/rect.js.src.html +1 -1
  130. package/docs/source/lib/goog/math/size.js.src.html +1 -1
  131. package/docs/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html +1 -1
  132. package/docs/source/lib/goog/net/xhrlike.js.src.html +1 -1
  133. package/docs/source/lib/goog/net/xmlhttp.js.src.html +1 -1
  134. package/docs/source/lib/goog/net/xmlhttpfactory.js.src.html +1 -1
  135. package/docs/source/lib/goog/object/object.js.src.html +1 -1
  136. package/docs/source/lib/goog/reflect/reflect.js.src.html +1 -1
  137. package/docs/source/lib/goog/string/string.js.src.html +1 -1
  138. package/docs/source/lib/goog/structs/collection.js.src.html +1 -1
  139. package/docs/source/lib/goog/structs/map.js.src.html +1 -1
  140. package/docs/source/lib/goog/structs/set.js.src.html +1 -1
  141. package/docs/source/lib/goog/structs/structs.js.src.html +1 -1
  142. package/docs/source/lib/goog/style/style.js.src.html +1 -1
  143. package/docs/source/lib/goog/testing/asserts.js.src.html +1 -1
  144. package/docs/source/lib/goog/testing/asynctestcase.js.src.html +1 -1
  145. package/docs/source/lib/goog/testing/events/events.js.src.html +1 -1
  146. package/docs/source/lib/goog/testing/functionmock.js.src.html +1 -1
  147. package/docs/source/lib/goog/testing/jsunit.js.src.html +1 -1
  148. package/docs/source/lib/goog/testing/loosemock.js.src.html +1 -1
  149. package/docs/source/lib/goog/testing/mock.js.src.html +1 -1
  150. package/docs/source/lib/goog/testing/mockclock.js.src.html +1 -1
  151. package/docs/source/lib/goog/testing/mockcontrol.js.src.html +1 -1
  152. package/docs/source/lib/goog/testing/mockinterface.js.src.html +1 -1
  153. package/docs/source/lib/goog/testing/mockmatchers.js.src.html +1 -1
  154. package/docs/source/lib/goog/testing/objectpropertystring.js.src.html +1 -1
  155. package/docs/source/lib/goog/testing/propertyreplacer.js.src.html +1 -1
  156. package/docs/source/lib/goog/testing/recordfunction.js.src.html +1 -1
  157. package/docs/source/lib/goog/testing/stacktrace.js.src.html +1 -1
  158. package/docs/source/lib/goog/testing/strictmock.js.src.html +1 -1
  159. package/docs/source/lib/goog/testing/testcase.js.src.html +1 -1
  160. package/docs/source/lib/goog/testing/testrunner.js.src.html +1 -1
  161. package/docs/source/lib/goog/testing/watchers.js.src.html +1 -1
  162. package/docs/source/lib/goog/uri/uri.js.src.html +1 -1
  163. package/docs/source/lib/goog/uri/utils.js.src.html +1 -1
  164. package/docs/source/lib/goog/useragent/product.js.src.html +1 -1
  165. package/docs/source/lib/goog/useragent/product_isversion.js.src.html +1 -1
  166. package/docs/source/lib/goog/useragent/useragent.js.src.html +1 -1
  167. package/docs/source/lib/webdriver/abstractbuilder.js.src.html +1 -1
  168. package/docs/source/lib/webdriver/actionsequence.js.src.html +1 -1
  169. package/docs/source/lib/webdriver/builder.js.src.html +1 -1
  170. package/docs/source/lib/webdriver/button.js.src.html +1 -1
  171. package/docs/source/lib/webdriver/capabilities.js.src.html +1 -1
  172. package/docs/source/lib/webdriver/command.js.src.html +1 -1
  173. package/docs/source/lib/webdriver/events.js.src.html +1 -1
  174. package/docs/source/lib/webdriver/firefoxdomexecutor.js.src.html +1 -1
  175. package/docs/source/lib/webdriver/http/corsclient.js.src.html +1 -1
  176. package/docs/source/lib/webdriver/http/http.js.src.html +1 -1
  177. package/docs/source/lib/webdriver/http/xhrclient.js.src.html +1 -1
  178. package/docs/source/lib/webdriver/key.js.src.html +1 -1
  179. package/docs/source/lib/webdriver/locators.js.src.html +1 -1
  180. package/docs/source/lib/webdriver/logging.js.src.html +1 -1
  181. package/docs/source/lib/webdriver/process.js.src.html +1 -1
  182. package/docs/source/lib/webdriver/promise.js.src.html +1 -1
  183. package/docs/source/lib/webdriver/session.js.src.html +1 -1
  184. package/docs/source/lib/webdriver/stacktrace.js.src.html +1 -1
  185. package/docs/source/lib/webdriver/testing/asserts.js.src.html +1 -1
  186. package/docs/source/lib/webdriver/testing/testcase.js.src.html +1 -1
  187. package/docs/source/lib/webdriver/until.js.src.html +1 -0
  188. package/docs/source/lib/webdriver/webdriver.js.src.html +1 -1
  189. package/docs/source/net/index.js.src.html +1 -1
  190. package/docs/source/net/portprober.js.src.html +1 -1
  191. package/docs/source/phantomjs.js.src.html +1 -1
  192. package/docs/source/proxy.js.src.html +1 -1
  193. package/docs/source/remote/index.js.src.html +1 -1
  194. package/docs/source/testing/assert.js.src.html +1 -1
  195. package/docs/source/testing/index.js.src.html +1 -1
  196. package/docs/types.js +1 -1
  197. package/example/google_search.js +9 -17
  198. package/example/google_search_generator.js +6 -7
  199. package/example/google_search_test.js +10 -18
  200. package/example/parallel_flows.js +4 -7
  201. package/index.js +6 -0
  202. package/lib/firefox/webdriver.xpi +0 -0
  203. package/lib/goog/deps.js +7 -5
  204. package/lib/test/index.js +0 -8
  205. package/lib/webdriver/promise.js +263 -251
  206. package/lib/webdriver/stacktrace.js +15 -1
  207. package/lib/webdriver/test/promise_flow_test.js +82 -76
  208. package/lib/webdriver/test/promise_test.js +22 -62
  209. package/lib/webdriver/test/stacktrace_test.js +18 -0
  210. package/lib/webdriver/test/until_test.js +388 -0
  211. package/lib/webdriver/test/webdriver_test.js +41 -0
  212. package/lib/webdriver/until.js +408 -0
  213. package/lib/webdriver/webdriver.js +91 -29
  214. package/package.json +2 -2
  215. package/test/element_finding_test.js +6 -6
  216. package/test/http/util_test.js +4 -5
  217. package/test/page_loading_test.js +7 -7
  218. package/test/stale_element_test.js +2 -10
  219. package/testing/index.js +9 -22
@@ -1 +1 @@
1
- <!DOCTYPE html><meta charset="UTF-8"><meta http-equiv="Content-Language" content="en" /><title>firefoxdomexecutor.js</title><link href="../../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>lib/webdriver/firefoxdomexecutor.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.<tr><td><a name="l2" href="#l2">2</a><td>//<tr><td><a name="l3" href="#l3">3</a><td>// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);<tr><td><a name="l4" href="#l4">4</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l5" href="#l5">5</a><td>// You may obtain a copy of the License at<tr><td><a name="l6" href="#l6">6</a><td>//<tr><td><a name="l7" href="#l7">7</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l8" href="#l8">8</a><td>//<tr><td><a name="l9" href="#l9">9</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l10" href="#l10">10</a><td>// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,<tr><td><a name="l11" href="#l11">11</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l12" href="#l12">12</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l13" href="#l13">13</a><td>// limitations under the License.<tr><td><a name="l14" href="#l14">14</a><td><tr><td><a name="l15" href="#l15">15</a><td>goog.provide(&#39;webdriver.FirefoxDomExecutor&#39;);<tr><td><a name="l16" href="#l16">16</a><td><tr><td><a name="l17" href="#l17">17</a><td>goog.require(&#39;bot.response&#39;);<tr><td><a name="l18" href="#l18">18</a><td>goog.require(&#39;goog.json&#39;);<tr><td><a name="l19" href="#l19">19</a><td>goog.require(&#39;goog.userAgent.product&#39;);<tr><td><a name="l20" href="#l20">20</a><td>goog.require(&#39;webdriver.Command&#39;);<tr><td><a name="l21" href="#l21">21</a><td>goog.require(&#39;webdriver.CommandName&#39;);<tr><td><a name="l22" href="#l22">22</a><td><tr><td><a name="l23" href="#l23">23</a><td><tr><td><a name="l24" href="#l24">24</a><td><tr><td><a name="l25" href="#l25">25</a><td>/**<tr><td><a name="l26" href="#l26">26</a><td> * @constructor<tr><td><a name="l27" href="#l27">27</a><td> * @implements {webdriver.CommandExecutor}<tr><td><a name="l28" href="#l28">28</a><td> */<tr><td><a name="l29" href="#l29">29</a><td>webdriver.FirefoxDomExecutor = function() {<tr><td><a name="l30" href="#l30">30</a><td> if (!webdriver.FirefoxDomExecutor.isAvailable()) {<tr><td><a name="l31" href="#l31">31</a><td> throw Error(<tr><td><a name="l32" href="#l32">32</a><td> &#39;The current environment does not support the FirefoxDomExecutor&#39;);<tr><td><a name="l33" href="#l33">33</a><td> }<tr><td><a name="l34" href="#l34">34</a><td><tr><td><a name="l35" href="#l35">35</a><td> /** @private {!Document} */<tr><td><a name="l36" href="#l36">36</a><td> this.doc_ = document;<tr><td><a name="l37" href="#l37">37</a><td><tr><td><a name="l38" href="#l38">38</a><td> /** @private {!Element} */<tr><td><a name="l39" href="#l39">39</a><td> this.docElement_ = document.documentElement;<tr><td><a name="l40" href="#l40">40</a><td><tr><td><a name="l41" href="#l41">41</a><td> this.docElement_.addEventListener(<tr><td><a name="l42" href="#l42">42</a><td> webdriver.FirefoxDomExecutor.EventType_.RESPONSE,<tr><td><a name="l43" href="#l43">43</a><td> goog.bind(this.onResponse_, this), false);<tr><td><a name="l44" href="#l44">44</a><td>};<tr><td><a name="l45" href="#l45">45</a><td><tr><td><a name="l46" href="#l46">46</a><td><tr><td><a name="l47" href="#l47">47</a><td>/**<tr><td><a name="l48" href="#l48">48</a><td> * @return {boolean} Whether the current environment supports the<tr><td><a name="l49" href="#l49">49</a><td> * FirefoxDomExecutor.<tr><td><a name="l50" href="#l50">50</a><td> */<tr><td><a name="l51" href="#l51">51</a><td>webdriver.FirefoxDomExecutor.isAvailable = function() {<tr><td><a name="l52" href="#l52">52</a><td> return goog.userAgent.product.FIREFOX &amp;&amp;<tr><td><a name="l53" href="#l53">53</a><td> typeof document !== &#39;undefined&#39; &amp;&amp;<tr><td><a name="l54" href="#l54">54</a><td> document.documentElement &amp;&amp;<tr><td><a name="l55" href="#l55">55</a><td> goog.isFunction(document.documentElement.hasAttribute) &amp;&amp;<tr><td><a name="l56" href="#l56">56</a><td> document.documentElement.hasAttribute(&#39;webdriver&#39;);<tr><td><a name="l57" href="#l57">57</a><td>};<tr><td><a name="l58" href="#l58">58</a><td><tr><td><a name="l59" href="#l59">59</a><td><tr><td><a name="l60" href="#l60">60</a><td>/**<tr><td><a name="l61" href="#l61">61</a><td> * Attributes used to communicate with the FirefoxDriver extension.<tr><td><a name="l62" href="#l62">62</a><td> * @enum {string}<tr><td><a name="l63" href="#l63">63</a><td> * @private<tr><td><a name="l64" href="#l64">64</a><td> */<tr><td><a name="l65" href="#l65">65</a><td>webdriver.FirefoxDomExecutor.Attribute_ = {<tr><td><a name="l66" href="#l66">66</a><td> COMMAND: &#39;command&#39;,<tr><td><a name="l67" href="#l67">67</a><td> RESPONSE: &#39;response&#39;<tr><td><a name="l68" href="#l68">68</a><td>};<tr><td><a name="l69" href="#l69">69</a><td><tr><td><a name="l70" href="#l70">70</a><td><tr><td><a name="l71" href="#l71">71</a><td>/**<tr><td><a name="l72" href="#l72">72</a><td> * Events used to communicate with the FirefoxDriver extension.<tr><td><a name="l73" href="#l73">73</a><td> * @enum {string}<tr><td><a name="l74" href="#l74">74</a><td> * @private<tr><td><a name="l75" href="#l75">75</a><td> */<tr><td><a name="l76" href="#l76">76</a><td>webdriver.FirefoxDomExecutor.EventType_ = {<tr><td><a name="l77" href="#l77">77</a><td> COMMAND: &#39;webdriverCommand&#39;,<tr><td><a name="l78" href="#l78">78</a><td> RESPONSE: &#39;webdriverResponse&#39;<tr><td><a name="l79" href="#l79">79</a><td>};<tr><td><a name="l80" href="#l80">80</a><td><tr><td><a name="l81" href="#l81">81</a><td><tr><td><a name="l82" href="#l82">82</a><td>/**<tr><td><a name="l83" href="#l83">83</a><td> * The pending command, if any.<tr><td><a name="l84" href="#l84">84</a><td> * @private {?{name:string, callback:!Function}}<tr><td><a name="l85" href="#l85">85</a><td> */<tr><td><a name="l86" href="#l86">86</a><td>webdriver.FirefoxDomExecutor.prototype.pendingCommand_ = null;<tr><td><a name="l87" href="#l87">87</a><td><tr><td><a name="l88" href="#l88">88</a><td><tr><td><a name="l89" href="#l89">89</a><td>/** @override */<tr><td><a name="l90" href="#l90">90</a><td>webdriver.FirefoxDomExecutor.prototype.execute = function(command, callback) {<tr><td><a name="l91" href="#l91">91</a><td> if (this.pendingCommand_) {<tr><td><a name="l92" href="#l92">92</a><td> throw Error(&#39;Currently awaiting a command response!&#39;);<tr><td><a name="l93" href="#l93">93</a><td> }<tr><td><a name="l94" href="#l94">94</a><td><tr><td><a name="l95" href="#l95">95</a><td> this.pendingCommand_ = {<tr><td><a name="l96" href="#l96">96</a><td> name: command.getName(),<tr><td><a name="l97" href="#l97">97</a><td> callback: callback<tr><td><a name="l98" href="#l98">98</a><td> };<tr><td><a name="l99" href="#l99">99</a><td><tr><td><a name="l100" href="#l100">100</a><td> var parameters = command.getParameters();<tr><td><a name="l101" href="#l101">101</a><td><tr><td><a name="l102" href="#l102">102</a><td> // There are two means for communicating with the FirefoxDriver: via<tr><td><a name="l103" href="#l103">103</a><td> // HTTP using WebDriver&#39;s wire protocol and over the DOM using a custom<tr><td><a name="l104" href="#l104">104</a><td> // JSON protocol. This class uses the latter. When the FirefoxDriver receives<tr><td><a name="l105" href="#l105">105</a><td> // commands over HTTP, it builds a parameters object from the URL parameters.<tr><td><a name="l106" href="#l106">106</a><td> // When an element ID is sent in the URL, it&#39;ll be decoded as just id:string<tr><td><a name="l107" href="#l107">107</a><td> // instead of id:{ELEMENT:string}. When switching to a frame by element,<tr><td><a name="l108" href="#l108">108</a><td> // however, the element ID is not sent through the URL, so we must make sure<tr><td><a name="l109" href="#l109">109</a><td> // to encode that parameter properly here. It would be nice if we unified<tr><td><a name="l110" href="#l110">110</a><td> // the two protocols used by the FirefoxDriver...<tr><td><a name="l111" href="#l111">111</a><td> if (parameters[&#39;id&#39;] &amp;&amp;<tr><td><a name="l112" href="#l112">112</a><td> parameters[&#39;id&#39;][&#39;ELEMENT&#39;] &amp;&amp;<tr><td><a name="l113" href="#l113">113</a><td> command.getName() != webdriver.CommandName.SWITCH_TO_FRAME) {<tr><td><a name="l114" href="#l114">114</a><td> parameters[&#39;id&#39;] = parameters[&#39;id&#39;][&#39;ELEMENT&#39;];<tr><td><a name="l115" href="#l115">115</a><td> }<tr><td><a name="l116" href="#l116">116</a><td> var json = goog.json.serialize({<tr><td><a name="l117" href="#l117">117</a><td> &#39;name&#39;: command.getName(),<tr><td><a name="l118" href="#l118">118</a><td> &#39;sessionId&#39;: parameters[&#39;sessionId&#39;],<tr><td><a name="l119" href="#l119">119</a><td> &#39;parameters&#39;: parameters<tr><td><a name="l120" href="#l120">120</a><td> });<tr><td><a name="l121" href="#l121">121</a><td> this.docElement_.setAttribute(<tr><td><a name="l122" href="#l122">122</a><td> webdriver.FirefoxDomExecutor.Attribute_.COMMAND, json);<tr><td><a name="l123" href="#l123">123</a><td><tr><td><a name="l124" href="#l124">124</a><td> var event = this.doc_.createEvent(&#39;Event&#39;);<tr><td><a name="l125" href="#l125">125</a><td> event.initEvent(webdriver.FirefoxDomExecutor.EventType_.COMMAND,<tr><td><a name="l126" href="#l126">126</a><td> /*canBubble=*/true, /*cancelable=*/true);<tr><td><a name="l127" href="#l127">127</a><td><tr><td><a name="l128" href="#l128">128</a><td> this.docElement_.dispatchEvent(event);<tr><td><a name="l129" href="#l129">129</a><td>};<tr><td><a name="l130" href="#l130">130</a><td><tr><td><a name="l131" href="#l131">131</a><td><tr><td><a name="l132" href="#l132">132</a><td>/** @private */<tr><td><a name="l133" href="#l133">133</a><td>webdriver.FirefoxDomExecutor.prototype.onResponse_ = function() {<tr><td><a name="l134" href="#l134">134</a><td> if (!this.pendingCommand_) {<tr><td><a name="l135" href="#l135">135</a><td> return; // Not expecting a response.<tr><td><a name="l136" href="#l136">136</a><td> }<tr><td><a name="l137" href="#l137">137</a><td><tr><td><a name="l138" href="#l138">138</a><td> var command = this.pendingCommand_;<tr><td><a name="l139" href="#l139">139</a><td> this.pendingCommand_ = null;<tr><td><a name="l140" href="#l140">140</a><td><tr><td><a name="l141" href="#l141">141</a><td> var json = this.docElement_.getAttribute(<tr><td><a name="l142" href="#l142">142</a><td> webdriver.FirefoxDomExecutor.Attribute_.RESPONSE);<tr><td><a name="l143" href="#l143">143</a><td> if (!json) {<tr><td><a name="l144" href="#l144">144</a><td> command.callback(Error(&#39;Empty command response!&#39;));<tr><td><a name="l145" href="#l145">145</a><td> return;<tr><td><a name="l146" href="#l146">146</a><td> }<tr><td><a name="l147" href="#l147">147</a><td><tr><td><a name="l148" href="#l148">148</a><td> this.docElement_.removeAttribute(<tr><td><a name="l149" href="#l149">149</a><td> webdriver.FirefoxDomExecutor.Attribute_.COMMAND);<tr><td><a name="l150" href="#l150">150</a><td> this.docElement_.removeAttribute(<tr><td><a name="l151" href="#l151">151</a><td> webdriver.FirefoxDomExecutor.Attribute_.RESPONSE);<tr><td><a name="l152" href="#l152">152</a><td><tr><td><a name="l153" href="#l153">153</a><td> try {<tr><td><a name="l154" href="#l154">154</a><td> var response = bot.response.checkResponse(<tr><td><a name="l155" href="#l155">155</a><td> /** @type {!bot.response.ResponseObject} */ (goog.json.parse(json)));<tr><td><a name="l156" href="#l156">156</a><td> } catch (ex) {<tr><td><a name="l157" href="#l157">157</a><td> command.callback(ex);<tr><td><a name="l158" href="#l158">158</a><td> return;<tr><td><a name="l159" href="#l159">159</a><td> }<tr><td><a name="l160" href="#l160">160</a><td><tr><td><a name="l161" href="#l161">161</a><td> // Prior to Selenium 2.35.0, two commands are required to fully create a<tr><td><a name="l162" href="#l162">162</a><td> // session: one to allocate the session, and another to fetch the<tr><td><a name="l163" href="#l163">163</a><td> // capabilities.<tr><td><a name="l164" href="#l164">164</a><td> if (command.name == webdriver.CommandName.NEW_SESSION &amp;&amp;<tr><td><a name="l165" href="#l165">165</a><td> goog.isString(response[&#39;value&#39;])) {<tr><td><a name="l166" href="#l166">166</a><td> var cmd = new webdriver.Command(webdriver.CommandName.DESCRIBE_SESSION).<tr><td><a name="l167" href="#l167">167</a><td> setParameter(&#39;sessionId&#39;, response[&#39;value&#39;]);<tr><td><a name="l168" href="#l168">168</a><td> this.execute(cmd, command.callback);<tr><td><a name="l169" href="#l169">169</a><td> } else {<tr><td><a name="l170" href="#l170">170</a><td> command.callback(null, response);<tr><td><a name="l171" href="#l171">171</a><td> }<tr><td><a name="l172" href="#l172">172</a><td>};</table></pre></main><nav id="topnav"><div><div id="menubutton"><label for="sidenav-toggle">Menu</label></div><form id="searchbox"><div><input type="search" placeholder="Search" tabindex="1"></div></form></div></nav><nav id="sidenav"><input type="checkbox" id="sidenav-types-ctrl" /><input type="checkbox" id="sidenav-files-ctrl" /><input type="checkbox" id="sidenav-modules-ctrl" /><a id="sidenav-overview"><div><h4>Overview</h4></div></a><div id="sidenav-types"><label for="sidenav-types-ctrl"><h4>Types</h4></label><i>Loading</i></div><div id="sidenav-modules"><label for="sidenav-modules-ctrl"><h4>Modules</h4></label><i>Loading</i></div><div id="sidenav-files"><label for="sidenav-files-ctrl"><h4>Files</h4></label><i>Loading</i></div><a href="license.html"><div><h4>License</h4></div></a></nav><div id="push-footer"></div></div><footer><a href="https://github.com/jleyba/js-dossier">Generated by dossier</a></footer><script src="../../../types.js"></script><script src="../../../dossier.js"></script>
1
+ <!DOCTYPE html><meta charset="UTF-8"><meta http-equiv="Content-Language" content="en" /><title>firefoxdomexecutor.js</title><link href="../../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>lib/webdriver/firefoxdomexecutor.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.<tr><td><a name="l2" href="#l2">2</a><td>//<tr><td><a name="l3" href="#l3">3</a><td>// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);<tr><td><a name="l4" href="#l4">4</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l5" href="#l5">5</a><td>// You may obtain a copy of the License at<tr><td><a name="l6" href="#l6">6</a><td>//<tr><td><a name="l7" href="#l7">7</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l8" href="#l8">8</a><td>//<tr><td><a name="l9" href="#l9">9</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l10" href="#l10">10</a><td>// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,<tr><td><a name="l11" href="#l11">11</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l12" href="#l12">12</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l13" href="#l13">13</a><td>// limitations under the License.<tr><td><a name="l14" href="#l14">14</a><td><tr><td><a name="l15" href="#l15">15</a><td>goog.provide(&#39;webdriver.FirefoxDomExecutor&#39;);<tr><td><a name="l16" href="#l16">16</a><td><tr><td><a name="l17" href="#l17">17</a><td>goog.require(&#39;bot.response&#39;);<tr><td><a name="l18" href="#l18">18</a><td>goog.require(&#39;goog.json&#39;);<tr><td><a name="l19" href="#l19">19</a><td>goog.require(&#39;goog.userAgent.product&#39;);<tr><td><a name="l20" href="#l20">20</a><td>goog.require(&#39;webdriver.Command&#39;);<tr><td><a name="l21" href="#l21">21</a><td>goog.require(&#39;webdriver.CommandName&#39;);<tr><td><a name="l22" href="#l22">22</a><td><tr><td><a name="l23" href="#l23">23</a><td><tr><td><a name="l24" href="#l24">24</a><td><tr><td><a name="l25" href="#l25">25</a><td>/**<tr><td><a name="l26" href="#l26">26</a><td> * @constructor<tr><td><a name="l27" href="#l27">27</a><td> * @implements {webdriver.CommandExecutor}<tr><td><a name="l28" href="#l28">28</a><td> */<tr><td><a name="l29" href="#l29">29</a><td>webdriver.FirefoxDomExecutor = function() {<tr><td><a name="l30" href="#l30">30</a><td> if (!webdriver.FirefoxDomExecutor.isAvailable()) {<tr><td><a name="l31" href="#l31">31</a><td> throw Error(<tr><td><a name="l32" href="#l32">32</a><td> &#39;The current environment does not support the FirefoxDomExecutor&#39;);<tr><td><a name="l33" href="#l33">33</a><td> }<tr><td><a name="l34" href="#l34">34</a><td><tr><td><a name="l35" href="#l35">35</a><td> /** @private {!Document} */<tr><td><a name="l36" href="#l36">36</a><td> this.doc_ = document;<tr><td><a name="l37" href="#l37">37</a><td><tr><td><a name="l38" href="#l38">38</a><td> /** @private {!Element} */<tr><td><a name="l39" href="#l39">39</a><td> this.docElement_ = document.documentElement;<tr><td><a name="l40" href="#l40">40</a><td><tr><td><a name="l41" href="#l41">41</a><td> this.docElement_.addEventListener(<tr><td><a name="l42" href="#l42">42</a><td> webdriver.FirefoxDomExecutor.EventType_.RESPONSE,<tr><td><a name="l43" href="#l43">43</a><td> goog.bind(this.onResponse_, this), false);<tr><td><a name="l44" href="#l44">44</a><td>};<tr><td><a name="l45" href="#l45">45</a><td><tr><td><a name="l46" href="#l46">46</a><td><tr><td><a name="l47" href="#l47">47</a><td>/**<tr><td><a name="l48" href="#l48">48</a><td> * @return {boolean} Whether the current environment supports the<tr><td><a name="l49" href="#l49">49</a><td> * FirefoxDomExecutor.<tr><td><a name="l50" href="#l50">50</a><td> */<tr><td><a name="l51" href="#l51">51</a><td>webdriver.FirefoxDomExecutor.isAvailable = function() {<tr><td><a name="l52" href="#l52">52</a><td> return goog.userAgent.product.FIREFOX &amp;&amp;<tr><td><a name="l53" href="#l53">53</a><td> typeof document !== &#39;undefined&#39; &amp;&amp;<tr><td><a name="l54" href="#l54">54</a><td> document.documentElement &amp;&amp;<tr><td><a name="l55" href="#l55">55</a><td> goog.isFunction(document.documentElement.hasAttribute) &amp;&amp;<tr><td><a name="l56" href="#l56">56</a><td> document.documentElement.hasAttribute(&#39;webdriver&#39;);<tr><td><a name="l57" href="#l57">57</a><td>};<tr><td><a name="l58" href="#l58">58</a><td><tr><td><a name="l59" href="#l59">59</a><td><tr><td><a name="l60" href="#l60">60</a><td>/**<tr><td><a name="l61" href="#l61">61</a><td> * Attributes used to communicate with the FirefoxDriver extension.<tr><td><a name="l62" href="#l62">62</a><td> * @enum {string}<tr><td><a name="l63" href="#l63">63</a><td> * @private<tr><td><a name="l64" href="#l64">64</a><td> */<tr><td><a name="l65" href="#l65">65</a><td>webdriver.FirefoxDomExecutor.Attribute_ = {<tr><td><a name="l66" href="#l66">66</a><td> COMMAND: &#39;command&#39;,<tr><td><a name="l67" href="#l67">67</a><td> RESPONSE: &#39;response&#39;<tr><td><a name="l68" href="#l68">68</a><td>};<tr><td><a name="l69" href="#l69">69</a><td><tr><td><a name="l70" href="#l70">70</a><td><tr><td><a name="l71" href="#l71">71</a><td>/**<tr><td><a name="l72" href="#l72">72</a><td> * Events used to communicate with the FirefoxDriver extension.<tr><td><a name="l73" href="#l73">73</a><td> * @enum {string}<tr><td><a name="l74" href="#l74">74</a><td> * @private<tr><td><a name="l75" href="#l75">75</a><td> */<tr><td><a name="l76" href="#l76">76</a><td>webdriver.FirefoxDomExecutor.EventType_ = {<tr><td><a name="l77" href="#l77">77</a><td> COMMAND: &#39;webdriverCommand&#39;,<tr><td><a name="l78" href="#l78">78</a><td> RESPONSE: &#39;webdriverResponse&#39;<tr><td><a name="l79" href="#l79">79</a><td>};<tr><td><a name="l80" href="#l80">80</a><td><tr><td><a name="l81" href="#l81">81</a><td><tr><td><a name="l82" href="#l82">82</a><td>/**<tr><td><a name="l83" href="#l83">83</a><td> * The pending command, if any.<tr><td><a name="l84" href="#l84">84</a><td> * @private {?{name:string, callback:!Function}}<tr><td><a name="l85" href="#l85">85</a><td> */<tr><td><a name="l86" href="#l86">86</a><td>webdriver.FirefoxDomExecutor.prototype.pendingCommand_ = null;<tr><td><a name="l87" href="#l87">87</a><td><tr><td><a name="l88" href="#l88">88</a><td><tr><td><a name="l89" href="#l89">89</a><td>/** @override */<tr><td><a name="l90" href="#l90">90</a><td>webdriver.FirefoxDomExecutor.prototype.execute = function(command, callback) {<tr><td><a name="l91" href="#l91">91</a><td> if (this.pendingCommand_) {<tr><td><a name="l92" href="#l92">92</a><td> throw Error(&#39;Currently awaiting a command response!&#39;);<tr><td><a name="l93" href="#l93">93</a><td> }<tr><td><a name="l94" href="#l94">94</a><td><tr><td><a name="l95" href="#l95">95</a><td> this.pendingCommand_ = {<tr><td><a name="l96" href="#l96">96</a><td> name: command.getName(),<tr><td><a name="l97" href="#l97">97</a><td> callback: callback<tr><td><a name="l98" href="#l98">98</a><td> };<tr><td><a name="l99" href="#l99">99</a><td><tr><td><a name="l100" href="#l100">100</a><td> var parameters = command.getParameters();<tr><td><a name="l101" href="#l101">101</a><td><tr><td><a name="l102" href="#l102">102</a><td> // There are two means for communicating with the FirefoxDriver: via<tr><td><a name="l103" href="#l103">103</a><td> // HTTP using WebDriver&#39;s wire protocol and over the DOM using a custom<tr><td><a name="l104" href="#l104">104</a><td> // JSON protocol. This class uses the latter. When the FirefoxDriver receives<tr><td><a name="l105" href="#l105">105</a><td> // commands over HTTP, it builds a parameters object from the URL parameters.<tr><td><a name="l106" href="#l106">106</a><td> // When an element ID is sent in the URL, it&#39;ll be decoded as just id:string<tr><td><a name="l107" href="#l107">107</a><td> // instead of id:{ELEMENT:string}. When switching to a frame by element,<tr><td><a name="l108" href="#l108">108</a><td> // however, the element ID is not sent through the URL, so we must make sure<tr><td><a name="l109" href="#l109">109</a><td> // to encode that parameter properly here. It would be nice if we unified<tr><td><a name="l110" href="#l110">110</a><td> // the two protocols used by the FirefoxDriver...<tr><td><a name="l111" href="#l111">111</a><td> if (parameters[&#39;id&#39;] &amp;&amp;<tr><td><a name="l112" href="#l112">112</a><td> parameters[&#39;id&#39;][&#39;ELEMENT&#39;] &amp;&amp;<tr><td><a name="l113" href="#l113">113</a><td> command.getName() != webdriver.CommandName.SWITCH_TO_FRAME) {<tr><td><a name="l114" href="#l114">114</a><td> parameters[&#39;id&#39;] = parameters[&#39;id&#39;][&#39;ELEMENT&#39;];<tr><td><a name="l115" href="#l115">115</a><td> }<tr><td><a name="l116" href="#l116">116</a><td> var json = goog.json.serialize({<tr><td><a name="l117" href="#l117">117</a><td> &#39;name&#39;: command.getName(),<tr><td><a name="l118" href="#l118">118</a><td> &#39;sessionId&#39;: parameters[&#39;sessionId&#39;],<tr><td><a name="l119" href="#l119">119</a><td> &#39;parameters&#39;: parameters<tr><td><a name="l120" href="#l120">120</a><td> });<tr><td><a name="l121" href="#l121">121</a><td> this.docElement_.setAttribute(<tr><td><a name="l122" href="#l122">122</a><td> webdriver.FirefoxDomExecutor.Attribute_.COMMAND, json);<tr><td><a name="l123" href="#l123">123</a><td><tr><td><a name="l124" href="#l124">124</a><td> var event = this.doc_.createEvent(&#39;Event&#39;);<tr><td><a name="l125" href="#l125">125</a><td> event.initEvent(webdriver.FirefoxDomExecutor.EventType_.COMMAND,<tr><td><a name="l126" href="#l126">126</a><td> /*canBubble=*/true, /*cancelable=*/true);<tr><td><a name="l127" href="#l127">127</a><td><tr><td><a name="l128" href="#l128">128</a><td> this.docElement_.dispatchEvent(event);<tr><td><a name="l129" href="#l129">129</a><td>};<tr><td><a name="l130" href="#l130">130</a><td><tr><td><a name="l131" href="#l131">131</a><td><tr><td><a name="l132" href="#l132">132</a><td>/** @private */<tr><td><a name="l133" href="#l133">133</a><td>webdriver.FirefoxDomExecutor.prototype.onResponse_ = function() {<tr><td><a name="l134" href="#l134">134</a><td> if (!this.pendingCommand_) {<tr><td><a name="l135" href="#l135">135</a><td> return; // Not expecting a response.<tr><td><a name="l136" href="#l136">136</a><td> }<tr><td><a name="l137" href="#l137">137</a><td><tr><td><a name="l138" href="#l138">138</a><td> var command = this.pendingCommand_;<tr><td><a name="l139" href="#l139">139</a><td> this.pendingCommand_ = null;<tr><td><a name="l140" href="#l140">140</a><td><tr><td><a name="l141" href="#l141">141</a><td> var json = this.docElement_.getAttribute(<tr><td><a name="l142" href="#l142">142</a><td> webdriver.FirefoxDomExecutor.Attribute_.RESPONSE);<tr><td><a name="l143" href="#l143">143</a><td> if (!json) {<tr><td><a name="l144" href="#l144">144</a><td> command.callback(Error(&#39;Empty command response!&#39;));<tr><td><a name="l145" href="#l145">145</a><td> return;<tr><td><a name="l146" href="#l146">146</a><td> }<tr><td><a name="l147" href="#l147">147</a><td><tr><td><a name="l148" href="#l148">148</a><td> this.docElement_.removeAttribute(<tr><td><a name="l149" href="#l149">149</a><td> webdriver.FirefoxDomExecutor.Attribute_.COMMAND);<tr><td><a name="l150" href="#l150">150</a><td> this.docElement_.removeAttribute(<tr><td><a name="l151" href="#l151">151</a><td> webdriver.FirefoxDomExecutor.Attribute_.RESPONSE);<tr><td><a name="l152" href="#l152">152</a><td><tr><td><a name="l153" href="#l153">153</a><td> try {<tr><td><a name="l154" href="#l154">154</a><td> var response = bot.response.checkResponse(<tr><td><a name="l155" href="#l155">155</a><td> /** @type {!bot.response.ResponseObject} */ (goog.json.parse(json)));<tr><td><a name="l156" href="#l156">156</a><td> } catch (ex) {<tr><td><a name="l157" href="#l157">157</a><td> command.callback(ex);<tr><td><a name="l158" href="#l158">158</a><td> return;<tr><td><a name="l159" href="#l159">159</a><td> }<tr><td><a name="l160" href="#l160">160</a><td><tr><td><a name="l161" href="#l161">161</a><td> // Prior to Selenium 2.35.0, two commands are required to fully create a<tr><td><a name="l162" href="#l162">162</a><td> // session: one to allocate the session, and another to fetch the<tr><td><a name="l163" href="#l163">163</a><td> // capabilities.<tr><td><a name="l164" href="#l164">164</a><td> if (command.name == webdriver.CommandName.NEW_SESSION &amp;&amp;<tr><td><a name="l165" href="#l165">165</a><td> goog.isString(response[&#39;value&#39;])) {<tr><td><a name="l166" href="#l166">166</a><td> var cmd = new webdriver.Command(webdriver.CommandName.DESCRIBE_SESSION).<tr><td><a name="l167" href="#l167">167</a><td> setParameter(&#39;sessionId&#39;, response[&#39;value&#39;]);<tr><td><a name="l168" href="#l168">168</a><td> this.execute(cmd, command.callback);<tr><td><a name="l169" href="#l169">169</a><td> } else {<tr><td><a name="l170" href="#l170">170</a><td> command.callback(null, response);<tr><td><a name="l171" href="#l171">171</a><td> }<tr><td><a name="l172" href="#l172">172</a><td>};</table></pre></main><nav id="topnav"><div><div id="menubutton"><label for="sidenav-toggle">Menu</label></div><form id="searchbox"><div><input type="search" placeholder="Search" tabindex="1"></div></form></div></nav><nav id="sidenav"><input type="checkbox" id="sidenav-types-ctrl" /><input type="checkbox" id="sidenav-files-ctrl" /><input type="checkbox" id="sidenav-modules-ctrl" /><a id="sidenav-overview"><div><h4>Overview</h4></div></a><div id="sidenav-types"><label for="sidenav-types-ctrl"><h4>Types</h4></label><i>Loading</i></div><div id="sidenav-modules"><label for="sidenav-modules-ctrl"><h4>Modules</h4></label><i>Loading</i></div><div id="sidenav-files"><label for="sidenav-files-ctrl"><h4>Files</h4></label><i>Loading</i></div><a href="../../../license.html"><div><h4>License</h4></div></a></nav><div id="push-footer"></div></div><footer><a href="https://github.com/jleyba/js-dossier">Generated by dossier</a></footer><script src="../../../types.js"></script><script src="../../../dossier.js"></script>
@@ -1 +1 @@
1
- <!DOCTYPE html><meta charset="UTF-8"><meta http-equiv="Content-Language" content="en" /><title>corsclient.js</title><link href="../../../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>lib/webdriver/http/corsclient.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.<tr><td><a name="l2" href="#l2">2</a><td>//<tr><td><a name="l3" href="#l3">3</a><td>// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);<tr><td><a name="l4" href="#l4">4</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l5" href="#l5">5</a><td>// You may obtain a copy of the License at<tr><td><a name="l6" href="#l6">6</a><td>//<tr><td><a name="l7" href="#l7">7</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l8" href="#l8">8</a><td>//<tr><td><a name="l9" href="#l9">9</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l10" href="#l10">10</a><td>// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,<tr><td><a name="l11" href="#l11">11</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l12" href="#l12">12</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l13" href="#l13">13</a><td>// limitations under the License.<tr><td><a name="l14" href="#l14">14</a><td><tr><td><a name="l15" href="#l15">15</a><td>goog.provide(&#39;webdriver.http.CorsClient&#39;);<tr><td><a name="l16" href="#l16">16</a><td><tr><td><a name="l17" href="#l17">17</a><td>goog.require(&#39;goog.json&#39;);<tr><td><a name="l18" href="#l18">18</a><td>goog.require(&#39;webdriver.http.Response&#39;);<tr><td><a name="l19" href="#l19">19</a><td><tr><td><a name="l20" href="#l20">20</a><td><tr><td><a name="l21" href="#l21">21</a><td><tr><td><a name="l22" href="#l22">22</a><td>/**<tr><td><a name="l23" href="#l23">23</a><td> * Communicates with a WebDriver server, which may be on a different domain,<tr><td><a name="l24" href="#l24">24</a><td> * using the &lt;a href=&quot;http://www.w3.org/TR/cors/&quot;&gt;cross-origin resource sharing<tr><td><a name="l25" href="#l25">25</a><td> * &lt;/a&gt; (CORS) extension to WebDriver&#39;s JSON wire protocol.<tr><td><a name="l26" href="#l26">26</a><td> *<tr><td><a name="l27" href="#l27">27</a><td> * &lt;p&gt;Each command from the standard JSON protocol will be encoded in a<tr><td><a name="l28" href="#l28">28</a><td> * JSON object with the following form:<tr><td><a name="l29" href="#l29">29</a><td> * {method:string, path:string, data:!Object}<tr><td><a name="l30" href="#l30">30</a><td> *<tr><td><a name="l31" href="#l31">31</a><td> * &lt;p&gt;The encoded command is then sent as a POST request to the server&#39;s /xdrpc<tr><td><a name="l32" href="#l32">32</a><td> * endpoint. The server will decode the command, re-route it to the appropriate<tr><td><a name="l33" href="#l33">33</a><td> * handler, and then return the command&#39;s response as a standard JSON response<tr><td><a name="l34" href="#l34">34</a><td> * object. The JSON responses will &lt;em&gt;always&lt;/em&gt; be returned with a 200<tr><td><a name="l35" href="#l35">35</a><td> * response from the server; clients must rely on the response&#39;s &quot;status&quot; field<tr><td><a name="l36" href="#l36">36</a><td> * to determine whether the command succeeded.<tr><td><a name="l37" href="#l37">37</a><td> *<tr><td><a name="l38" href="#l38">38</a><td> * &lt;p&gt;This client cannot be used with the standard wire protocol due to<tr><td><a name="l39" href="#l39">39</a><td> * limitations in the various browser implementations of the CORS specification:<tr><td><a name="l40" href="#l40">40</a><td> * &lt;ul&gt;<tr><td><a name="l41" href="#l41">41</a><td> * &lt;li&gt;IE&#39;s &lt;a href=&quot;http://goo.gl/6l3kA&quot;&gt;XDomainRequest&lt;/a&gt; object is only<tr><td><a name="l42" href="#l42">42</a><td> * capable of generating the types of requests that may be generated through<tr><td><a name="l43" href="#l43">43</a><td> * a standard &lt;a href=&quot;http://goo.gl/vgzAU&quot;&gt;HTML form&lt;/a&gt; - it can not send<tr><td><a name="l44" href="#l44">44</a><td> * DELETE requests, as is required in the wire protocol.<tr><td><a name="l45" href="#l45">45</a><td> * &lt;li&gt;WebKit&#39;s implementation of CORS does not follow the spec and forbids<tr><td><a name="l46" href="#l46">46</a><td> * redirects: https://bugs.webkit.org/show_bug.cgi?id=57600<tr><td><a name="l47" href="#l47">47</a><td> * This limitation appears to be intentional and is documented in WebKit&#39;s<tr><td><a name="l48" href="#l48">48</a><td> * Layout tests:<tr><td><a name="l49" href="#l49">49</a><td> * //LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects.html<tr><td><a name="l50" href="#l50">50</a><td> * &lt;li&gt;If the server does not return a 2xx response, IE and Opera&#39;s<tr><td><a name="l51" href="#l51">51</a><td> * implementations will fire the XDomainRequest/XMLHttpRequest object&#39;s<tr><td><a name="l52" href="#l52">52</a><td> * onerror handler, but without the corresponding response text returned by<tr><td><a name="l53" href="#l53">53</a><td> * the server. This renders IE and Opera incapable of handling command<tr><td><a name="l54" href="#l54">54</a><td> * failures in the standard JSON protocol.<tr><td><a name="l55" href="#l55">55</a><td> * &lt;/ul&gt;<tr><td><a name="l56" href="#l56">56</a><td> *<tr><td><a name="l57" href="#l57">57</a><td> * @param {string} url URL for the WebDriver server to send commands to.<tr><td><a name="l58" href="#l58">58</a><td> * @constructor<tr><td><a name="l59" href="#l59">59</a><td> * @implements {webdriver.http.Client}<tr><td><a name="l60" href="#l60">60</a><td> * @see &lt;a href=&quot;http://www.w3.org/TR/cors/&quot;&gt;CORS Spec&lt;/a&gt;<tr><td><a name="l61" href="#l61">61</a><td> * @see &lt;a href=&quot;http://code.google.com/p/selenium/wiki/JsonWireProtocol&quot;&gt;<tr><td><a name="l62" href="#l62">62</a><td> * JSON wire protocol&lt;/a&gt;<tr><td><a name="l63" href="#l63">63</a><td> */<tr><td><a name="l64" href="#l64">64</a><td>webdriver.http.CorsClient = function(url) {<tr><td><a name="l65" href="#l65">65</a><td> if (!webdriver.http.CorsClient.isAvailable()) {<tr><td><a name="l66" href="#l66">66</a><td> throw Error(&#39;The current environment does not support cross-origin &#39; +<tr><td><a name="l67" href="#l67">67</a><td> &#39;resource sharing&#39;);<tr><td><a name="l68" href="#l68">68</a><td> }<tr><td><a name="l69" href="#l69">69</a><td><tr><td><a name="l70" href="#l70">70</a><td> /** @private {string} */<tr><td><a name="l71" href="#l71">71</a><td> this.url_ = url + webdriver.http.CorsClient.XDRPC_ENDPOINT;<tr><td><a name="l72" href="#l72">72</a><td>};<tr><td><a name="l73" href="#l73">73</a><td><tr><td><a name="l74" href="#l74">74</a><td><tr><td><a name="l75" href="#l75">75</a><td>/**<tr><td><a name="l76" href="#l76">76</a><td> * Resource URL to send commands to on the server.<tr><td><a name="l77" href="#l77">77</a><td> * @type {string}<tr><td><a name="l78" href="#l78">78</a><td> * @const<tr><td><a name="l79" href="#l79">79</a><td> */<tr><td><a name="l80" href="#l80">80</a><td>webdriver.http.CorsClient.XDRPC_ENDPOINT = &#39;/xdrpc&#39;;<tr><td><a name="l81" href="#l81">81</a><td><tr><td><a name="l82" href="#l82">82</a><td><tr><td><a name="l83" href="#l83">83</a><td>/**<tr><td><a name="l84" href="#l84">84</a><td> * Tests whether the current environment supports cross-origin resource sharing.<tr><td><a name="l85" href="#l85">85</a><td> * @return {boolean} Whether cross-origin resource sharing is supported.<tr><td><a name="l86" href="#l86">86</a><td> * @see http://www.w3.org/TR/cors/<tr><td><a name="l87" href="#l87">87</a><td> */<tr><td><a name="l88" href="#l88">88</a><td>webdriver.http.CorsClient.isAvailable = function() {<tr><td><a name="l89" href="#l89">89</a><td> return typeof XDomainRequest !== &#39;undefined&#39; ||<tr><td><a name="l90" href="#l90">90</a><td> (typeof XMLHttpRequest !== &#39;undefined&#39; &amp;&amp;<tr><td><a name="l91" href="#l91">91</a><td> goog.isBoolean(new XMLHttpRequest().withCredentials));<tr><td><a name="l92" href="#l92">92</a><td>};<tr><td><a name="l93" href="#l93">93</a><td><tr><td><a name="l94" href="#l94">94</a><td><tr><td><a name="l95" href="#l95">95</a><td>/** @override */<tr><td><a name="l96" href="#l96">96</a><td>webdriver.http.CorsClient.prototype.send = function(request, callback) {<tr><td><a name="l97" href="#l97">97</a><td> try {<tr><td><a name="l98" href="#l98">98</a><td> var xhr = new (typeof XDomainRequest !== &#39;undefined&#39; ?<tr><td><a name="l99" href="#l99">99</a><td> XDomainRequest : XMLHttpRequest);<tr><td><a name="l100" href="#l100">100</a><td> xhr.open(&#39;POST&#39;, this.url_, true);<tr><td><a name="l101" href="#l101">101</a><td><tr><td><a name="l102" href="#l102">102</a><td> xhr.onload = function() {<tr><td><a name="l103" href="#l103">103</a><td> callback(null, webdriver.http.Response.fromXmlHttpRequest(<tr><td><a name="l104" href="#l104">104</a><td> /** @type {!XMLHttpRequest} */ (xhr)));<tr><td><a name="l105" href="#l105">105</a><td> };<tr><td><a name="l106" href="#l106">106</a><td><tr><td><a name="l107" href="#l107">107</a><td> var url = this.url_;<tr><td><a name="l108" href="#l108">108</a><td> xhr.onerror = function() {<tr><td><a name="l109" href="#l109">109</a><td> callback(Error([<tr><td><a name="l110" href="#l110">110</a><td> &#39;Unable to send request: POST &#39;, url,<tr><td><a name="l111" href="#l111">111</a><td> &#39;\nPerhaps the server did not respond to the preflight request &#39;,<tr><td><a name="l112" href="#l112">112</a><td> &#39;with valid access control headers?&#39;<tr><td><a name="l113" href="#l113">113</a><td> ].join(&#39;&#39;)));<tr><td><a name="l114" href="#l114">114</a><td> };<tr><td><a name="l115" href="#l115">115</a><td><tr><td><a name="l116" href="#l116">116</a><td> // Define event handlers for all events on the XDomainRequest. Apparently,<tr><td><a name="l117" href="#l117">117</a><td> // if we don&#39;t do this, IE9+10 will silently abort our request. Yay IE.<tr><td><a name="l118" href="#l118">118</a><td> // Note, we&#39;re not using goog.nullFunction, because it tends to get<tr><td><a name="l119" href="#l119">119</a><td> // optimized away by the compiler, which leaves us where we were before.<tr><td><a name="l120" href="#l120">120</a><td> xhr.onprogress = xhr.ontimeout = function() {};<tr><td><a name="l121" href="#l121">121</a><td><tr><td><a name="l122" href="#l122">122</a><td> xhr.send(goog.json.serialize({<tr><td><a name="l123" href="#l123">123</a><td> &#39;method&#39;: request.method,<tr><td><a name="l124" href="#l124">124</a><td> &#39;path&#39;: request.path,<tr><td><a name="l125" href="#l125">125</a><td> &#39;data&#39;: request.data<tr><td><a name="l126" href="#l126">126</a><td> }));<tr><td><a name="l127" href="#l127">127</a><td> } catch (ex) {<tr><td><a name="l128" href="#l128">128</a><td> callback(ex);<tr><td><a name="l129" href="#l129">129</a><td> }<tr><td><a name="l130" href="#l130">130</a><td>};</table></pre></main><nav id="topnav"><div><div id="menubutton"><label for="sidenav-toggle">Menu</label></div><form id="searchbox"><div><input type="search" placeholder="Search" tabindex="1"></div></form></div></nav><nav id="sidenav"><input type="checkbox" id="sidenav-types-ctrl" /><input type="checkbox" id="sidenav-files-ctrl" /><input type="checkbox" id="sidenav-modules-ctrl" /><a id="sidenav-overview"><div><h4>Overview</h4></div></a><div id="sidenav-types"><label for="sidenav-types-ctrl"><h4>Types</h4></label><i>Loading</i></div><div id="sidenav-modules"><label for="sidenav-modules-ctrl"><h4>Modules</h4></label><i>Loading</i></div><div id="sidenav-files"><label for="sidenav-files-ctrl"><h4>Files</h4></label><i>Loading</i></div><a href="license.html"><div><h4>License</h4></div></a></nav><div id="push-footer"></div></div><footer><a href="https://github.com/jleyba/js-dossier">Generated by dossier</a></footer><script src="../../../../types.js"></script><script src="../../../../dossier.js"></script>
1
+ <!DOCTYPE html><meta charset="UTF-8"><meta http-equiv="Content-Language" content="en" /><title>corsclient.js</title><link href="../../../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>lib/webdriver/http/corsclient.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.<tr><td><a name="l2" href="#l2">2</a><td>//<tr><td><a name="l3" href="#l3">3</a><td>// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);<tr><td><a name="l4" href="#l4">4</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l5" href="#l5">5</a><td>// You may obtain a copy of the License at<tr><td><a name="l6" href="#l6">6</a><td>//<tr><td><a name="l7" href="#l7">7</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l8" href="#l8">8</a><td>//<tr><td><a name="l9" href="#l9">9</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l10" href="#l10">10</a><td>// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,<tr><td><a name="l11" href="#l11">11</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l12" href="#l12">12</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l13" href="#l13">13</a><td>// limitations under the License.<tr><td><a name="l14" href="#l14">14</a><td><tr><td><a name="l15" href="#l15">15</a><td>goog.provide(&#39;webdriver.http.CorsClient&#39;);<tr><td><a name="l16" href="#l16">16</a><td><tr><td><a name="l17" href="#l17">17</a><td>goog.require(&#39;goog.json&#39;);<tr><td><a name="l18" href="#l18">18</a><td>goog.require(&#39;webdriver.http.Response&#39;);<tr><td><a name="l19" href="#l19">19</a><td><tr><td><a name="l20" href="#l20">20</a><td><tr><td><a name="l21" href="#l21">21</a><td><tr><td><a name="l22" href="#l22">22</a><td>/**<tr><td><a name="l23" href="#l23">23</a><td> * Communicates with a WebDriver server, which may be on a different domain,<tr><td><a name="l24" href="#l24">24</a><td> * using the &lt;a href=&quot;http://www.w3.org/TR/cors/&quot;&gt;cross-origin resource sharing<tr><td><a name="l25" href="#l25">25</a><td> * &lt;/a&gt; (CORS) extension to WebDriver&#39;s JSON wire protocol.<tr><td><a name="l26" href="#l26">26</a><td> *<tr><td><a name="l27" href="#l27">27</a><td> * &lt;p&gt;Each command from the standard JSON protocol will be encoded in a<tr><td><a name="l28" href="#l28">28</a><td> * JSON object with the following form:<tr><td><a name="l29" href="#l29">29</a><td> * {method:string, path:string, data:!Object}<tr><td><a name="l30" href="#l30">30</a><td> *<tr><td><a name="l31" href="#l31">31</a><td> * &lt;p&gt;The encoded command is then sent as a POST request to the server&#39;s /xdrpc<tr><td><a name="l32" href="#l32">32</a><td> * endpoint. The server will decode the command, re-route it to the appropriate<tr><td><a name="l33" href="#l33">33</a><td> * handler, and then return the command&#39;s response as a standard JSON response<tr><td><a name="l34" href="#l34">34</a><td> * object. The JSON responses will &lt;em&gt;always&lt;/em&gt; be returned with a 200<tr><td><a name="l35" href="#l35">35</a><td> * response from the server; clients must rely on the response&#39;s &quot;status&quot; field<tr><td><a name="l36" href="#l36">36</a><td> * to determine whether the command succeeded.<tr><td><a name="l37" href="#l37">37</a><td> *<tr><td><a name="l38" href="#l38">38</a><td> * &lt;p&gt;This client cannot be used with the standard wire protocol due to<tr><td><a name="l39" href="#l39">39</a><td> * limitations in the various browser implementations of the CORS specification:<tr><td><a name="l40" href="#l40">40</a><td> * &lt;ul&gt;<tr><td><a name="l41" href="#l41">41</a><td> * &lt;li&gt;IE&#39;s &lt;a href=&quot;http://goo.gl/6l3kA&quot;&gt;XDomainRequest&lt;/a&gt; object is only<tr><td><a name="l42" href="#l42">42</a><td> * capable of generating the types of requests that may be generated through<tr><td><a name="l43" href="#l43">43</a><td> * a standard &lt;a href=&quot;http://goo.gl/vgzAU&quot;&gt;HTML form&lt;/a&gt; - it can not send<tr><td><a name="l44" href="#l44">44</a><td> * DELETE requests, as is required in the wire protocol.<tr><td><a name="l45" href="#l45">45</a><td> * &lt;li&gt;WebKit&#39;s implementation of CORS does not follow the spec and forbids<tr><td><a name="l46" href="#l46">46</a><td> * redirects: https://bugs.webkit.org/show_bug.cgi?id=57600<tr><td><a name="l47" href="#l47">47</a><td> * This limitation appears to be intentional and is documented in WebKit&#39;s<tr><td><a name="l48" href="#l48">48</a><td> * Layout tests:<tr><td><a name="l49" href="#l49">49</a><td> * //LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects.html<tr><td><a name="l50" href="#l50">50</a><td> * &lt;li&gt;If the server does not return a 2xx response, IE and Opera&#39;s<tr><td><a name="l51" href="#l51">51</a><td> * implementations will fire the XDomainRequest/XMLHttpRequest object&#39;s<tr><td><a name="l52" href="#l52">52</a><td> * onerror handler, but without the corresponding response text returned by<tr><td><a name="l53" href="#l53">53</a><td> * the server. This renders IE and Opera incapable of handling command<tr><td><a name="l54" href="#l54">54</a><td> * failures in the standard JSON protocol.<tr><td><a name="l55" href="#l55">55</a><td> * &lt;/ul&gt;<tr><td><a name="l56" href="#l56">56</a><td> *<tr><td><a name="l57" href="#l57">57</a><td> * @param {string} url URL for the WebDriver server to send commands to.<tr><td><a name="l58" href="#l58">58</a><td> * @constructor<tr><td><a name="l59" href="#l59">59</a><td> * @implements {webdriver.http.Client}<tr><td><a name="l60" href="#l60">60</a><td> * @see &lt;a href=&quot;http://www.w3.org/TR/cors/&quot;&gt;CORS Spec&lt;/a&gt;<tr><td><a name="l61" href="#l61">61</a><td> * @see &lt;a href=&quot;http://code.google.com/p/selenium/wiki/JsonWireProtocol&quot;&gt;<tr><td><a name="l62" href="#l62">62</a><td> * JSON wire protocol&lt;/a&gt;<tr><td><a name="l63" href="#l63">63</a><td> */<tr><td><a name="l64" href="#l64">64</a><td>webdriver.http.CorsClient = function(url) {<tr><td><a name="l65" href="#l65">65</a><td> if (!webdriver.http.CorsClient.isAvailable()) {<tr><td><a name="l66" href="#l66">66</a><td> throw Error(&#39;The current environment does not support cross-origin &#39; +<tr><td><a name="l67" href="#l67">67</a><td> &#39;resource sharing&#39;);<tr><td><a name="l68" href="#l68">68</a><td> }<tr><td><a name="l69" href="#l69">69</a><td><tr><td><a name="l70" href="#l70">70</a><td> /** @private {string} */<tr><td><a name="l71" href="#l71">71</a><td> this.url_ = url + webdriver.http.CorsClient.XDRPC_ENDPOINT;<tr><td><a name="l72" href="#l72">72</a><td>};<tr><td><a name="l73" href="#l73">73</a><td><tr><td><a name="l74" href="#l74">74</a><td><tr><td><a name="l75" href="#l75">75</a><td>/**<tr><td><a name="l76" href="#l76">76</a><td> * Resource URL to send commands to on the server.<tr><td><a name="l77" href="#l77">77</a><td> * @type {string}<tr><td><a name="l78" href="#l78">78</a><td> * @const<tr><td><a name="l79" href="#l79">79</a><td> */<tr><td><a name="l80" href="#l80">80</a><td>webdriver.http.CorsClient.XDRPC_ENDPOINT = &#39;/xdrpc&#39;;<tr><td><a name="l81" href="#l81">81</a><td><tr><td><a name="l82" href="#l82">82</a><td><tr><td><a name="l83" href="#l83">83</a><td>/**<tr><td><a name="l84" href="#l84">84</a><td> * Tests whether the current environment supports cross-origin resource sharing.<tr><td><a name="l85" href="#l85">85</a><td> * @return {boolean} Whether cross-origin resource sharing is supported.<tr><td><a name="l86" href="#l86">86</a><td> * @see http://www.w3.org/TR/cors/<tr><td><a name="l87" href="#l87">87</a><td> */<tr><td><a name="l88" href="#l88">88</a><td>webdriver.http.CorsClient.isAvailable = function() {<tr><td><a name="l89" href="#l89">89</a><td> return typeof XDomainRequest !== &#39;undefined&#39; ||<tr><td><a name="l90" href="#l90">90</a><td> (typeof XMLHttpRequest !== &#39;undefined&#39; &amp;&amp;<tr><td><a name="l91" href="#l91">91</a><td> goog.isBoolean(new XMLHttpRequest().withCredentials));<tr><td><a name="l92" href="#l92">92</a><td>};<tr><td><a name="l93" href="#l93">93</a><td><tr><td><a name="l94" href="#l94">94</a><td><tr><td><a name="l95" href="#l95">95</a><td>/** @override */<tr><td><a name="l96" href="#l96">96</a><td>webdriver.http.CorsClient.prototype.send = function(request, callback) {<tr><td><a name="l97" href="#l97">97</a><td> try {<tr><td><a name="l98" href="#l98">98</a><td> var xhr = new (typeof XDomainRequest !== &#39;undefined&#39; ?<tr><td><a name="l99" href="#l99">99</a><td> XDomainRequest : XMLHttpRequest);<tr><td><a name="l100" href="#l100">100</a><td> xhr.open(&#39;POST&#39;, this.url_, true);<tr><td><a name="l101" href="#l101">101</a><td><tr><td><a name="l102" href="#l102">102</a><td> xhr.onload = function() {<tr><td><a name="l103" href="#l103">103</a><td> callback(null, webdriver.http.Response.fromXmlHttpRequest(<tr><td><a name="l104" href="#l104">104</a><td> /** @type {!XMLHttpRequest} */ (xhr)));<tr><td><a name="l105" href="#l105">105</a><td> };<tr><td><a name="l106" href="#l106">106</a><td><tr><td><a name="l107" href="#l107">107</a><td> var url = this.url_;<tr><td><a name="l108" href="#l108">108</a><td> xhr.onerror = function() {<tr><td><a name="l109" href="#l109">109</a><td> callback(Error([<tr><td><a name="l110" href="#l110">110</a><td> &#39;Unable to send request: POST &#39;, url,<tr><td><a name="l111" href="#l111">111</a><td> &#39;\nPerhaps the server did not respond to the preflight request &#39;,<tr><td><a name="l112" href="#l112">112</a><td> &#39;with valid access control headers?&#39;<tr><td><a name="l113" href="#l113">113</a><td> ].join(&#39;&#39;)));<tr><td><a name="l114" href="#l114">114</a><td> };<tr><td><a name="l115" href="#l115">115</a><td><tr><td><a name="l116" href="#l116">116</a><td> // Define event handlers for all events on the XDomainRequest. Apparently,<tr><td><a name="l117" href="#l117">117</a><td> // if we don&#39;t do this, IE9+10 will silently abort our request. Yay IE.<tr><td><a name="l118" href="#l118">118</a><td> // Note, we&#39;re not using goog.nullFunction, because it tends to get<tr><td><a name="l119" href="#l119">119</a><td> // optimized away by the compiler, which leaves us where we were before.<tr><td><a name="l120" href="#l120">120</a><td> xhr.onprogress = xhr.ontimeout = function() {};<tr><td><a name="l121" href="#l121">121</a><td><tr><td><a name="l122" href="#l122">122</a><td> xhr.send(goog.json.serialize({<tr><td><a name="l123" href="#l123">123</a><td> &#39;method&#39;: request.method,<tr><td><a name="l124" href="#l124">124</a><td> &#39;path&#39;: request.path,<tr><td><a name="l125" href="#l125">125</a><td> &#39;data&#39;: request.data<tr><td><a name="l126" href="#l126">126</a><td> }));<tr><td><a name="l127" href="#l127">127</a><td> } catch (ex) {<tr><td><a name="l128" href="#l128">128</a><td> callback(ex);<tr><td><a name="l129" href="#l129">129</a><td> }<tr><td><a name="l130" href="#l130">130</a><td>};</table></pre></main><nav id="topnav"><div><div id="menubutton"><label for="sidenav-toggle">Menu</label></div><form id="searchbox"><div><input type="search" placeholder="Search" tabindex="1"></div></form></div></nav><nav id="sidenav"><input type="checkbox" id="sidenav-types-ctrl" /><input type="checkbox" id="sidenav-files-ctrl" /><input type="checkbox" id="sidenav-modules-ctrl" /><a id="sidenav-overview"><div><h4>Overview</h4></div></a><div id="sidenav-types"><label for="sidenav-types-ctrl"><h4>Types</h4></label><i>Loading</i></div><div id="sidenav-modules"><label for="sidenav-modules-ctrl"><h4>Modules</h4></label><i>Loading</i></div><div id="sidenav-files"><label for="sidenav-files-ctrl"><h4>Files</h4></label><i>Loading</i></div><a href="../../../../license.html"><div><h4>License</h4></div></a></nav><div id="push-footer"></div></div><footer><a href="https://github.com/jleyba/js-dossier">Generated by dossier</a></footer><script src="../../../../types.js"></script><script src="../../../../dossier.js"></script>
@@ -1 +1 @@
1
- <!DOCTYPE html><meta charset="UTF-8"><meta http-equiv="Content-Language" content="en" /><title>http.js</title><link href="../../../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>lib/webdriver/http/http.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.<tr><td><a name="l2" href="#l2">2</a><td>//<tr><td><a name="l3" href="#l3">3</a><td>// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);<tr><td><a name="l4" href="#l4">4</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l5" href="#l5">5</a><td>// You may obtain a copy of the License at<tr><td><a name="l6" href="#l6">6</a><td>//<tr><td><a name="l7" href="#l7">7</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l8" href="#l8">8</a><td>//<tr><td><a name="l9" href="#l9">9</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l10" href="#l10">10</a><td>// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,<tr><td><a name="l11" href="#l11">11</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l12" href="#l12">12</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l13" href="#l13">13</a><td>// limitations under the License.<tr><td><a name="l14" href="#l14">14</a><td><tr><td><a name="l15" href="#l15">15</a><td>/**<tr><td><a name="l16" href="#l16">16</a><td> * @fileoverview Defines a {@code webdriver.CommandExecutor} that communicates<tr><td><a name="l17" href="#l17">17</a><td> * with a server over HTTP.<tr><td><a name="l18" href="#l18">18</a><td> */<tr><td><a name="l19" href="#l19">19</a><td><tr><td><a name="l20" href="#l20">20</a><td>goog.provide(&#39;webdriver.http.Client&#39;);<tr><td><a name="l21" href="#l21">21</a><td>goog.provide(&#39;webdriver.http.Executor&#39;);<tr><td><a name="l22" href="#l22">22</a><td>goog.provide(&#39;webdriver.http.Request&#39;);<tr><td><a name="l23" href="#l23">23</a><td>goog.provide(&#39;webdriver.http.Response&#39;);<tr><td><a name="l24" href="#l24">24</a><td><tr><td><a name="l25" href="#l25">25</a><td>goog.require(&#39;bot.ErrorCode&#39;);<tr><td><a name="l26" href="#l26">26</a><td>goog.require(&#39;goog.array&#39;);<tr><td><a name="l27" href="#l27">27</a><td>goog.require(&#39;goog.json&#39;);<tr><td><a name="l28" href="#l28">28</a><td>goog.require(&#39;webdriver.CommandName&#39;);<tr><td><a name="l29" href="#l29">29</a><td>goog.require(&#39;webdriver.promise.Deferred&#39;);<tr><td><a name="l30" href="#l30">30</a><td><tr><td><a name="l31" href="#l31">31</a><td><tr><td><a name="l32" href="#l32">32</a><td><tr><td><a name="l33" href="#l33">33</a><td>/**<tr><td><a name="l34" href="#l34">34</a><td> * Interface used for sending individual HTTP requests to the server.<tr><td><a name="l35" href="#l35">35</a><td> * @interface<tr><td><a name="l36" href="#l36">36</a><td> */<tr><td><a name="l37" href="#l37">37</a><td>webdriver.http.Client = function() {<tr><td><a name="l38" href="#l38">38</a><td>};<tr><td><a name="l39" href="#l39">39</a><td><tr><td><a name="l40" href="#l40">40</a><td><tr><td><a name="l41" href="#l41">41</a><td>/**<tr><td><a name="l42" href="#l42">42</a><td> * Sends a request to the server. If an error occurs while sending the request,<tr><td><a name="l43" href="#l43">43</a><td> * such as a failure to connect to the server, the provided callback will be<tr><td><a name="l44" href="#l44">44</a><td> * invoked with a non-null {@code Error} describing the error. Otherwise, when<tr><td><a name="l45" href="#l45">45</a><td> * the server&#39;s response has been received, the callback will be invoked with a<tr><td><a name="l46" href="#l46">46</a><td> * null Error and non-null {@code webdriver.http.Response} object.<tr><td><a name="l47" href="#l47">47</a><td> *<tr><td><a name="l48" href="#l48">48</a><td> * @param {!webdriver.http.Request} request The request to send.<tr><td><a name="l49" href="#l49">49</a><td> * @param {function(Error, !webdriver.http.Response=)} callback the function to<tr><td><a name="l50" href="#l50">50</a><td> * invoke when the server&#39;s response is ready.<tr><td><a name="l51" href="#l51">51</a><td> */<tr><td><a name="l52" href="#l52">52</a><td>webdriver.http.Client.prototype.send = function(request, callback) {<tr><td><a name="l53" href="#l53">53</a><td>};<tr><td><a name="l54" href="#l54">54</a><td><tr><td><a name="l55" href="#l55">55</a><td><tr><td><a name="l56" href="#l56">56</a><td><tr><td><a name="l57" href="#l57">57</a><td>/**<tr><td><a name="l58" href="#l58">58</a><td> * A command executor that communicates with a server using the WebDriver<tr><td><a name="l59" href="#l59">59</a><td> * command protocol.<tr><td><a name="l60" href="#l60">60</a><td> * @param {!webdriver.http.Client} client The client to use when sending<tr><td><a name="l61" href="#l61">61</a><td> * requests to the server.<tr><td><a name="l62" href="#l62">62</a><td> * @constructor<tr><td><a name="l63" href="#l63">63</a><td> * @implements {webdriver.CommandExecutor}<tr><td><a name="l64" href="#l64">64</a><td> */<tr><td><a name="l65" href="#l65">65</a><td>webdriver.http.Executor = function(client) {<tr><td><a name="l66" href="#l66">66</a><td><tr><td><a name="l67" href="#l67">67</a><td> /**<tr><td><a name="l68" href="#l68">68</a><td> * Client used to communicate with the server.<tr><td><a name="l69" href="#l69">69</a><td> * @private {!webdriver.http.Client}<tr><td><a name="l70" href="#l70">70</a><td> */<tr><td><a name="l71" href="#l71">71</a><td> this.client_ = client;<tr><td><a name="l72" href="#l72">72</a><td>};<tr><td><a name="l73" href="#l73">73</a><td><tr><td><a name="l74" href="#l74">74</a><td><tr><td><a name="l75" href="#l75">75</a><td>/** @override */<tr><td><a name="l76" href="#l76">76</a><td>webdriver.http.Executor.prototype.execute = function(command, callback) {<tr><td><a name="l77" href="#l77">77</a><td> var resource = webdriver.http.Executor.COMMAND_MAP_[command.getName()];<tr><td><a name="l78" href="#l78">78</a><td> if (!resource) {<tr><td><a name="l79" href="#l79">79</a><td> throw new Error(&#39;Unrecognized command: &#39; + command.getName());<tr><td><a name="l80" href="#l80">80</a><td> }<tr><td><a name="l81" href="#l81">81</a><td><tr><td><a name="l82" href="#l82">82</a><td> var parameters = command.getParameters();<tr><td><a name="l83" href="#l83">83</a><td> var path = webdriver.http.Executor.buildPath_(resource.path, parameters);<tr><td><a name="l84" href="#l84">84</a><td> var request = new webdriver.http.Request(resource.method, path, parameters);<tr><td><a name="l85" href="#l85">85</a><td><tr><td><a name="l86" href="#l86">86</a><td> this.client_.send(request, function(e, response) {<tr><td><a name="l87" href="#l87">87</a><td> var responseObj;<tr><td><a name="l88" href="#l88">88</a><td> if (!e) {<tr><td><a name="l89" href="#l89">89</a><td> try {<tr><td><a name="l90" href="#l90">90</a><td> responseObj = webdriver.http.Executor.parseHttpResponse_(<tr><td><a name="l91" href="#l91">91</a><td> /** @type {!webdriver.http.Response} */ (response));<tr><td><a name="l92" href="#l92">92</a><td> } catch (ex) {<tr><td><a name="l93" href="#l93">93</a><td> e = ex;<tr><td><a name="l94" href="#l94">94</a><td> }<tr><td><a name="l95" href="#l95">95</a><td> }<tr><td><a name="l96" href="#l96">96</a><td> callback(e, responseObj);<tr><td><a name="l97" href="#l97">97</a><td> });<tr><td><a name="l98" href="#l98">98</a><td>};<tr><td><a name="l99" href="#l99">99</a><td><tr><td><a name="l100" href="#l100">100</a><td><tr><td><a name="l101" href="#l101">101</a><td>/**<tr><td><a name="l102" href="#l102">102</a><td> * Builds a fully qualified path using the given set of command parameters. Each<tr><td><a name="l103" href="#l103">103</a><td> * path segment prefixed with &#39;:&#39; will be replaced by the value of the<tr><td><a name="l104" href="#l104">104</a><td> * corresponding parameter. All parameters spliced into the path will be<tr><td><a name="l105" href="#l105">105</a><td> * removed from the parameter map.<tr><td><a name="l106" href="#l106">106</a><td> * @param {string} path The original resource path.<tr><td><a name="l107" href="#l107">107</a><td> * @param {!Object.&lt;*&gt;} parameters The parameters object to splice into<tr><td><a name="l108" href="#l108">108</a><td> * the path.<tr><td><a name="l109" href="#l109">109</a><td> * @return {string} The modified path.<tr><td><a name="l110" href="#l110">110</a><td> * @private<tr><td><a name="l111" href="#l111">111</a><td> */<tr><td><a name="l112" href="#l112">112</a><td>webdriver.http.Executor.buildPath_ = function(path, parameters) {<tr><td><a name="l113" href="#l113">113</a><td> var pathParameters = path.match(/\/:(\w+)\b/g);<tr><td><a name="l114" href="#l114">114</a><td> if (pathParameters) {<tr><td><a name="l115" href="#l115">115</a><td> for (var i = 0; i &lt; pathParameters.length; ++i) {<tr><td><a name="l116" href="#l116">116</a><td> var key = pathParameters[i].substring(2); // Trim the /:<tr><td><a name="l117" href="#l117">117</a><td> if (key in parameters) {<tr><td><a name="l118" href="#l118">118</a><td> var value = parameters[key];<tr><td><a name="l119" href="#l119">119</a><td> // TODO: move webdriver.WebElement.ELEMENT definition to a<tr><td><a name="l120" href="#l120">120</a><td> // common file so we can reference it here without pulling in all of<tr><td><a name="l121" href="#l121">121</a><td> // webdriver.WebElement&#39;s dependencies.<tr><td><a name="l122" href="#l122">122</a><td> if (value &amp;&amp; value[&#39;ELEMENT&#39;]) {<tr><td><a name="l123" href="#l123">123</a><td> // When inserting a WebElement into the URL, only use its ID value,<tr><td><a name="l124" href="#l124">124</a><td> // not the full JSON.<tr><td><a name="l125" href="#l125">125</a><td> value = value[&#39;ELEMENT&#39;];<tr><td><a name="l126" href="#l126">126</a><td> }<tr><td><a name="l127" href="#l127">127</a><td> path = path.replace(pathParameters[i], &#39;/&#39; + value);<tr><td><a name="l128" href="#l128">128</a><td> delete parameters[key];<tr><td><a name="l129" href="#l129">129</a><td> } else {<tr><td><a name="l130" href="#l130">130</a><td> throw new Error(&#39;Missing required parameter: &#39; + key);<tr><td><a name="l131" href="#l131">131</a><td> }<tr><td><a name="l132" href="#l132">132</a><td> }<tr><td><a name="l133" href="#l133">133</a><td> }<tr><td><a name="l134" href="#l134">134</a><td> return path;<tr><td><a name="l135" href="#l135">135</a><td>};<tr><td><a name="l136" href="#l136">136</a><td><tr><td><a name="l137" href="#l137">137</a><td><tr><td><a name="l138" href="#l138">138</a><td>/**<tr><td><a name="l139" href="#l139">139</a><td> * Callback used to parse {@link webdriver.http.Response} objects from a<tr><td><a name="l140" href="#l140">140</a><td> * {@link webdriver.http.Client}.<tr><td><a name="l141" href="#l141">141</a><td> * @param {!webdriver.http.Response} httpResponse The HTTP response to parse.<tr><td><a name="l142" href="#l142">142</a><td> * @return {!bot.response.ResponseObject} The parsed response.<tr><td><a name="l143" href="#l143">143</a><td> * @private<tr><td><a name="l144" href="#l144">144</a><td> */<tr><td><a name="l145" href="#l145">145</a><td>webdriver.http.Executor.parseHttpResponse_ = function(httpResponse) {<tr><td><a name="l146" href="#l146">146</a><td> try {<tr><td><a name="l147" href="#l147">147</a><td> return /** @type {!bot.response.ResponseObject} */ (goog.json.parse(<tr><td><a name="l148" href="#l148">148</a><td> httpResponse.body));<tr><td><a name="l149" href="#l149">149</a><td> } catch (ex) {<tr><td><a name="l150" href="#l150">150</a><td> // Whoops, looks like the server sent us a malformed response. We&#39;ll need<tr><td><a name="l151" href="#l151">151</a><td> // to manually build a response object based on the response code.<tr><td><a name="l152" href="#l152">152</a><td> }<tr><td><a name="l153" href="#l153">153</a><td><tr><td><a name="l154" href="#l154">154</a><td> var response = {<tr><td><a name="l155" href="#l155">155</a><td> &#39;status&#39;: bot.ErrorCode.SUCCESS,<tr><td><a name="l156" href="#l156">156</a><td> &#39;value&#39;: httpResponse.body.replace(/\r\n/g, &#39;\n&#39;)<tr><td><a name="l157" href="#l157">157</a><td> };<tr><td><a name="l158" href="#l158">158</a><td><tr><td><a name="l159" href="#l159">159</a><td> if (!(httpResponse.status &gt; 199 &amp;&amp; httpResponse.status &lt; 300)) {<tr><td><a name="l160" href="#l160">160</a><td> // 404 represents an unknown command; anything else is a generic unknown<tr><td><a name="l161" href="#l161">161</a><td> // error.<tr><td><a name="l162" href="#l162">162</a><td> response[&#39;status&#39;] = httpResponse.status == 404 ?<tr><td><a name="l163" href="#l163">163</a><td> bot.ErrorCode.UNKNOWN_COMMAND :<tr><td><a name="l164" href="#l164">164</a><td> bot.ErrorCode.UNKNOWN_ERROR;<tr><td><a name="l165" href="#l165">165</a><td> }<tr><td><a name="l166" href="#l166">166</a><td><tr><td><a name="l167" href="#l167">167</a><td> return response;<tr><td><a name="l168" href="#l168">168</a><td>};<tr><td><a name="l169" href="#l169">169</a><td><tr><td><a name="l170" href="#l170">170</a><td><tr><td><a name="l171" href="#l171">171</a><td>/**<tr><td><a name="l172" href="#l172">172</a><td> * Maps command names to resource locator.<tr><td><a name="l173" href="#l173">173</a><td> * @private {!Object.&lt;{method:string, path:string}&gt;}<tr><td><a name="l174" href="#l174">174</a><td> * @const<tr><td><a name="l175" href="#l175">175</a><td> */<tr><td><a name="l176" href="#l176">176</a><td>webdriver.http.Executor.COMMAND_MAP_ = (function() {<tr><td><a name="l177" href="#l177">177</a><td> return new Builder().<tr><td><a name="l178" href="#l178">178</a><td> put(webdriver.CommandName.GET_SERVER_STATUS, get(&#39;/status&#39;)).<tr><td><a name="l179" href="#l179">179</a><td> put(webdriver.CommandName.NEW_SESSION, post(&#39;/session&#39;)).<tr><td><a name="l180" href="#l180">180</a><td> put(webdriver.CommandName.GET_SESSIONS, get(&#39;/sessions&#39;)).<tr><td><a name="l181" href="#l181">181</a><td> put(webdriver.CommandName.DESCRIBE_SESSION, get(&#39;/session/:sessionId&#39;)).<tr><td><a name="l182" href="#l182">182</a><td> put(webdriver.CommandName.QUIT, del(&#39;/session/:sessionId&#39;)).<tr><td><a name="l183" href="#l183">183</a><td> put(webdriver.CommandName.CLOSE, del(&#39;/session/:sessionId/window&#39;)).<tr><td><a name="l184" href="#l184">184</a><td> put(webdriver.CommandName.GET_CURRENT_WINDOW_HANDLE,<tr><td><a name="l185" href="#l185">185</a><td> get(&#39;/session/:sessionId/window_handle&#39;)).<tr><td><a name="l186" href="#l186">186</a><td> put(webdriver.CommandName.GET_WINDOW_HANDLES,<tr><td><a name="l187" href="#l187">187</a><td> get(&#39;/session/:sessionId/window_handles&#39;)).<tr><td><a name="l188" href="#l188">188</a><td> put(webdriver.CommandName.GET_CURRENT_URL,<tr><td><a name="l189" href="#l189">189</a><td> get(&#39;/session/:sessionId/url&#39;)).<tr><td><a name="l190" href="#l190">190</a><td> put(webdriver.CommandName.GET, post(&#39;/session/:sessionId/url&#39;)).<tr><td><a name="l191" href="#l191">191</a><td> put(webdriver.CommandName.GO_BACK, post(&#39;/session/:sessionId/back&#39;)).<tr><td><a name="l192" href="#l192">192</a><td> put(webdriver.CommandName.GO_FORWARD,<tr><td><a name="l193" href="#l193">193</a><td> post(&#39;/session/:sessionId/forward&#39;)).<tr><td><a name="l194" href="#l194">194</a><td> put(webdriver.CommandName.REFRESH,<tr><td><a name="l195" href="#l195">195</a><td> post(&#39;/session/:sessionId/refresh&#39;)).<tr><td><a name="l196" href="#l196">196</a><td> put(webdriver.CommandName.ADD_COOKIE,<tr><td><a name="l197" href="#l197">197</a><td> post(&#39;/session/:sessionId/cookie&#39;)).<tr><td><a name="l198" href="#l198">198</a><td> put(webdriver.CommandName.GET_ALL_COOKIES,<tr><td><a name="l199" href="#l199">199</a><td> get(&#39;/session/:sessionId/cookie&#39;)).<tr><td><a name="l200" href="#l200">200</a><td> put(webdriver.CommandName.DELETE_ALL_COOKIES,<tr><td><a name="l201" href="#l201">201</a><td> del(&#39;/session/:sessionId/cookie&#39;)).<tr><td><a name="l202" href="#l202">202</a><td> put(webdriver.CommandName.DELETE_COOKIE,<tr><td><a name="l203" href="#l203">203</a><td> del(&#39;/session/:sessionId/cookie/:name&#39;)).<tr><td><a name="l204" href="#l204">204</a><td> put(webdriver.CommandName.FIND_ELEMENT,<tr><td><a name="l205" href="#l205">205</a><td> post(&#39;/session/:sessionId/element&#39;)).<tr><td><a name="l206" href="#l206">206</a><td> put(webdriver.CommandName.FIND_ELEMENTS,<tr><td><a name="l207" href="#l207">207</a><td> post(&#39;/session/:sessionId/elements&#39;)).<tr><td><a name="l208" href="#l208">208</a><td> put(webdriver.CommandName.GET_ACTIVE_ELEMENT,<tr><td><a name="l209" href="#l209">209</a><td> post(&#39;/session/:sessionId/element/active&#39;)).<tr><td><a name="l210" href="#l210">210</a><td> put(webdriver.CommandName.FIND_CHILD_ELEMENT,<tr><td><a name="l211" href="#l211">211</a><td> post(&#39;/session/:sessionId/element/:id/element&#39;)).<tr><td><a name="l212" href="#l212">212</a><td> put(webdriver.CommandName.FIND_CHILD_ELEMENTS,<tr><td><a name="l213" href="#l213">213</a><td> post(&#39;/session/:sessionId/element/:id/elements&#39;)).<tr><td><a name="l214" href="#l214">214</a><td> put(webdriver.CommandName.CLEAR_ELEMENT,<tr><td><a name="l215" href="#l215">215</a><td> post(&#39;/session/:sessionId/element/:id/clear&#39;)).<tr><td><a name="l216" href="#l216">216</a><td> put(webdriver.CommandName.CLICK_ELEMENT,<tr><td><a name="l217" href="#l217">217</a><td> post(&#39;/session/:sessionId/element/:id/click&#39;)).<tr><td><a name="l218" href="#l218">218</a><td> put(webdriver.CommandName.SEND_KEYS_TO_ELEMENT,<tr><td><a name="l219" href="#l219">219</a><td> post(&#39;/session/:sessionId/element/:id/value&#39;)).<tr><td><a name="l220" href="#l220">220</a><td> put(webdriver.CommandName.SUBMIT_ELEMENT,<tr><td><a name="l221" href="#l221">221</a><td> post(&#39;/session/:sessionId/element/:id/submit&#39;)).<tr><td><a name="l222" href="#l222">222</a><td> put(webdriver.CommandName.GET_ELEMENT_TEXT,<tr><td><a name="l223" href="#l223">223</a><td> get(&#39;/session/:sessionId/element/:id/text&#39;)).<tr><td><a name="l224" href="#l224">224</a><td> put(webdriver.CommandName.GET_ELEMENT_TAG_NAME,<tr><td><a name="l225" href="#l225">225</a><td> get(&#39;/session/:sessionId/element/:id/name&#39;)).<tr><td><a name="l226" href="#l226">226</a><td> put(webdriver.CommandName.IS_ELEMENT_SELECTED,<tr><td><a name="l227" href="#l227">227</a><td> get(&#39;/session/:sessionId/element/:id/selected&#39;)).<tr><td><a name="l228" href="#l228">228</a><td> put(webdriver.CommandName.IS_ELEMENT_ENABLED,<tr><td><a name="l229" href="#l229">229</a><td> get(&#39;/session/:sessionId/element/:id/enabled&#39;)).<tr><td><a name="l230" href="#l230">230</a><td> put(webdriver.CommandName.IS_ELEMENT_DISPLAYED,<tr><td><a name="l231" href="#l231">231</a><td> get(&#39;/session/:sessionId/element/:id/displayed&#39;)).<tr><td><a name="l232" href="#l232">232</a><td> put(webdriver.CommandName.GET_ELEMENT_LOCATION,<tr><td><a name="l233" href="#l233">233</a><td> get(&#39;/session/:sessionId/element/:id/location&#39;)).<tr><td><a name="l234" href="#l234">234</a><td> put(webdriver.CommandName.GET_ELEMENT_SIZE,<tr><td><a name="l235" href="#l235">235</a><td> get(&#39;/session/:sessionId/element/:id/size&#39;)).<tr><td><a name="l236" href="#l236">236</a><td> put(webdriver.CommandName.GET_ELEMENT_ATTRIBUTE,<tr><td><a name="l237" href="#l237">237</a><td> get(&#39;/session/:sessionId/element/:id/attribute/:name&#39;)).<tr><td><a name="l238" href="#l238">238</a><td> put(webdriver.CommandName.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,<tr><td><a name="l239" href="#l239">239</a><td> get(&#39;/session/:sessionId/element/:id/css/:propertyName&#39;)).<tr><td><a name="l240" href="#l240">240</a><td> put(webdriver.CommandName.ELEMENT_EQUALS,<tr><td><a name="l241" href="#l241">241</a><td> get(&#39;/session/:sessionId/element/:id/equals/:other&#39;)).<tr><td><a name="l242" href="#l242">242</a><td> put(webdriver.CommandName.SWITCH_TO_WINDOW,<tr><td><a name="l243" href="#l243">243</a><td> post(&#39;/session/:sessionId/window&#39;)).<tr><td><a name="l244" href="#l244">244</a><td> put(webdriver.CommandName.MAXIMIZE_WINDOW,<tr><td><a name="l245" href="#l245">245</a><td> post(&#39;/session/:sessionId/window/:windowHandle/maximize&#39;)).<tr><td><a name="l246" href="#l246">246</a><td> put(webdriver.CommandName.GET_WINDOW_POSITION,<tr><td><a name="l247" href="#l247">247</a><td> get(&#39;/session/:sessionId/window/:windowHandle/position&#39;)).<tr><td><a name="l248" href="#l248">248</a><td> put(webdriver.CommandName.SET_WINDOW_POSITION,<tr><td><a name="l249" href="#l249">249</a><td> post(&#39;/session/:sessionId/window/:windowHandle/position&#39;)).<tr><td><a name="l250" href="#l250">250</a><td> put(webdriver.CommandName.GET_WINDOW_SIZE,<tr><td><a name="l251" href="#l251">251</a><td> get(&#39;/session/:sessionId/window/:windowHandle/size&#39;)).<tr><td><a name="l252" href="#l252">252</a><td> put(webdriver.CommandName.SET_WINDOW_SIZE,<tr><td><a name="l253" href="#l253">253</a><td> post(&#39;/session/:sessionId/window/:windowHandle/size&#39;)).<tr><td><a name="l254" href="#l254">254</a><td> put(webdriver.CommandName.SWITCH_TO_FRAME,<tr><td><a name="l255" href="#l255">255</a><td> post(&#39;/session/:sessionId/frame&#39;)).<tr><td><a name="l256" href="#l256">256</a><td> put(webdriver.CommandName.GET_PAGE_SOURCE,<tr><td><a name="l257" href="#l257">257</a><td> get(&#39;/session/:sessionId/source&#39;)).<tr><td><a name="l258" href="#l258">258</a><td> put(webdriver.CommandName.GET_TITLE,<tr><td><a name="l259" href="#l259">259</a><td> get(&#39;/session/:sessionId/title&#39;)).<tr><td><a name="l260" href="#l260">260</a><td> put(webdriver.CommandName.EXECUTE_SCRIPT,<tr><td><a name="l261" href="#l261">261</a><td> post(&#39;/session/:sessionId/execute&#39;)).<tr><td><a name="l262" href="#l262">262</a><td> put(webdriver.CommandName.EXECUTE_ASYNC_SCRIPT,<tr><td><a name="l263" href="#l263">263</a><td> post(&#39;/session/:sessionId/execute_async&#39;)).<tr><td><a name="l264" href="#l264">264</a><td> put(webdriver.CommandName.SCREENSHOT,<tr><td><a name="l265" href="#l265">265</a><td> get(&#39;/session/:sessionId/screenshot&#39;)).<tr><td><a name="l266" href="#l266">266</a><td> put(webdriver.CommandName.SET_TIMEOUT,<tr><td><a name="l267" href="#l267">267</a><td> post(&#39;/session/:sessionId/timeouts&#39;)).<tr><td><a name="l268" href="#l268">268</a><td> put(webdriver.CommandName.SET_SCRIPT_TIMEOUT,<tr><td><a name="l269" href="#l269">269</a><td> post(&#39;/session/:sessionId/timeouts/async_script&#39;)).<tr><td><a name="l270" href="#l270">270</a><td> put(webdriver.CommandName.IMPLICITLY_WAIT,<tr><td><a name="l271" href="#l271">271</a><td> post(&#39;/session/:sessionId/timeouts/implicit_wait&#39;)).<tr><td><a name="l272" href="#l272">272</a><td> put(webdriver.CommandName.MOVE_TO, post(&#39;/session/:sessionId/moveto&#39;)).<tr><td><a name="l273" href="#l273">273</a><td> put(webdriver.CommandName.CLICK, post(&#39;/session/:sessionId/click&#39;)).<tr><td><a name="l274" href="#l274">274</a><td> put(webdriver.CommandName.DOUBLE_CLICK,<tr><td><a name="l275" href="#l275">275</a><td> post(&#39;/session/:sessionId/doubleclick&#39;)).<tr><td><a name="l276" href="#l276">276</a><td> put(webdriver.CommandName.MOUSE_DOWN,<tr><td><a name="l277" href="#l277">277</a><td> post(&#39;/session/:sessionId/buttondown&#39;)).<tr><td><a name="l278" href="#l278">278</a><td> put(webdriver.CommandName.MOUSE_UP, post(&#39;/session/:sessionId/buttonup&#39;)).<tr><td><a name="l279" href="#l279">279</a><td> put(webdriver.CommandName.MOVE_TO, post(&#39;/session/:sessionId/moveto&#39;)).<tr><td><a name="l280" href="#l280">280</a><td> put(webdriver.CommandName.SEND_KEYS_TO_ACTIVE_ELEMENT,<tr><td><a name="l281" href="#l281">281</a><td> post(&#39;/session/:sessionId/keys&#39;)).<tr><td><a name="l282" href="#l282">282</a><td> put(webdriver.CommandName.ACCEPT_ALERT,<tr><td><a name="l283" href="#l283">283</a><td> post(&#39;/session/:sessionId/accept_alert&#39;)).<tr><td><a name="l284" href="#l284">284</a><td> put(webdriver.CommandName.DISMISS_ALERT,<tr><td><a name="l285" href="#l285">285</a><td> post(&#39;/session/:sessionId/dismiss_alert&#39;)).<tr><td><a name="l286" href="#l286">286</a><td> put(webdriver.CommandName.GET_ALERT_TEXT,<tr><td><a name="l287" href="#l287">287</a><td> get(&#39;/session/:sessionId/alert_text&#39;)).<tr><td><a name="l288" href="#l288">288</a><td> put(webdriver.CommandName.SET_ALERT_TEXT,<tr><td><a name="l289" href="#l289">289</a><td> post(&#39;/session/:sessionId/alert_text&#39;)).<tr><td><a name="l290" href="#l290">290</a><td> put(webdriver.CommandName.GET_LOG, post(&#39;/session/:sessionId/log&#39;)).<tr><td><a name="l291" href="#l291">291</a><td> put(webdriver.CommandName.GET_AVAILABLE_LOG_TYPES,<tr><td><a name="l292" href="#l292">292</a><td> get(&#39;/session/:sessionId/log/types&#39;)).<tr><td><a name="l293" href="#l293">293</a><td> put(webdriver.CommandName.GET_SESSION_LOGS, post(&#39;/logs&#39;)).<tr><td><a name="l294" href="#l294">294</a><td> build();<tr><td><a name="l295" href="#l295">295</a><td><tr><td><a name="l296" href="#l296">296</a><td> /** @constructor */<tr><td><a name="l297" href="#l297">297</a><td> function Builder() {<tr><td><a name="l298" href="#l298">298</a><td> var map = {};<tr><td><a name="l299" href="#l299">299</a><td><tr><td><a name="l300" href="#l300">300</a><td> this.put = function(name, resource) {<tr><td><a name="l301" href="#l301">301</a><td> map[name] = resource;<tr><td><a name="l302" href="#l302">302</a><td> return this;<tr><td><a name="l303" href="#l303">303</a><td> };<tr><td><a name="l304" href="#l304">304</a><td><tr><td><a name="l305" href="#l305">305</a><td> this.build = function() {<tr><td><a name="l306" href="#l306">306</a><td> return map;<tr><td><a name="l307" href="#l307">307</a><td> };<tr><td><a name="l308" href="#l308">308</a><td> }<tr><td><a name="l309" href="#l309">309</a><td><tr><td><a name="l310" href="#l310">310</a><td> function post(path) { return resource(&#39;POST&#39;, path); }<tr><td><a name="l311" href="#l311">311</a><td> function del(path) { return resource(&#39;DELETE&#39;, path); }<tr><td><a name="l312" href="#l312">312</a><td> function get(path) { return resource(&#39;GET&#39;, path); }<tr><td><a name="l313" href="#l313">313</a><td> function resource(method, path) { return {method: method, path: path}; }<tr><td><a name="l314" href="#l314">314</a><td>})();<tr><td><a name="l315" href="#l315">315</a><td><tr><td><a name="l316" href="#l316">316</a><td><tr><td><a name="l317" href="#l317">317</a><td>/**<tr><td><a name="l318" href="#l318">318</a><td> * Converts a headers object to a HTTP header block string.<tr><td><a name="l319" href="#l319">319</a><td> * @param {!Object.&lt;string&gt;} headers The headers object to convert.<tr><td><a name="l320" href="#l320">320</a><td> * @return {string} The headers as a string.<tr><td><a name="l321" href="#l321">321</a><td> * @private<tr><td><a name="l322" href="#l322">322</a><td> */<tr><td><a name="l323" href="#l323">323</a><td>webdriver.http.headersToString_ = function(headers) {<tr><td><a name="l324" href="#l324">324</a><td> var ret = [];<tr><td><a name="l325" href="#l325">325</a><td> for (var key in headers) {<tr><td><a name="l326" href="#l326">326</a><td> ret.push(key + &#39;: &#39; + headers[key]);<tr><td><a name="l327" href="#l327">327</a><td> }<tr><td><a name="l328" href="#l328">328</a><td> return ret.join(&#39;\n&#39;);<tr><td><a name="l329" href="#l329">329</a><td>};<tr><td><a name="l330" href="#l330">330</a><td><tr><td><a name="l331" href="#l331">331</a><td><tr><td><a name="l332" href="#l332">332</a><td><tr><td><a name="l333" href="#l333">333</a><td>/**<tr><td><a name="l334" href="#l334">334</a><td> * Describes a partial HTTP request. This class is a &quot;partial&quot; request and only<tr><td><a name="l335" href="#l335">335</a><td> * defines the path on the server to send a request to. It is each<tr><td><a name="l336" href="#l336">336</a><td> * {@code webdriver.http.Client}&#39;s responsibility to build the full URL for the<tr><td><a name="l337" href="#l337">337</a><td> * final request.<tr><td><a name="l338" href="#l338">338</a><td> * @param {string} method The HTTP method to use for the request.<tr><td><a name="l339" href="#l339">339</a><td> * @param {string} path Path on the server to send the request to.<tr><td><a name="l340" href="#l340">340</a><td> * @param {Object=} opt_data This request&#39;s JSON data.<tr><td><a name="l341" href="#l341">341</a><td> * @constructor<tr><td><a name="l342" href="#l342">342</a><td> */<tr><td><a name="l343" href="#l343">343</a><td>webdriver.http.Request = function(method, path, opt_data) {<tr><td><a name="l344" href="#l344">344</a><td><tr><td><a name="l345" href="#l345">345</a><td> /**<tr><td><a name="l346" href="#l346">346</a><td> * The HTTP method to use for the request.<tr><td><a name="l347" href="#l347">347</a><td> * @type {string}<tr><td><a name="l348" href="#l348">348</a><td> */<tr><td><a name="l349" href="#l349">349</a><td> this.method = method;<tr><td><a name="l350" href="#l350">350</a><td><tr><td><a name="l351" href="#l351">351</a><td> /**<tr><td><a name="l352" href="#l352">352</a><td> * The path on the server to send the request to.<tr><td><a name="l353" href="#l353">353</a><td> * @type {string}<tr><td><a name="l354" href="#l354">354</a><td> */<tr><td><a name="l355" href="#l355">355</a><td> this.path = path;<tr><td><a name="l356" href="#l356">356</a><td><tr><td><a name="l357" href="#l357">357</a><td> /**<tr><td><a name="l358" href="#l358">358</a><td> * This request&#39;s body.<tr><td><a name="l359" href="#l359">359</a><td> * @type {!Object}<tr><td><a name="l360" href="#l360">360</a><td> */<tr><td><a name="l361" href="#l361">361</a><td> this.data = opt_data || {};<tr><td><a name="l362" href="#l362">362</a><td><tr><td><a name="l363" href="#l363">363</a><td> /**<tr><td><a name="l364" href="#l364">364</a><td> * The headers to send with the request.<tr><td><a name="l365" href="#l365">365</a><td> * @type {!Object.&lt;(string|number)&gt;}<tr><td><a name="l366" href="#l366">366</a><td> */<tr><td><a name="l367" href="#l367">367</a><td> this.headers = {&#39;Accept&#39;: &#39;application/json; charset=utf-8&#39;};<tr><td><a name="l368" href="#l368">368</a><td>};<tr><td><a name="l369" href="#l369">369</a><td><tr><td><a name="l370" href="#l370">370</a><td><tr><td><a name="l371" href="#l371">371</a><td>/** @override */<tr><td><a name="l372" href="#l372">372</a><td>webdriver.http.Request.prototype.toString = function() {<tr><td><a name="l373" href="#l373">373</a><td> return [<tr><td><a name="l374" href="#l374">374</a><td> this.method + &#39; &#39; + this.path + &#39; HTTP/1.1&#39;,<tr><td><a name="l375" href="#l375">375</a><td> webdriver.http.headersToString_(this.headers),<tr><td><a name="l376" href="#l376">376</a><td> &#39;&#39;,<tr><td><a name="l377" href="#l377">377</a><td> goog.json.serialize(this.data)<tr><td><a name="l378" href="#l378">378</a><td> ].join(&#39;\n&#39;);<tr><td><a name="l379" href="#l379">379</a><td>};<tr><td><a name="l380" href="#l380">380</a><td><tr><td><a name="l381" href="#l381">381</a><td><tr><td><a name="l382" href="#l382">382</a><td><tr><td><a name="l383" href="#l383">383</a><td>/**<tr><td><a name="l384" href="#l384">384</a><td> * Represents a HTTP response.<tr><td><a name="l385" href="#l385">385</a><td> * @param {number} status The response code.<tr><td><a name="l386" href="#l386">386</a><td> * @param {!Object.&lt;string&gt;} headers The response headers. All header<tr><td><a name="l387" href="#l387">387</a><td> * names will be converted to lowercase strings for consistent lookups.<tr><td><a name="l388" href="#l388">388</a><td> * @param {string} body The response body.<tr><td><a name="l389" href="#l389">389</a><td> * @constructor<tr><td><a name="l390" href="#l390">390</a><td> */<tr><td><a name="l391" href="#l391">391</a><td>webdriver.http.Response = function(status, headers, body) {<tr><td><a name="l392" href="#l392">392</a><td><tr><td><a name="l393" href="#l393">393</a><td> /**<tr><td><a name="l394" href="#l394">394</a><td> * The HTTP response code.<tr><td><a name="l395" href="#l395">395</a><td> * @type {number}<tr><td><a name="l396" href="#l396">396</a><td> */<tr><td><a name="l397" href="#l397">397</a><td> this.status = status;<tr><td><a name="l398" href="#l398">398</a><td><tr><td><a name="l399" href="#l399">399</a><td> /**<tr><td><a name="l400" href="#l400">400</a><td> * The response body.<tr><td><a name="l401" href="#l401">401</a><td> * @type {string}<tr><td><a name="l402" href="#l402">402</a><td> */<tr><td><a name="l403" href="#l403">403</a><td> this.body = body;<tr><td><a name="l404" href="#l404">404</a><td><tr><td><a name="l405" href="#l405">405</a><td> /**<tr><td><a name="l406" href="#l406">406</a><td> * The response body.<tr><td><a name="l407" href="#l407">407</a><td> * @type {!Object.&lt;string&gt;}<tr><td><a name="l408" href="#l408">408</a><td> */<tr><td><a name="l409" href="#l409">409</a><td> this.headers = {};<tr><td><a name="l410" href="#l410">410</a><td> for (var header in headers) {<tr><td><a name="l411" href="#l411">411</a><td> this.headers[header.toLowerCase()] = headers[header];<tr><td><a name="l412" href="#l412">412</a><td> }<tr><td><a name="l413" href="#l413">413</a><td>};<tr><td><a name="l414" href="#l414">414</a><td><tr><td><a name="l415" href="#l415">415</a><td><tr><td><a name="l416" href="#l416">416</a><td>/**<tr><td><a name="l417" href="#l417">417</a><td> * Builds a {@code webdriver.http.Response} from a {@code XMLHttpRequest} or<tr><td><a name="l418" href="#l418">418</a><td> * {@code XDomainRequest} response object.<tr><td><a name="l419" href="#l419">419</a><td> * @param {!(XDomainRequest|XMLHttpRequest)} xhr The request to parse.<tr><td><a name="l420" href="#l420">420</a><td> * @return {!webdriver.http.Response} The parsed response.<tr><td><a name="l421" href="#l421">421</a><td> */<tr><td><a name="l422" href="#l422">422</a><td>webdriver.http.Response.fromXmlHttpRequest = function(xhr) {<tr><td><a name="l423" href="#l423">423</a><td> var headers = {};<tr><td><a name="l424" href="#l424">424</a><td><tr><td><a name="l425" href="#l425">425</a><td> // getAllResponseHeaders is only available on XMLHttpRequest objects.<tr><td><a name="l426" href="#l426">426</a><td> if (xhr.getAllResponseHeaders) {<tr><td><a name="l427" href="#l427">427</a><td> var tmp = xhr.getAllResponseHeaders();<tr><td><a name="l428" href="#l428">428</a><td> if (tmp) {<tr><td><a name="l429" href="#l429">429</a><td> tmp = tmp.replace(/\r\n/g, &#39;\n&#39;).split(&#39;\n&#39;);<tr><td><a name="l430" href="#l430">430</a><td> goog.array.forEach(tmp, function(header) {<tr><td><a name="l431" href="#l431">431</a><td> var parts = header.split(/\s*:\s*/, 2);<tr><td><a name="l432" href="#l432">432</a><td> if (parts[0]) {<tr><td><a name="l433" href="#l433">433</a><td> headers[parts[0]] = parts[1] || &#39;&#39;;<tr><td><a name="l434" href="#l434">434</a><td> }<tr><td><a name="l435" href="#l435">435</a><td> });<tr><td><a name="l436" href="#l436">436</a><td> }<tr><td><a name="l437" href="#l437">437</a><td> }<tr><td><a name="l438" href="#l438">438</a><td><tr><td><a name="l439" href="#l439">439</a><td> // If xhr is a XDomainRequest object, it will not have a status.<tr><td><a name="l440" href="#l440">440</a><td> // However, if we&#39;re parsing the response from a XDomainRequest, then<tr><td><a name="l441" href="#l441">441</a><td> // that request must have been a success, so we can assume status == 200.<tr><td><a name="l442" href="#l442">442</a><td> var status = xhr.status || 200;<tr><td><a name="l443" href="#l443">443</a><td> return new webdriver.http.Response(status, headers,<tr><td><a name="l444" href="#l444">444</a><td> xhr.responseText.replace(/\0/g, &#39;&#39;));<tr><td><a name="l445" href="#l445">445</a><td>};<tr><td><a name="l446" href="#l446">446</a><td><tr><td><a name="l447" href="#l447">447</a><td><tr><td><a name="l448" href="#l448">448</a><td>/** @override */<tr><td><a name="l449" href="#l449">449</a><td>webdriver.http.Response.prototype.toString = function() {<tr><td><a name="l450" href="#l450">450</a><td> var headers = webdriver.http.headersToString_(this.headers);<tr><td><a name="l451" href="#l451">451</a><td> var ret = [&#39;HTTP/1.1 &#39; + this.status, headers];<tr><td><a name="l452" href="#l452">452</a><td><tr><td><a name="l453" href="#l453">453</a><td> if (headers) {<tr><td><a name="l454" href="#l454">454</a><td> ret.push(&#39;&#39;);<tr><td><a name="l455" href="#l455">455</a><td> }<tr><td><a name="l456" href="#l456">456</a><td><tr><td><a name="l457" href="#l457">457</a><td> if (this.body) {<tr><td><a name="l458" href="#l458">458</a><td> ret.push(this.body);<tr><td><a name="l459" href="#l459">459</a><td> }<tr><td><a name="l460" href="#l460">460</a><td><tr><td><a name="l461" href="#l461">461</a><td> return ret.join(&#39;\n&#39;);<tr><td><a name="l462" href="#l462">462</a><td>};</table></pre></main><nav id="topnav"><div><div id="menubutton"><label for="sidenav-toggle">Menu</label></div><form id="searchbox"><div><input type="search" placeholder="Search" tabindex="1"></div></form></div></nav><nav id="sidenav"><input type="checkbox" id="sidenav-types-ctrl" /><input type="checkbox" id="sidenav-files-ctrl" /><input type="checkbox" id="sidenav-modules-ctrl" /><a id="sidenav-overview"><div><h4>Overview</h4></div></a><div id="sidenav-types"><label for="sidenav-types-ctrl"><h4>Types</h4></label><i>Loading</i></div><div id="sidenav-modules"><label for="sidenav-modules-ctrl"><h4>Modules</h4></label><i>Loading</i></div><div id="sidenav-files"><label for="sidenav-files-ctrl"><h4>Files</h4></label><i>Loading</i></div><a href="license.html"><div><h4>License</h4></div></a></nav><div id="push-footer"></div></div><footer><a href="https://github.com/jleyba/js-dossier">Generated by dossier</a></footer><script src="../../../../types.js"></script><script src="../../../../dossier.js"></script>
1
+ <!DOCTYPE html><meta charset="UTF-8"><meta http-equiv="Content-Language" content="en" /><title>http.js</title><link href="../../../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>lib/webdriver/http/http.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2011 Software Freedom Conservancy. All Rights Reserved.<tr><td><a name="l2" href="#l2">2</a><td>//<tr><td><a name="l3" href="#l3">3</a><td>// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);<tr><td><a name="l4" href="#l4">4</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l5" href="#l5">5</a><td>// You may obtain a copy of the License at<tr><td><a name="l6" href="#l6">6</a><td>//<tr><td><a name="l7" href="#l7">7</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l8" href="#l8">8</a><td>//<tr><td><a name="l9" href="#l9">9</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l10" href="#l10">10</a><td>// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,<tr><td><a name="l11" href="#l11">11</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l12" href="#l12">12</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l13" href="#l13">13</a><td>// limitations under the License.<tr><td><a name="l14" href="#l14">14</a><td><tr><td><a name="l15" href="#l15">15</a><td>/**<tr><td><a name="l16" href="#l16">16</a><td> * @fileoverview Defines a {@code webdriver.CommandExecutor} that communicates<tr><td><a name="l17" href="#l17">17</a><td> * with a server over HTTP.<tr><td><a name="l18" href="#l18">18</a><td> */<tr><td><a name="l19" href="#l19">19</a><td><tr><td><a name="l20" href="#l20">20</a><td>goog.provide(&#39;webdriver.http.Client&#39;);<tr><td><a name="l21" href="#l21">21</a><td>goog.provide(&#39;webdriver.http.Executor&#39;);<tr><td><a name="l22" href="#l22">22</a><td>goog.provide(&#39;webdriver.http.Request&#39;);<tr><td><a name="l23" href="#l23">23</a><td>goog.provide(&#39;webdriver.http.Response&#39;);<tr><td><a name="l24" href="#l24">24</a><td><tr><td><a name="l25" href="#l25">25</a><td>goog.require(&#39;bot.ErrorCode&#39;);<tr><td><a name="l26" href="#l26">26</a><td>goog.require(&#39;goog.array&#39;);<tr><td><a name="l27" href="#l27">27</a><td>goog.require(&#39;goog.json&#39;);<tr><td><a name="l28" href="#l28">28</a><td>goog.require(&#39;webdriver.CommandName&#39;);<tr><td><a name="l29" href="#l29">29</a><td>goog.require(&#39;webdriver.promise.Deferred&#39;);<tr><td><a name="l30" href="#l30">30</a><td><tr><td><a name="l31" href="#l31">31</a><td><tr><td><a name="l32" href="#l32">32</a><td><tr><td><a name="l33" href="#l33">33</a><td>/**<tr><td><a name="l34" href="#l34">34</a><td> * Interface used for sending individual HTTP requests to the server.<tr><td><a name="l35" href="#l35">35</a><td> * @interface<tr><td><a name="l36" href="#l36">36</a><td> */<tr><td><a name="l37" href="#l37">37</a><td>webdriver.http.Client = function() {<tr><td><a name="l38" href="#l38">38</a><td>};<tr><td><a name="l39" href="#l39">39</a><td><tr><td><a name="l40" href="#l40">40</a><td><tr><td><a name="l41" href="#l41">41</a><td>/**<tr><td><a name="l42" href="#l42">42</a><td> * Sends a request to the server. If an error occurs while sending the request,<tr><td><a name="l43" href="#l43">43</a><td> * such as a failure to connect to the server, the provided callback will be<tr><td><a name="l44" href="#l44">44</a><td> * invoked with a non-null {@code Error} describing the error. Otherwise, when<tr><td><a name="l45" href="#l45">45</a><td> * the server&#39;s response has been received, the callback will be invoked with a<tr><td><a name="l46" href="#l46">46</a><td> * null Error and non-null {@code webdriver.http.Response} object.<tr><td><a name="l47" href="#l47">47</a><td> *<tr><td><a name="l48" href="#l48">48</a><td> * @param {!webdriver.http.Request} request The request to send.<tr><td><a name="l49" href="#l49">49</a><td> * @param {function(Error, !webdriver.http.Response=)} callback the function to<tr><td><a name="l50" href="#l50">50</a><td> * invoke when the server&#39;s response is ready.<tr><td><a name="l51" href="#l51">51</a><td> */<tr><td><a name="l52" href="#l52">52</a><td>webdriver.http.Client.prototype.send = function(request, callback) {<tr><td><a name="l53" href="#l53">53</a><td>};<tr><td><a name="l54" href="#l54">54</a><td><tr><td><a name="l55" href="#l55">55</a><td><tr><td><a name="l56" href="#l56">56</a><td><tr><td><a name="l57" href="#l57">57</a><td>/**<tr><td><a name="l58" href="#l58">58</a><td> * A command executor that communicates with a server using the WebDriver<tr><td><a name="l59" href="#l59">59</a><td> * command protocol.<tr><td><a name="l60" href="#l60">60</a><td> * @param {!webdriver.http.Client} client The client to use when sending<tr><td><a name="l61" href="#l61">61</a><td> * requests to the server.<tr><td><a name="l62" href="#l62">62</a><td> * @constructor<tr><td><a name="l63" href="#l63">63</a><td> * @implements {webdriver.CommandExecutor}<tr><td><a name="l64" href="#l64">64</a><td> */<tr><td><a name="l65" href="#l65">65</a><td>webdriver.http.Executor = function(client) {<tr><td><a name="l66" href="#l66">66</a><td><tr><td><a name="l67" href="#l67">67</a><td> /**<tr><td><a name="l68" href="#l68">68</a><td> * Client used to communicate with the server.<tr><td><a name="l69" href="#l69">69</a><td> * @private {!webdriver.http.Client}<tr><td><a name="l70" href="#l70">70</a><td> */<tr><td><a name="l71" href="#l71">71</a><td> this.client_ = client;<tr><td><a name="l72" href="#l72">72</a><td>};<tr><td><a name="l73" href="#l73">73</a><td><tr><td><a name="l74" href="#l74">74</a><td><tr><td><a name="l75" href="#l75">75</a><td>/** @override */<tr><td><a name="l76" href="#l76">76</a><td>webdriver.http.Executor.prototype.execute = function(command, callback) {<tr><td><a name="l77" href="#l77">77</a><td> var resource = webdriver.http.Executor.COMMAND_MAP_[command.getName()];<tr><td><a name="l78" href="#l78">78</a><td> if (!resource) {<tr><td><a name="l79" href="#l79">79</a><td> throw new Error(&#39;Unrecognized command: &#39; + command.getName());<tr><td><a name="l80" href="#l80">80</a><td> }<tr><td><a name="l81" href="#l81">81</a><td><tr><td><a name="l82" href="#l82">82</a><td> var parameters = command.getParameters();<tr><td><a name="l83" href="#l83">83</a><td> var path = webdriver.http.Executor.buildPath_(resource.path, parameters);<tr><td><a name="l84" href="#l84">84</a><td> var request = new webdriver.http.Request(resource.method, path, parameters);<tr><td><a name="l85" href="#l85">85</a><td><tr><td><a name="l86" href="#l86">86</a><td> this.client_.send(request, function(e, response) {<tr><td><a name="l87" href="#l87">87</a><td> var responseObj;<tr><td><a name="l88" href="#l88">88</a><td> if (!e) {<tr><td><a name="l89" href="#l89">89</a><td> try {<tr><td><a name="l90" href="#l90">90</a><td> responseObj = webdriver.http.Executor.parseHttpResponse_(<tr><td><a name="l91" href="#l91">91</a><td> /** @type {!webdriver.http.Response} */ (response));<tr><td><a name="l92" href="#l92">92</a><td> } catch (ex) {<tr><td><a name="l93" href="#l93">93</a><td> e = ex;<tr><td><a name="l94" href="#l94">94</a><td> }<tr><td><a name="l95" href="#l95">95</a><td> }<tr><td><a name="l96" href="#l96">96</a><td> callback(e, responseObj);<tr><td><a name="l97" href="#l97">97</a><td> });<tr><td><a name="l98" href="#l98">98</a><td>};<tr><td><a name="l99" href="#l99">99</a><td><tr><td><a name="l100" href="#l100">100</a><td><tr><td><a name="l101" href="#l101">101</a><td>/**<tr><td><a name="l102" href="#l102">102</a><td> * Builds a fully qualified path using the given set of command parameters. Each<tr><td><a name="l103" href="#l103">103</a><td> * path segment prefixed with &#39;:&#39; will be replaced by the value of the<tr><td><a name="l104" href="#l104">104</a><td> * corresponding parameter. All parameters spliced into the path will be<tr><td><a name="l105" href="#l105">105</a><td> * removed from the parameter map.<tr><td><a name="l106" href="#l106">106</a><td> * @param {string} path The original resource path.<tr><td><a name="l107" href="#l107">107</a><td> * @param {!Object.&lt;*&gt;} parameters The parameters object to splice into<tr><td><a name="l108" href="#l108">108</a><td> * the path.<tr><td><a name="l109" href="#l109">109</a><td> * @return {string} The modified path.<tr><td><a name="l110" href="#l110">110</a><td> * @private<tr><td><a name="l111" href="#l111">111</a><td> */<tr><td><a name="l112" href="#l112">112</a><td>webdriver.http.Executor.buildPath_ = function(path, parameters) {<tr><td><a name="l113" href="#l113">113</a><td> var pathParameters = path.match(/\/:(\w+)\b/g);<tr><td><a name="l114" href="#l114">114</a><td> if (pathParameters) {<tr><td><a name="l115" href="#l115">115</a><td> for (var i = 0; i &lt; pathParameters.length; ++i) {<tr><td><a name="l116" href="#l116">116</a><td> var key = pathParameters[i].substring(2); // Trim the /:<tr><td><a name="l117" href="#l117">117</a><td> if (key in parameters) {<tr><td><a name="l118" href="#l118">118</a><td> var value = parameters[key];<tr><td><a name="l119" href="#l119">119</a><td> // TODO: move webdriver.WebElement.ELEMENT definition to a<tr><td><a name="l120" href="#l120">120</a><td> // common file so we can reference it here without pulling in all of<tr><td><a name="l121" href="#l121">121</a><td> // webdriver.WebElement&#39;s dependencies.<tr><td><a name="l122" href="#l122">122</a><td> if (value &amp;&amp; value[&#39;ELEMENT&#39;]) {<tr><td><a name="l123" href="#l123">123</a><td> // When inserting a WebElement into the URL, only use its ID value,<tr><td><a name="l124" href="#l124">124</a><td> // not the full JSON.<tr><td><a name="l125" href="#l125">125</a><td> value = value[&#39;ELEMENT&#39;];<tr><td><a name="l126" href="#l126">126</a><td> }<tr><td><a name="l127" href="#l127">127</a><td> path = path.replace(pathParameters[i], &#39;/&#39; + value);<tr><td><a name="l128" href="#l128">128</a><td> delete parameters[key];<tr><td><a name="l129" href="#l129">129</a><td> } else {<tr><td><a name="l130" href="#l130">130</a><td> throw new Error(&#39;Missing required parameter: &#39; + key);<tr><td><a name="l131" href="#l131">131</a><td> }<tr><td><a name="l132" href="#l132">132</a><td> }<tr><td><a name="l133" href="#l133">133</a><td> }<tr><td><a name="l134" href="#l134">134</a><td> return path;<tr><td><a name="l135" href="#l135">135</a><td>};<tr><td><a name="l136" href="#l136">136</a><td><tr><td><a name="l137" href="#l137">137</a><td><tr><td><a name="l138" href="#l138">138</a><td>/**<tr><td><a name="l139" href="#l139">139</a><td> * Callback used to parse {@link webdriver.http.Response} objects from a<tr><td><a name="l140" href="#l140">140</a><td> * {@link webdriver.http.Client}.<tr><td><a name="l141" href="#l141">141</a><td> * @param {!webdriver.http.Response} httpResponse The HTTP response to parse.<tr><td><a name="l142" href="#l142">142</a><td> * @return {!bot.response.ResponseObject} The parsed response.<tr><td><a name="l143" href="#l143">143</a><td> * @private<tr><td><a name="l144" href="#l144">144</a><td> */<tr><td><a name="l145" href="#l145">145</a><td>webdriver.http.Executor.parseHttpResponse_ = function(httpResponse) {<tr><td><a name="l146" href="#l146">146</a><td> try {<tr><td><a name="l147" href="#l147">147</a><td> return /** @type {!bot.response.ResponseObject} */ (goog.json.parse(<tr><td><a name="l148" href="#l148">148</a><td> httpResponse.body));<tr><td><a name="l149" href="#l149">149</a><td> } catch (ex) {<tr><td><a name="l150" href="#l150">150</a><td> // Whoops, looks like the server sent us a malformed response. We&#39;ll need<tr><td><a name="l151" href="#l151">151</a><td> // to manually build a response object based on the response code.<tr><td><a name="l152" href="#l152">152</a><td> }<tr><td><a name="l153" href="#l153">153</a><td><tr><td><a name="l154" href="#l154">154</a><td> var response = {<tr><td><a name="l155" href="#l155">155</a><td> &#39;status&#39;: bot.ErrorCode.SUCCESS,<tr><td><a name="l156" href="#l156">156</a><td> &#39;value&#39;: httpResponse.body.replace(/\r\n/g, &#39;\n&#39;)<tr><td><a name="l157" href="#l157">157</a><td> };<tr><td><a name="l158" href="#l158">158</a><td><tr><td><a name="l159" href="#l159">159</a><td> if (!(httpResponse.status &gt; 199 &amp;&amp; httpResponse.status &lt; 300)) {<tr><td><a name="l160" href="#l160">160</a><td> // 404 represents an unknown command; anything else is a generic unknown<tr><td><a name="l161" href="#l161">161</a><td> // error.<tr><td><a name="l162" href="#l162">162</a><td> response[&#39;status&#39;] = httpResponse.status == 404 ?<tr><td><a name="l163" href="#l163">163</a><td> bot.ErrorCode.UNKNOWN_COMMAND :<tr><td><a name="l164" href="#l164">164</a><td> bot.ErrorCode.UNKNOWN_ERROR;<tr><td><a name="l165" href="#l165">165</a><td> }<tr><td><a name="l166" href="#l166">166</a><td><tr><td><a name="l167" href="#l167">167</a><td> return response;<tr><td><a name="l168" href="#l168">168</a><td>};<tr><td><a name="l169" href="#l169">169</a><td><tr><td><a name="l170" href="#l170">170</a><td><tr><td><a name="l171" href="#l171">171</a><td>/**<tr><td><a name="l172" href="#l172">172</a><td> * Maps command names to resource locator.<tr><td><a name="l173" href="#l173">173</a><td> * @private {!Object.&lt;{method:string, path:string}&gt;}<tr><td><a name="l174" href="#l174">174</a><td> * @const<tr><td><a name="l175" href="#l175">175</a><td> */<tr><td><a name="l176" href="#l176">176</a><td>webdriver.http.Executor.COMMAND_MAP_ = (function() {<tr><td><a name="l177" href="#l177">177</a><td> return new Builder().<tr><td><a name="l178" href="#l178">178</a><td> put(webdriver.CommandName.GET_SERVER_STATUS, get(&#39;/status&#39;)).<tr><td><a name="l179" href="#l179">179</a><td> put(webdriver.CommandName.NEW_SESSION, post(&#39;/session&#39;)).<tr><td><a name="l180" href="#l180">180</a><td> put(webdriver.CommandName.GET_SESSIONS, get(&#39;/sessions&#39;)).<tr><td><a name="l181" href="#l181">181</a><td> put(webdriver.CommandName.DESCRIBE_SESSION, get(&#39;/session/:sessionId&#39;)).<tr><td><a name="l182" href="#l182">182</a><td> put(webdriver.CommandName.QUIT, del(&#39;/session/:sessionId&#39;)).<tr><td><a name="l183" href="#l183">183</a><td> put(webdriver.CommandName.CLOSE, del(&#39;/session/:sessionId/window&#39;)).<tr><td><a name="l184" href="#l184">184</a><td> put(webdriver.CommandName.GET_CURRENT_WINDOW_HANDLE,<tr><td><a name="l185" href="#l185">185</a><td> get(&#39;/session/:sessionId/window_handle&#39;)).<tr><td><a name="l186" href="#l186">186</a><td> put(webdriver.CommandName.GET_WINDOW_HANDLES,<tr><td><a name="l187" href="#l187">187</a><td> get(&#39;/session/:sessionId/window_handles&#39;)).<tr><td><a name="l188" href="#l188">188</a><td> put(webdriver.CommandName.GET_CURRENT_URL,<tr><td><a name="l189" href="#l189">189</a><td> get(&#39;/session/:sessionId/url&#39;)).<tr><td><a name="l190" href="#l190">190</a><td> put(webdriver.CommandName.GET, post(&#39;/session/:sessionId/url&#39;)).<tr><td><a name="l191" href="#l191">191</a><td> put(webdriver.CommandName.GO_BACK, post(&#39;/session/:sessionId/back&#39;)).<tr><td><a name="l192" href="#l192">192</a><td> put(webdriver.CommandName.GO_FORWARD,<tr><td><a name="l193" href="#l193">193</a><td> post(&#39;/session/:sessionId/forward&#39;)).<tr><td><a name="l194" href="#l194">194</a><td> put(webdriver.CommandName.REFRESH,<tr><td><a name="l195" href="#l195">195</a><td> post(&#39;/session/:sessionId/refresh&#39;)).<tr><td><a name="l196" href="#l196">196</a><td> put(webdriver.CommandName.ADD_COOKIE,<tr><td><a name="l197" href="#l197">197</a><td> post(&#39;/session/:sessionId/cookie&#39;)).<tr><td><a name="l198" href="#l198">198</a><td> put(webdriver.CommandName.GET_ALL_COOKIES,<tr><td><a name="l199" href="#l199">199</a><td> get(&#39;/session/:sessionId/cookie&#39;)).<tr><td><a name="l200" href="#l200">200</a><td> put(webdriver.CommandName.DELETE_ALL_COOKIES,<tr><td><a name="l201" href="#l201">201</a><td> del(&#39;/session/:sessionId/cookie&#39;)).<tr><td><a name="l202" href="#l202">202</a><td> put(webdriver.CommandName.DELETE_COOKIE,<tr><td><a name="l203" href="#l203">203</a><td> del(&#39;/session/:sessionId/cookie/:name&#39;)).<tr><td><a name="l204" href="#l204">204</a><td> put(webdriver.CommandName.FIND_ELEMENT,<tr><td><a name="l205" href="#l205">205</a><td> post(&#39;/session/:sessionId/element&#39;)).<tr><td><a name="l206" href="#l206">206</a><td> put(webdriver.CommandName.FIND_ELEMENTS,<tr><td><a name="l207" href="#l207">207</a><td> post(&#39;/session/:sessionId/elements&#39;)).<tr><td><a name="l208" href="#l208">208</a><td> put(webdriver.CommandName.GET_ACTIVE_ELEMENT,<tr><td><a name="l209" href="#l209">209</a><td> post(&#39;/session/:sessionId/element/active&#39;)).<tr><td><a name="l210" href="#l210">210</a><td> put(webdriver.CommandName.FIND_CHILD_ELEMENT,<tr><td><a name="l211" href="#l211">211</a><td> post(&#39;/session/:sessionId/element/:id/element&#39;)).<tr><td><a name="l212" href="#l212">212</a><td> put(webdriver.CommandName.FIND_CHILD_ELEMENTS,<tr><td><a name="l213" href="#l213">213</a><td> post(&#39;/session/:sessionId/element/:id/elements&#39;)).<tr><td><a name="l214" href="#l214">214</a><td> put(webdriver.CommandName.CLEAR_ELEMENT,<tr><td><a name="l215" href="#l215">215</a><td> post(&#39;/session/:sessionId/element/:id/clear&#39;)).<tr><td><a name="l216" href="#l216">216</a><td> put(webdriver.CommandName.CLICK_ELEMENT,<tr><td><a name="l217" href="#l217">217</a><td> post(&#39;/session/:sessionId/element/:id/click&#39;)).<tr><td><a name="l218" href="#l218">218</a><td> put(webdriver.CommandName.SEND_KEYS_TO_ELEMENT,<tr><td><a name="l219" href="#l219">219</a><td> post(&#39;/session/:sessionId/element/:id/value&#39;)).<tr><td><a name="l220" href="#l220">220</a><td> put(webdriver.CommandName.SUBMIT_ELEMENT,<tr><td><a name="l221" href="#l221">221</a><td> post(&#39;/session/:sessionId/element/:id/submit&#39;)).<tr><td><a name="l222" href="#l222">222</a><td> put(webdriver.CommandName.GET_ELEMENT_TEXT,<tr><td><a name="l223" href="#l223">223</a><td> get(&#39;/session/:sessionId/element/:id/text&#39;)).<tr><td><a name="l224" href="#l224">224</a><td> put(webdriver.CommandName.GET_ELEMENT_TAG_NAME,<tr><td><a name="l225" href="#l225">225</a><td> get(&#39;/session/:sessionId/element/:id/name&#39;)).<tr><td><a name="l226" href="#l226">226</a><td> put(webdriver.CommandName.IS_ELEMENT_SELECTED,<tr><td><a name="l227" href="#l227">227</a><td> get(&#39;/session/:sessionId/element/:id/selected&#39;)).<tr><td><a name="l228" href="#l228">228</a><td> put(webdriver.CommandName.IS_ELEMENT_ENABLED,<tr><td><a name="l229" href="#l229">229</a><td> get(&#39;/session/:sessionId/element/:id/enabled&#39;)).<tr><td><a name="l230" href="#l230">230</a><td> put(webdriver.CommandName.IS_ELEMENT_DISPLAYED,<tr><td><a name="l231" href="#l231">231</a><td> get(&#39;/session/:sessionId/element/:id/displayed&#39;)).<tr><td><a name="l232" href="#l232">232</a><td> put(webdriver.CommandName.GET_ELEMENT_LOCATION,<tr><td><a name="l233" href="#l233">233</a><td> get(&#39;/session/:sessionId/element/:id/location&#39;)).<tr><td><a name="l234" href="#l234">234</a><td> put(webdriver.CommandName.GET_ELEMENT_SIZE,<tr><td><a name="l235" href="#l235">235</a><td> get(&#39;/session/:sessionId/element/:id/size&#39;)).<tr><td><a name="l236" href="#l236">236</a><td> put(webdriver.CommandName.GET_ELEMENT_ATTRIBUTE,<tr><td><a name="l237" href="#l237">237</a><td> get(&#39;/session/:sessionId/element/:id/attribute/:name&#39;)).<tr><td><a name="l238" href="#l238">238</a><td> put(webdriver.CommandName.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,<tr><td><a name="l239" href="#l239">239</a><td> get(&#39;/session/:sessionId/element/:id/css/:propertyName&#39;)).<tr><td><a name="l240" href="#l240">240</a><td> put(webdriver.CommandName.ELEMENT_EQUALS,<tr><td><a name="l241" href="#l241">241</a><td> get(&#39;/session/:sessionId/element/:id/equals/:other&#39;)).<tr><td><a name="l242" href="#l242">242</a><td> put(webdriver.CommandName.SWITCH_TO_WINDOW,<tr><td><a name="l243" href="#l243">243</a><td> post(&#39;/session/:sessionId/window&#39;)).<tr><td><a name="l244" href="#l244">244</a><td> put(webdriver.CommandName.MAXIMIZE_WINDOW,<tr><td><a name="l245" href="#l245">245</a><td> post(&#39;/session/:sessionId/window/:windowHandle/maximize&#39;)).<tr><td><a name="l246" href="#l246">246</a><td> put(webdriver.CommandName.GET_WINDOW_POSITION,<tr><td><a name="l247" href="#l247">247</a><td> get(&#39;/session/:sessionId/window/:windowHandle/position&#39;)).<tr><td><a name="l248" href="#l248">248</a><td> put(webdriver.CommandName.SET_WINDOW_POSITION,<tr><td><a name="l249" href="#l249">249</a><td> post(&#39;/session/:sessionId/window/:windowHandle/position&#39;)).<tr><td><a name="l250" href="#l250">250</a><td> put(webdriver.CommandName.GET_WINDOW_SIZE,<tr><td><a name="l251" href="#l251">251</a><td> get(&#39;/session/:sessionId/window/:windowHandle/size&#39;)).<tr><td><a name="l252" href="#l252">252</a><td> put(webdriver.CommandName.SET_WINDOW_SIZE,<tr><td><a name="l253" href="#l253">253</a><td> post(&#39;/session/:sessionId/window/:windowHandle/size&#39;)).<tr><td><a name="l254" href="#l254">254</a><td> put(webdriver.CommandName.SWITCH_TO_FRAME,<tr><td><a name="l255" href="#l255">255</a><td> post(&#39;/session/:sessionId/frame&#39;)).<tr><td><a name="l256" href="#l256">256</a><td> put(webdriver.CommandName.GET_PAGE_SOURCE,<tr><td><a name="l257" href="#l257">257</a><td> get(&#39;/session/:sessionId/source&#39;)).<tr><td><a name="l258" href="#l258">258</a><td> put(webdriver.CommandName.GET_TITLE,<tr><td><a name="l259" href="#l259">259</a><td> get(&#39;/session/:sessionId/title&#39;)).<tr><td><a name="l260" href="#l260">260</a><td> put(webdriver.CommandName.EXECUTE_SCRIPT,<tr><td><a name="l261" href="#l261">261</a><td> post(&#39;/session/:sessionId/execute&#39;)).<tr><td><a name="l262" href="#l262">262</a><td> put(webdriver.CommandName.EXECUTE_ASYNC_SCRIPT,<tr><td><a name="l263" href="#l263">263</a><td> post(&#39;/session/:sessionId/execute_async&#39;)).<tr><td><a name="l264" href="#l264">264</a><td> put(webdriver.CommandName.SCREENSHOT,<tr><td><a name="l265" href="#l265">265</a><td> get(&#39;/session/:sessionId/screenshot&#39;)).<tr><td><a name="l266" href="#l266">266</a><td> put(webdriver.CommandName.SET_TIMEOUT,<tr><td><a name="l267" href="#l267">267</a><td> post(&#39;/session/:sessionId/timeouts&#39;)).<tr><td><a name="l268" href="#l268">268</a><td> put(webdriver.CommandName.SET_SCRIPT_TIMEOUT,<tr><td><a name="l269" href="#l269">269</a><td> post(&#39;/session/:sessionId/timeouts/async_script&#39;)).<tr><td><a name="l270" href="#l270">270</a><td> put(webdriver.CommandName.IMPLICITLY_WAIT,<tr><td><a name="l271" href="#l271">271</a><td> post(&#39;/session/:sessionId/timeouts/implicit_wait&#39;)).<tr><td><a name="l272" href="#l272">272</a><td> put(webdriver.CommandName.MOVE_TO, post(&#39;/session/:sessionId/moveto&#39;)).<tr><td><a name="l273" href="#l273">273</a><td> put(webdriver.CommandName.CLICK, post(&#39;/session/:sessionId/click&#39;)).<tr><td><a name="l274" href="#l274">274</a><td> put(webdriver.CommandName.DOUBLE_CLICK,<tr><td><a name="l275" href="#l275">275</a><td> post(&#39;/session/:sessionId/doubleclick&#39;)).<tr><td><a name="l276" href="#l276">276</a><td> put(webdriver.CommandName.MOUSE_DOWN,<tr><td><a name="l277" href="#l277">277</a><td> post(&#39;/session/:sessionId/buttondown&#39;)).<tr><td><a name="l278" href="#l278">278</a><td> put(webdriver.CommandName.MOUSE_UP, post(&#39;/session/:sessionId/buttonup&#39;)).<tr><td><a name="l279" href="#l279">279</a><td> put(webdriver.CommandName.MOVE_TO, post(&#39;/session/:sessionId/moveto&#39;)).<tr><td><a name="l280" href="#l280">280</a><td> put(webdriver.CommandName.SEND_KEYS_TO_ACTIVE_ELEMENT,<tr><td><a name="l281" href="#l281">281</a><td> post(&#39;/session/:sessionId/keys&#39;)).<tr><td><a name="l282" href="#l282">282</a><td> put(webdriver.CommandName.ACCEPT_ALERT,<tr><td><a name="l283" href="#l283">283</a><td> post(&#39;/session/:sessionId/accept_alert&#39;)).<tr><td><a name="l284" href="#l284">284</a><td> put(webdriver.CommandName.DISMISS_ALERT,<tr><td><a name="l285" href="#l285">285</a><td> post(&#39;/session/:sessionId/dismiss_alert&#39;)).<tr><td><a name="l286" href="#l286">286</a><td> put(webdriver.CommandName.GET_ALERT_TEXT,<tr><td><a name="l287" href="#l287">287</a><td> get(&#39;/session/:sessionId/alert_text&#39;)).<tr><td><a name="l288" href="#l288">288</a><td> put(webdriver.CommandName.SET_ALERT_TEXT,<tr><td><a name="l289" href="#l289">289</a><td> post(&#39;/session/:sessionId/alert_text&#39;)).<tr><td><a name="l290" href="#l290">290</a><td> put(webdriver.CommandName.GET_LOG, post(&#39;/session/:sessionId/log&#39;)).<tr><td><a name="l291" href="#l291">291</a><td> put(webdriver.CommandName.GET_AVAILABLE_LOG_TYPES,<tr><td><a name="l292" href="#l292">292</a><td> get(&#39;/session/:sessionId/log/types&#39;)).<tr><td><a name="l293" href="#l293">293</a><td> put(webdriver.CommandName.GET_SESSION_LOGS, post(&#39;/logs&#39;)).<tr><td><a name="l294" href="#l294">294</a><td> build();<tr><td><a name="l295" href="#l295">295</a><td><tr><td><a name="l296" href="#l296">296</a><td> /** @constructor */<tr><td><a name="l297" href="#l297">297</a><td> function Builder() {<tr><td><a name="l298" href="#l298">298</a><td> var map = {};<tr><td><a name="l299" href="#l299">299</a><td><tr><td><a name="l300" href="#l300">300</a><td> this.put = function(name, resource) {<tr><td><a name="l301" href="#l301">301</a><td> map[name] = resource;<tr><td><a name="l302" href="#l302">302</a><td> return this;<tr><td><a name="l303" href="#l303">303</a><td> };<tr><td><a name="l304" href="#l304">304</a><td><tr><td><a name="l305" href="#l305">305</a><td> this.build = function() {<tr><td><a name="l306" href="#l306">306</a><td> return map;<tr><td><a name="l307" href="#l307">307</a><td> };<tr><td><a name="l308" href="#l308">308</a><td> }<tr><td><a name="l309" href="#l309">309</a><td><tr><td><a name="l310" href="#l310">310</a><td> function post(path) { return resource(&#39;POST&#39;, path); }<tr><td><a name="l311" href="#l311">311</a><td> function del(path) { return resource(&#39;DELETE&#39;, path); }<tr><td><a name="l312" href="#l312">312</a><td> function get(path) { return resource(&#39;GET&#39;, path); }<tr><td><a name="l313" href="#l313">313</a><td> function resource(method, path) { return {method: method, path: path}; }<tr><td><a name="l314" href="#l314">314</a><td>})();<tr><td><a name="l315" href="#l315">315</a><td><tr><td><a name="l316" href="#l316">316</a><td><tr><td><a name="l317" href="#l317">317</a><td>/**<tr><td><a name="l318" href="#l318">318</a><td> * Converts a headers object to a HTTP header block string.<tr><td><a name="l319" href="#l319">319</a><td> * @param {!Object.&lt;string&gt;} headers The headers object to convert.<tr><td><a name="l320" href="#l320">320</a><td> * @return {string} The headers as a string.<tr><td><a name="l321" href="#l321">321</a><td> * @private<tr><td><a name="l322" href="#l322">322</a><td> */<tr><td><a name="l323" href="#l323">323</a><td>webdriver.http.headersToString_ = function(headers) {<tr><td><a name="l324" href="#l324">324</a><td> var ret = [];<tr><td><a name="l325" href="#l325">325</a><td> for (var key in headers) {<tr><td><a name="l326" href="#l326">326</a><td> ret.push(key + &#39;: &#39; + headers[key]);<tr><td><a name="l327" href="#l327">327</a><td> }<tr><td><a name="l328" href="#l328">328</a><td> return ret.join(&#39;\n&#39;);<tr><td><a name="l329" href="#l329">329</a><td>};<tr><td><a name="l330" href="#l330">330</a><td><tr><td><a name="l331" href="#l331">331</a><td><tr><td><a name="l332" href="#l332">332</a><td><tr><td><a name="l333" href="#l333">333</a><td>/**<tr><td><a name="l334" href="#l334">334</a><td> * Describes a partial HTTP request. This class is a &quot;partial&quot; request and only<tr><td><a name="l335" href="#l335">335</a><td> * defines the path on the server to send a request to. It is each<tr><td><a name="l336" href="#l336">336</a><td> * {@code webdriver.http.Client}&#39;s responsibility to build the full URL for the<tr><td><a name="l337" href="#l337">337</a><td> * final request.<tr><td><a name="l338" href="#l338">338</a><td> * @param {string} method The HTTP method to use for the request.<tr><td><a name="l339" href="#l339">339</a><td> * @param {string} path Path on the server to send the request to.<tr><td><a name="l340" href="#l340">340</a><td> * @param {Object=} opt_data This request&#39;s JSON data.<tr><td><a name="l341" href="#l341">341</a><td> * @constructor<tr><td><a name="l342" href="#l342">342</a><td> */<tr><td><a name="l343" href="#l343">343</a><td>webdriver.http.Request = function(method, path, opt_data) {<tr><td><a name="l344" href="#l344">344</a><td><tr><td><a name="l345" href="#l345">345</a><td> /**<tr><td><a name="l346" href="#l346">346</a><td> * The HTTP method to use for the request.<tr><td><a name="l347" href="#l347">347</a><td> * @type {string}<tr><td><a name="l348" href="#l348">348</a><td> */<tr><td><a name="l349" href="#l349">349</a><td> this.method = method;<tr><td><a name="l350" href="#l350">350</a><td><tr><td><a name="l351" href="#l351">351</a><td> /**<tr><td><a name="l352" href="#l352">352</a><td> * The path on the server to send the request to.<tr><td><a name="l353" href="#l353">353</a><td> * @type {string}<tr><td><a name="l354" href="#l354">354</a><td> */<tr><td><a name="l355" href="#l355">355</a><td> this.path = path;<tr><td><a name="l356" href="#l356">356</a><td><tr><td><a name="l357" href="#l357">357</a><td> /**<tr><td><a name="l358" href="#l358">358</a><td> * This request&#39;s body.<tr><td><a name="l359" href="#l359">359</a><td> * @type {!Object}<tr><td><a name="l360" href="#l360">360</a><td> */<tr><td><a name="l361" href="#l361">361</a><td> this.data = opt_data || {};<tr><td><a name="l362" href="#l362">362</a><td><tr><td><a name="l363" href="#l363">363</a><td> /**<tr><td><a name="l364" href="#l364">364</a><td> * The headers to send with the request.<tr><td><a name="l365" href="#l365">365</a><td> * @type {!Object.&lt;(string|number)&gt;}<tr><td><a name="l366" href="#l366">366</a><td> */<tr><td><a name="l367" href="#l367">367</a><td> this.headers = {&#39;Accept&#39;: &#39;application/json; charset=utf-8&#39;};<tr><td><a name="l368" href="#l368">368</a><td>};<tr><td><a name="l369" href="#l369">369</a><td><tr><td><a name="l370" href="#l370">370</a><td><tr><td><a name="l371" href="#l371">371</a><td>/** @override */<tr><td><a name="l372" href="#l372">372</a><td>webdriver.http.Request.prototype.toString = function() {<tr><td><a name="l373" href="#l373">373</a><td> return [<tr><td><a name="l374" href="#l374">374</a><td> this.method + &#39; &#39; + this.path + &#39; HTTP/1.1&#39;,<tr><td><a name="l375" href="#l375">375</a><td> webdriver.http.headersToString_(this.headers),<tr><td><a name="l376" href="#l376">376</a><td> &#39;&#39;,<tr><td><a name="l377" href="#l377">377</a><td> goog.json.serialize(this.data)<tr><td><a name="l378" href="#l378">378</a><td> ].join(&#39;\n&#39;);<tr><td><a name="l379" href="#l379">379</a><td>};<tr><td><a name="l380" href="#l380">380</a><td><tr><td><a name="l381" href="#l381">381</a><td><tr><td><a name="l382" href="#l382">382</a><td><tr><td><a name="l383" href="#l383">383</a><td>/**<tr><td><a name="l384" href="#l384">384</a><td> * Represents a HTTP response.<tr><td><a name="l385" href="#l385">385</a><td> * @param {number} status The response code.<tr><td><a name="l386" href="#l386">386</a><td> * @param {!Object.&lt;string&gt;} headers The response headers. All header<tr><td><a name="l387" href="#l387">387</a><td> * names will be converted to lowercase strings for consistent lookups.<tr><td><a name="l388" href="#l388">388</a><td> * @param {string} body The response body.<tr><td><a name="l389" href="#l389">389</a><td> * @constructor<tr><td><a name="l390" href="#l390">390</a><td> */<tr><td><a name="l391" href="#l391">391</a><td>webdriver.http.Response = function(status, headers, body) {<tr><td><a name="l392" href="#l392">392</a><td><tr><td><a name="l393" href="#l393">393</a><td> /**<tr><td><a name="l394" href="#l394">394</a><td> * The HTTP response code.<tr><td><a name="l395" href="#l395">395</a><td> * @type {number}<tr><td><a name="l396" href="#l396">396</a><td> */<tr><td><a name="l397" href="#l397">397</a><td> this.status = status;<tr><td><a name="l398" href="#l398">398</a><td><tr><td><a name="l399" href="#l399">399</a><td> /**<tr><td><a name="l400" href="#l400">400</a><td> * The response body.<tr><td><a name="l401" href="#l401">401</a><td> * @type {string}<tr><td><a name="l402" href="#l402">402</a><td> */<tr><td><a name="l403" href="#l403">403</a><td> this.body = body;<tr><td><a name="l404" href="#l404">404</a><td><tr><td><a name="l405" href="#l405">405</a><td> /**<tr><td><a name="l406" href="#l406">406</a><td> * The response body.<tr><td><a name="l407" href="#l407">407</a><td> * @type {!Object.&lt;string&gt;}<tr><td><a name="l408" href="#l408">408</a><td> */<tr><td><a name="l409" href="#l409">409</a><td> this.headers = {};<tr><td><a name="l410" href="#l410">410</a><td> for (var header in headers) {<tr><td><a name="l411" href="#l411">411</a><td> this.headers[header.toLowerCase()] = headers[header];<tr><td><a name="l412" href="#l412">412</a><td> }<tr><td><a name="l413" href="#l413">413</a><td>};<tr><td><a name="l414" href="#l414">414</a><td><tr><td><a name="l415" href="#l415">415</a><td><tr><td><a name="l416" href="#l416">416</a><td>/**<tr><td><a name="l417" href="#l417">417</a><td> * Builds a {@code webdriver.http.Response} from a {@code XMLHttpRequest} or<tr><td><a name="l418" href="#l418">418</a><td> * {@code XDomainRequest} response object.<tr><td><a name="l419" href="#l419">419</a><td> * @param {!(XDomainRequest|XMLHttpRequest)} xhr The request to parse.<tr><td><a name="l420" href="#l420">420</a><td> * @return {!webdriver.http.Response} The parsed response.<tr><td><a name="l421" href="#l421">421</a><td> */<tr><td><a name="l422" href="#l422">422</a><td>webdriver.http.Response.fromXmlHttpRequest = function(xhr) {<tr><td><a name="l423" href="#l423">423</a><td> var headers = {};<tr><td><a name="l424" href="#l424">424</a><td><tr><td><a name="l425" href="#l425">425</a><td> // getAllResponseHeaders is only available on XMLHttpRequest objects.<tr><td><a name="l426" href="#l426">426</a><td> if (xhr.getAllResponseHeaders) {<tr><td><a name="l427" href="#l427">427</a><td> var tmp = xhr.getAllResponseHeaders();<tr><td><a name="l428" href="#l428">428</a><td> if (tmp) {<tr><td><a name="l429" href="#l429">429</a><td> tmp = tmp.replace(/\r\n/g, &#39;\n&#39;).split(&#39;\n&#39;);<tr><td><a name="l430" href="#l430">430</a><td> goog.array.forEach(tmp, function(header) {<tr><td><a name="l431" href="#l431">431</a><td> var parts = header.split(/\s*:\s*/, 2);<tr><td><a name="l432" href="#l432">432</a><td> if (parts[0]) {<tr><td><a name="l433" href="#l433">433</a><td> headers[parts[0]] = parts[1] || &#39;&#39;;<tr><td><a name="l434" href="#l434">434</a><td> }<tr><td><a name="l435" href="#l435">435</a><td> });<tr><td><a name="l436" href="#l436">436</a><td> }<tr><td><a name="l437" href="#l437">437</a><td> }<tr><td><a name="l438" href="#l438">438</a><td><tr><td><a name="l439" href="#l439">439</a><td> // If xhr is a XDomainRequest object, it will not have a status.<tr><td><a name="l440" href="#l440">440</a><td> // However, if we&#39;re parsing the response from a XDomainRequest, then<tr><td><a name="l441" href="#l441">441</a><td> // that request must have been a success, so we can assume status == 200.<tr><td><a name="l442" href="#l442">442</a><td> var status = xhr.status || 200;<tr><td><a name="l443" href="#l443">443</a><td> return new webdriver.http.Response(status, headers,<tr><td><a name="l444" href="#l444">444</a><td> xhr.responseText.replace(/\0/g, &#39;&#39;));<tr><td><a name="l445" href="#l445">445</a><td>};<tr><td><a name="l446" href="#l446">446</a><td><tr><td><a name="l447" href="#l447">447</a><td><tr><td><a name="l448" href="#l448">448</a><td>/** @override */<tr><td><a name="l449" href="#l449">449</a><td>webdriver.http.Response.prototype.toString = function() {<tr><td><a name="l450" href="#l450">450</a><td> var headers = webdriver.http.headersToString_(this.headers);<tr><td><a name="l451" href="#l451">451</a><td> var ret = [&#39;HTTP/1.1 &#39; + this.status, headers];<tr><td><a name="l452" href="#l452">452</a><td><tr><td><a name="l453" href="#l453">453</a><td> if (headers) {<tr><td><a name="l454" href="#l454">454</a><td> ret.push(&#39;&#39;);<tr><td><a name="l455" href="#l455">455</a><td> }<tr><td><a name="l456" href="#l456">456</a><td><tr><td><a name="l457" href="#l457">457</a><td> if (this.body) {<tr><td><a name="l458" href="#l458">458</a><td> ret.push(this.body);<tr><td><a name="l459" href="#l459">459</a><td> }<tr><td><a name="l460" href="#l460">460</a><td><tr><td><a name="l461" href="#l461">461</a><td> return ret.join(&#39;\n&#39;);<tr><td><a name="l462" href="#l462">462</a><td>};</table></pre></main><nav id="topnav"><div><div id="menubutton"><label for="sidenav-toggle">Menu</label></div><form id="searchbox"><div><input type="search" placeholder="Search" tabindex="1"></div></form></div></nav><nav id="sidenav"><input type="checkbox" id="sidenav-types-ctrl" /><input type="checkbox" id="sidenav-files-ctrl" /><input type="checkbox" id="sidenav-modules-ctrl" /><a id="sidenav-overview"><div><h4>Overview</h4></div></a><div id="sidenav-types"><label for="sidenav-types-ctrl"><h4>Types</h4></label><i>Loading</i></div><div id="sidenav-modules"><label for="sidenav-modules-ctrl"><h4>Modules</h4></label><i>Loading</i></div><div id="sidenav-files"><label for="sidenav-files-ctrl"><h4>Files</h4></label><i>Loading</i></div><a href="../../../../license.html"><div><h4>License</h4></div></a></nav><div id="push-footer"></div></div><footer><a href="https://github.com/jleyba/js-dossier">Generated by dossier</a></footer><script src="../../../../types.js"></script><script src="../../../../dossier.js"></script>