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.
- package/CHANGES.md +20 -0
- package/README.md +8 -13
- package/builder.js +4 -3
- package/docs/class_webdriver_Alert.html +6 -6
- package/docs/class_webdriver_AlertPromise.html +6 -6
- package/docs/class_webdriver_UnhandledAlertError.html +4 -4
- package/docs/class_webdriver_WebDriver.html +39 -37
- package/docs/class_webdriver_WebDriver_Logs.html +3 -3
- package/docs/class_webdriver_WebDriver_Navigation.html +5 -5
- package/docs/class_webdriver_WebDriver_Options.html +9 -9
- package/docs/class_webdriver_WebDriver_TargetLocator.html +6 -6
- package/docs/class_webdriver_WebDriver_Timeouts.html +4 -4
- package/docs/class_webdriver_WebDriver_Window.html +6 -6
- package/docs/class_webdriver_WebElement.html +23 -23
- package/docs/class_webdriver_WebElementPromise.html +22 -22
- package/docs/class_webdriver_promise_CancellationError.html +3 -0
- package/docs/class_webdriver_promise_ControlFlow.html +32 -32
- package/docs/class_webdriver_promise_Deferred.html +7 -8
- package/docs/class_webdriver_promise_Frame_.html +14 -30
- package/docs/class_webdriver_promise_Promise.html +2 -2
- package/docs/class_webdriver_promise_Task_.html +12 -12
- package/docs/class_webdriver_until_Condition.html +3 -0
- package/docs/enum_webdriver_Key.html +1 -1
- package/docs/enum_webdriver_promise_ControlFlow_EventType.html +1 -1
- package/docs/enum_webdriver_promise_Deferred_State_.html +1 -1
- package/docs/index.html +8 -13
- package/docs/interface_webdriver_promise_Thenable.html +8 -10
- package/docs/license.html +1 -1
- package/docs/module_selenium-webdriver.html +2 -2
- package/docs/module_selenium-webdriver__base.html +1 -1
- package/docs/module_selenium-webdriver__base_class_Context.html +1 -1
- package/docs/module_selenium-webdriver_builder.html +1 -1
- package/docs/module_selenium-webdriver_builder_class_Builder.html +1 -1
- package/docs/module_selenium-webdriver_chrome.html +1 -1
- package/docs/module_selenium-webdriver_chrome_class_Driver.html +2 -2
- package/docs/module_selenium-webdriver_chrome_class_Options.html +2 -2
- package/docs/module_selenium-webdriver_chrome_class_ServiceBuilder.html +1 -1
- package/docs/module_selenium-webdriver_error.html +1 -1
- package/docs/module_selenium-webdriver_executors.html +1 -1
- package/docs/module_selenium-webdriver_firefox.html +1 -1
- package/docs/module_selenium-webdriver_firefox_binary.html +1 -1
- package/docs/module_selenium-webdriver_firefox_binary_class_Binary.html +1 -1
- package/docs/module_selenium-webdriver_firefox_class_Driver.html +2 -2
- package/docs/module_selenium-webdriver_firefox_class_Options.html +1 -1
- package/docs/module_selenium-webdriver_firefox_extension.html +1 -1
- package/docs/module_selenium-webdriver_firefox_profile.html +1 -1
- package/docs/module_selenium-webdriver_firefox_profile_class_Profile.html +1 -1
- package/docs/module_selenium-webdriver_http.html +1 -1
- package/docs/module_selenium-webdriver_http_class_HttpClient.html +1 -1
- package/docs/module_selenium-webdriver_http_util.html +1 -1
- package/docs/module_selenium-webdriver_io.html +1 -1
- package/docs/module_selenium-webdriver_io_exec.html +1 -1
- package/docs/module_selenium-webdriver_net.html +1 -1
- package/docs/module_selenium-webdriver_net_portprober.html +1 -1
- package/docs/module_selenium-webdriver_phantomjs.html +1 -1
- package/docs/module_selenium-webdriver_phantomjs_class_Driver.html +2 -2
- package/docs/module_selenium-webdriver_proxy.html +1 -1
- package/docs/module_selenium-webdriver_remote.html +1 -1
- package/docs/module_selenium-webdriver_remote_class_DriverService.html +2 -2
- package/docs/module_selenium-webdriver_remote_class_SeleniumServer.html +2 -2
- package/docs/module_selenium-webdriver_testing.html +16 -29
- package/docs/module_selenium-webdriver_testing_assert.html +1 -1
- package/docs/namespace_webdriver_promise.html +18 -20
- package/docs/namespace_webdriver_stacktrace.html +15 -15
- package/docs/namespace_webdriver_until.html +32 -0
- package/docs/source/_base.js.src.html +1 -1
- package/docs/source/builder.js.src.html +1 -1
- package/docs/source/chrome.js.src.html +1 -1
- package/docs/source/error.js.src.html +1 -1
- package/docs/source/executors.js.src.html +1 -1
- package/docs/source/firefox/binary.js.src.html +1 -1
- package/docs/source/firefox/extension.js.src.html +1 -1
- package/docs/source/firefox/index.js.src.html +1 -1
- package/docs/source/firefox/profile.js.src.html +1 -1
- package/docs/source/http/index.js.src.html +1 -1
- package/docs/source/http/util.js.src.html +1 -1
- package/docs/source/index.js.src.html +1 -1
- package/docs/source/io/exec.js.src.html +1 -1
- package/docs/source/io/index.js.src.html +1 -1
- package/docs/source/lib/atoms/error.js.src.html +1 -1
- package/docs/source/lib/atoms/json.js.src.html +1 -1
- package/docs/source/lib/atoms/response.js.src.html +1 -1
- package/docs/source/lib/atoms/userAgent.js.src.html +1 -1
- package/docs/source/lib/goog/array/array.js.src.html +1 -1
- package/docs/source/lib/goog/asserts/asserts.js.src.html +1 -1
- package/docs/source/lib/goog/async/nexttick.js.src.html +1 -1
- package/docs/source/lib/goog/async/run.js.src.html +1 -1
- package/docs/source/lib/goog/base.js.src.html +1 -1
- package/docs/source/lib/goog/debug/debug.js.src.html +1 -1
- package/docs/source/lib/goog/debug/entrypointregistry.js.src.html +1 -1
- package/docs/source/lib/goog/debug/error.js.src.html +1 -1
- package/docs/source/lib/goog/debug/logbuffer.js.src.html +1 -1
- package/docs/source/lib/goog/debug/logger.js.src.html +1 -1
- package/docs/source/lib/goog/debug/logrecord.js.src.html +1 -1
- package/docs/source/lib/goog/deps.js.src.html +1 -1
- package/docs/source/lib/goog/disposable/disposable.js.src.html +1 -1
- package/docs/source/lib/goog/disposable/idisposable.js.src.html +1 -1
- package/docs/source/lib/goog/dom/browserfeature.js.src.html +1 -1
- package/docs/source/lib/goog/dom/dom.js.src.html +1 -1
- package/docs/source/lib/goog/dom/nodetype.js.src.html +1 -1
- package/docs/source/lib/goog/dom/tagname.js.src.html +1 -1
- package/docs/source/lib/goog/dom/vendor.js.src.html +1 -1
- package/docs/source/lib/goog/events/browserevent.js.src.html +1 -1
- package/docs/source/lib/goog/events/browserfeature.js.src.html +1 -1
- package/docs/source/lib/goog/events/event.js.src.html +1 -1
- package/docs/source/lib/goog/events/eventid.js.src.html +1 -1
- package/docs/source/lib/goog/events/events.js.src.html +1 -1
- package/docs/source/lib/goog/events/eventtarget.js.src.html +1 -1
- package/docs/source/lib/goog/events/eventtype.js.src.html +1 -1
- package/docs/source/lib/goog/events/keycodes.js.src.html +1 -1
- package/docs/source/lib/goog/events/listenable.js.src.html +1 -1
- package/docs/source/lib/goog/events/listener.js.src.html +1 -1
- package/docs/source/lib/goog/events/listenermap.js.src.html +1 -1
- package/docs/source/lib/goog/functions/functions.js.src.html +1 -1
- package/docs/source/lib/goog/iter/iter.js.src.html +1 -1
- package/docs/source/lib/goog/json/json.js.src.html +1 -1
- package/docs/source/lib/goog/labs/testing/assertthat.js.src.html +1 -1
- package/docs/source/lib/goog/labs/testing/logicmatcher.js.src.html +1 -1
- package/docs/source/lib/goog/labs/testing/matcher.js.src.html +1 -1
- package/docs/source/lib/goog/labs/testing/numbermatcher.js.src.html +1 -1
- package/docs/source/lib/goog/labs/testing/objectmatcher.js.src.html +1 -1
- package/docs/source/lib/goog/labs/testing/stringmatcher.js.src.html +1 -1
- package/docs/source/lib/goog/labs/useragent/browser.js.src.html +1 -1
- package/docs/source/lib/goog/labs/useragent/engine.js.src.html +1 -1
- package/docs/source/lib/goog/labs/useragent/util.js.src.html +1 -1
- package/docs/source/lib/goog/math/box.js.src.html +1 -1
- package/docs/source/lib/goog/math/coordinate.js.src.html +1 -1
- package/docs/source/lib/goog/math/math.js.src.html +1 -1
- package/docs/source/lib/goog/math/rect.js.src.html +1 -1
- package/docs/source/lib/goog/math/size.js.src.html +1 -1
- package/docs/source/lib/goog/net/wrapperxmlhttpfactory.js.src.html +1 -1
- package/docs/source/lib/goog/net/xhrlike.js.src.html +1 -1
- package/docs/source/lib/goog/net/xmlhttp.js.src.html +1 -1
- package/docs/source/lib/goog/net/xmlhttpfactory.js.src.html +1 -1
- package/docs/source/lib/goog/object/object.js.src.html +1 -1
- package/docs/source/lib/goog/reflect/reflect.js.src.html +1 -1
- package/docs/source/lib/goog/string/string.js.src.html +1 -1
- package/docs/source/lib/goog/structs/collection.js.src.html +1 -1
- package/docs/source/lib/goog/structs/map.js.src.html +1 -1
- package/docs/source/lib/goog/structs/set.js.src.html +1 -1
- package/docs/source/lib/goog/structs/structs.js.src.html +1 -1
- package/docs/source/lib/goog/style/style.js.src.html +1 -1
- package/docs/source/lib/goog/testing/asserts.js.src.html +1 -1
- package/docs/source/lib/goog/testing/asynctestcase.js.src.html +1 -1
- package/docs/source/lib/goog/testing/events/events.js.src.html +1 -1
- package/docs/source/lib/goog/testing/functionmock.js.src.html +1 -1
- package/docs/source/lib/goog/testing/jsunit.js.src.html +1 -1
- package/docs/source/lib/goog/testing/loosemock.js.src.html +1 -1
- package/docs/source/lib/goog/testing/mock.js.src.html +1 -1
- package/docs/source/lib/goog/testing/mockclock.js.src.html +1 -1
- package/docs/source/lib/goog/testing/mockcontrol.js.src.html +1 -1
- package/docs/source/lib/goog/testing/mockinterface.js.src.html +1 -1
- package/docs/source/lib/goog/testing/mockmatchers.js.src.html +1 -1
- package/docs/source/lib/goog/testing/objectpropertystring.js.src.html +1 -1
- package/docs/source/lib/goog/testing/propertyreplacer.js.src.html +1 -1
- package/docs/source/lib/goog/testing/recordfunction.js.src.html +1 -1
- package/docs/source/lib/goog/testing/stacktrace.js.src.html +1 -1
- package/docs/source/lib/goog/testing/strictmock.js.src.html +1 -1
- package/docs/source/lib/goog/testing/testcase.js.src.html +1 -1
- package/docs/source/lib/goog/testing/testrunner.js.src.html +1 -1
- package/docs/source/lib/goog/testing/watchers.js.src.html +1 -1
- package/docs/source/lib/goog/uri/uri.js.src.html +1 -1
- package/docs/source/lib/goog/uri/utils.js.src.html +1 -1
- package/docs/source/lib/goog/useragent/product.js.src.html +1 -1
- package/docs/source/lib/goog/useragent/product_isversion.js.src.html +1 -1
- package/docs/source/lib/goog/useragent/useragent.js.src.html +1 -1
- package/docs/source/lib/webdriver/abstractbuilder.js.src.html +1 -1
- package/docs/source/lib/webdriver/actionsequence.js.src.html +1 -1
- package/docs/source/lib/webdriver/builder.js.src.html +1 -1
- package/docs/source/lib/webdriver/button.js.src.html +1 -1
- package/docs/source/lib/webdriver/capabilities.js.src.html +1 -1
- package/docs/source/lib/webdriver/command.js.src.html +1 -1
- package/docs/source/lib/webdriver/events.js.src.html +1 -1
- package/docs/source/lib/webdriver/firefoxdomexecutor.js.src.html +1 -1
- package/docs/source/lib/webdriver/http/corsclient.js.src.html +1 -1
- package/docs/source/lib/webdriver/http/http.js.src.html +1 -1
- package/docs/source/lib/webdriver/http/xhrclient.js.src.html +1 -1
- package/docs/source/lib/webdriver/key.js.src.html +1 -1
- package/docs/source/lib/webdriver/locators.js.src.html +1 -1
- package/docs/source/lib/webdriver/logging.js.src.html +1 -1
- package/docs/source/lib/webdriver/process.js.src.html +1 -1
- package/docs/source/lib/webdriver/promise.js.src.html +1 -1
- package/docs/source/lib/webdriver/session.js.src.html +1 -1
- package/docs/source/lib/webdriver/stacktrace.js.src.html +1 -1
- package/docs/source/lib/webdriver/testing/asserts.js.src.html +1 -1
- package/docs/source/lib/webdriver/testing/testcase.js.src.html +1 -1
- package/docs/source/lib/webdriver/until.js.src.html +1 -0
- package/docs/source/lib/webdriver/webdriver.js.src.html +1 -1
- package/docs/source/net/index.js.src.html +1 -1
- package/docs/source/net/portprober.js.src.html +1 -1
- package/docs/source/phantomjs.js.src.html +1 -1
- package/docs/source/proxy.js.src.html +1 -1
- package/docs/source/remote/index.js.src.html +1 -1
- package/docs/source/testing/assert.js.src.html +1 -1
- package/docs/source/testing/index.js.src.html +1 -1
- package/docs/types.js +1 -1
- package/example/google_search.js +9 -17
- package/example/google_search_generator.js +6 -7
- package/example/google_search_test.js +10 -18
- package/example/parallel_flows.js +4 -7
- package/index.js +6 -0
- package/lib/firefox/webdriver.xpi +0 -0
- package/lib/goog/deps.js +7 -5
- package/lib/test/index.js +0 -8
- package/lib/webdriver/promise.js +263 -251
- package/lib/webdriver/stacktrace.js +15 -1
- package/lib/webdriver/test/promise_flow_test.js +82 -76
- package/lib/webdriver/test/promise_test.js +22 -62
- package/lib/webdriver/test/stacktrace_test.js +18 -0
- package/lib/webdriver/test/until_test.js +388 -0
- package/lib/webdriver/test/webdriver_test.js +41 -0
- package/lib/webdriver/until.js +408 -0
- package/lib/webdriver/webdriver.js +91 -29
- package/package.json +2 -2
- package/test/element_finding_test.js +6 -6
- package/test/http/util_test.js +4 -5
- package/test/page_loading_test.js +7 -7
- package/test/stale_element_test.js +2 -10
- package/testing/index.js +9 -22
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><meta charset="UTF-8"><meta http-equiv="Content-Language" content="en" /><title>index.js</title><link href="../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>net/index.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2013 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2013 Software Freedom Conservancy<tr><td><a name="l3" href="#l3">3</a><td>//<tr><td><a name="l4" href="#l4">4</a><td>// Licensed under the Apache License, Version 2.0 (the "License");<tr><td><a name="l5" href="#l5">5</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l6" href="#l6">6</a><td>// You may obtain a copy of the License at<tr><td><a name="l7" href="#l7">7</a><td>//<tr><td><a name="l8" href="#l8">8</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l9" href="#l9">9</a><td>//<tr><td><a name="l10" href="#l10">10</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l11" href="#l11">11</a><td>// distributed under the License is distributed on an "AS IS" BASIS,<tr><td><a name="l12" href="#l12">12</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l13" href="#l13">13</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l14" href="#l14">14</a><td>// limitations under the License.<tr><td><a name="l15" href="#l15">15</a><td><tr><td><a name="l16" href="#l16">16</a><td>'use strict';<tr><td><a name="l17" href="#l17">17</a><td><tr><td><a name="l18" href="#l18">18</a><td>var os = require('os');<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>function getLoInterface() {<tr><td><a name="l22" href="#l22">22</a><td> var name;<tr><td><a name="l23" href="#l23">23</a><td> if (process.platform === 'darwin') {<tr><td><a name="l24" href="#l24">24</a><td> name = 'lo0';<tr><td><a name="l25" href="#l25">25</a><td> } else if (process.platform === 'linux') {<tr><td><a name="l26" href="#l26">26</a><td> name = 'lo';<tr><td><a name="l27" href="#l27">27</a><td> }<tr><td><a name="l28" href="#l28">28</a><td> return name ? os.networkInterfaces()[name] : null;<tr><td><a name="l29" href="#l29">29</a><td>}<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> * Queries the system network interfaces for an IP address.<tr><td><a name="l34" href="#l34">34</a><td> * @param {boolean} loopback Whether to find a loopback address.<tr><td><a name="l35" href="#l35">35</a><td> * @param {string=} opt_family The IP family (IPv4 or IPv6). Defaults to IPv4.<tr><td><a name="l36" href="#l36">36</a><td> * @return {string} The located IP address or undefined.<tr><td><a name="l37" href="#l37">37</a><td> */<tr><td><a name="l38" href="#l38">38</a><td>function getAddress(loopback, opt_family) {<tr><td><a name="l39" href="#l39">39</a><td> var family = opt_family || 'IPv4';<tr><td><a name="l40" href="#l40">40</a><td> var addresses = [];<tr><td><a name="l41" href="#l41">41</a><td><tr><td><a name="l42" href="#l42">42</a><td> var interfaces;<tr><td><a name="l43" href="#l43">43</a><td> if (loopback) {<tr><td><a name="l44" href="#l44">44</a><td> var lo = getLoInterface();<tr><td><a name="l45" href="#l45">45</a><td> interfaces = lo ? [lo] : null;<tr><td><a name="l46" href="#l46">46</a><td> }<tr><td><a name="l47" href="#l47">47</a><td> interfaces = interfaces || os.networkInterfaces();<tr><td><a name="l48" href="#l48">48</a><td> for (var key in interfaces) {<tr><td><a name="l49" href="#l49">49</a><td> interfaces[key].forEach(function(ipAddress) {<tr><td><a name="l50" href="#l50">50</a><td> if (ipAddress.family === family &&<tr><td><a name="l51" href="#l51">51</a><td> ipAddress.internal === loopback) {<tr><td><a name="l52" href="#l52">52</a><td> addresses.push(ipAddress.address);<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> return addresses[0];<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>// PUBLIC API<tr><td><a name="l61" href="#l61">61</a><td><tr><td><a name="l62" href="#l62">62</a><td><tr><td><a name="l63" href="#l63">63</a><td>/**<tr><td><a name="l64" href="#l64">64</a><td> * Retrieves the external IP address for this host.<tr><td><a name="l65" href="#l65">65</a><td> * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4".<tr><td><a name="l66" href="#l66">66</a><td> * @return {string} The IP address or undefined if not available.<tr><td><a name="l67" href="#l67">67</a><td> */<tr><td><a name="l68" href="#l68">68</a><td>exports.getAddress = function(opt_family) {<tr><td><a name="l69" href="#l69">69</a><td> return getAddress(false, opt_family);<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><tr><td><a name="l73" href="#l73">73</a><td>/**<tr><td><a name="l74" href="#l74">74</a><td> * Retrieves a loopback address for this machine.<tr><td><a name="l75" href="#l75">75</a><td> * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4".<tr><td><a name="l76" href="#l76">76</a><td> * @return {string} The IP address or undefined if not available.<tr><td><a name="l77" href="#l77">77</a><td> */<tr><td><a name="l78" href="#l78">78</a><td>exports.getLoopbackAddress = function(opt_family) {<tr><td><a name="l79" href="#l79">79</a><td> return getAddress(true, opt_family);<tr><td><a name="l80" href="#l80">80</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>index.js</title><link href="../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>net/index.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2013 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2013 Software Freedom Conservancy<tr><td><a name="l3" href="#l3">3</a><td>//<tr><td><a name="l4" href="#l4">4</a><td>// Licensed under the Apache License, Version 2.0 (the "License");<tr><td><a name="l5" href="#l5">5</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l6" href="#l6">6</a><td>// You may obtain a copy of the License at<tr><td><a name="l7" href="#l7">7</a><td>//<tr><td><a name="l8" href="#l8">8</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l9" href="#l9">9</a><td>//<tr><td><a name="l10" href="#l10">10</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l11" href="#l11">11</a><td>// distributed under the License is distributed on an "AS IS" BASIS,<tr><td><a name="l12" href="#l12">12</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l13" href="#l13">13</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l14" href="#l14">14</a><td>// limitations under the License.<tr><td><a name="l15" href="#l15">15</a><td><tr><td><a name="l16" href="#l16">16</a><td>'use strict';<tr><td><a name="l17" href="#l17">17</a><td><tr><td><a name="l18" href="#l18">18</a><td>var os = require('os');<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>function getLoInterface() {<tr><td><a name="l22" href="#l22">22</a><td> var name;<tr><td><a name="l23" href="#l23">23</a><td> if (process.platform === 'darwin') {<tr><td><a name="l24" href="#l24">24</a><td> name = 'lo0';<tr><td><a name="l25" href="#l25">25</a><td> } else if (process.platform === 'linux') {<tr><td><a name="l26" href="#l26">26</a><td> name = 'lo';<tr><td><a name="l27" href="#l27">27</a><td> }<tr><td><a name="l28" href="#l28">28</a><td> return name ? os.networkInterfaces()[name] : null;<tr><td><a name="l29" href="#l29">29</a><td>}<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> * Queries the system network interfaces for an IP address.<tr><td><a name="l34" href="#l34">34</a><td> * @param {boolean} loopback Whether to find a loopback address.<tr><td><a name="l35" href="#l35">35</a><td> * @param {string=} opt_family The IP family (IPv4 or IPv6). Defaults to IPv4.<tr><td><a name="l36" href="#l36">36</a><td> * @return {string} The located IP address or undefined.<tr><td><a name="l37" href="#l37">37</a><td> */<tr><td><a name="l38" href="#l38">38</a><td>function getAddress(loopback, opt_family) {<tr><td><a name="l39" href="#l39">39</a><td> var family = opt_family || 'IPv4';<tr><td><a name="l40" href="#l40">40</a><td> var addresses = [];<tr><td><a name="l41" href="#l41">41</a><td><tr><td><a name="l42" href="#l42">42</a><td> var interfaces;<tr><td><a name="l43" href="#l43">43</a><td> if (loopback) {<tr><td><a name="l44" href="#l44">44</a><td> var lo = getLoInterface();<tr><td><a name="l45" href="#l45">45</a><td> interfaces = lo ? [lo] : null;<tr><td><a name="l46" href="#l46">46</a><td> }<tr><td><a name="l47" href="#l47">47</a><td> interfaces = interfaces || os.networkInterfaces();<tr><td><a name="l48" href="#l48">48</a><td> for (var key in interfaces) {<tr><td><a name="l49" href="#l49">49</a><td> interfaces[key].forEach(function(ipAddress) {<tr><td><a name="l50" href="#l50">50</a><td> if (ipAddress.family === family &&<tr><td><a name="l51" href="#l51">51</a><td> ipAddress.internal === loopback) {<tr><td><a name="l52" href="#l52">52</a><td> addresses.push(ipAddress.address);<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> return addresses[0];<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>// PUBLIC API<tr><td><a name="l61" href="#l61">61</a><td><tr><td><a name="l62" href="#l62">62</a><td><tr><td><a name="l63" href="#l63">63</a><td>/**<tr><td><a name="l64" href="#l64">64</a><td> * Retrieves the external IP address for this host.<tr><td><a name="l65" href="#l65">65</a><td> * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4".<tr><td><a name="l66" href="#l66">66</a><td> * @return {string} The IP address or undefined if not available.<tr><td><a name="l67" href="#l67">67</a><td> */<tr><td><a name="l68" href="#l68">68</a><td>exports.getAddress = function(opt_family) {<tr><td><a name="l69" href="#l69">69</a><td> return getAddress(false, opt_family);<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><tr><td><a name="l73" href="#l73">73</a><td>/**<tr><td><a name="l74" href="#l74">74</a><td> * Retrieves a loopback address for this machine.<tr><td><a name="l75" href="#l75">75</a><td> * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4".<tr><td><a name="l76" href="#l76">76</a><td> * @return {string} The IP address or undefined if not available.<tr><td><a name="l77" href="#l77">77</a><td> */<tr><td><a name="l78" href="#l78">78</a><td>exports.getLoopbackAddress = function(opt_family) {<tr><td><a name="l79" href="#l79">79</a><td> return getAddress(true, opt_family);<tr><td><a name="l80" href="#l80">80</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>portprober.js</title><link href="../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>net/portprober.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2013 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2013 Software Freedom Conservancy<tr><td><a name="l3" href="#l3">3</a><td>//<tr><td><a name="l4" href="#l4">4</a><td>// Licensed under the Apache License, Version 2.0 (the "License");<tr><td><a name="l5" href="#l5">5</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l6" href="#l6">6</a><td>// You may obtain a copy of the License at<tr><td><a name="l7" href="#l7">7</a><td>//<tr><td><a name="l8" href="#l8">8</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l9" href="#l9">9</a><td>//<tr><td><a name="l10" href="#l10">10</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l11" href="#l11">11</a><td>// distributed under the License is distributed on an "AS IS" BASIS,<tr><td><a name="l12" href="#l12">12</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l13" href="#l13">13</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l14" href="#l14">14</a><td>// limitations under the License.<tr><td><a name="l15" href="#l15">15</a><td><tr><td><a name="l16" href="#l16">16</a><td>'use strict';<tr><td><a name="l17" href="#l17">17</a><td><tr><td><a name="l18" href="#l18">18</a><td>var exec = require('child_process').exec,<tr><td><a name="l19" href="#l19">19</a><td> fs = require('fs'),<tr><td><a name="l20" href="#l20">20</a><td> net = require('net');<tr><td><a name="l21" href="#l21">21</a><td><tr><td><a name="l22" href="#l22">22</a><td>var promise = require('../index').promise;<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> * The IANA suggested ephemeral port range.<tr><td><a name="l27" href="#l27">27</a><td> * @type {{min: number, max: number}}<tr><td><a name="l28" href="#l28">28</a><td> * @const<tr><td><a name="l29" href="#l29">29</a><td> * @see http://en.wikipedia.org/wiki/Ephemeral_ports<tr><td><a name="l30" href="#l30">30</a><td> */<tr><td><a name="l31" href="#l31">31</a><td>var DEFAULT_IANA_RANGE = {min: 49152, max: 65535};<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>/**<tr><td><a name="l35" href="#l35">35</a><td> * The epheremal port range for the current system. Lazily computed on first<tr><td><a name="l36" href="#l36">36</a><td> * access.<tr><td><a name="l37" href="#l37">37</a><td> * @type {webdriver.promise.Promise.<{min: number, max: number}>}<tr><td><a name="l38" href="#l38">38</a><td> */<tr><td><a name="l39" href="#l39">39</a><td>var systemRange = null;<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>/**<tr><td><a name="l43" href="#l43">43</a><td> * Computes the ephemeral port range for the current system. This is based on<tr><td><a name="l44" href="#l44">44</a><td> * http://stackoverflow.com/a/924337.<tr><td><a name="l45" href="#l45">45</a><td> * @return {webdriver.promise.Promise.<{min: number, max: number}>} A promise<tr><td><a name="l46" href="#l46">46</a><td> * that will resolve to the ephemeral port range of the current system.<tr><td><a name="l47" href="#l47">47</a><td> */<tr><td><a name="l48" href="#l48">48</a><td>function findSystemPortRange() {<tr><td><a name="l49" href="#l49">49</a><td> if (systemRange) {<tr><td><a name="l50" href="#l50">50</a><td> return systemRange;<tr><td><a name="l51" href="#l51">51</a><td> }<tr><td><a name="l52" href="#l52">52</a><td> var range = process.platform === 'win32' ?<tr><td><a name="l53" href="#l53">53</a><td> findWindowsPortRange() : findUnixPortRange();<tr><td><a name="l54" href="#l54">54</a><td> return systemRange = range.thenCatch(function() {<tr><td><a name="l55" href="#l55">55</a><td> return DEFAULT_IANA_RANGE;<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><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> * Executes a command and returns its output if it succeeds.<tr><td><a name="l62" href="#l62">62</a><td> * @param {string} cmd The command to execute.<tr><td><a name="l63" href="#l63">63</a><td> * @return {!webdriver.promise.Promise.<string>} A promise that will resolve<tr><td><a name="l64" href="#l64">64</a><td> * with the command's stdout data.<tr><td><a name="l65" href="#l65">65</a><td> */<tr><td><a name="l66" href="#l66">66</a><td>function execute(cmd) {<tr><td><a name="l67" href="#l67">67</a><td> var result = promise.defer();<tr><td><a name="l68" href="#l68">68</a><td> exec(cmd, function(err, stdout) {<tr><td><a name="l69" href="#l69">69</a><td> if (err) {<tr><td><a name="l70" href="#l70">70</a><td> result.reject(err);<tr><td><a name="l71" href="#l71">71</a><td> } else {<tr><td><a name="l72" href="#l72">72</a><td> result.fulfill(stdout);<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> return result.promise;<tr><td><a name="l76" href="#l76">76</a><td>}<tr><td><a name="l77" href="#l77">77</a><td><tr><td><a name="l78" href="#l78">78</a><td><tr><td><a name="l79" href="#l79">79</a><td>/**<tr><td><a name="l80" href="#l80">80</a><td> * Computes the ephemeral port range for a Unix-like system.<tr><td><a name="l81" href="#l81">81</a><td> * @return {!webdriver.promise.Promise.<{min: number, max: number}>} A promise<tr><td><a name="l82" href="#l82">82</a><td> * that will resolve with the ephemeral port range on the current system.<tr><td><a name="l83" href="#l83">83</a><td> */<tr><td><a name="l84" href="#l84">84</a><td>function findUnixPortRange() {<tr><td><a name="l85" href="#l85">85</a><td> var cmd;<tr><td><a name="l86" href="#l86">86</a><td> if (process.platform === 'sunos') {<tr><td><a name="l87" href="#l87">87</a><td> cmd =<tr><td><a name="l88" href="#l88">88</a><td> '/usr/sbin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port';<tr><td><a name="l89" href="#l89">89</a><td> } else if (fs.existsSync('/proc/sys/net/ipv4/ip_local_port_range')) {<tr><td><a name="l90" href="#l90">90</a><td> // Linux<tr><td><a name="l91" href="#l91">91</a><td> cmd = 'cat /proc/sys/net/ipv4/ip_local_port_range';<tr><td><a name="l92" href="#l92">92</a><td> } else {<tr><td><a name="l93" href="#l93">93</a><td> cmd = 'sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last' +<tr><td><a name="l94" href="#l94">94</a><td> ' | sed -e "s/.*:\\s*//"';<tr><td><a name="l95" href="#l95">95</a><td> }<tr><td><a name="l96" href="#l96">96</a><td><tr><td><a name="l97" href="#l97">97</a><td> return execute(cmd).then(function(stdout) {<tr><td><a name="l98" href="#l98">98</a><td> if (!stdout || !stdout.length) return DEFAULT_IANA_RANGE;<tr><td><a name="l99" href="#l99">99</a><td> var range = stdout.trim().split(/\s+/).map(Number);<tr><td><a name="l100" href="#l100">100</a><td> if (range.some(isNaN)) return DEFAULT_IANA_RANGE;<tr><td><a name="l101" href="#l101">101</a><td> return {min: range[0], max: range[1]};<tr><td><a name="l102" href="#l102">102</a><td> });<tr><td><a name="l103" href="#l103">103</a><td>}<tr><td><a name="l104" href="#l104">104</a><td><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> * Computes the ephemeral port range for a Windows system.<tr><td><a name="l108" href="#l108">108</a><td> * @return {!webdriver.promise.Promise.<{min: number, max: number}>} A promise<tr><td><a name="l109" href="#l109">109</a><td> * that will resolve with the ephemeral port range on the current system.<tr><td><a name="l110" href="#l110">110</a><td> */<tr><td><a name="l111" href="#l111">111</a><td>function findWindowsPortRange() {<tr><td><a name="l112" href="#l112">112</a><td> var deferredRange = promise.defer();<tr><td><a name="l113" href="#l113">113</a><td> // First, check if we're running on XP. If this initial command fails,<tr><td><a name="l114" href="#l114">114</a><td> // we just fallback on the default IANA range.<tr><td><a name="l115" href="#l115">115</a><td> return execute('cmd.exe /c ver').then(function(stdout) {<tr><td><a name="l116" href="#l116">116</a><td> if (/Windows XP/.test(stdout)) {<tr><td><a name="l117" href="#l117">117</a><td> // TODO: Try to read these values from the registry.<tr><td><a name="l118" href="#l118">118</a><td> return {min: 1025, max: 5000};<tr><td><a name="l119" href="#l119">119</a><td> } else {<tr><td><a name="l120" href="#l120">120</a><td> return execute('netsh int ipv4 show dynamicport tcp').<tr><td><a name="l121" href="#l121">121</a><td> then(function(stdout) {<tr><td><a name="l122" href="#l122">122</a><td> /* > netsh int ipv4 show dynamicport tcp<tr><td><a name="l123" href="#l123">123</a><td> Protocol tcp Dynamic Port Range<tr><td><a name="l124" href="#l124">124</a><td> ---------------------------------<tr><td><a name="l125" href="#l125">125</a><td> Start Port : 49152<tr><td><a name="l126" href="#l126">126</a><td> Number of Ports : 16384<tr><td><a name="l127" href="#l127">127</a><td> */<tr><td><a name="l128" href="#l128">128</a><td> var range = stdout.split(/\n/).filter(function(line) {<tr><td><a name="l129" href="#l129">129</a><td> return /.*:\s*\d+/.test(line);<tr><td><a name="l130" href="#l130">130</a><td> }).map(function(line) {<tr><td><a name="l131" href="#l131">131</a><td> return Number(line.split(/:\s*/)[1]);<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 {<tr><td><a name="l135" href="#l135">135</a><td> min: range[0],<tr><td><a name="l136" href="#l136">136</a><td> max: range[0] + range[1]<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> }<tr><td><a name="l140" href="#l140">140</a><td> });<tr><td><a name="l141" href="#l141">141</a><td>}<tr><td><a name="l142" href="#l142">142</a><td><tr><td><a name="l143" href="#l143">143</a><td><tr><td><a name="l144" href="#l144">144</a><td>/**<tr><td><a name="l145" href="#l145">145</a><td> * Tests if a port is free.<tr><td><a name="l146" href="#l146">146</a><td> * @param {number} port The port to test.<tr><td><a name="l147" href="#l147">147</a><td> * @param {string=} opt_host The bound host to test the {@code port} against.<tr><td><a name="l148" href="#l148">148</a><td> * Defaults to {@code INADDR_ANY}.<tr><td><a name="l149" href="#l149">149</a><td> * @return {!webdriver.promise.Promise.<boolean>} A promise that will resolve<tr><td><a name="l150" href="#l150">150</a><td> * with whether the port is free.<tr><td><a name="l151" href="#l151">151</a><td> */<tr><td><a name="l152" href="#l152">152</a><td>function isFree(port, opt_host) {<tr><td><a name="l153" href="#l153">153</a><td> var result = promise.defer(function() {<tr><td><a name="l154" href="#l154">154</a><td> server.cancel();<tr><td><a name="l155" href="#l155">155</a><td> });<tr><td><a name="l156" href="#l156">156</a><td><tr><td><a name="l157" href="#l157">157</a><td> var server = net.createServer().on('error', function(e) {<tr><td><a name="l158" href="#l158">158</a><td> if (e.code === 'EADDRINUSE') {<tr><td><a name="l159" href="#l159">159</a><td> result.fulfill(false);<tr><td><a name="l160" href="#l160">160</a><td> } else {<tr><td><a name="l161" href="#l161">161</a><td> result.reject(e);<tr><td><a name="l162" href="#l162">162</a><td> }<tr><td><a name="l163" href="#l163">163</a><td> });<tr><td><a name="l164" href="#l164">164</a><td><tr><td><a name="l165" href="#l165">165</a><td> server.listen(port, opt_host, function() {<tr><td><a name="l166" href="#l166">166</a><td> server.close(function() {<tr><td><a name="l167" href="#l167">167</a><td> result.fulfill(true);<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> return result.promise;<tr><td><a name="l172" href="#l172">172</a><td>}<tr><td><a name="l173" href="#l173">173</a><td><tr><td><a name="l174" href="#l174">174</a><td><tr><td><a name="l175" href="#l175">175</a><td>/**<tr><td><a name="l176" href="#l176">176</a><td> * @param {string=} opt_host The bound host to test the {@code port} against.<tr><td><a name="l177" href="#l177">177</a><td> * Defaults to {@code INADDR_ANY}.<tr><td><a name="l178" href="#l178">178</a><td> * @return {!webdriver.promise.Promise.<number>} A promise that will resolve<tr><td><a name="l179" href="#l179">179</a><td> * to a free port. If a port cannot be found, the promise will be<tr><td><a name="l180" href="#l180">180</a><td> * rejected.<tr><td><a name="l181" href="#l181">181</a><td> */<tr><td><a name="l182" href="#l182">182</a><td>function findFreePort(opt_host) {<tr><td><a name="l183" href="#l183">183</a><td> return findSystemPortRange().then(function(range) {<tr><td><a name="l184" href="#l184">184</a><td> var attempts = 0;<tr><td><a name="l185" href="#l185">185</a><td> var deferredPort = promise.defer();<tr><td><a name="l186" href="#l186">186</a><td> findPort();<tr><td><a name="l187" href="#l187">187</a><td> return deferredPort.promise;<tr><td><a name="l188" href="#l188">188</a><td><tr><td><a name="l189" href="#l189">189</a><td> function findPort() {<tr><td><a name="l190" href="#l190">190</a><td> attempts += 1;<tr><td><a name="l191" href="#l191">191</a><td> if (attempts > 10) {<tr><td><a name="l192" href="#l192">192</a><td> deferredPort.reject(Error('Unable to find a free port'));<tr><td><a name="l193" href="#l193">193</a><td> }<tr><td><a name="l194" href="#l194">194</a><td><tr><td><a name="l195" href="#l195">195</a><td> var port = Math.floor(<tr><td><a name="l196" href="#l196">196</a><td> Math.random() * (range.max - range.min) + range.min);<tr><td><a name="l197" href="#l197">197</a><td> isFree(port, opt_host).then(function(isFree) {<tr><td><a name="l198" href="#l198">198</a><td> if (isFree) {<tr><td><a name="l199" href="#l199">199</a><td> deferredPort.fulfill(port);<tr><td><a name="l200" href="#l200">200</a><td> } else {<tr><td><a name="l201" href="#l201">201</a><td> findPort();<tr><td><a name="l202" href="#l202">202</a><td> }<tr><td><a name="l203" href="#l203">203</a><td> });<tr><td><a name="l204" href="#l204">204</a><td> }<tr><td><a name="l205" href="#l205">205</a><td> });<tr><td><a name="l206" href="#l206">206</a><td>}<tr><td><a name="l207" href="#l207">207</a><td><tr><td><a name="l208" href="#l208">208</a><td><tr><td><a name="l209" href="#l209">209</a><td>// PUBLIC API<tr><td><a name="l210" href="#l210">210</a><td><tr><td><a name="l211" href="#l211">211</a><td><tr><td><a name="l212" href="#l212">212</a><td>exports.findFreePort = findFreePort;<tr><td><a name="l213" href="#l213">213</a><td>exports.isFree = isFree;</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>portprober.js</title><link href="../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>net/portprober.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2013 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2013 Software Freedom Conservancy<tr><td><a name="l3" href="#l3">3</a><td>//<tr><td><a name="l4" href="#l4">4</a><td>// Licensed under the Apache License, Version 2.0 (the "License");<tr><td><a name="l5" href="#l5">5</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l6" href="#l6">6</a><td>// You may obtain a copy of the License at<tr><td><a name="l7" href="#l7">7</a><td>//<tr><td><a name="l8" href="#l8">8</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l9" href="#l9">9</a><td>//<tr><td><a name="l10" href="#l10">10</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l11" href="#l11">11</a><td>// distributed under the License is distributed on an "AS IS" BASIS,<tr><td><a name="l12" href="#l12">12</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l13" href="#l13">13</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l14" href="#l14">14</a><td>// limitations under the License.<tr><td><a name="l15" href="#l15">15</a><td><tr><td><a name="l16" href="#l16">16</a><td>'use strict';<tr><td><a name="l17" href="#l17">17</a><td><tr><td><a name="l18" href="#l18">18</a><td>var exec = require('child_process').exec,<tr><td><a name="l19" href="#l19">19</a><td> fs = require('fs'),<tr><td><a name="l20" href="#l20">20</a><td> net = require('net');<tr><td><a name="l21" href="#l21">21</a><td><tr><td><a name="l22" href="#l22">22</a><td>var promise = require('../index').promise;<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> * The IANA suggested ephemeral port range.<tr><td><a name="l27" href="#l27">27</a><td> * @type {{min: number, max: number}}<tr><td><a name="l28" href="#l28">28</a><td> * @const<tr><td><a name="l29" href="#l29">29</a><td> * @see http://en.wikipedia.org/wiki/Ephemeral_ports<tr><td><a name="l30" href="#l30">30</a><td> */<tr><td><a name="l31" href="#l31">31</a><td>var DEFAULT_IANA_RANGE = {min: 49152, max: 65535};<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>/**<tr><td><a name="l35" href="#l35">35</a><td> * The epheremal port range for the current system. Lazily computed on first<tr><td><a name="l36" href="#l36">36</a><td> * access.<tr><td><a name="l37" href="#l37">37</a><td> * @type {webdriver.promise.Promise.<{min: number, max: number}>}<tr><td><a name="l38" href="#l38">38</a><td> */<tr><td><a name="l39" href="#l39">39</a><td>var systemRange = null;<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>/**<tr><td><a name="l43" href="#l43">43</a><td> * Computes the ephemeral port range for the current system. This is based on<tr><td><a name="l44" href="#l44">44</a><td> * http://stackoverflow.com/a/924337.<tr><td><a name="l45" href="#l45">45</a><td> * @return {webdriver.promise.Promise.<{min: number, max: number}>} A promise<tr><td><a name="l46" href="#l46">46</a><td> * that will resolve to the ephemeral port range of the current system.<tr><td><a name="l47" href="#l47">47</a><td> */<tr><td><a name="l48" href="#l48">48</a><td>function findSystemPortRange() {<tr><td><a name="l49" href="#l49">49</a><td> if (systemRange) {<tr><td><a name="l50" href="#l50">50</a><td> return systemRange;<tr><td><a name="l51" href="#l51">51</a><td> }<tr><td><a name="l52" href="#l52">52</a><td> var range = process.platform === 'win32' ?<tr><td><a name="l53" href="#l53">53</a><td> findWindowsPortRange() : findUnixPortRange();<tr><td><a name="l54" href="#l54">54</a><td> return systemRange = range.thenCatch(function() {<tr><td><a name="l55" href="#l55">55</a><td> return DEFAULT_IANA_RANGE;<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><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> * Executes a command and returns its output if it succeeds.<tr><td><a name="l62" href="#l62">62</a><td> * @param {string} cmd The command to execute.<tr><td><a name="l63" href="#l63">63</a><td> * @return {!webdriver.promise.Promise.<string>} A promise that will resolve<tr><td><a name="l64" href="#l64">64</a><td> * with the command's stdout data.<tr><td><a name="l65" href="#l65">65</a><td> */<tr><td><a name="l66" href="#l66">66</a><td>function execute(cmd) {<tr><td><a name="l67" href="#l67">67</a><td> var result = promise.defer();<tr><td><a name="l68" href="#l68">68</a><td> exec(cmd, function(err, stdout) {<tr><td><a name="l69" href="#l69">69</a><td> if (err) {<tr><td><a name="l70" href="#l70">70</a><td> result.reject(err);<tr><td><a name="l71" href="#l71">71</a><td> } else {<tr><td><a name="l72" href="#l72">72</a><td> result.fulfill(stdout);<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> return result.promise;<tr><td><a name="l76" href="#l76">76</a><td>}<tr><td><a name="l77" href="#l77">77</a><td><tr><td><a name="l78" href="#l78">78</a><td><tr><td><a name="l79" href="#l79">79</a><td>/**<tr><td><a name="l80" href="#l80">80</a><td> * Computes the ephemeral port range for a Unix-like system.<tr><td><a name="l81" href="#l81">81</a><td> * @return {!webdriver.promise.Promise.<{min: number, max: number}>} A promise<tr><td><a name="l82" href="#l82">82</a><td> * that will resolve with the ephemeral port range on the current system.<tr><td><a name="l83" href="#l83">83</a><td> */<tr><td><a name="l84" href="#l84">84</a><td>function findUnixPortRange() {<tr><td><a name="l85" href="#l85">85</a><td> var cmd;<tr><td><a name="l86" href="#l86">86</a><td> if (process.platform === 'sunos') {<tr><td><a name="l87" href="#l87">87</a><td> cmd =<tr><td><a name="l88" href="#l88">88</a><td> '/usr/sbin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port';<tr><td><a name="l89" href="#l89">89</a><td> } else if (fs.existsSync('/proc/sys/net/ipv4/ip_local_port_range')) {<tr><td><a name="l90" href="#l90">90</a><td> // Linux<tr><td><a name="l91" href="#l91">91</a><td> cmd = 'cat /proc/sys/net/ipv4/ip_local_port_range';<tr><td><a name="l92" href="#l92">92</a><td> } else {<tr><td><a name="l93" href="#l93">93</a><td> cmd = 'sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last' +<tr><td><a name="l94" href="#l94">94</a><td> ' | sed -e "s/.*:\\s*//"';<tr><td><a name="l95" href="#l95">95</a><td> }<tr><td><a name="l96" href="#l96">96</a><td><tr><td><a name="l97" href="#l97">97</a><td> return execute(cmd).then(function(stdout) {<tr><td><a name="l98" href="#l98">98</a><td> if (!stdout || !stdout.length) return DEFAULT_IANA_RANGE;<tr><td><a name="l99" href="#l99">99</a><td> var range = stdout.trim().split(/\s+/).map(Number);<tr><td><a name="l100" href="#l100">100</a><td> if (range.some(isNaN)) return DEFAULT_IANA_RANGE;<tr><td><a name="l101" href="#l101">101</a><td> return {min: range[0], max: range[1]};<tr><td><a name="l102" href="#l102">102</a><td> });<tr><td><a name="l103" href="#l103">103</a><td>}<tr><td><a name="l104" href="#l104">104</a><td><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> * Computes the ephemeral port range for a Windows system.<tr><td><a name="l108" href="#l108">108</a><td> * @return {!webdriver.promise.Promise.<{min: number, max: number}>} A promise<tr><td><a name="l109" href="#l109">109</a><td> * that will resolve with the ephemeral port range on the current system.<tr><td><a name="l110" href="#l110">110</a><td> */<tr><td><a name="l111" href="#l111">111</a><td>function findWindowsPortRange() {<tr><td><a name="l112" href="#l112">112</a><td> var deferredRange = promise.defer();<tr><td><a name="l113" href="#l113">113</a><td> // First, check if we're running on XP. If this initial command fails,<tr><td><a name="l114" href="#l114">114</a><td> // we just fallback on the default IANA range.<tr><td><a name="l115" href="#l115">115</a><td> return execute('cmd.exe /c ver').then(function(stdout) {<tr><td><a name="l116" href="#l116">116</a><td> if (/Windows XP/.test(stdout)) {<tr><td><a name="l117" href="#l117">117</a><td> // TODO: Try to read these values from the registry.<tr><td><a name="l118" href="#l118">118</a><td> return {min: 1025, max: 5000};<tr><td><a name="l119" href="#l119">119</a><td> } else {<tr><td><a name="l120" href="#l120">120</a><td> return execute('netsh int ipv4 show dynamicport tcp').<tr><td><a name="l121" href="#l121">121</a><td> then(function(stdout) {<tr><td><a name="l122" href="#l122">122</a><td> /* > netsh int ipv4 show dynamicport tcp<tr><td><a name="l123" href="#l123">123</a><td> Protocol tcp Dynamic Port Range<tr><td><a name="l124" href="#l124">124</a><td> ---------------------------------<tr><td><a name="l125" href="#l125">125</a><td> Start Port : 49152<tr><td><a name="l126" href="#l126">126</a><td> Number of Ports : 16384<tr><td><a name="l127" href="#l127">127</a><td> */<tr><td><a name="l128" href="#l128">128</a><td> var range = stdout.split(/\n/).filter(function(line) {<tr><td><a name="l129" href="#l129">129</a><td> return /.*:\s*\d+/.test(line);<tr><td><a name="l130" href="#l130">130</a><td> }).map(function(line) {<tr><td><a name="l131" href="#l131">131</a><td> return Number(line.split(/:\s*/)[1]);<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 {<tr><td><a name="l135" href="#l135">135</a><td> min: range[0],<tr><td><a name="l136" href="#l136">136</a><td> max: range[0] + range[1]<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> }<tr><td><a name="l140" href="#l140">140</a><td> });<tr><td><a name="l141" href="#l141">141</a><td>}<tr><td><a name="l142" href="#l142">142</a><td><tr><td><a name="l143" href="#l143">143</a><td><tr><td><a name="l144" href="#l144">144</a><td>/**<tr><td><a name="l145" href="#l145">145</a><td> * Tests if a port is free.<tr><td><a name="l146" href="#l146">146</a><td> * @param {number} port The port to test.<tr><td><a name="l147" href="#l147">147</a><td> * @param {string=} opt_host The bound host to test the {@code port} against.<tr><td><a name="l148" href="#l148">148</a><td> * Defaults to {@code INADDR_ANY}.<tr><td><a name="l149" href="#l149">149</a><td> * @return {!webdriver.promise.Promise.<boolean>} A promise that will resolve<tr><td><a name="l150" href="#l150">150</a><td> * with whether the port is free.<tr><td><a name="l151" href="#l151">151</a><td> */<tr><td><a name="l152" href="#l152">152</a><td>function isFree(port, opt_host) {<tr><td><a name="l153" href="#l153">153</a><td> var result = promise.defer(function() {<tr><td><a name="l154" href="#l154">154</a><td> server.cancel();<tr><td><a name="l155" href="#l155">155</a><td> });<tr><td><a name="l156" href="#l156">156</a><td><tr><td><a name="l157" href="#l157">157</a><td> var server = net.createServer().on('error', function(e) {<tr><td><a name="l158" href="#l158">158</a><td> if (e.code === 'EADDRINUSE') {<tr><td><a name="l159" href="#l159">159</a><td> result.fulfill(false);<tr><td><a name="l160" href="#l160">160</a><td> } else {<tr><td><a name="l161" href="#l161">161</a><td> result.reject(e);<tr><td><a name="l162" href="#l162">162</a><td> }<tr><td><a name="l163" href="#l163">163</a><td> });<tr><td><a name="l164" href="#l164">164</a><td><tr><td><a name="l165" href="#l165">165</a><td> server.listen(port, opt_host, function() {<tr><td><a name="l166" href="#l166">166</a><td> server.close(function() {<tr><td><a name="l167" href="#l167">167</a><td> result.fulfill(true);<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> return result.promise;<tr><td><a name="l172" href="#l172">172</a><td>}<tr><td><a name="l173" href="#l173">173</a><td><tr><td><a name="l174" href="#l174">174</a><td><tr><td><a name="l175" href="#l175">175</a><td>/**<tr><td><a name="l176" href="#l176">176</a><td> * @param {string=} opt_host The bound host to test the {@code port} against.<tr><td><a name="l177" href="#l177">177</a><td> * Defaults to {@code INADDR_ANY}.<tr><td><a name="l178" href="#l178">178</a><td> * @return {!webdriver.promise.Promise.<number>} A promise that will resolve<tr><td><a name="l179" href="#l179">179</a><td> * to a free port. If a port cannot be found, the promise will be<tr><td><a name="l180" href="#l180">180</a><td> * rejected.<tr><td><a name="l181" href="#l181">181</a><td> */<tr><td><a name="l182" href="#l182">182</a><td>function findFreePort(opt_host) {<tr><td><a name="l183" href="#l183">183</a><td> return findSystemPortRange().then(function(range) {<tr><td><a name="l184" href="#l184">184</a><td> var attempts = 0;<tr><td><a name="l185" href="#l185">185</a><td> var deferredPort = promise.defer();<tr><td><a name="l186" href="#l186">186</a><td> findPort();<tr><td><a name="l187" href="#l187">187</a><td> return deferredPort.promise;<tr><td><a name="l188" href="#l188">188</a><td><tr><td><a name="l189" href="#l189">189</a><td> function findPort() {<tr><td><a name="l190" href="#l190">190</a><td> attempts += 1;<tr><td><a name="l191" href="#l191">191</a><td> if (attempts > 10) {<tr><td><a name="l192" href="#l192">192</a><td> deferredPort.reject(Error('Unable to find a free port'));<tr><td><a name="l193" href="#l193">193</a><td> }<tr><td><a name="l194" href="#l194">194</a><td><tr><td><a name="l195" href="#l195">195</a><td> var port = Math.floor(<tr><td><a name="l196" href="#l196">196</a><td> Math.random() * (range.max - range.min) + range.min);<tr><td><a name="l197" href="#l197">197</a><td> isFree(port, opt_host).then(function(isFree) {<tr><td><a name="l198" href="#l198">198</a><td> if (isFree) {<tr><td><a name="l199" href="#l199">199</a><td> deferredPort.fulfill(port);<tr><td><a name="l200" href="#l200">200</a><td> } else {<tr><td><a name="l201" href="#l201">201</a><td> findPort();<tr><td><a name="l202" href="#l202">202</a><td> }<tr><td><a name="l203" href="#l203">203</a><td> });<tr><td><a name="l204" href="#l204">204</a><td> }<tr><td><a name="l205" href="#l205">205</a><td> });<tr><td><a name="l206" href="#l206">206</a><td>}<tr><td><a name="l207" href="#l207">207</a><td><tr><td><a name="l208" href="#l208">208</a><td><tr><td><a name="l209" href="#l209">209</a><td>// PUBLIC API<tr><td><a name="l210" href="#l210">210</a><td><tr><td><a name="l211" href="#l211">211</a><td><tr><td><a name="l212" href="#l212">212</a><td>exports.findFreePort = findFreePort;<tr><td><a name="l213" href="#l213">213</a><td>exports.isFree = isFree;</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>phantomjs.js</title><link href="../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>phantomjs.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2013 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2013 Software Freedom Conservancy<tr><td><a name="l3" href="#l3">3</a><td>//<tr><td><a name="l4" href="#l4">4</a><td>// Licensed under the Apache License, Version 2.0 (the "License");<tr><td><a name="l5" href="#l5">5</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l6" href="#l6">6</a><td>// You may obtain a copy of the License at<tr><td><a name="l7" href="#l7">7</a><td>//<tr><td><a name="l8" href="#l8">8</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l9" href="#l9">9</a><td>//<tr><td><a name="l10" href="#l10">10</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l11" href="#l11">11</a><td>// distributed under the License is distributed on an "AS IS" BASIS,<tr><td><a name="l12" href="#l12">12</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l13" href="#l13">13</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l14" href="#l14">14</a><td>// limitations under the License.<tr><td><a name="l15" href="#l15">15</a><td><tr><td><a name="l16" href="#l16">16</a><td>'use strict';<tr><td><a name="l17" href="#l17">17</a><td><tr><td><a name="l18" href="#l18">18</a><td>var fs = require('fs'),<tr><td><a name="l19" href="#l19">19</a><td> util = require('util');<tr><td><a name="l20" href="#l20">20</a><td><tr><td><a name="l21" href="#l21">21</a><td>var webdriver = require('./index'),<tr><td><a name="l22" href="#l22">22</a><td> executors = require('./executors'),<tr><td><a name="l23" href="#l23">23</a><td> io = require('./io'),<tr><td><a name="l24" href="#l24">24</a><td> portprober = require('./net/portprober'),<tr><td><a name="l25" href="#l25">25</a><td> remote = require('./remote');<tr><td><a name="l26" href="#l26">26</a><td><tr><td><a name="l27" href="#l27">27</a><td><tr><td><a name="l28" href="#l28">28</a><td>/**<tr><td><a name="l29" href="#l29">29</a><td> * Name of the PhantomJS executable.<tr><td><a name="l30" href="#l30">30</a><td> * @type {string}<tr><td><a name="l31" href="#l31">31</a><td> * @const<tr><td><a name="l32" href="#l32">32</a><td> */<tr><td><a name="l33" href="#l33">33</a><td>var PHANTOMJS_EXE =<tr><td><a name="l34" href="#l34">34</a><td> process.platform === 'win32' ? 'phantomjs.exe' : 'phantomjs';<tr><td><a name="l35" href="#l35">35</a><td><tr><td><a name="l36" href="#l36">36</a><td><tr><td><a name="l37" href="#l37">37</a><td>/**<tr><td><a name="l38" href="#l38">38</a><td> * Capability that designates the location of the PhantomJS executable to use.<tr><td><a name="l39" href="#l39">39</a><td> * @type {string}<tr><td><a name="l40" href="#l40">40</a><td> * @const<tr><td><a name="l41" href="#l41">41</a><td> */<tr><td><a name="l42" href="#l42">42</a><td>var BINARY_PATH_CAPABILITY = 'phantomjs.binary.path';<tr><td><a name="l43" href="#l43">43</a><td><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> * Capability that designates the CLI arguments to pass to PhantomJS.<tr><td><a name="l47" href="#l47">47</a><td> * @type {string}<tr><td><a name="l48" href="#l48">48</a><td> * @const<tr><td><a name="l49" href="#l49">49</a><td> */<tr><td><a name="l50" href="#l50">50</a><td>var CLI_ARGS_CAPABILITY = 'phantomjs.cli.args';<tr><td><a name="l51" href="#l51">51</a><td><tr><td><a name="l52" href="#l52">52</a><td><tr><td><a name="l53" href="#l53">53</a><td>/**<tr><td><a name="l54" href="#l54">54</a><td> * Default log file to use if one is not specified through CLI args.<tr><td><a name="l55" href="#l55">55</a><td> * @type {string}<tr><td><a name="l56" href="#l56">56</a><td> * @const<tr><td><a name="l57" href="#l57">57</a><td> */<tr><td><a name="l58" href="#l58">58</a><td>var DEFAULT_LOG_FILE = 'phantomjsdriver.log';<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>/**<tr><td><a name="l62" href="#l62">62</a><td> * Finds the PhantomJS executable.<tr><td><a name="l63" href="#l63">63</a><td> * @param {string=} opt_exe Path to the executable to use.<tr><td><a name="l64" href="#l64">64</a><td> * @return {string} The located executable.<tr><td><a name="l65" href="#l65">65</a><td> * @throws {Error} If the executable cannot be found on the PATH, or if the<tr><td><a name="l66" href="#l66">66</a><td> * provided executable path does not exist.<tr><td><a name="l67" href="#l67">67</a><td> */<tr><td><a name="l68" href="#l68">68</a><td>function findExecutable(opt_exe) {<tr><td><a name="l69" href="#l69">69</a><td> var exe = opt_exe || io.findInPath(PHANTOMJS_EXE, true);<tr><td><a name="l70" href="#l70">70</a><td> if (!exe) {<tr><td><a name="l71" href="#l71">71</a><td> throw Error(<tr><td><a name="l72" href="#l72">72</a><td> 'The PhantomJS executable could not be found on the current PATH. ' +<tr><td><a name="l73" href="#l73">73</a><td> 'Please download the latest version from ' +<tr><td><a name="l74" href="#l74">74</a><td> 'http://phantomjs.org/download.html and ensure it can be found on ' +<tr><td><a name="l75" href="#l75">75</a><td> 'your PATH. For more information, see ' +<tr><td><a name="l76" href="#l76">76</a><td> 'https://github.com/ariya/phantomjs/wiki');<tr><td><a name="l77" href="#l77">77</a><td> }<tr><td><a name="l78" href="#l78">78</a><td> if (!fs.existsSync(exe)) {<tr><td><a name="l79" href="#l79">79</a><td> throw Error('File does not exist: ' + exe);<tr><td><a name="l80" href="#l80">80</a><td> }<tr><td><a name="l81" href="#l81">81</a><td> return exe;<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><tr><td><a name="l85" href="#l85">85</a><td>/**<tr><td><a name="l86" href="#l86">86</a><td> * Maps WebDriver logging level name to those recognised by PhantomJS.<tr><td><a name="l87" href="#l87">87</a><td> * @type {!Object.<string, string>}<tr><td><a name="l88" href="#l88">88</a><td> * @const<tr><td><a name="l89" href="#l89">89</a><td> */<tr><td><a name="l90" href="#l90">90</a><td>var WEBDRIVER_TO_PHANTOMJS_LEVEL = (function() {<tr><td><a name="l91" href="#l91">91</a><td> var map = {};<tr><td><a name="l92" href="#l92">92</a><td> map[webdriver.logging.Level.ALL.name] = 'DEBUG';<tr><td><a name="l93" href="#l93">93</a><td> map[webdriver.logging.Level.DEBUG.name] = 'DEBUG';<tr><td><a name="l94" href="#l94">94</a><td> map[webdriver.logging.Level.INFO.name] = 'INFO';<tr><td><a name="l95" href="#l95">95</a><td> map[webdriver.logging.Level.WARNING.name] = 'WARN';<tr><td><a name="l96" href="#l96">96</a><td> map[webdriver.logging.Level.SEVERE.name] = 'ERROR';<tr><td><a name="l97" href="#l97">97</a><td> return map;<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> * Creates a new PhantomJS WebDriver client.<tr><td><a name="l103" href="#l103">103</a><td> * @param {webdriver.Capabilities=} opt_capabilities The desired capabilities.<tr><td><a name="l104" href="#l104">104</a><td> * @param {webdriver.promise.ControlFlow=} opt_flow The control flow to use, or<tr><td><a name="l105" href="#l105">105</a><td> * {@code null} to use the currently active flow.<tr><td><a name="l106" href="#l106">106</a><td> * @return {!webdriver.WebDriver} A new WebDriver instance.<tr><td><a name="l107" href="#l107">107</a><td> * @deprecated Use {@link Driver}.<tr><td><a name="l108" href="#l108">108</a><td> */<tr><td><a name="l109" href="#l109">109</a><td>function createDriver(opt_capabilities, opt_flow) {<tr><td><a name="l110" href="#l110">110</a><td> return new Driver(opt_capabilities, opt_flow);<tr><td><a name="l111" href="#l111">111</a><td>}<tr><td><a name="l112" href="#l112">112</a><td><tr><td><a name="l113" href="#l113">113</a><td><tr><td><a name="l114" href="#l114">114</a><td>/**<tr><td><a name="l115" href="#l115">115</a><td> * Creates a new WebDriver client for PhantomJS.<tr><td><a name="l116" href="#l116">116</a><td> *<tr><td><a name="l117" href="#l117">117</a><td> * @param {webdriver.Capabilities=} opt_capabilities The desired capabilities.<tr><td><a name="l118" href="#l118">118</a><td> * @param {webdriver.promise.ControlFlow=} opt_flow The control flow to use, or<tr><td><a name="l119" href="#l119">119</a><td> * {@code null} to use the currently active flow.<tr><td><a name="l120" href="#l120">120</a><td> * @constructor<tr><td><a name="l121" href="#l121">121</a><td> * @extends {webdriver.WebDriver}<tr><td><a name="l122" href="#l122">122</a><td> */<tr><td><a name="l123" href="#l123">123</a><td>var Driver = function(opt_capabilities, opt_flow) {<tr><td><a name="l124" href="#l124">124</a><td> var capabilities = opt_capabilities || webdriver.Capabilities.phantomjs();<tr><td><a name="l125" href="#l125">125</a><td> var exe = findExecutable(capabilities.get(BINARY_PATH_CAPABILITY));<tr><td><a name="l126" href="#l126">126</a><td> var args = ['--webdriver-logfile=' + DEFAULT_LOG_FILE];<tr><td><a name="l127" href="#l127">127</a><td><tr><td><a name="l128" href="#l128">128</a><td> var logPrefs = capabilities.get(webdriver.Capability.LOGGING_PREFS);<tr><td><a name="l129" href="#l129">129</a><td> if (logPrefs instanceof webdriver.logging.Preferences) {<tr><td><a name="l130" href="#l130">130</a><td> logPrefs = logPrefs.toJSON();<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> if (logPrefs && logPrefs[webdriver.logging.Type.DRIVER]) {<tr><td><a name="l134" href="#l134">134</a><td> var level = WEBDRIVER_TO_PHANTOMJS_LEVEL[<tr><td><a name="l135" href="#l135">135</a><td> logPrefs[webdriver.logging.Type.DRIVER]];<tr><td><a name="l136" href="#l136">136</a><td> if (level) {<tr><td><a name="l137" href="#l137">137</a><td> args.push('--webdriver-loglevel=' + level);<tr><td><a name="l138" href="#l138">138</a><td> }<tr><td><a name="l139" href="#l139">139</a><td> }<tr><td><a name="l140" href="#l140">140</a><td><tr><td><a name="l141" href="#l141">141</a><td> var proxy = capabilities.get(webdriver.Capability.PROXY);<tr><td><a name="l142" href="#l142">142</a><td> if (proxy) {<tr><td><a name="l143" href="#l143">143</a><td> switch (proxy.proxyType) {<tr><td><a name="l144" href="#l144">144</a><td> case 'manual':<tr><td><a name="l145" href="#l145">145</a><td> if (proxy.httpProxy) {<tr><td><a name="l146" href="#l146">146</a><td> args.push(<tr><td><a name="l147" href="#l147">147</a><td> '--proxy-type=http',<tr><td><a name="l148" href="#l148">148</a><td> '--proxy=http://' + proxy.httpProxy);<tr><td><a name="l149" href="#l149">149</a><td> }<tr><td><a name="l150" href="#l150">150</a><td> break;<tr><td><a name="l151" href="#l151">151</a><td> case 'pac':<tr><td><a name="l152" href="#l152">152</a><td> throw Error('PhantomJS does not support Proxy PAC files');<tr><td><a name="l153" href="#l153">153</a><td> case 'system':<tr><td><a name="l154" href="#l154">154</a><td> args.push('--proxy-type=system');<tr><td><a name="l155" href="#l155">155</a><td> break;<tr><td><a name="l156" href="#l156">156</a><td> case 'direct':<tr><td><a name="l157" href="#l157">157</a><td> args.push('--proxy-type=none');<tr><td><a name="l158" href="#l158">158</a><td> break;<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> args = args.concat(capabilities.get(CLI_ARGS_CAPABILITY) || []);<tr><td><a name="l162" href="#l162">162</a><td><tr><td><a name="l163" href="#l163">163</a><td> var port = portprober.findFreePort();<tr><td><a name="l164" href="#l164">164</a><td> var service = new remote.DriverService(exe, {<tr><td><a name="l165" href="#l165">165</a><td> port: port,<tr><td><a name="l166" href="#l166">166</a><td> args: webdriver.promise.when(port, function(port) {<tr><td><a name="l167" href="#l167">167</a><td> args.push('--webdriver=' + port);<tr><td><a name="l168" href="#l168">168</a><td> return args;<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> var executor = executors.createExecutor(service.start());<tr><td><a name="l173" href="#l173">173</a><td> var driver = webdriver.WebDriver.createSession(<tr><td><a name="l174" href="#l174">174</a><td> executor, capabilities, opt_flow);<tr><td><a name="l175" href="#l175">175</a><td><tr><td><a name="l176" href="#l176">176</a><td> webdriver.WebDriver.call(<tr><td><a name="l177" href="#l177">177</a><td> this, driver.getSession(), executor, driver.controlFlow());<tr><td><a name="l178" href="#l178">178</a><td><tr><td><a name="l179" href="#l179">179</a><td> var boundQuit = this.quit.bind(this);<tr><td><a name="l180" href="#l180">180</a><td><tr><td><a name="l181" href="#l181">181</a><td> /** @override */<tr><td><a name="l182" href="#l182">182</a><td> this.quit = function() {<tr><td><a name="l183" href="#l183">183</a><td> return boundQuit().thenFinally(service.kill.bind(service));<tr><td><a name="l184" href="#l184">184</a><td> };<tr><td><a name="l185" href="#l185">185</a><td> return driver;<tr><td><a name="l186" href="#l186">186</a><td>};<tr><td><a name="l187" href="#l187">187</a><td>util.inherits(Driver, webdriver.WebDriver);<tr><td><a name="l188" href="#l188">188</a><td><tr><td><a name="l189" href="#l189">189</a><td><tr><td><a name="l190" href="#l190">190</a><td>// PUBLIC API<tr><td><a name="l191" href="#l191">191</a><td><tr><td><a name="l192" href="#l192">192</a><td>exports.Driver = Driver;<tr><td><a name="l193" href="#l193">193</a><td>exports.createDriver = createDriver;</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>phantomjs.js</title><link href="../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>phantomjs.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2013 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2013 Software Freedom Conservancy<tr><td><a name="l3" href="#l3">3</a><td>//<tr><td><a name="l4" href="#l4">4</a><td>// Licensed under the Apache License, Version 2.0 (the "License");<tr><td><a name="l5" href="#l5">5</a><td>// you may not use this file except in compliance with the License.<tr><td><a name="l6" href="#l6">6</a><td>// You may obtain a copy of the License at<tr><td><a name="l7" href="#l7">7</a><td>//<tr><td><a name="l8" href="#l8">8</a><td>// http://www.apache.org/licenses/LICENSE-2.0<tr><td><a name="l9" href="#l9">9</a><td>//<tr><td><a name="l10" href="#l10">10</a><td>// Unless required by applicable law or agreed to in writing, software<tr><td><a name="l11" href="#l11">11</a><td>// distributed under the License is distributed on an "AS IS" BASIS,<tr><td><a name="l12" href="#l12">12</a><td>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<tr><td><a name="l13" href="#l13">13</a><td>// See the License for the specific language governing permissions and<tr><td><a name="l14" href="#l14">14</a><td>// limitations under the License.<tr><td><a name="l15" href="#l15">15</a><td><tr><td><a name="l16" href="#l16">16</a><td>'use strict';<tr><td><a name="l17" href="#l17">17</a><td><tr><td><a name="l18" href="#l18">18</a><td>var fs = require('fs'),<tr><td><a name="l19" href="#l19">19</a><td> util = require('util');<tr><td><a name="l20" href="#l20">20</a><td><tr><td><a name="l21" href="#l21">21</a><td>var webdriver = require('./index'),<tr><td><a name="l22" href="#l22">22</a><td> executors = require('./executors'),<tr><td><a name="l23" href="#l23">23</a><td> io = require('./io'),<tr><td><a name="l24" href="#l24">24</a><td> portprober = require('./net/portprober'),<tr><td><a name="l25" href="#l25">25</a><td> remote = require('./remote');<tr><td><a name="l26" href="#l26">26</a><td><tr><td><a name="l27" href="#l27">27</a><td><tr><td><a name="l28" href="#l28">28</a><td>/**<tr><td><a name="l29" href="#l29">29</a><td> * Name of the PhantomJS executable.<tr><td><a name="l30" href="#l30">30</a><td> * @type {string}<tr><td><a name="l31" href="#l31">31</a><td> * @const<tr><td><a name="l32" href="#l32">32</a><td> */<tr><td><a name="l33" href="#l33">33</a><td>var PHANTOMJS_EXE =<tr><td><a name="l34" href="#l34">34</a><td> process.platform === 'win32' ? 'phantomjs.exe' : 'phantomjs';<tr><td><a name="l35" href="#l35">35</a><td><tr><td><a name="l36" href="#l36">36</a><td><tr><td><a name="l37" href="#l37">37</a><td>/**<tr><td><a name="l38" href="#l38">38</a><td> * Capability that designates the location of the PhantomJS executable to use.<tr><td><a name="l39" href="#l39">39</a><td> * @type {string}<tr><td><a name="l40" href="#l40">40</a><td> * @const<tr><td><a name="l41" href="#l41">41</a><td> */<tr><td><a name="l42" href="#l42">42</a><td>var BINARY_PATH_CAPABILITY = 'phantomjs.binary.path';<tr><td><a name="l43" href="#l43">43</a><td><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> * Capability that designates the CLI arguments to pass to PhantomJS.<tr><td><a name="l47" href="#l47">47</a><td> * @type {string}<tr><td><a name="l48" href="#l48">48</a><td> * @const<tr><td><a name="l49" href="#l49">49</a><td> */<tr><td><a name="l50" href="#l50">50</a><td>var CLI_ARGS_CAPABILITY = 'phantomjs.cli.args';<tr><td><a name="l51" href="#l51">51</a><td><tr><td><a name="l52" href="#l52">52</a><td><tr><td><a name="l53" href="#l53">53</a><td>/**<tr><td><a name="l54" href="#l54">54</a><td> * Default log file to use if one is not specified through CLI args.<tr><td><a name="l55" href="#l55">55</a><td> * @type {string}<tr><td><a name="l56" href="#l56">56</a><td> * @const<tr><td><a name="l57" href="#l57">57</a><td> */<tr><td><a name="l58" href="#l58">58</a><td>var DEFAULT_LOG_FILE = 'phantomjsdriver.log';<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>/**<tr><td><a name="l62" href="#l62">62</a><td> * Finds the PhantomJS executable.<tr><td><a name="l63" href="#l63">63</a><td> * @param {string=} opt_exe Path to the executable to use.<tr><td><a name="l64" href="#l64">64</a><td> * @return {string} The located executable.<tr><td><a name="l65" href="#l65">65</a><td> * @throws {Error} If the executable cannot be found on the PATH, or if the<tr><td><a name="l66" href="#l66">66</a><td> * provided executable path does not exist.<tr><td><a name="l67" href="#l67">67</a><td> */<tr><td><a name="l68" href="#l68">68</a><td>function findExecutable(opt_exe) {<tr><td><a name="l69" href="#l69">69</a><td> var exe = opt_exe || io.findInPath(PHANTOMJS_EXE, true);<tr><td><a name="l70" href="#l70">70</a><td> if (!exe) {<tr><td><a name="l71" href="#l71">71</a><td> throw Error(<tr><td><a name="l72" href="#l72">72</a><td> 'The PhantomJS executable could not be found on the current PATH. ' +<tr><td><a name="l73" href="#l73">73</a><td> 'Please download the latest version from ' +<tr><td><a name="l74" href="#l74">74</a><td> 'http://phantomjs.org/download.html and ensure it can be found on ' +<tr><td><a name="l75" href="#l75">75</a><td> 'your PATH. For more information, see ' +<tr><td><a name="l76" href="#l76">76</a><td> 'https://github.com/ariya/phantomjs/wiki');<tr><td><a name="l77" href="#l77">77</a><td> }<tr><td><a name="l78" href="#l78">78</a><td> if (!fs.existsSync(exe)) {<tr><td><a name="l79" href="#l79">79</a><td> throw Error('File does not exist: ' + exe);<tr><td><a name="l80" href="#l80">80</a><td> }<tr><td><a name="l81" href="#l81">81</a><td> return exe;<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><tr><td><a name="l85" href="#l85">85</a><td>/**<tr><td><a name="l86" href="#l86">86</a><td> * Maps WebDriver logging level name to those recognised by PhantomJS.<tr><td><a name="l87" href="#l87">87</a><td> * @type {!Object.<string, string>}<tr><td><a name="l88" href="#l88">88</a><td> * @const<tr><td><a name="l89" href="#l89">89</a><td> */<tr><td><a name="l90" href="#l90">90</a><td>var WEBDRIVER_TO_PHANTOMJS_LEVEL = (function() {<tr><td><a name="l91" href="#l91">91</a><td> var map = {};<tr><td><a name="l92" href="#l92">92</a><td> map[webdriver.logging.Level.ALL.name] = 'DEBUG';<tr><td><a name="l93" href="#l93">93</a><td> map[webdriver.logging.Level.DEBUG.name] = 'DEBUG';<tr><td><a name="l94" href="#l94">94</a><td> map[webdriver.logging.Level.INFO.name] = 'INFO';<tr><td><a name="l95" href="#l95">95</a><td> map[webdriver.logging.Level.WARNING.name] = 'WARN';<tr><td><a name="l96" href="#l96">96</a><td> map[webdriver.logging.Level.SEVERE.name] = 'ERROR';<tr><td><a name="l97" href="#l97">97</a><td> return map;<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> * Creates a new PhantomJS WebDriver client.<tr><td><a name="l103" href="#l103">103</a><td> * @param {webdriver.Capabilities=} opt_capabilities The desired capabilities.<tr><td><a name="l104" href="#l104">104</a><td> * @param {webdriver.promise.ControlFlow=} opt_flow The control flow to use, or<tr><td><a name="l105" href="#l105">105</a><td> * {@code null} to use the currently active flow.<tr><td><a name="l106" href="#l106">106</a><td> * @return {!webdriver.WebDriver} A new WebDriver instance.<tr><td><a name="l107" href="#l107">107</a><td> * @deprecated Use {@link Driver}.<tr><td><a name="l108" href="#l108">108</a><td> */<tr><td><a name="l109" href="#l109">109</a><td>function createDriver(opt_capabilities, opt_flow) {<tr><td><a name="l110" href="#l110">110</a><td> return new Driver(opt_capabilities, opt_flow);<tr><td><a name="l111" href="#l111">111</a><td>}<tr><td><a name="l112" href="#l112">112</a><td><tr><td><a name="l113" href="#l113">113</a><td><tr><td><a name="l114" href="#l114">114</a><td>/**<tr><td><a name="l115" href="#l115">115</a><td> * Creates a new WebDriver client for PhantomJS.<tr><td><a name="l116" href="#l116">116</a><td> *<tr><td><a name="l117" href="#l117">117</a><td> * @param {webdriver.Capabilities=} opt_capabilities The desired capabilities.<tr><td><a name="l118" href="#l118">118</a><td> * @param {webdriver.promise.ControlFlow=} opt_flow The control flow to use, or<tr><td><a name="l119" href="#l119">119</a><td> * {@code null} to use the currently active flow.<tr><td><a name="l120" href="#l120">120</a><td> * @constructor<tr><td><a name="l121" href="#l121">121</a><td> * @extends {webdriver.WebDriver}<tr><td><a name="l122" href="#l122">122</a><td> */<tr><td><a name="l123" href="#l123">123</a><td>var Driver = function(opt_capabilities, opt_flow) {<tr><td><a name="l124" href="#l124">124</a><td> var capabilities = opt_capabilities || webdriver.Capabilities.phantomjs();<tr><td><a name="l125" href="#l125">125</a><td> var exe = findExecutable(capabilities.get(BINARY_PATH_CAPABILITY));<tr><td><a name="l126" href="#l126">126</a><td> var args = ['--webdriver-logfile=' + DEFAULT_LOG_FILE];<tr><td><a name="l127" href="#l127">127</a><td><tr><td><a name="l128" href="#l128">128</a><td> var logPrefs = capabilities.get(webdriver.Capability.LOGGING_PREFS);<tr><td><a name="l129" href="#l129">129</a><td> if (logPrefs instanceof webdriver.logging.Preferences) {<tr><td><a name="l130" href="#l130">130</a><td> logPrefs = logPrefs.toJSON();<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> if (logPrefs && logPrefs[webdriver.logging.Type.DRIVER]) {<tr><td><a name="l134" href="#l134">134</a><td> var level = WEBDRIVER_TO_PHANTOMJS_LEVEL[<tr><td><a name="l135" href="#l135">135</a><td> logPrefs[webdriver.logging.Type.DRIVER]];<tr><td><a name="l136" href="#l136">136</a><td> if (level) {<tr><td><a name="l137" href="#l137">137</a><td> args.push('--webdriver-loglevel=' + level);<tr><td><a name="l138" href="#l138">138</a><td> }<tr><td><a name="l139" href="#l139">139</a><td> }<tr><td><a name="l140" href="#l140">140</a><td><tr><td><a name="l141" href="#l141">141</a><td> var proxy = capabilities.get(webdriver.Capability.PROXY);<tr><td><a name="l142" href="#l142">142</a><td> if (proxy) {<tr><td><a name="l143" href="#l143">143</a><td> switch (proxy.proxyType) {<tr><td><a name="l144" href="#l144">144</a><td> case 'manual':<tr><td><a name="l145" href="#l145">145</a><td> if (proxy.httpProxy) {<tr><td><a name="l146" href="#l146">146</a><td> args.push(<tr><td><a name="l147" href="#l147">147</a><td> '--proxy-type=http',<tr><td><a name="l148" href="#l148">148</a><td> '--proxy=http://' + proxy.httpProxy);<tr><td><a name="l149" href="#l149">149</a><td> }<tr><td><a name="l150" href="#l150">150</a><td> break;<tr><td><a name="l151" href="#l151">151</a><td> case 'pac':<tr><td><a name="l152" href="#l152">152</a><td> throw Error('PhantomJS does not support Proxy PAC files');<tr><td><a name="l153" href="#l153">153</a><td> case 'system':<tr><td><a name="l154" href="#l154">154</a><td> args.push('--proxy-type=system');<tr><td><a name="l155" href="#l155">155</a><td> break;<tr><td><a name="l156" href="#l156">156</a><td> case 'direct':<tr><td><a name="l157" href="#l157">157</a><td> args.push('--proxy-type=none');<tr><td><a name="l158" href="#l158">158</a><td> break;<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> args = args.concat(capabilities.get(CLI_ARGS_CAPABILITY) || []);<tr><td><a name="l162" href="#l162">162</a><td><tr><td><a name="l163" href="#l163">163</a><td> var port = portprober.findFreePort();<tr><td><a name="l164" href="#l164">164</a><td> var service = new remote.DriverService(exe, {<tr><td><a name="l165" href="#l165">165</a><td> port: port,<tr><td><a name="l166" href="#l166">166</a><td> args: webdriver.promise.when(port, function(port) {<tr><td><a name="l167" href="#l167">167</a><td> args.push('--webdriver=' + port);<tr><td><a name="l168" href="#l168">168</a><td> return args;<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> var executor = executors.createExecutor(service.start());<tr><td><a name="l173" href="#l173">173</a><td> var driver = webdriver.WebDriver.createSession(<tr><td><a name="l174" href="#l174">174</a><td> executor, capabilities, opt_flow);<tr><td><a name="l175" href="#l175">175</a><td><tr><td><a name="l176" href="#l176">176</a><td> webdriver.WebDriver.call(<tr><td><a name="l177" href="#l177">177</a><td> this, driver.getSession(), executor, driver.controlFlow());<tr><td><a name="l178" href="#l178">178</a><td><tr><td><a name="l179" href="#l179">179</a><td> var boundQuit = this.quit.bind(this);<tr><td><a name="l180" href="#l180">180</a><td><tr><td><a name="l181" href="#l181">181</a><td> /** @override */<tr><td><a name="l182" href="#l182">182</a><td> this.quit = function() {<tr><td><a name="l183" href="#l183">183</a><td> return boundQuit().thenFinally(service.kill.bind(service));<tr><td><a name="l184" href="#l184">184</a><td> };<tr><td><a name="l185" href="#l185">185</a><td> return driver;<tr><td><a name="l186" href="#l186">186</a><td>};<tr><td><a name="l187" href="#l187">187</a><td>util.inherits(Driver, webdriver.WebDriver);<tr><td><a name="l188" href="#l188">188</a><td><tr><td><a name="l189" href="#l189">189</a><td><tr><td><a name="l190" href="#l190">190</a><td>// PUBLIC API<tr><td><a name="l191" href="#l191">191</a><td><tr><td><a name="l192" href="#l192">192</a><td>exports.Driver = Driver;<tr><td><a name="l193" href="#l193">193</a><td>exports.createDriver = createDriver;</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>proxy.js</title><link href="../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>proxy.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2013 Selenium committers<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 "License");<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 "AS IS" 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 functions for configuring a webdriver proxy:<tr><td><a name="l17" href="#l17">17</a><td> * <pre><code><tr><td><a name="l18" href="#l18">18</a><td> * var webdriver = require('selenium-webdriver'),<tr><td><a name="l19" href="#l19">19</a><td> * proxy = require('selenium-webdriver/proxy');<tr><td><a name="l20" href="#l20">20</a><td> *<tr><td><a name="l21" href="#l21">21</a><td> * var driver = new webdriver.Builder()<tr><td><a name="l22" href="#l22">22</a><td> * .withCapabilities(webdriver.Capabilities.chrome())<tr><td><a name="l23" href="#l23">23</a><td> * .setProxy(proxy.manual({http: 'host:1234'}))<tr><td><a name="l24" href="#l24">24</a><td> * .build();<tr><td><a name="l25" href="#l25">25</a><td> * </code></pre><tr><td><a name="l26" href="#l26">26</a><td> */<tr><td><a name="l27" href="#l27">27</a><td><tr><td><a name="l28" href="#l28">28</a><td>'use strict';<tr><td><a name="l29" href="#l29">29</a><td><tr><td><a name="l30" href="#l30">30</a><td>var util = require('util');<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>// PUBLIC API<tr><td><a name="l35" href="#l35">35</a><td><tr><td><a name="l36" href="#l36">36</a><td><tr><td><a name="l37" href="#l37">37</a><td>/**<tr><td><a name="l38" href="#l38">38</a><td> * Configures WebDriver to bypass all browser proxies.<tr><td><a name="l39" href="#l39">39</a><td> * @return {!webdriver.ProxyConfig} A new proxy configuration object.<tr><td><a name="l40" href="#l40">40</a><td> */<tr><td><a name="l41" href="#l41">41</a><td>exports.direct = function() {<tr><td><a name="l42" href="#l42">42</a><td> return {proxyType: 'direct'};<tr><td><a name="l43" href="#l43">43</a><td>};<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> * Manually configures the browser proxy. The following options are<tr><td><a name="l48" href="#l48">48</a><td> * supported:<tr><td><a name="l49" href="#l49">49</a><td> * <ul><tr><td><a name="l50" href="#l50">50</a><td> * <li>{@code ftp}: Proxy host to use for FTP requests<tr><td><a name="l51" href="#l51">51</a><td> * <li>{@code http}: Proxy host to use for HTTP requests<tr><td><a name="l52" href="#l52">52</a><td> * <li>{@code https}: Proxy host to use for HTTPS requests<tr><td><a name="l53" href="#l53">53</a><td> * <li>{@code bypass}: A list of hosts requests should directly connect to,<tr><td><a name="l54" href="#l54">54</a><td> * bypassing any other proxies for that request. May be specified as a<tr><td><a name="l55" href="#l55">55</a><td> * comma separated string, or a list of strings.<tr><td><a name="l56" href="#l56">56</a><td> * </ul><tr><td><a name="l57" href="#l57">57</a><td> *<tr><td><a name="l58" href="#l58">58</a><td> * Behavior is undefined for FTP, HTTP, and HTTPS requests if the<tr><td><a name="l59" href="#l59">59</a><td> * corresponding key is omitted from the configuration options.<tr><td><a name="l60" href="#l60">60</a><td> *<tr><td><a name="l61" href="#l61">61</a><td> * @param {{ftp: (string|undefined),<tr><td><a name="l62" href="#l62">62</a><td> * http: (string|undefined),<tr><td><a name="l63" href="#l63">63</a><td> * https: (string|undefined),<tr><td><a name="l64" href="#l64">64</a><td> * bypass: (string|!Array.<string>|undefined)}} options Proxy<tr><td><a name="l65" href="#l65">65</a><td> * configuration options.<tr><td><a name="l66" href="#l66">66</a><td> * @return {!webdriver.ProxyConfig} A new proxy configuration object.<tr><td><a name="l67" href="#l67">67</a><td> */<tr><td><a name="l68" href="#l68">68</a><td>exports.manual = function(options) {<tr><td><a name="l69" href="#l69">69</a><td> return {<tr><td><a name="l70" href="#l70">70</a><td> proxyType: 'manual',<tr><td><a name="l71" href="#l71">71</a><td> ftpProxy: options.ftp,<tr><td><a name="l72" href="#l72">72</a><td> httpProxy: options.http,<tr><td><a name="l73" href="#l73">73</a><td> sslProxy: options.https,<tr><td><a name="l74" href="#l74">74</a><td> noProxy: util.isArray(options.bypass) ?<tr><td><a name="l75" href="#l75">75</a><td> options.bypass.join(',') : options.bypass<tr><td><a name="l76" href="#l76">76</a><td> };<tr><td><a name="l77" href="#l77">77</a><td>};<tr><td><a name="l78" href="#l78">78</a><td><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> * Configures WebDriver to configure the browser proxy using the PAC file at<tr><td><a name="l82" href="#l82">82</a><td> * the given URL.<tr><td><a name="l83" href="#l83">83</a><td> * @param {string} url URL for the PAC proxy to use.<tr><td><a name="l84" href="#l84">84</a><td> * @return {!webdriver.ProxyConfig} A new proxy configuration object.<tr><td><a name="l85" href="#l85">85</a><td> */<tr><td><a name="l86" href="#l86">86</a><td>exports.pac = function(url) {<tr><td><a name="l87" href="#l87">87</a><td> return {<tr><td><a name="l88" href="#l88">88</a><td> proxyType: 'pac',<tr><td><a name="l89" href="#l89">89</a><td> proxyAutoconfigUrl: url<tr><td><a name="l90" href="#l90">90</a><td> };<tr><td><a name="l91" href="#l91">91</a><td>};<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> * Configures WebDriver to use the current system's proxy.<tr><td><a name="l96" href="#l96">96</a><td> * @return {!webdriver.ProxyConfig} A new proxy configuration object.<tr><td><a name="l97" href="#l97">97</a><td> */<tr><td><a name="l98" href="#l98">98</a><td>exports.system = function() {<tr><td><a name="l99" href="#l99">99</a><td> return {proxyType: 'system'};<tr><td><a name="l100" href="#l100">100</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>proxy.js</title><link href="../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>proxy.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2013 Selenium committers<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 "License");<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 "AS IS" 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 functions for configuring a webdriver proxy:<tr><td><a name="l17" href="#l17">17</a><td> * <pre><code><tr><td><a name="l18" href="#l18">18</a><td> * var webdriver = require('selenium-webdriver'),<tr><td><a name="l19" href="#l19">19</a><td> * proxy = require('selenium-webdriver/proxy');<tr><td><a name="l20" href="#l20">20</a><td> *<tr><td><a name="l21" href="#l21">21</a><td> * var driver = new webdriver.Builder()<tr><td><a name="l22" href="#l22">22</a><td> * .withCapabilities(webdriver.Capabilities.chrome())<tr><td><a name="l23" href="#l23">23</a><td> * .setProxy(proxy.manual({http: 'host:1234'}))<tr><td><a name="l24" href="#l24">24</a><td> * .build();<tr><td><a name="l25" href="#l25">25</a><td> * </code></pre><tr><td><a name="l26" href="#l26">26</a><td> */<tr><td><a name="l27" href="#l27">27</a><td><tr><td><a name="l28" href="#l28">28</a><td>'use strict';<tr><td><a name="l29" href="#l29">29</a><td><tr><td><a name="l30" href="#l30">30</a><td>var util = require('util');<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>// PUBLIC API<tr><td><a name="l35" href="#l35">35</a><td><tr><td><a name="l36" href="#l36">36</a><td><tr><td><a name="l37" href="#l37">37</a><td>/**<tr><td><a name="l38" href="#l38">38</a><td> * Configures WebDriver to bypass all browser proxies.<tr><td><a name="l39" href="#l39">39</a><td> * @return {!webdriver.ProxyConfig} A new proxy configuration object.<tr><td><a name="l40" href="#l40">40</a><td> */<tr><td><a name="l41" href="#l41">41</a><td>exports.direct = function() {<tr><td><a name="l42" href="#l42">42</a><td> return {proxyType: 'direct'};<tr><td><a name="l43" href="#l43">43</a><td>};<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> * Manually configures the browser proxy. The following options are<tr><td><a name="l48" href="#l48">48</a><td> * supported:<tr><td><a name="l49" href="#l49">49</a><td> * <ul><tr><td><a name="l50" href="#l50">50</a><td> * <li>{@code ftp}: Proxy host to use for FTP requests<tr><td><a name="l51" href="#l51">51</a><td> * <li>{@code http}: Proxy host to use for HTTP requests<tr><td><a name="l52" href="#l52">52</a><td> * <li>{@code https}: Proxy host to use for HTTPS requests<tr><td><a name="l53" href="#l53">53</a><td> * <li>{@code bypass}: A list of hosts requests should directly connect to,<tr><td><a name="l54" href="#l54">54</a><td> * bypassing any other proxies for that request. May be specified as a<tr><td><a name="l55" href="#l55">55</a><td> * comma separated string, or a list of strings.<tr><td><a name="l56" href="#l56">56</a><td> * </ul><tr><td><a name="l57" href="#l57">57</a><td> *<tr><td><a name="l58" href="#l58">58</a><td> * Behavior is undefined for FTP, HTTP, and HTTPS requests if the<tr><td><a name="l59" href="#l59">59</a><td> * corresponding key is omitted from the configuration options.<tr><td><a name="l60" href="#l60">60</a><td> *<tr><td><a name="l61" href="#l61">61</a><td> * @param {{ftp: (string|undefined),<tr><td><a name="l62" href="#l62">62</a><td> * http: (string|undefined),<tr><td><a name="l63" href="#l63">63</a><td> * https: (string|undefined),<tr><td><a name="l64" href="#l64">64</a><td> * bypass: (string|!Array.<string>|undefined)}} options Proxy<tr><td><a name="l65" href="#l65">65</a><td> * configuration options.<tr><td><a name="l66" href="#l66">66</a><td> * @return {!webdriver.ProxyConfig} A new proxy configuration object.<tr><td><a name="l67" href="#l67">67</a><td> */<tr><td><a name="l68" href="#l68">68</a><td>exports.manual = function(options) {<tr><td><a name="l69" href="#l69">69</a><td> return {<tr><td><a name="l70" href="#l70">70</a><td> proxyType: 'manual',<tr><td><a name="l71" href="#l71">71</a><td> ftpProxy: options.ftp,<tr><td><a name="l72" href="#l72">72</a><td> httpProxy: options.http,<tr><td><a name="l73" href="#l73">73</a><td> sslProxy: options.https,<tr><td><a name="l74" href="#l74">74</a><td> noProxy: util.isArray(options.bypass) ?<tr><td><a name="l75" href="#l75">75</a><td> options.bypass.join(',') : options.bypass<tr><td><a name="l76" href="#l76">76</a><td> };<tr><td><a name="l77" href="#l77">77</a><td>};<tr><td><a name="l78" href="#l78">78</a><td><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> * Configures WebDriver to configure the browser proxy using the PAC file at<tr><td><a name="l82" href="#l82">82</a><td> * the given URL.<tr><td><a name="l83" href="#l83">83</a><td> * @param {string} url URL for the PAC proxy to use.<tr><td><a name="l84" href="#l84">84</a><td> * @return {!webdriver.ProxyConfig} A new proxy configuration object.<tr><td><a name="l85" href="#l85">85</a><td> */<tr><td><a name="l86" href="#l86">86</a><td>exports.pac = function(url) {<tr><td><a name="l87" href="#l87">87</a><td> return {<tr><td><a name="l88" href="#l88">88</a><td> proxyType: 'pac',<tr><td><a name="l89" href="#l89">89</a><td> proxyAutoconfigUrl: url<tr><td><a name="l90" href="#l90">90</a><td> };<tr><td><a name="l91" href="#l91">91</a><td>};<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> * Configures WebDriver to use the current system's proxy.<tr><td><a name="l96" href="#l96">96</a><td> * @return {!webdriver.ProxyConfig} A new proxy configuration object.<tr><td><a name="l97" href="#l97">97</a><td> */<tr><td><a name="l98" href="#l98">98</a><td>exports.system = function() {<tr><td><a name="l99" href="#l99">99</a><td> return {proxyType: 'system'};<tr><td><a name="l100" href="#l100">100</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>
|