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>extension.js</title><link href="../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>firefox/extension.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2014 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2014 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>/** @fileoverview Utilities for working with Firefox extensions. */<tr><td><a name="l17" href="#l17">17</a><td><tr><td><a name="l18" href="#l18">18</a><td>'use strict';<tr><td><a name="l19" href="#l19">19</a><td><tr><td><a name="l20" href="#l20">20</a><td>var AdmZip = require('adm-zip'),<tr><td><a name="l21" href="#l21">21</a><td> fs = require('fs'),<tr><td><a name="l22" href="#l22">22</a><td> path = require('path'),<tr><td><a name="l23" href="#l23">23</a><td> util = require('util'),<tr><td><a name="l24" href="#l24">24</a><td> xml = require('xml2js');<tr><td><a name="l25" href="#l25">25</a><td><tr><td><a name="l26" href="#l26">26</a><td>var promise = require('..').promise,<tr><td><a name="l27" href="#l27">27</a><td> checkedCall = promise.checkedNodeCall,<tr><td><a name="l28" href="#l28">28</a><td> io = require('../io');<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> * Thrown when there an add-on is malformed.<tr><td><a name="l33" href="#l33">33</a><td> * @param {string} msg The error message.<tr><td><a name="l34" href="#l34">34</a><td> * @constructor<tr><td><a name="l35" href="#l35">35</a><td> * @extends {Error}<tr><td><a name="l36" href="#l36">36</a><td> */<tr><td><a name="l37" href="#l37">37</a><td>function AddonFormatError(msg) {<tr><td><a name="l38" href="#l38">38</a><td> Error.call(this);<tr><td><a name="l39" href="#l39">39</a><td><tr><td><a name="l40" href="#l40">40</a><td> Error.captureStackTrace(this, AddonFormatError);<tr><td><a name="l41" href="#l41">41</a><td><tr><td><a name="l42" href="#l42">42</a><td> /** @override */<tr><td><a name="l43" href="#l43">43</a><td> this.name = AddonFormatError.name;<tr><td><a name="l44" href="#l44">44</a><td><tr><td><a name="l45" href="#l45">45</a><td> /** @override */<tr><td><a name="l46" href="#l46">46</a><td> this.message = msg;<tr><td><a name="l47" href="#l47">47</a><td>}<tr><td><a name="l48" href="#l48">48</a><td>util.inherits(AddonFormatError, Error);<tr><td><a name="l49" href="#l49">49</a><td><tr><td><a name="l50" href="#l50">50</a><td><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> * Installs an extension to the given directory.<tr><td><a name="l54" href="#l54">54</a><td> * @param {string} extension Path to the extension to install, as either a xpi<tr><td><a name="l55" href="#l55">55</a><td> * file or a directory.<tr><td><a name="l56" href="#l56">56</a><td> * @param {string} dir Path to the directory to install the extension in.<tr><td><a name="l57" href="#l57">57</a><td> * @return {!promise.Promise.<string>} A promise for the add-on ID once<tr><td><a name="l58" href="#l58">58</a><td> * installed.<tr><td><a name="l59" href="#l59">59</a><td> */<tr><td><a name="l60" href="#l60">60</a><td>function install(extension, dir) {<tr><td><a name="l61" href="#l61">61</a><td> return getDetails(extension).then(function(details) {<tr><td><a name="l62" href="#l62">62</a><td> function returnId() { return details.id; }<tr><td><a name="l63" href="#l63">63</a><td><tr><td><a name="l64" href="#l64">64</a><td> var dst = path.join(dir, details.id);<tr><td><a name="l65" href="#l65">65</a><td> if (extension.slice(-4) === '.xpi') {<tr><td><a name="l66" href="#l66">66</a><td> if (!details.unpack) {<tr><td><a name="l67" href="#l67">67</a><td> return io.copy(extension, dst + '.xpi').then(returnId);<tr><td><a name="l68" href="#l68">68</a><td> } else {<tr><td><a name="l69" href="#l69">69</a><td> return checkedCall(fs.readFile, extension).then(function(buff) {<tr><td><a name="l70" href="#l70">70</a><td> var zip = new AdmZip(buff);<tr><td><a name="l71" href="#l71">71</a><td> // TODO: find an async library for inflating a zip archive.<tr><td><a name="l72" href="#l72">72</a><td> new AdmZip(buff).extractAllTo(dst, true);<tr><td><a name="l73" href="#l73">73</a><td> }).then(returnId);<tr><td><a name="l74" href="#l74">74</a><td> }<tr><td><a name="l75" href="#l75">75</a><td> } else {<tr><td><a name="l76" href="#l76">76</a><td> return io.copyDir(extension, dst).then(returnId);<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><tr><td><a name="l82" href="#l82">82</a><td>/**<tr><td><a name="l83" href="#l83">83</a><td> * Describes a Firefox add-on.<tr><td><a name="l84" href="#l84">84</a><td> * @typedef {{id: string, name: string, version: string, unpack: boolean}}<tr><td><a name="l85" href="#l85">85</a><td> */<tr><td><a name="l86" href="#l86">86</a><td>var AddonDetails;<tr><td><a name="l87" href="#l87">87</a><td><tr><td><a name="l88" href="#l88">88</a><td><tr><td><a name="l89" href="#l89">89</a><td>/**<tr><td><a name="l90" href="#l90">90</a><td> * Extracts the details needed to install an add-on.<tr><td><a name="l91" href="#l91">91</a><td> * @param {string} addonPath Path to the extension directory.<tr><td><a name="l92" href="#l92">92</a><td> * @return {!promise.Promise.<!AddonDetails>} A promise for the add-on details.<tr><td><a name="l93" href="#l93">93</a><td> */<tr><td><a name="l94" href="#l94">94</a><td>function getDetails(addonPath) {<tr><td><a name="l95" href="#l95">95</a><td> return readManifest(addonPath).then(function(doc) {<tr><td><a name="l96" href="#l96">96</a><td> var em = getNamespaceId(doc, 'http://www.mozilla.org/2004/em-rdf#');<tr><td><a name="l97" href="#l97">97</a><td> var rdf = getNamespaceId(<tr><td><a name="l98" href="#l98">98</a><td> doc, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');<tr><td><a name="l99" href="#l99">99</a><td><tr><td><a name="l100" href="#l100">100</a><td> var description = doc[rdf + 'RDF'][rdf + 'Description'][0];<tr><td><a name="l101" href="#l101">101</a><td> var details = {<tr><td><a name="l102" href="#l102">102</a><td> id: getNodeText(description, em + 'id'),<tr><td><a name="l103" href="#l103">103</a><td> name: getNodeText(description, em + 'name'),<tr><td><a name="l104" href="#l104">104</a><td> version: getNodeText(description, em + 'version'),<tr><td><a name="l105" href="#l105">105</a><td> unpack: getNodeText(description, em + 'unpack') || false<tr><td><a name="l106" href="#l106">106</a><td> };<tr><td><a name="l107" href="#l107">107</a><td><tr><td><a name="l108" href="#l108">108</a><td> if (typeof details.unpack === 'string') {<tr><td><a name="l109" href="#l109">109</a><td> details.unpack = details.unpack.toLowerCase() === 'true';<tr><td><a name="l110" href="#l110">110</a><td> }<tr><td><a name="l111" href="#l111">111</a><td><tr><td><a name="l112" href="#l112">112</a><td> if (!details.id) {<tr><td><a name="l113" href="#l113">113</a><td> throw new AddonFormatError('Could not find add-on ID for ' + addonPath);<tr><td><a name="l114" href="#l114">114</a><td> }<tr><td><a name="l115" href="#l115">115</a><td><tr><td><a name="l116" href="#l116">116</a><td> return details;<tr><td><a name="l117" href="#l117">117</a><td> });<tr><td><a name="l118" href="#l118">118</a><td><tr><td><a name="l119" href="#l119">119</a><td> function getNodeText(node, name) {<tr><td><a name="l120" href="#l120">120</a><td> return node[name] && node[name][0] || '';<tr><td><a name="l121" href="#l121">121</a><td> }<tr><td><a name="l122" href="#l122">122</a><td><tr><td><a name="l123" href="#l123">123</a><td> function getNamespaceId(doc, url) {<tr><td><a name="l124" href="#l124">124</a><td> var keys = Object.keys(doc);<tr><td><a name="l125" href="#l125">125</a><td> if (keys.length !== 1) {<tr><td><a name="l126" href="#l126">126</a><td> throw new AddonFormatError('Malformed manifest for add-on ' + addonPath);<tr><td><a name="l127" href="#l127">127</a><td> }<tr><td><a name="l128" href="#l128">128</a><td><tr><td><a name="l129" href="#l129">129</a><td> var namespaces = doc[keys[0]].$;<tr><td><a name="l130" href="#l130">130</a><td> var id = '';<tr><td><a name="l131" href="#l131">131</a><td> Object.keys(namespaces).some(function(ns) {<tr><td><a name="l132" href="#l132">132</a><td> if (namespaces[ns] !== url) {<tr><td><a name="l133" href="#l133">133</a><td> return false;<tr><td><a name="l134" href="#l134">134</a><td> }<tr><td><a name="l135" href="#l135">135</a><td><tr><td><a name="l136" href="#l136">136</a><td> if (ns.indexOf(':') != -1) {<tr><td><a name="l137" href="#l137">137</a><td> id = ns.split(':')[1] + ':';<tr><td><a name="l138" href="#l138">138</a><td> }<tr><td><a name="l139" href="#l139">139</a><td> return true;<tr><td><a name="l140" href="#l140">140</a><td> });<tr><td><a name="l141" href="#l141">141</a><td> return id;<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><tr><td><a name="l146" href="#l146">146</a><td>/**<tr><td><a name="l147" href="#l147">147</a><td> * Reads the manifest for a Firefox add-on.<tr><td><a name="l148" href="#l148">148</a><td> * @param {string} addonPath Path to a Firefox add-on as a xpi or an extension.<tr><td><a name="l149" href="#l149">149</a><td> * @return {!promise.Promise.<!Object>} A promise for the parsed manifest.<tr><td><a name="l150" href="#l150">150</a><td> */<tr><td><a name="l151" href="#l151">151</a><td>function readManifest(addonPath) {<tr><td><a name="l152" href="#l152">152</a><td> var manifest;<tr><td><a name="l153" href="#l153">153</a><td><tr><td><a name="l154" href="#l154">154</a><td> if (addonPath.slice(-4) === '.xpi') {<tr><td><a name="l155" href="#l155">155</a><td> manifest = checkedCall(fs.readFile, addonPath).then(function(buff) {<tr><td><a name="l156" href="#l156">156</a><td> var zip = new AdmZip(buff);<tr><td><a name="l157" href="#l157">157</a><td> if (!zip.getEntry('install.rdf')) {<tr><td><a name="l158" href="#l158">158</a><td> throw new AddonFormatError(<tr><td><a name="l159" href="#l159">159</a><td> 'Could not find install.rdf in ' + addonPath);<tr><td><a name="l160" href="#l160">160</a><td> }<tr><td><a name="l161" href="#l161">161</a><td> var done = promise.defer();<tr><td><a name="l162" href="#l162">162</a><td> zip.readAsTextAsync('install.rdf', done.fulfill);<tr><td><a name="l163" href="#l163">163</a><td> return done.promise;<tr><td><a name="l164" href="#l164">164</a><td> });<tr><td><a name="l165" href="#l165">165</a><td> } else {<tr><td><a name="l166" href="#l166">166</a><td> manifest = checkedCall(fs.stat, addonPath).then(function(stats) {<tr><td><a name="l167" href="#l167">167</a><td> if (!stats.isDirectory()) {<tr><td><a name="l168" href="#l168">168</a><td> throw Error(<tr><td><a name="l169" href="#l169">169</a><td> 'Add-on path is niether a xpi nor a directory: ' + addonPath);<tr><td><a name="l170" href="#l170">170</a><td> }<tr><td><a name="l171" href="#l171">171</a><td> return checkedCall(fs.readFile, path.join(addonPath, 'install.rdf'));<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> return manifest.then(function(content) {<tr><td><a name="l176" href="#l176">176</a><td> return checkedCall(xml.parseString, content);<tr><td><a name="l177" href="#l177">177</a><td> });<tr><td><a name="l178" href="#l178">178</a><td>}<tr><td><a name="l179" href="#l179">179</a><td><tr><td><a name="l180" href="#l180">180</a><td><tr><td><a name="l181" href="#l181">181</a><td>// PUBLIC API<tr><td><a name="l182" href="#l182">182</a><td><tr><td><a name="l183" href="#l183">183</a><td><tr><td><a name="l184" href="#l184">184</a><td>exports.install = install;</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>extension.js</title><link href="../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>firefox/extension.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2014 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2014 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>/** @fileoverview Utilities for working with Firefox extensions. */<tr><td><a name="l17" href="#l17">17</a><td><tr><td><a name="l18" href="#l18">18</a><td>'use strict';<tr><td><a name="l19" href="#l19">19</a><td><tr><td><a name="l20" href="#l20">20</a><td>var AdmZip = require('adm-zip'),<tr><td><a name="l21" href="#l21">21</a><td> fs = require('fs'),<tr><td><a name="l22" href="#l22">22</a><td> path = require('path'),<tr><td><a name="l23" href="#l23">23</a><td> util = require('util'),<tr><td><a name="l24" href="#l24">24</a><td> xml = require('xml2js');<tr><td><a name="l25" href="#l25">25</a><td><tr><td><a name="l26" href="#l26">26</a><td>var promise = require('..').promise,<tr><td><a name="l27" href="#l27">27</a><td> checkedCall = promise.checkedNodeCall,<tr><td><a name="l28" href="#l28">28</a><td> io = require('../io');<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> * Thrown when there an add-on is malformed.<tr><td><a name="l33" href="#l33">33</a><td> * @param {string} msg The error message.<tr><td><a name="l34" href="#l34">34</a><td> * @constructor<tr><td><a name="l35" href="#l35">35</a><td> * @extends {Error}<tr><td><a name="l36" href="#l36">36</a><td> */<tr><td><a name="l37" href="#l37">37</a><td>function AddonFormatError(msg) {<tr><td><a name="l38" href="#l38">38</a><td> Error.call(this);<tr><td><a name="l39" href="#l39">39</a><td><tr><td><a name="l40" href="#l40">40</a><td> Error.captureStackTrace(this, AddonFormatError);<tr><td><a name="l41" href="#l41">41</a><td><tr><td><a name="l42" href="#l42">42</a><td> /** @override */<tr><td><a name="l43" href="#l43">43</a><td> this.name = AddonFormatError.name;<tr><td><a name="l44" href="#l44">44</a><td><tr><td><a name="l45" href="#l45">45</a><td> /** @override */<tr><td><a name="l46" href="#l46">46</a><td> this.message = msg;<tr><td><a name="l47" href="#l47">47</a><td>}<tr><td><a name="l48" href="#l48">48</a><td>util.inherits(AddonFormatError, Error);<tr><td><a name="l49" href="#l49">49</a><td><tr><td><a name="l50" href="#l50">50</a><td><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> * Installs an extension to the given directory.<tr><td><a name="l54" href="#l54">54</a><td> * @param {string} extension Path to the extension to install, as either a xpi<tr><td><a name="l55" href="#l55">55</a><td> * file or a directory.<tr><td><a name="l56" href="#l56">56</a><td> * @param {string} dir Path to the directory to install the extension in.<tr><td><a name="l57" href="#l57">57</a><td> * @return {!promise.Promise.<string>} A promise for the add-on ID once<tr><td><a name="l58" href="#l58">58</a><td> * installed.<tr><td><a name="l59" href="#l59">59</a><td> */<tr><td><a name="l60" href="#l60">60</a><td>function install(extension, dir) {<tr><td><a name="l61" href="#l61">61</a><td> return getDetails(extension).then(function(details) {<tr><td><a name="l62" href="#l62">62</a><td> function returnId() { return details.id; }<tr><td><a name="l63" href="#l63">63</a><td><tr><td><a name="l64" href="#l64">64</a><td> var dst = path.join(dir, details.id);<tr><td><a name="l65" href="#l65">65</a><td> if (extension.slice(-4) === '.xpi') {<tr><td><a name="l66" href="#l66">66</a><td> if (!details.unpack) {<tr><td><a name="l67" href="#l67">67</a><td> return io.copy(extension, dst + '.xpi').then(returnId);<tr><td><a name="l68" href="#l68">68</a><td> } else {<tr><td><a name="l69" href="#l69">69</a><td> return checkedCall(fs.readFile, extension).then(function(buff) {<tr><td><a name="l70" href="#l70">70</a><td> var zip = new AdmZip(buff);<tr><td><a name="l71" href="#l71">71</a><td> // TODO: find an async library for inflating a zip archive.<tr><td><a name="l72" href="#l72">72</a><td> new AdmZip(buff).extractAllTo(dst, true);<tr><td><a name="l73" href="#l73">73</a><td> }).then(returnId);<tr><td><a name="l74" href="#l74">74</a><td> }<tr><td><a name="l75" href="#l75">75</a><td> } else {<tr><td><a name="l76" href="#l76">76</a><td> return io.copyDir(extension, dst).then(returnId);<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><tr><td><a name="l82" href="#l82">82</a><td>/**<tr><td><a name="l83" href="#l83">83</a><td> * Describes a Firefox add-on.<tr><td><a name="l84" href="#l84">84</a><td> * @typedef {{id: string, name: string, version: string, unpack: boolean}}<tr><td><a name="l85" href="#l85">85</a><td> */<tr><td><a name="l86" href="#l86">86</a><td>var AddonDetails;<tr><td><a name="l87" href="#l87">87</a><td><tr><td><a name="l88" href="#l88">88</a><td><tr><td><a name="l89" href="#l89">89</a><td>/**<tr><td><a name="l90" href="#l90">90</a><td> * Extracts the details needed to install an add-on.<tr><td><a name="l91" href="#l91">91</a><td> * @param {string} addonPath Path to the extension directory.<tr><td><a name="l92" href="#l92">92</a><td> * @return {!promise.Promise.<!AddonDetails>} A promise for the add-on details.<tr><td><a name="l93" href="#l93">93</a><td> */<tr><td><a name="l94" href="#l94">94</a><td>function getDetails(addonPath) {<tr><td><a name="l95" href="#l95">95</a><td> return readManifest(addonPath).then(function(doc) {<tr><td><a name="l96" href="#l96">96</a><td> var em = getNamespaceId(doc, 'http://www.mozilla.org/2004/em-rdf#');<tr><td><a name="l97" href="#l97">97</a><td> var rdf = getNamespaceId(<tr><td><a name="l98" href="#l98">98</a><td> doc, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');<tr><td><a name="l99" href="#l99">99</a><td><tr><td><a name="l100" href="#l100">100</a><td> var description = doc[rdf + 'RDF'][rdf + 'Description'][0];<tr><td><a name="l101" href="#l101">101</a><td> var details = {<tr><td><a name="l102" href="#l102">102</a><td> id: getNodeText(description, em + 'id'),<tr><td><a name="l103" href="#l103">103</a><td> name: getNodeText(description, em + 'name'),<tr><td><a name="l104" href="#l104">104</a><td> version: getNodeText(description, em + 'version'),<tr><td><a name="l105" href="#l105">105</a><td> unpack: getNodeText(description, em + 'unpack') || false<tr><td><a name="l106" href="#l106">106</a><td> };<tr><td><a name="l107" href="#l107">107</a><td><tr><td><a name="l108" href="#l108">108</a><td> if (typeof details.unpack === 'string') {<tr><td><a name="l109" href="#l109">109</a><td> details.unpack = details.unpack.toLowerCase() === 'true';<tr><td><a name="l110" href="#l110">110</a><td> }<tr><td><a name="l111" href="#l111">111</a><td><tr><td><a name="l112" href="#l112">112</a><td> if (!details.id) {<tr><td><a name="l113" href="#l113">113</a><td> throw new AddonFormatError('Could not find add-on ID for ' + addonPath);<tr><td><a name="l114" href="#l114">114</a><td> }<tr><td><a name="l115" href="#l115">115</a><td><tr><td><a name="l116" href="#l116">116</a><td> return details;<tr><td><a name="l117" href="#l117">117</a><td> });<tr><td><a name="l118" href="#l118">118</a><td><tr><td><a name="l119" href="#l119">119</a><td> function getNodeText(node, name) {<tr><td><a name="l120" href="#l120">120</a><td> return node[name] && node[name][0] || '';<tr><td><a name="l121" href="#l121">121</a><td> }<tr><td><a name="l122" href="#l122">122</a><td><tr><td><a name="l123" href="#l123">123</a><td> function getNamespaceId(doc, url) {<tr><td><a name="l124" href="#l124">124</a><td> var keys = Object.keys(doc);<tr><td><a name="l125" href="#l125">125</a><td> if (keys.length !== 1) {<tr><td><a name="l126" href="#l126">126</a><td> throw new AddonFormatError('Malformed manifest for add-on ' + addonPath);<tr><td><a name="l127" href="#l127">127</a><td> }<tr><td><a name="l128" href="#l128">128</a><td><tr><td><a name="l129" href="#l129">129</a><td> var namespaces = doc[keys[0]].$;<tr><td><a name="l130" href="#l130">130</a><td> var id = '';<tr><td><a name="l131" href="#l131">131</a><td> Object.keys(namespaces).some(function(ns) {<tr><td><a name="l132" href="#l132">132</a><td> if (namespaces[ns] !== url) {<tr><td><a name="l133" href="#l133">133</a><td> return false;<tr><td><a name="l134" href="#l134">134</a><td> }<tr><td><a name="l135" href="#l135">135</a><td><tr><td><a name="l136" href="#l136">136</a><td> if (ns.indexOf(':') != -1) {<tr><td><a name="l137" href="#l137">137</a><td> id = ns.split(':')[1] + ':';<tr><td><a name="l138" href="#l138">138</a><td> }<tr><td><a name="l139" href="#l139">139</a><td> return true;<tr><td><a name="l140" href="#l140">140</a><td> });<tr><td><a name="l141" href="#l141">141</a><td> return id;<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><tr><td><a name="l146" href="#l146">146</a><td>/**<tr><td><a name="l147" href="#l147">147</a><td> * Reads the manifest for a Firefox add-on.<tr><td><a name="l148" href="#l148">148</a><td> * @param {string} addonPath Path to a Firefox add-on as a xpi or an extension.<tr><td><a name="l149" href="#l149">149</a><td> * @return {!promise.Promise.<!Object>} A promise for the parsed manifest.<tr><td><a name="l150" href="#l150">150</a><td> */<tr><td><a name="l151" href="#l151">151</a><td>function readManifest(addonPath) {<tr><td><a name="l152" href="#l152">152</a><td> var manifest;<tr><td><a name="l153" href="#l153">153</a><td><tr><td><a name="l154" href="#l154">154</a><td> if (addonPath.slice(-4) === '.xpi') {<tr><td><a name="l155" href="#l155">155</a><td> manifest = checkedCall(fs.readFile, addonPath).then(function(buff) {<tr><td><a name="l156" href="#l156">156</a><td> var zip = new AdmZip(buff);<tr><td><a name="l157" href="#l157">157</a><td> if (!zip.getEntry('install.rdf')) {<tr><td><a name="l158" href="#l158">158</a><td> throw new AddonFormatError(<tr><td><a name="l159" href="#l159">159</a><td> 'Could not find install.rdf in ' + addonPath);<tr><td><a name="l160" href="#l160">160</a><td> }<tr><td><a name="l161" href="#l161">161</a><td> var done = promise.defer();<tr><td><a name="l162" href="#l162">162</a><td> zip.readAsTextAsync('install.rdf', done.fulfill);<tr><td><a name="l163" href="#l163">163</a><td> return done.promise;<tr><td><a name="l164" href="#l164">164</a><td> });<tr><td><a name="l165" href="#l165">165</a><td> } else {<tr><td><a name="l166" href="#l166">166</a><td> manifest = checkedCall(fs.stat, addonPath).then(function(stats) {<tr><td><a name="l167" href="#l167">167</a><td> if (!stats.isDirectory()) {<tr><td><a name="l168" href="#l168">168</a><td> throw Error(<tr><td><a name="l169" href="#l169">169</a><td> 'Add-on path is niether a xpi nor a directory: ' + addonPath);<tr><td><a name="l170" href="#l170">170</a><td> }<tr><td><a name="l171" href="#l171">171</a><td> return checkedCall(fs.readFile, path.join(addonPath, 'install.rdf'));<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> return manifest.then(function(content) {<tr><td><a name="l176" href="#l176">176</a><td> return checkedCall(xml.parseString, content);<tr><td><a name="l177" href="#l177">177</a><td> });<tr><td><a name="l178" href="#l178">178</a><td>}<tr><td><a name="l179" href="#l179">179</a><td><tr><td><a name="l180" href="#l180">180</a><td><tr><td><a name="l181" href="#l181">181</a><td>// PUBLIC API<tr><td><a name="l182" href="#l182">182</a><td><tr><td><a name="l183" href="#l183">183</a><td><tr><td><a name="l184" href="#l184">184</a><td>exports.install = install;</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>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>firefox/index.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2014 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2014 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 url = require('url'),<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 Binary = require('./binary').Binary,<tr><td><a name="l22" href="#l22">22</a><td> Profile = require('./profile').Profile,<tr><td><a name="l23" href="#l23">23</a><td> decodeProfile = require('./profile').decode,<tr><td><a name="l24" href="#l24">24</a><td> webdriver = require('..'),<tr><td><a name="l25" href="#l25">25</a><td> executors = require('../executors'),<tr><td><a name="l26" href="#l26">26</a><td> httpUtil = require('../http/util'),<tr><td><a name="l27" href="#l27">27</a><td> net = require('../net'),<tr><td><a name="l28" href="#l28">28</a><td> portprober = require('../net/portprober');<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> * Configuration options for the FirefoxDriver.<tr><td><a name="l33" href="#l33">33</a><td> * @constructor<tr><td><a name="l34" href="#l34">34</a><td> */<tr><td><a name="l35" href="#l35">35</a><td>var Options = function() {<tr><td><a name="l36" href="#l36">36</a><td> /** @private {Profile} */<tr><td><a name="l37" href="#l37">37</a><td> this.profile_ = null;<tr><td><a name="l38" href="#l38">38</a><td><tr><td><a name="l39" href="#l39">39</a><td> /** @private {Binary} */<tr><td><a name="l40" href="#l40">40</a><td> this.binary_ = null;<tr><td><a name="l41" href="#l41">41</a><td><tr><td><a name="l42" href="#l42">42</a><td> /** @private {webdriver.logging.Preferences} */<tr><td><a name="l43" href="#l43">43</a><td> this.logPrefs_ = null;<tr><td><a name="l44" href="#l44">44</a><td><tr><td><a name="l45" href="#l45">45</a><td> /** @private {webdriver.ProxyConfig} */<tr><td><a name="l46" href="#l46">46</a><td> this.proxy_ = null;<tr><td><a name="l47" href="#l47">47</a><td>};<tr><td><a name="l48" href="#l48">48</a><td><tr><td><a name="l49" href="#l49">49</a><td><tr><td><a name="l50" href="#l50">50</a><td>/**<tr><td><a name="l51" href="#l51">51</a><td> * Sets the profile to use. The profile may be specified as a<tr><td><a name="l52" href="#l52">52</a><td> * {@link Profile} object or as the path to an existing Firefox profile to use<tr><td><a name="l53" href="#l53">53</a><td> * as a template.<tr><td><a name="l54" href="#l54">54</a><td> *<tr><td><a name="l55" href="#l55">55</a><td> * @param {(string|!Profile)} profile The profile to use.<tr><td><a name="l56" href="#l56">56</a><td> * @return {!Options} A self reference.<tr><td><a name="l57" href="#l57">57</a><td> */<tr><td><a name="l58" href="#l58">58</a><td>Options.prototype.setProfile = function(profile) {<tr><td><a name="l59" href="#l59">59</a><td> if (typeof profile === 'string') {<tr><td><a name="l60" href="#l60">60</a><td> profile = new Profile(profile);<tr><td><a name="l61" href="#l61">61</a><td> }<tr><td><a name="l62" href="#l62">62</a><td> this.profile_ = profile;<tr><td><a name="l63" href="#l63">63</a><td> return this;<tr><td><a name="l64" href="#l64">64</a><td>};<tr><td><a name="l65" href="#l65">65</a><td><tr><td><a name="l66" href="#l66">66</a><td><tr><td><a name="l67" href="#l67">67</a><td>/**<tr><td><a name="l68" href="#l68">68</a><td> * Sets the binary to use. The binary may be specified as the path to a Firefox<tr><td><a name="l69" href="#l69">69</a><td> * executable, or as a {@link Binary} object.<tr><td><a name="l70" href="#l70">70</a><td> *<tr><td><a name="l71" href="#l71">71</a><td> * @param {(string|!Binary)} binary The binary to use.<tr><td><a name="l72" href="#l72">72</a><td> * @return {!Options} A self reference.<tr><td><a name="l73" href="#l73">73</a><td> */<tr><td><a name="l74" href="#l74">74</a><td>Options.prototype.setBinary = function(binary) {<tr><td><a name="l75" href="#l75">75</a><td> if (typeof binary === 'string') {<tr><td><a name="l76" href="#l76">76</a><td> binary = new Binary(binary);<tr><td><a name="l77" href="#l77">77</a><td> }<tr><td><a name="l78" href="#l78">78</a><td> this.binary_ = binary;<tr><td><a name="l79" href="#l79">79</a><td> return this;<tr><td><a name="l80" href="#l80">80</a><td>};<tr><td><a name="l81" href="#l81">81</a><td><tr><td><a name="l82" href="#l82">82</a><td><tr><td><a name="l83" href="#l83">83</a><td>/**<tr><td><a name="l84" href="#l84">84</a><td> * Sets the logging preferences for the new session.<tr><td><a name="l85" href="#l85">85</a><td> * @param {webdriver.logging.Preferences} prefs The logging preferences.<tr><td><a name="l86" href="#l86">86</a><td> * @return {!Options} A self reference.<tr><td><a name="l87" href="#l87">87</a><td> */<tr><td><a name="l88" href="#l88">88</a><td>Options.prototype.setLoggingPreferences = function(prefs) {<tr><td><a name="l89" href="#l89">89</a><td> this.logPrefs_ = prefs;<tr><td><a name="l90" href="#l90">90</a><td> return this;<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> * Sets the proxy to use.<tr><td><a name="l96" href="#l96">96</a><td> *<tr><td><a name="l97" href="#l97">97</a><td> * @param {webdriver.ProxyConfig} proxy The proxy configuration to use.<tr><td><a name="l98" href="#l98">98</a><td> * @return {!Options} A self reference.<tr><td><a name="l99" href="#l99">99</a><td> */<tr><td><a name="l100" href="#l100">100</a><td>Options.prototype.setProxy = function(proxy) {<tr><td><a name="l101" href="#l101">101</a><td> this.proxy_ = proxy;<tr><td><a name="l102" href="#l102">102</a><td> return this;<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> * Converts these options to a {@link webdriver.Capabilities} instance.<tr><td><a name="l108" href="#l108">108</a><td> *<tr><td><a name="l109" href="#l109">109</a><td> * @return {!webdriver.Capabilities} A new capabilities object.<tr><td><a name="l110" href="#l110">110</a><td> */<tr><td><a name="l111" href="#l111">111</a><td>Options.prototype.toCapabilities = function(opt_remote) {<tr><td><a name="l112" href="#l112">112</a><td> var caps = webdriver.Capabilities.firefox();<tr><td><a name="l113" href="#l113">113</a><td> if (this.logPrefs_) {<tr><td><a name="l114" href="#l114">114</a><td> caps.set(webdriver.Capability.LOGGING_PREFS, this.logPrefs_);<tr><td><a name="l115" href="#l115">115</a><td> }<tr><td><a name="l116" href="#l116">116</a><td> if (this.proxy_) {<tr><td><a name="l117" href="#l117">117</a><td> caps.set(webdriver.Capability.PROXY, this.proxy_);<tr><td><a name="l118" href="#l118">118</a><td> }<tr><td><a name="l119" href="#l119">119</a><td> if (this.binary_) {<tr><td><a name="l120" href="#l120">120</a><td> caps.set('firefox_binary', this.binary_);<tr><td><a name="l121" href="#l121">121</a><td> }<tr><td><a name="l122" href="#l122">122</a><td> if (this.profile_) {<tr><td><a name="l123" href="#l123">123</a><td> caps.set('firefox_profile', this.profile_);<tr><td><a name="l124" href="#l124">124</a><td> }<tr><td><a name="l125" href="#l125">125</a><td> return caps;<tr><td><a name="l126" href="#l126">126</a><td>};<tr><td><a name="l127" href="#l127">127</a><td><tr><td><a name="l128" href="#l128">128</a><td><tr><td><a name="l129" href="#l129">129</a><td>/**<tr><td><a name="l130" href="#l130">130</a><td> * A WebDriver client for Firefox.<tr><td><a name="l131" href="#l131">131</a><td> *<tr><td><a name="l132" href="#l132">132</a><td> * @param {(Options|webdriver.Capabilities|Object)=} opt_config The<tr><td><a name="l133" href="#l133">133</a><td> * configuration options for this driver, specified as either an<tr><td><a name="l134" href="#l134">134</a><td> * {@link Options} or {@link webdriver.Capabilities}, or as a raw hash<tr><td><a name="l135" href="#l135">135</a><td> * object.<tr><td><a name="l136" href="#l136">136</a><td> * @param {webdriver.promise.ControlFlow=} opt_flow The flow to<tr><td><a name="l137" href="#l137">137</a><td> * schedule commands through. Defaults to the active flow object.<tr><td><a name="l138" href="#l138">138</a><td> * @constructor<tr><td><a name="l139" href="#l139">139</a><td> * @extends {webdriver.WebDriver}<tr><td><a name="l140" href="#l140">140</a><td> */<tr><td><a name="l141" href="#l141">141</a><td>var Driver = function(opt_config, opt_flow) {<tr><td><a name="l142" href="#l142">142</a><td> var caps;<tr><td><a name="l143" href="#l143">143</a><td> if (opt_config instanceof Options) {<tr><td><a name="l144" href="#l144">144</a><td> caps = opt_config.toCapabilities();<tr><td><a name="l145" href="#l145">145</a><td> } else {<tr><td><a name="l146" href="#l146">146</a><td> caps = new webdriver.Capabilities(opt_config);<tr><td><a name="l147" href="#l147">147</a><td> }<tr><td><a name="l148" href="#l148">148</a><td><tr><td><a name="l149" href="#l149">149</a><td> var binary = caps.get('firefox_binary') || new Binary();<tr><td><a name="l150" href="#l150">150</a><td> if (typeof binary === 'string') {<tr><td><a name="l151" href="#l151">151</a><td> binary = new Binary(binary);<tr><td><a name="l152" href="#l152">152</a><td> }<tr><td><a name="l153" href="#l153">153</a><td><tr><td><a name="l154" href="#l154">154</a><td> var profile = caps.get('firefox_profile') || new Profile();<tr><td><a name="l155" href="#l155">155</a><td><tr><td><a name="l156" href="#l156">156</a><td> caps.set('firefox_binary', null);<tr><td><a name="l157" href="#l157">157</a><td> caps.set('firefox_profile', null);<tr><td><a name="l158" href="#l158">158</a><td><tr><td><a name="l159" href="#l159">159</a><td> var serverUrl = portprober.findFreePort().then(function(port) {<tr><td><a name="l160" href="#l160">160</a><td> var prepareProfile;<tr><td><a name="l161" href="#l161">161</a><td> if (typeof profile === 'string') {<tr><td><a name="l162" href="#l162">162</a><td> prepareProfile = decodeProfile(profile).then(function(dir) {<tr><td><a name="l163" href="#l163">163</a><td> var profile = new Profile(dir);<tr><td><a name="l164" href="#l164">164</a><td> profile.setPreference('webdriver_firefox_port', port);<tr><td><a name="l165" href="#l165">165</a><td> return profile.writeToDisk();<tr><td><a name="l166" href="#l166">166</a><td> });<tr><td><a name="l167" href="#l167">167</a><td> } else {<tr><td><a name="l168" href="#l168">168</a><td> profile.setPreference('webdriver_firefox_port', port);<tr><td><a name="l169" href="#l169">169</a><td> prepareProfile = profile.writeToDisk();<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> return prepareProfile.then(function(dir) {<tr><td><a name="l173" href="#l173">173</a><td> return binary.launch(dir);<tr><td><a name="l174" href="#l174">174</a><td> }).then(function() {<tr><td><a name="l175" href="#l175">175</a><td> var serverUrl = url.format({<tr><td><a name="l176" href="#l176">176</a><td> protocol: 'http',<tr><td><a name="l177" href="#l177">177</a><td> hostname: net.getLoopbackAddress(),<tr><td><a name="l178" href="#l178">178</a><td> port: port,<tr><td><a name="l179" href="#l179">179</a><td> pathname: '/hub'<tr><td><a name="l180" href="#l180">180</a><td> });<tr><td><a name="l181" href="#l181">181</a><td><tr><td><a name="l182" href="#l182">182</a><td> return httpUtil.waitForServer(serverUrl, 45 * 1000).then(function() {<tr><td><a name="l183" href="#l183">183</a><td> return serverUrl;<tr><td><a name="l184" href="#l184">184</a><td> });<tr><td><a name="l185" href="#l185">185</a><td> });<tr><td><a name="l186" href="#l186">186</a><td> });<tr><td><a name="l187" href="#l187">187</a><td><tr><td><a name="l188" href="#l188">188</a><td> var executor = executors.createExecutor(serverUrl);<tr><td><a name="l189" href="#l189">189</a><td> var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow);<tr><td><a name="l190" href="#l190">190</a><td><tr><td><a name="l191" href="#l191">191</a><td> webdriver.WebDriver.call(this, driver.getSession(), executor, opt_flow);<tr><td><a name="l192" href="#l192">192</a><td>};<tr><td><a name="l193" href="#l193">193</a><td>util.inherits(Driver, webdriver.WebDriver);<tr><td><a name="l194" href="#l194">194</a><td><tr><td><a name="l195" href="#l195">195</a><td><tr><td><a name="l196" href="#l196">196</a><td>// PUBLIC API<tr><td><a name="l197" href="#l197">197</a><td><tr><td><a name="l198" href="#l198">198</a><td><tr><td><a name="l199" href="#l199">199</a><td>exports.Binary = Binary;<tr><td><a name="l200" href="#l200">200</a><td>exports.Driver = Driver;<tr><td><a name="l201" href="#l201">201</a><td>exports.Options = Options;<tr><td><a name="l202" href="#l202">202</a><td>exports.Profile = Profile;</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>firefox/index.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2014 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2014 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 url = require('url'),<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 Binary = require('./binary').Binary,<tr><td><a name="l22" href="#l22">22</a><td> Profile = require('./profile').Profile,<tr><td><a name="l23" href="#l23">23</a><td> decodeProfile = require('./profile').decode,<tr><td><a name="l24" href="#l24">24</a><td> webdriver = require('..'),<tr><td><a name="l25" href="#l25">25</a><td> executors = require('../executors'),<tr><td><a name="l26" href="#l26">26</a><td> httpUtil = require('../http/util'),<tr><td><a name="l27" href="#l27">27</a><td> net = require('../net'),<tr><td><a name="l28" href="#l28">28</a><td> portprober = require('../net/portprober');<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> * Configuration options for the FirefoxDriver.<tr><td><a name="l33" href="#l33">33</a><td> * @constructor<tr><td><a name="l34" href="#l34">34</a><td> */<tr><td><a name="l35" href="#l35">35</a><td>var Options = function() {<tr><td><a name="l36" href="#l36">36</a><td> /** @private {Profile} */<tr><td><a name="l37" href="#l37">37</a><td> this.profile_ = null;<tr><td><a name="l38" href="#l38">38</a><td><tr><td><a name="l39" href="#l39">39</a><td> /** @private {Binary} */<tr><td><a name="l40" href="#l40">40</a><td> this.binary_ = null;<tr><td><a name="l41" href="#l41">41</a><td><tr><td><a name="l42" href="#l42">42</a><td> /** @private {webdriver.logging.Preferences} */<tr><td><a name="l43" href="#l43">43</a><td> this.logPrefs_ = null;<tr><td><a name="l44" href="#l44">44</a><td><tr><td><a name="l45" href="#l45">45</a><td> /** @private {webdriver.ProxyConfig} */<tr><td><a name="l46" href="#l46">46</a><td> this.proxy_ = null;<tr><td><a name="l47" href="#l47">47</a><td>};<tr><td><a name="l48" href="#l48">48</a><td><tr><td><a name="l49" href="#l49">49</a><td><tr><td><a name="l50" href="#l50">50</a><td>/**<tr><td><a name="l51" href="#l51">51</a><td> * Sets the profile to use. The profile may be specified as a<tr><td><a name="l52" href="#l52">52</a><td> * {@link Profile} object or as the path to an existing Firefox profile to use<tr><td><a name="l53" href="#l53">53</a><td> * as a template.<tr><td><a name="l54" href="#l54">54</a><td> *<tr><td><a name="l55" href="#l55">55</a><td> * @param {(string|!Profile)} profile The profile to use.<tr><td><a name="l56" href="#l56">56</a><td> * @return {!Options} A self reference.<tr><td><a name="l57" href="#l57">57</a><td> */<tr><td><a name="l58" href="#l58">58</a><td>Options.prototype.setProfile = function(profile) {<tr><td><a name="l59" href="#l59">59</a><td> if (typeof profile === 'string') {<tr><td><a name="l60" href="#l60">60</a><td> profile = new Profile(profile);<tr><td><a name="l61" href="#l61">61</a><td> }<tr><td><a name="l62" href="#l62">62</a><td> this.profile_ = profile;<tr><td><a name="l63" href="#l63">63</a><td> return this;<tr><td><a name="l64" href="#l64">64</a><td>};<tr><td><a name="l65" href="#l65">65</a><td><tr><td><a name="l66" href="#l66">66</a><td><tr><td><a name="l67" href="#l67">67</a><td>/**<tr><td><a name="l68" href="#l68">68</a><td> * Sets the binary to use. The binary may be specified as the path to a Firefox<tr><td><a name="l69" href="#l69">69</a><td> * executable, or as a {@link Binary} object.<tr><td><a name="l70" href="#l70">70</a><td> *<tr><td><a name="l71" href="#l71">71</a><td> * @param {(string|!Binary)} binary The binary to use.<tr><td><a name="l72" href="#l72">72</a><td> * @return {!Options} A self reference.<tr><td><a name="l73" href="#l73">73</a><td> */<tr><td><a name="l74" href="#l74">74</a><td>Options.prototype.setBinary = function(binary) {<tr><td><a name="l75" href="#l75">75</a><td> if (typeof binary === 'string') {<tr><td><a name="l76" href="#l76">76</a><td> binary = new Binary(binary);<tr><td><a name="l77" href="#l77">77</a><td> }<tr><td><a name="l78" href="#l78">78</a><td> this.binary_ = binary;<tr><td><a name="l79" href="#l79">79</a><td> return this;<tr><td><a name="l80" href="#l80">80</a><td>};<tr><td><a name="l81" href="#l81">81</a><td><tr><td><a name="l82" href="#l82">82</a><td><tr><td><a name="l83" href="#l83">83</a><td>/**<tr><td><a name="l84" href="#l84">84</a><td> * Sets the logging preferences for the new session.<tr><td><a name="l85" href="#l85">85</a><td> * @param {webdriver.logging.Preferences} prefs The logging preferences.<tr><td><a name="l86" href="#l86">86</a><td> * @return {!Options} A self reference.<tr><td><a name="l87" href="#l87">87</a><td> */<tr><td><a name="l88" href="#l88">88</a><td>Options.prototype.setLoggingPreferences = function(prefs) {<tr><td><a name="l89" href="#l89">89</a><td> this.logPrefs_ = prefs;<tr><td><a name="l90" href="#l90">90</a><td> return this;<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> * Sets the proxy to use.<tr><td><a name="l96" href="#l96">96</a><td> *<tr><td><a name="l97" href="#l97">97</a><td> * @param {webdriver.ProxyConfig} proxy The proxy configuration to use.<tr><td><a name="l98" href="#l98">98</a><td> * @return {!Options} A self reference.<tr><td><a name="l99" href="#l99">99</a><td> */<tr><td><a name="l100" href="#l100">100</a><td>Options.prototype.setProxy = function(proxy) {<tr><td><a name="l101" href="#l101">101</a><td> this.proxy_ = proxy;<tr><td><a name="l102" href="#l102">102</a><td> return this;<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> * Converts these options to a {@link webdriver.Capabilities} instance.<tr><td><a name="l108" href="#l108">108</a><td> *<tr><td><a name="l109" href="#l109">109</a><td> * @return {!webdriver.Capabilities} A new capabilities object.<tr><td><a name="l110" href="#l110">110</a><td> */<tr><td><a name="l111" href="#l111">111</a><td>Options.prototype.toCapabilities = function(opt_remote) {<tr><td><a name="l112" href="#l112">112</a><td> var caps = webdriver.Capabilities.firefox();<tr><td><a name="l113" href="#l113">113</a><td> if (this.logPrefs_) {<tr><td><a name="l114" href="#l114">114</a><td> caps.set(webdriver.Capability.LOGGING_PREFS, this.logPrefs_);<tr><td><a name="l115" href="#l115">115</a><td> }<tr><td><a name="l116" href="#l116">116</a><td> if (this.proxy_) {<tr><td><a name="l117" href="#l117">117</a><td> caps.set(webdriver.Capability.PROXY, this.proxy_);<tr><td><a name="l118" href="#l118">118</a><td> }<tr><td><a name="l119" href="#l119">119</a><td> if (this.binary_) {<tr><td><a name="l120" href="#l120">120</a><td> caps.set('firefox_binary', this.binary_);<tr><td><a name="l121" href="#l121">121</a><td> }<tr><td><a name="l122" href="#l122">122</a><td> if (this.profile_) {<tr><td><a name="l123" href="#l123">123</a><td> caps.set('firefox_profile', this.profile_);<tr><td><a name="l124" href="#l124">124</a><td> }<tr><td><a name="l125" href="#l125">125</a><td> return caps;<tr><td><a name="l126" href="#l126">126</a><td>};<tr><td><a name="l127" href="#l127">127</a><td><tr><td><a name="l128" href="#l128">128</a><td><tr><td><a name="l129" href="#l129">129</a><td>/**<tr><td><a name="l130" href="#l130">130</a><td> * A WebDriver client for Firefox.<tr><td><a name="l131" href="#l131">131</a><td> *<tr><td><a name="l132" href="#l132">132</a><td> * @param {(Options|webdriver.Capabilities|Object)=} opt_config The<tr><td><a name="l133" href="#l133">133</a><td> * configuration options for this driver, specified as either an<tr><td><a name="l134" href="#l134">134</a><td> * {@link Options} or {@link webdriver.Capabilities}, or as a raw hash<tr><td><a name="l135" href="#l135">135</a><td> * object.<tr><td><a name="l136" href="#l136">136</a><td> * @param {webdriver.promise.ControlFlow=} opt_flow The flow to<tr><td><a name="l137" href="#l137">137</a><td> * schedule commands through. Defaults to the active flow object.<tr><td><a name="l138" href="#l138">138</a><td> * @constructor<tr><td><a name="l139" href="#l139">139</a><td> * @extends {webdriver.WebDriver}<tr><td><a name="l140" href="#l140">140</a><td> */<tr><td><a name="l141" href="#l141">141</a><td>var Driver = function(opt_config, opt_flow) {<tr><td><a name="l142" href="#l142">142</a><td> var caps;<tr><td><a name="l143" href="#l143">143</a><td> if (opt_config instanceof Options) {<tr><td><a name="l144" href="#l144">144</a><td> caps = opt_config.toCapabilities();<tr><td><a name="l145" href="#l145">145</a><td> } else {<tr><td><a name="l146" href="#l146">146</a><td> caps = new webdriver.Capabilities(opt_config);<tr><td><a name="l147" href="#l147">147</a><td> }<tr><td><a name="l148" href="#l148">148</a><td><tr><td><a name="l149" href="#l149">149</a><td> var binary = caps.get('firefox_binary') || new Binary();<tr><td><a name="l150" href="#l150">150</a><td> if (typeof binary === 'string') {<tr><td><a name="l151" href="#l151">151</a><td> binary = new Binary(binary);<tr><td><a name="l152" href="#l152">152</a><td> }<tr><td><a name="l153" href="#l153">153</a><td><tr><td><a name="l154" href="#l154">154</a><td> var profile = caps.get('firefox_profile') || new Profile();<tr><td><a name="l155" href="#l155">155</a><td><tr><td><a name="l156" href="#l156">156</a><td> caps.set('firefox_binary', null);<tr><td><a name="l157" href="#l157">157</a><td> caps.set('firefox_profile', null);<tr><td><a name="l158" href="#l158">158</a><td><tr><td><a name="l159" href="#l159">159</a><td> var serverUrl = portprober.findFreePort().then(function(port) {<tr><td><a name="l160" href="#l160">160</a><td> var prepareProfile;<tr><td><a name="l161" href="#l161">161</a><td> if (typeof profile === 'string') {<tr><td><a name="l162" href="#l162">162</a><td> prepareProfile = decodeProfile(profile).then(function(dir) {<tr><td><a name="l163" href="#l163">163</a><td> var profile = new Profile(dir);<tr><td><a name="l164" href="#l164">164</a><td> profile.setPreference('webdriver_firefox_port', port);<tr><td><a name="l165" href="#l165">165</a><td> return profile.writeToDisk();<tr><td><a name="l166" href="#l166">166</a><td> });<tr><td><a name="l167" href="#l167">167</a><td> } else {<tr><td><a name="l168" href="#l168">168</a><td> profile.setPreference('webdriver_firefox_port', port);<tr><td><a name="l169" href="#l169">169</a><td> prepareProfile = profile.writeToDisk();<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> return prepareProfile.then(function(dir) {<tr><td><a name="l173" href="#l173">173</a><td> return binary.launch(dir);<tr><td><a name="l174" href="#l174">174</a><td> }).then(function() {<tr><td><a name="l175" href="#l175">175</a><td> var serverUrl = url.format({<tr><td><a name="l176" href="#l176">176</a><td> protocol: 'http',<tr><td><a name="l177" href="#l177">177</a><td> hostname: net.getLoopbackAddress(),<tr><td><a name="l178" href="#l178">178</a><td> port: port,<tr><td><a name="l179" href="#l179">179</a><td> pathname: '/hub'<tr><td><a name="l180" href="#l180">180</a><td> });<tr><td><a name="l181" href="#l181">181</a><td><tr><td><a name="l182" href="#l182">182</a><td> return httpUtil.waitForServer(serverUrl, 45 * 1000).then(function() {<tr><td><a name="l183" href="#l183">183</a><td> return serverUrl;<tr><td><a name="l184" href="#l184">184</a><td> });<tr><td><a name="l185" href="#l185">185</a><td> });<tr><td><a name="l186" href="#l186">186</a><td> });<tr><td><a name="l187" href="#l187">187</a><td><tr><td><a name="l188" href="#l188">188</a><td> var executor = executors.createExecutor(serverUrl);<tr><td><a name="l189" href="#l189">189</a><td> var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow);<tr><td><a name="l190" href="#l190">190</a><td><tr><td><a name="l191" href="#l191">191</a><td> webdriver.WebDriver.call(this, driver.getSession(), executor, opt_flow);<tr><td><a name="l192" href="#l192">192</a><td>};<tr><td><a name="l193" href="#l193">193</a><td>util.inherits(Driver, webdriver.WebDriver);<tr><td><a name="l194" href="#l194">194</a><td><tr><td><a name="l195" href="#l195">195</a><td><tr><td><a name="l196" href="#l196">196</a><td>// PUBLIC API<tr><td><a name="l197" href="#l197">197</a><td><tr><td><a name="l198" href="#l198">198</a><td><tr><td><a name="l199" href="#l199">199</a><td>exports.Binary = Binary;<tr><td><a name="l200" href="#l200">200</a><td>exports.Driver = Driver;<tr><td><a name="l201" href="#l201">201</a><td>exports.Options = Options;<tr><td><a name="l202" href="#l202">202</a><td>exports.Profile = Profile;</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>profile.js</title><link href="../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>firefox/profile.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2014 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2014 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 AdmZip = require('adm-zip'),<tr><td><a name="l19" href="#l19">19</a><td> fs = require('fs'),<tr><td><a name="l20" href="#l20">20</a><td> path = require('path'),<tr><td><a name="l21" href="#l21">21</a><td> vm = require('vm');<tr><td><a name="l22" href="#l22">22</a><td><tr><td><a name="l23" href="#l23">23</a><td>var promise = require('..').promise,<tr><td><a name="l24" href="#l24">24</a><td> _base = require('../_base'),<tr><td><a name="l25" href="#l25">25</a><td> io = require('../io'),<tr><td><a name="l26" href="#l26">26</a><td> extension = require('./extension');<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>/** @const */<tr><td><a name="l30" href="#l30">30</a><td>var WEBDRIVER_PREFERENCES_PATH = _base.isDevMode()<tr><td><a name="l31" href="#l31">31</a><td> ? path.join(__dirname, '../../../firefox-driver/webdriver.json')<tr><td><a name="l32" href="#l32">32</a><td> : path.join(__dirname, '../lib/firefox/webdriver.json');<tr><td><a name="l33" href="#l33">33</a><td><tr><td><a name="l34" href="#l34">34</a><td>/** @const */<tr><td><a name="l35" href="#l35">35</a><td>var WEBDRIVER_EXTENSION_PATH = _base.isDevMode()<tr><td><a name="l36" href="#l36">36</a><td> ? path.join(__dirname,<tr><td><a name="l37" href="#l37">37</a><td> '../../../../build/javascript/firefox-driver/webdriver.xpi')<tr><td><a name="l38" href="#l38">38</a><td> : path.join(__dirname, '../lib/firefox/webdriver.xpi');<tr><td><a name="l39" href="#l39">39</a><td><tr><td><a name="l40" href="#l40">40</a><td>/** @const */<tr><td><a name="l41" href="#l41">41</a><td>var WEBDRIVER_EXTENSION_NAME = 'fxdriver@googlecode.com';<tr><td><a name="l42" href="#l42">42</a><td><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>/** @type {Object} */<tr><td><a name="l46" href="#l46">46</a><td>var defaultPreferences = null;<tr><td><a name="l47" href="#l47">47</a><td><tr><td><a name="l48" href="#l48">48</a><td>/**<tr><td><a name="l49" href="#l49">49</a><td> * Synchronously loads the default preferences used for the FirefoxDriver.<tr><td><a name="l50" href="#l50">50</a><td> * @return {!Object} The default preferences JSON object.<tr><td><a name="l51" href="#l51">51</a><td> */<tr><td><a name="l52" href="#l52">52</a><td>function getDefaultPreferences() {<tr><td><a name="l53" href="#l53">53</a><td> if (!defaultPreferences) {<tr><td><a name="l54" href="#l54">54</a><td> var contents = fs.readFileSync(WEBDRIVER_PREFERENCES_PATH, 'utf8');<tr><td><a name="l55" href="#l55">55</a><td> defaultPreferences = JSON.parse(contents);<tr><td><a name="l56" href="#l56">56</a><td> }<tr><td><a name="l57" href="#l57">57</a><td> return defaultPreferences;<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>/**<tr><td><a name="l62" href="#l62">62</a><td> * Parses a user.js file in a Firefox profile directory.<tr><td><a name="l63" href="#l63">63</a><td> * @param {string} f Path to the file to parse.<tr><td><a name="l64" href="#l64">64</a><td> * @return {!promise.Promise.<!Object>} A promise for the parsed preferences as<tr><td><a name="l65" href="#l65">65</a><td> * a JSON object. If the file does not exist, an empty object will be<tr><td><a name="l66" href="#l66">66</a><td> * returned.<tr><td><a name="l67" href="#l67">67</a><td> */<tr><td><a name="l68" href="#l68">68</a><td>function loadUserPrefs(f) {<tr><td><a name="l69" href="#l69">69</a><td> var done = promise.defer();<tr><td><a name="l70" href="#l70">70</a><td> fs.readFile(f, function(err, contents) {<tr><td><a name="l71" href="#l71">71</a><td> if (err && err.code === 'ENOENT') {<tr><td><a name="l72" href="#l72">72</a><td> done.fulfill({});<tr><td><a name="l73" href="#l73">73</a><td> return;<tr><td><a name="l74" href="#l74">74</a><td> }<tr><td><a name="l75" href="#l75">75</a><td><tr><td><a name="l76" href="#l76">76</a><td> if (err) {<tr><td><a name="l77" href="#l77">77</a><td> done.reject(err);<tr><td><a name="l78" href="#l78">78</a><td> return;<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> var prefs = {};<tr><td><a name="l82" href="#l82">82</a><td> var context = vm.createContext({<tr><td><a name="l83" href="#l83">83</a><td> 'user_pref': function(key, value) {<tr><td><a name="l84" href="#l84">84</a><td> prefs[key] = value;<tr><td><a name="l85" href="#l85">85</a><td> }<tr><td><a name="l86" href="#l86">86</a><td> });<tr><td><a name="l87" href="#l87">87</a><td><tr><td><a name="l88" href="#l88">88</a><td> vm.runInContext(contents, context, f);<tr><td><a name="l89" href="#l89">89</a><td> done.fulfill(prefs);<tr><td><a name="l90" href="#l90">90</a><td> });<tr><td><a name="l91" href="#l91">91</a><td> return done.promise;<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>/**<tr><td><a name="l96" href="#l96">96</a><td> * Copies the properties of one object into another.<tr><td><a name="l97" href="#l97">97</a><td> * @param {!Object} a The destination object.<tr><td><a name="l98" href="#l98">98</a><td> * @param {!Object} b The source object to apply as a mixin.<tr><td><a name="l99" href="#l99">99</a><td> */<tr><td><a name="l100" href="#l100">100</a><td>function mixin(a, b) {<tr><td><a name="l101" href="#l101">101</a><td> Object.keys(b).forEach(function(key) {<tr><td><a name="l102" href="#l102">102</a><td> a[key] = b[key];<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>/**<tr><td><a name="l108" href="#l108">108</a><td> * @param {!Object} defaults The default preferences to write. Will be<tr><td><a name="l109" href="#l109">109</a><td> * overridden by user.js preferences in the template directory and the<tr><td><a name="l110" href="#l110">110</a><td> * frozen preferences required by WebDriver.<tr><td><a name="l111" href="#l111">111</a><td> * @param {string} dir Path to the directory write the file to.<tr><td><a name="l112" href="#l112">112</a><td> * @return {!promise.Promise.<string>} A promise for the profile directory,<tr><td><a name="l113" href="#l113">113</a><td> * to be fulfilled when user preferences have been written.<tr><td><a name="l114" href="#l114">114</a><td> */<tr><td><a name="l115" href="#l115">115</a><td>function writeUserPrefs(prefs, dir) {<tr><td><a name="l116" href="#l116">116</a><td> var userPrefs = path.join(dir, 'user.js');<tr><td><a name="l117" href="#l117">117</a><td> return loadUserPrefs(userPrefs).then(function(overrides) {<tr><td><a name="l118" href="#l118">118</a><td> mixin(prefs, overrides);<tr><td><a name="l119" href="#l119">119</a><td> mixin(prefs, getDefaultPreferences()['frozen']);<tr><td><a name="l120" href="#l120">120</a><td><tr><td><a name="l121" href="#l121">121</a><td> var contents = Object.keys(prefs).map(function(key) {<tr><td><a name="l122" href="#l122">122</a><td> return 'user_pref(' + JSON.stringify(key) + ', ' +<tr><td><a name="l123" href="#l123">123</a><td> JSON.stringify(prefs[key]) + ');';<tr><td><a name="l124" href="#l124">124</a><td> }).join('\n');<tr><td><a name="l125" href="#l125">125</a><td><tr><td><a name="l126" href="#l126">126</a><td> var done = promise.defer();<tr><td><a name="l127" href="#l127">127</a><td> fs.writeFile(userPrefs, contents, function(err) {<tr><td><a name="l128" href="#l128">128</a><td> err && done.reject(err) || done.fulfill(dir);<tr><td><a name="l129" href="#l129">129</a><td> });<tr><td><a name="l130" href="#l130">130</a><td> return done.promise;<tr><td><a name="l131" href="#l131">131</a><td> });<tr><td><a name="l132" href="#l132">132</a><td>};<tr><td><a name="l133" href="#l133">133</a><td><tr><td><a name="l134" href="#l134">134</a><td><tr><td><a name="l135" href="#l135">135</a><td>/**<tr><td><a name="l136" href="#l136">136</a><td> * Installs a group of extensions in the given profile directory. If the<tr><td><a name="l137" href="#l137">137</a><td> * WebDriver extension is not included in this set, the default version<tr><td><a name="l138" href="#l138">138</a><td> * bundled with this package will be installed.<tr><td><a name="l139" href="#l139">139</a><td> * @param {!Array.<string>} extensions The extensions to install, as a<tr><td><a name="l140" href="#l140">140</a><td> * path to an unpacked extension directory or a path to a xpi file.<tr><td><a name="l141" href="#l141">141</a><td> * @param {string} dir The profile directory to install to.<tr><td><a name="l142" href="#l142">142</a><td> * @param {boolean=} opt_excludeWebDriverExt Whether to skip installation of<tr><td><a name="l143" href="#l143">143</a><td> * the default WebDriver extension.<tr><td><a name="l144" href="#l144">144</a><td> * @return {!promise.Promise.<string>} A promise for the main profile directory<tr><td><a name="l145" href="#l145">145</a><td> * once all extensions have been installed.<tr><td><a name="l146" href="#l146">146</a><td> */<tr><td><a name="l147" href="#l147">147</a><td>function installExtensions(extensions, dir, opt_excludeWebDriverExt) {<tr><td><a name="l148" href="#l148">148</a><td> var hasWebDriver = !!opt_excludeWebDriverExt;<tr><td><a name="l149" href="#l149">149</a><td> var next = 0;<tr><td><a name="l150" href="#l150">150</a><td> var extensionDir = path.join(dir, 'extensions');<tr><td><a name="l151" href="#l151">151</a><td> var done = promise.defer();<tr><td><a name="l152" href="#l152">152</a><td><tr><td><a name="l153" href="#l153">153</a><td> return io.exists(extensionDir).then(function(exists) {<tr><td><a name="l154" href="#l154">154</a><td> if (!exists) {<tr><td><a name="l155" href="#l155">155</a><td> return promise.checkedNodeCall(fs.mkdir, extensionDir);<tr><td><a name="l156" href="#l156">156</a><td> }<tr><td><a name="l157" href="#l157">157</a><td> }).then(function() {<tr><td><a name="l158" href="#l158">158</a><td> installNext();<tr><td><a name="l159" href="#l159">159</a><td> return done.promise;<tr><td><a name="l160" href="#l160">160</a><td> });<tr><td><a name="l161" href="#l161">161</a><td><tr><td><a name="l162" href="#l162">162</a><td> function installNext() {<tr><td><a name="l163" href="#l163">163</a><td> if (!done.isPending()) {<tr><td><a name="l164" href="#l164">164</a><td> return;<tr><td><a name="l165" href="#l165">165</a><td> }<tr><td><a name="l166" href="#l166">166</a><td><tr><td><a name="l167" href="#l167">167</a><td> if (next >= extensions.length) {<tr><td><a name="l168" href="#l168">168</a><td> if (hasWebDriver) {<tr><td><a name="l169" href="#l169">169</a><td> done.fulfill(dir);<tr><td><a name="l170" href="#l170">170</a><td> } else {<tr><td><a name="l171" href="#l171">171</a><td> install(WEBDRIVER_EXTENSION_PATH);<tr><td><a name="l172" href="#l172">172</a><td> }<tr><td><a name="l173" href="#l173">173</a><td> } else {<tr><td><a name="l174" href="#l174">174</a><td> install(extensions[next++]);<tr><td><a name="l175" href="#l175">175</a><td> }<tr><td><a name="l176" href="#l176">176</a><td> }<tr><td><a name="l177" href="#l177">177</a><td><tr><td><a name="l178" href="#l178">178</a><td> function install(ext) {<tr><td><a name="l179" href="#l179">179</a><td> extension.install(ext, extensionDir).then(function(id) {<tr><td><a name="l180" href="#l180">180</a><td> hasWebDriver = hasWebDriver || (id === WEBDRIVER_EXTENSION_NAME);<tr><td><a name="l181" href="#l181">181</a><td> installNext();<tr><td><a name="l182" href="#l182">182</a><td> }, done.reject);<tr><td><a name="l183" href="#l183">183</a><td> }<tr><td><a name="l184" href="#l184">184</a><td>}<tr><td><a name="l185" href="#l185">185</a><td><tr><td><a name="l186" href="#l186">186</a><td><tr><td><a name="l187" href="#l187">187</a><td>/**<tr><td><a name="l188" href="#l188">188</a><td> * Decodes a base64 encoded profile.<tr><td><a name="l189" href="#l189">189</a><td> * @param {string} data The base64 encoded string.<tr><td><a name="l190" href="#l190">190</a><td> * @return {!promise.Promise.<string>} A promise for the path to the decoded<tr><td><a name="l191" href="#l191">191</a><td> * profile directory.<tr><td><a name="l192" href="#l192">192</a><td> */<tr><td><a name="l193" href="#l193">193</a><td>function decode(data) {<tr><td><a name="l194" href="#l194">194</a><td> return io.tmpFile().then(function(file) {<tr><td><a name="l195" href="#l195">195</a><td> var buf = new Buffer(data, 'base64');<tr><td><a name="l196" href="#l196">196</a><td> return promise.checkedNodeCall(fs.writeFile, file, buf).then(function() {<tr><td><a name="l197" href="#l197">197</a><td> return io.tmpDir();<tr><td><a name="l198" href="#l198">198</a><td> }).then(function(dir) {<tr><td><a name="l199" href="#l199">199</a><td> var zip = new AdmZip(file);<tr><td><a name="l200" href="#l200">200</a><td> zip.extractAllTo(dir); // Sync only? Why?? :-(<tr><td><a name="l201" href="#l201">201</a><td> return dir;<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> * Models a Firefox proifle directory for use with the FirefoxDriver. The<tr><td><a name="l210" href="#l210">210</a><td> * {@code Proifle} directory uses an in-memory model until {@link #writeToDisk}<tr><td><a name="l211" href="#l211">211</a><td> * is called.<tr><td><a name="l212" href="#l212">212</a><td> * @param {string=} opt_dir Path to an existing Firefox profile directory to<tr><td><a name="l213" href="#l213">213</a><td> * use a template for this profile. If not specified, a blank profile will<tr><td><a name="l214" href="#l214">214</a><td> * be used.<tr><td><a name="l215" href="#l215">215</a><td> * @constructor<tr><td><a name="l216" href="#l216">216</a><td> */<tr><td><a name="l217" href="#l217">217</a><td>var Profile = function(opt_dir) {<tr><td><a name="l218" href="#l218">218</a><td> /** @private {!Object} */<tr><td><a name="l219" href="#l219">219</a><td> this.preferences_ = {};<tr><td><a name="l220" href="#l220">220</a><td><tr><td><a name="l221" href="#l221">221</a><td> mixin(this.preferences_, getDefaultPreferences()['mutable']);<tr><td><a name="l222" href="#l222">222</a><td> mixin(this.preferences_, getDefaultPreferences()['frozen']);<tr><td><a name="l223" href="#l223">223</a><td><tr><td><a name="l224" href="#l224">224</a><td> /** @private {boolean} */<tr><td><a name="l225" href="#l225">225</a><td> this.nativeEventsEnabled_ = true;<tr><td><a name="l226" href="#l226">226</a><td><tr><td><a name="l227" href="#l227">227</a><td> /** @private {(string|undefined)} */<tr><td><a name="l228" href="#l228">228</a><td> this.template_ = opt_dir;<tr><td><a name="l229" href="#l229">229</a><td><tr><td><a name="l230" href="#l230">230</a><td> /** @private {number} */<tr><td><a name="l231" href="#l231">231</a><td> this.port_ = 0;<tr><td><a name="l232" href="#l232">232</a><td><tr><td><a name="l233" href="#l233">233</a><td> /** @private {!Array.<string>} */<tr><td><a name="l234" href="#l234">234</a><td> this.extensions_ = [];<tr><td><a name="l235" href="#l235">235</a><td>};<tr><td><a name="l236" href="#l236">236</a><td><tr><td><a name="l237" href="#l237">237</a><td><tr><td><a name="l238" href="#l238">238</a><td>/**<tr><td><a name="l239" href="#l239">239</a><td> * Registers an extension to be included with this profile.<tr><td><a name="l240" href="#l240">240</a><td> * @param {string} extension Path to the extension to include, as either an<tr><td><a name="l241" href="#l241">241</a><td> * unpacked extension directory or the path to a xpi file.<tr><td><a name="l242" href="#l242">242</a><td> */<tr><td><a name="l243" href="#l243">243</a><td>Profile.prototype.addExtension = function(extension) {<tr><td><a name="l244" href="#l244">244</a><td> this.extensions_.push(extension);<tr><td><a name="l245" href="#l245">245</a><td>};<tr><td><a name="l246" href="#l246">246</a><td><tr><td><a name="l247" href="#l247">247</a><td><tr><td><a name="l248" href="#l248">248</a><td>/**<tr><td><a name="l249" href="#l249">249</a><td> * Sets a desired preference for this profile.<tr><td><a name="l250" href="#l250">250</a><td> * @param {string} key The preference key.<tr><td><a name="l251" href="#l251">251</a><td> * @param {(string|number|boolean)} value The preference value.<tr><td><a name="l252" href="#l252">252</a><td> * @throws {Error} If attempting to set a frozen preference.<tr><td><a name="l253" href="#l253">253</a><td> */<tr><td><a name="l254" href="#l254">254</a><td>Profile.prototype.setPreference = function(key, value) {<tr><td><a name="l255" href="#l255">255</a><td> var frozen = getDefaultPreferences()['frozen'];<tr><td><a name="l256" href="#l256">256</a><td> if (frozen.hasOwnProperty(key) && frozen[key] !== value) {<tr><td><a name="l257" href="#l257">257</a><td> throw Error('You may not set ' + key + '=' + JSON.stringify(value)<tr><td><a name="l258" href="#l258">258</a><td> + '; value is frozen for proper WebDriver functionality ('<tr><td><a name="l259" href="#l259">259</a><td> + key + '=' + JSON.stringify(frozen[key]) + ')');<tr><td><a name="l260" href="#l260">260</a><td> }<tr><td><a name="l261" href="#l261">261</a><td> this.preferences_[key] = value;<tr><td><a name="l262" href="#l262">262</a><td>};<tr><td><a name="l263" href="#l263">263</a><td><tr><td><a name="l264" href="#l264">264</a><td><tr><td><a name="l265" href="#l265">265</a><td>/**<tr><td><a name="l266" href="#l266">266</a><td> * Returns the currently configured value of a profile preference. This does<tr><td><a name="l267" href="#l267">267</a><td> * not include any defaults defined in the profile's template directory user.js<tr><td><a name="l268" href="#l268">268</a><td> * file (if a template were specified on construction).<tr><td><a name="l269" href="#l269">269</a><td> * @param {string} key The desired preference.<tr><td><a name="l270" href="#l270">270</a><td> * @return {(string|number|boolean|undefined)} The current value of the<tr><td><a name="l271" href="#l271">271</a><td> * requested preference.<tr><td><a name="l272" href="#l272">272</a><td> */<tr><td><a name="l273" href="#l273">273</a><td>Profile.prototype.getPreference = function(key) {<tr><td><a name="l274" href="#l274">274</a><td> return this.preferences_[key];<tr><td><a name="l275" href="#l275">275</a><td>};<tr><td><a name="l276" href="#l276">276</a><td><tr><td><a name="l277" href="#l277">277</a><td><tr><td><a name="l278" href="#l278">278</a><td>/**<tr><td><a name="l279" href="#l279">279</a><td> * @return {number} The port this profile is currently configured to use, or<tr><td><a name="l280" href="#l280">280</a><td> * 0 if the port will be selected at random when the profile is written<tr><td><a name="l281" href="#l281">281</a><td> * to disk.<tr><td><a name="l282" href="#l282">282</a><td> */<tr><td><a name="l283" href="#l283">283</a><td>Profile.prototype.getPort = function() {<tr><td><a name="l284" href="#l284">284</a><td> return this.port_;<tr><td><a name="l285" href="#l285">285</a><td>};<tr><td><a name="l286" href="#l286">286</a><td><tr><td><a name="l287" href="#l287">287</a><td><tr><td><a name="l288" href="#l288">288</a><td>/**<tr><td><a name="l289" href="#l289">289</a><td> * Sets the port to use for the WebDriver extension loaded by this profile.<tr><td><a name="l290" href="#l290">290</a><td> * @param {number} port The desired port, or 0 to use any free port.<tr><td><a name="l291" href="#l291">291</a><td> */<tr><td><a name="l292" href="#l292">292</a><td>Profile.prototype.setPort = function(port) {<tr><td><a name="l293" href="#l293">293</a><td> this.port_ = port;<tr><td><a name="l294" href="#l294">294</a><td>};<tr><td><a name="l295" href="#l295">295</a><td><tr><td><a name="l296" href="#l296">296</a><td><tr><td><a name="l297" href="#l297">297</a><td>/**<tr><td><a name="l298" href="#l298">298</a><td> * @return {boolean} Whether the FirefoxDriver is configured to automatically<tr><td><a name="l299" href="#l299">299</a><td> * accept untrusted SSL certificates.<tr><td><a name="l300" href="#l300">300</a><td> */<tr><td><a name="l301" href="#l301">301</a><td>Profile.prototype.acceptUntrustedCerts = function() {<tr><td><a name="l302" href="#l302">302</a><td> return !!this.preferences_['webdriver_accept_untrusted_certs'];<tr><td><a name="l303" href="#l303">303</a><td>};<tr><td><a name="l304" href="#l304">304</a><td><tr><td><a name="l305" href="#l305">305</a><td><tr><td><a name="l306" href="#l306">306</a><td>/**<tr><td><a name="l307" href="#l307">307</a><td> * Sets whether the FirefoxDriver should automatically accept untrusted SSL<tr><td><a name="l308" href="#l308">308</a><td> * certificates.<tr><td><a name="l309" href="#l309">309</a><td> * @param {boolean} value .<tr><td><a name="l310" href="#l310">310</a><td> */<tr><td><a name="l311" href="#l311">311</a><td>Profile.prototype.setAcceptUntrustedCerts = function(value) {<tr><td><a name="l312" href="#l312">312</a><td> this.preferences_['webdriver_accept_untrusted_certs'] = !!value;<tr><td><a name="l313" href="#l313">313</a><td>};<tr><td><a name="l314" href="#l314">314</a><td><tr><td><a name="l315" href="#l315">315</a><td><tr><td><a name="l316" href="#l316">316</a><td>/**<tr><td><a name="l317" href="#l317">317</a><td> * Sets whether to assume untrusted certificates come from untrusted issuers.<tr><td><a name="l318" href="#l318">318</a><td> * @param {boolean} value .<tr><td><a name="l319" href="#l319">319</a><td> */<tr><td><a name="l320" href="#l320">320</a><td>Profile.prototype.setAssumeUntrustedCertIssuer = function(value) {<tr><td><a name="l321" href="#l321">321</a><td> this.preferences_['webdriver_assume_untrusted_issuer'] = !!value;<tr><td><a name="l322" href="#l322">322</a><td>};<tr><td><a name="l323" href="#l323">323</a><td><tr><td><a name="l324" href="#l324">324</a><td><tr><td><a name="l325" href="#l325">325</a><td>/**<tr><td><a name="l326" href="#l326">326</a><td> * @return {boolean} Whether to assume untrusted certs come from untrusted<tr><td><a name="l327" href="#l327">327</a><td> * issuers.<tr><td><a name="l328" href="#l328">328</a><td> */<tr><td><a name="l329" href="#l329">329</a><td>Profile.prototype.assumeUntrustedCertIssuer = function() {<tr><td><a name="l330" href="#l330">330</a><td> return !!this.preferences_['webdriver_assume_untrusted_issuer'];<tr><td><a name="l331" href="#l331">331</a><td>};<tr><td><a name="l332" href="#l332">332</a><td><tr><td><a name="l333" href="#l333">333</a><td><tr><td><a name="l334" href="#l334">334</a><td>/**<tr><td><a name="l335" href="#l335">335</a><td> * Sets whether to use native events with this profile.<tr><td><a name="l336" href="#l336">336</a><td> * @param {boolean} enabled .<tr><td><a name="l337" href="#l337">337</a><td> */<tr><td><a name="l338" href="#l338">338</a><td>Profile.prototype.setNativeEventsEnabled = function(enabled) {<tr><td><a name="l339" href="#l339">339</a><td> this.nativeEventsEnabled_ = enabled;<tr><td><a name="l340" href="#l340">340</a><td>};<tr><td><a name="l341" href="#l341">341</a><td><tr><td><a name="l342" href="#l342">342</a><td><tr><td><a name="l343" href="#l343">343</a><td>/**<tr><td><a name="l344" href="#l344">344</a><td> * Returns whether native events are enabled in this profile.<tr><td><a name="l345" href="#l345">345</a><td> * @return {boolean} .<tr><td><a name="l346" href="#l346">346</a><td> */<tr><td><a name="l347" href="#l347">347</a><td>Profile.prototype.nativeEventsEnabled = function() {<tr><td><a name="l348" href="#l348">348</a><td> return this.nativeEventsEnabled_;<tr><td><a name="l349" href="#l349">349</a><td>};<tr><td><a name="l350" href="#l350">350</a><td><tr><td><a name="l351" href="#l351">351</a><td><tr><td><a name="l352" href="#l352">352</a><td>/**<tr><td><a name="l353" href="#l353">353</a><td> * Writes this profile to disk.<tr><td><a name="l354" href="#l354">354</a><td> * @param {boolean=} opt_excludeWebDriverExt Whether to exclude the WebDriver<tr><td><a name="l355" href="#l355">355</a><td> * extension from the generated profile. Used to reduce the size of an<tr><td><a name="l356" href="#l356">356</a><td> * {@link #encode() encoded profile} since the server will always install<tr><td><a name="l357" href="#l357">357</a><td> * the extension itself.<tr><td><a name="l358" href="#l358">358</a><td> * @return {!promise.Promise.<string>} A promise for the path to the new<tr><td><a name="l359" href="#l359">359</a><td> * profile directory.<tr><td><a name="l360" href="#l360">360</a><td> */<tr><td><a name="l361" href="#l361">361</a><td>Profile.prototype.writeToDisk = function(opt_excludeWebDriverExt) {<tr><td><a name="l362" href="#l362">362</a><td> var profileDir = io.tmpDir();<tr><td><a name="l363" href="#l363">363</a><td> if (this.template_) {<tr><td><a name="l364" href="#l364">364</a><td> profileDir = profileDir.then(function(dir) {<tr><td><a name="l365" href="#l365">365</a><td> return io.copyDir(<tr><td><a name="l366" href="#l366">366</a><td> this.template_, dir, /(parent\.lock|lock|\.parentlock)/);<tr><td><a name="l367" href="#l367">367</a><td> }.bind(this));<tr><td><a name="l368" href="#l368">368</a><td> }<tr><td><a name="l369" href="#l369">369</a><td><tr><td><a name="l370" href="#l370">370</a><td> // Freeze preferences for async operations.<tr><td><a name="l371" href="#l371">371</a><td> var prefs = {};<tr><td><a name="l372" href="#l372">372</a><td> mixin(prefs, this.preferences_);<tr><td><a name="l373" href="#l373">373</a><td><tr><td><a name="l374" href="#l374">374</a><td> // Freeze extensions for async operations.<tr><td><a name="l375" href="#l375">375</a><td> var extensions = this.extensions_.concat();<tr><td><a name="l376" href="#l376">376</a><td><tr><td><a name="l377" href="#l377">377</a><td> return profileDir.then(function(dir) {<tr><td><a name="l378" href="#l378">378</a><td> return writeUserPrefs(prefs, dir);<tr><td><a name="l379" href="#l379">379</a><td> }).then(function(dir) {<tr><td><a name="l380" href="#l380">380</a><td> return installExtensions(extensions, dir, !!opt_excludeWebDriverExt);<tr><td><a name="l381" href="#l381">381</a><td> });<tr><td><a name="l382" href="#l382">382</a><td>};<tr><td><a name="l383" href="#l383">383</a><td><tr><td><a name="l384" href="#l384">384</a><td><tr><td><a name="l385" href="#l385">385</a><td>/**<tr><td><a name="l386" href="#l386">386</a><td> * Encodes this profile as a zipped, base64 encoded directory.<tr><td><a name="l387" href="#l387">387</a><td> * @return {!promise.Promise.<string>} A promise for the encoded profile.<tr><td><a name="l388" href="#l388">388</a><td> */<tr><td><a name="l389" href="#l389">389</a><td>Profile.prototype.encode = function() {<tr><td><a name="l390" href="#l390">390</a><td> return this.writeToDisk(true).then(function(dir) {<tr><td><a name="l391" href="#l391">391</a><td> var zip = new AdmZip();<tr><td><a name="l392" href="#l392">392</a><td> zip.addLocalFolder(dir, '');<tr><td><a name="l393" href="#l393">393</a><td> return io.tmpFile().then(function(file) {<tr><td><a name="l394" href="#l394">394</a><td> zip.writeZip(file); // Sync! Why oh why :-(<tr><td><a name="l395" href="#l395">395</a><td> return promise.checkedNodeCall(fs.readFile, file);<tr><td><a name="l396" href="#l396">396</a><td> });<tr><td><a name="l397" href="#l397">397</a><td> }).then(function(data) {<tr><td><a name="l398" href="#l398">398</a><td> return new Buffer(data).toString('base64');<tr><td><a name="l399" href="#l399">399</a><td> });<tr><td><a name="l400" href="#l400">400</a><td>};<tr><td><a name="l401" href="#l401">401</a><td><tr><td><a name="l402" href="#l402">402</a><td><tr><td><a name="l403" href="#l403">403</a><td>// PUBLIC API<tr><td><a name="l404" href="#l404">404</a><td><tr><td><a name="l405" href="#l405">405</a><td><tr><td><a name="l406" href="#l406">406</a><td>exports.Profile = Profile;<tr><td><a name="l407" href="#l407">407</a><td>exports.decode = decode;<tr><td><a name="l408" href="#l408">408</a><td>exports.loadUserPrefs = loadUserPrefs;</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>profile.js</title><link href="../../dossier.css" rel="stylesheet" type="text/css"><div id="main-wrapper"><input type="checkbox" id="sidenav-toggle" /><main><header><h1>firefox/profile.js</h1></header><pre><table class="srcfile"><tbody><tr><td><a name="l1" href="#l1">1</a><td>// Copyright 2014 Selenium committers<tr><td><a name="l2" href="#l2">2</a><td>// Copyright 2014 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 AdmZip = require('adm-zip'),<tr><td><a name="l19" href="#l19">19</a><td> fs = require('fs'),<tr><td><a name="l20" href="#l20">20</a><td> path = require('path'),<tr><td><a name="l21" href="#l21">21</a><td> vm = require('vm');<tr><td><a name="l22" href="#l22">22</a><td><tr><td><a name="l23" href="#l23">23</a><td>var promise = require('..').promise,<tr><td><a name="l24" href="#l24">24</a><td> _base = require('../_base'),<tr><td><a name="l25" href="#l25">25</a><td> io = require('../io'),<tr><td><a name="l26" href="#l26">26</a><td> extension = require('./extension');<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>/** @const */<tr><td><a name="l30" href="#l30">30</a><td>var WEBDRIVER_PREFERENCES_PATH = _base.isDevMode()<tr><td><a name="l31" href="#l31">31</a><td> ? path.join(__dirname, '../../../firefox-driver/webdriver.json')<tr><td><a name="l32" href="#l32">32</a><td> : path.join(__dirname, '../lib/firefox/webdriver.json');<tr><td><a name="l33" href="#l33">33</a><td><tr><td><a name="l34" href="#l34">34</a><td>/** @const */<tr><td><a name="l35" href="#l35">35</a><td>var WEBDRIVER_EXTENSION_PATH = _base.isDevMode()<tr><td><a name="l36" href="#l36">36</a><td> ? path.join(__dirname,<tr><td><a name="l37" href="#l37">37</a><td> '../../../../build/javascript/firefox-driver/webdriver.xpi')<tr><td><a name="l38" href="#l38">38</a><td> : path.join(__dirname, '../lib/firefox/webdriver.xpi');<tr><td><a name="l39" href="#l39">39</a><td><tr><td><a name="l40" href="#l40">40</a><td>/** @const */<tr><td><a name="l41" href="#l41">41</a><td>var WEBDRIVER_EXTENSION_NAME = 'fxdriver@googlecode.com';<tr><td><a name="l42" href="#l42">42</a><td><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>/** @type {Object} */<tr><td><a name="l46" href="#l46">46</a><td>var defaultPreferences = null;<tr><td><a name="l47" href="#l47">47</a><td><tr><td><a name="l48" href="#l48">48</a><td>/**<tr><td><a name="l49" href="#l49">49</a><td> * Synchronously loads the default preferences used for the FirefoxDriver.<tr><td><a name="l50" href="#l50">50</a><td> * @return {!Object} The default preferences JSON object.<tr><td><a name="l51" href="#l51">51</a><td> */<tr><td><a name="l52" href="#l52">52</a><td>function getDefaultPreferences() {<tr><td><a name="l53" href="#l53">53</a><td> if (!defaultPreferences) {<tr><td><a name="l54" href="#l54">54</a><td> var contents = fs.readFileSync(WEBDRIVER_PREFERENCES_PATH, 'utf8');<tr><td><a name="l55" href="#l55">55</a><td> defaultPreferences = JSON.parse(contents);<tr><td><a name="l56" href="#l56">56</a><td> }<tr><td><a name="l57" href="#l57">57</a><td> return defaultPreferences;<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>/**<tr><td><a name="l62" href="#l62">62</a><td> * Parses a user.js file in a Firefox profile directory.<tr><td><a name="l63" href="#l63">63</a><td> * @param {string} f Path to the file to parse.<tr><td><a name="l64" href="#l64">64</a><td> * @return {!promise.Promise.<!Object>} A promise for the parsed preferences as<tr><td><a name="l65" href="#l65">65</a><td> * a JSON object. If the file does not exist, an empty object will be<tr><td><a name="l66" href="#l66">66</a><td> * returned.<tr><td><a name="l67" href="#l67">67</a><td> */<tr><td><a name="l68" href="#l68">68</a><td>function loadUserPrefs(f) {<tr><td><a name="l69" href="#l69">69</a><td> var done = promise.defer();<tr><td><a name="l70" href="#l70">70</a><td> fs.readFile(f, function(err, contents) {<tr><td><a name="l71" href="#l71">71</a><td> if (err && err.code === 'ENOENT') {<tr><td><a name="l72" href="#l72">72</a><td> done.fulfill({});<tr><td><a name="l73" href="#l73">73</a><td> return;<tr><td><a name="l74" href="#l74">74</a><td> }<tr><td><a name="l75" href="#l75">75</a><td><tr><td><a name="l76" href="#l76">76</a><td> if (err) {<tr><td><a name="l77" href="#l77">77</a><td> done.reject(err);<tr><td><a name="l78" href="#l78">78</a><td> return;<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> var prefs = {};<tr><td><a name="l82" href="#l82">82</a><td> var context = vm.createContext({<tr><td><a name="l83" href="#l83">83</a><td> 'user_pref': function(key, value) {<tr><td><a name="l84" href="#l84">84</a><td> prefs[key] = value;<tr><td><a name="l85" href="#l85">85</a><td> }<tr><td><a name="l86" href="#l86">86</a><td> });<tr><td><a name="l87" href="#l87">87</a><td><tr><td><a name="l88" href="#l88">88</a><td> vm.runInContext(contents, context, f);<tr><td><a name="l89" href="#l89">89</a><td> done.fulfill(prefs);<tr><td><a name="l90" href="#l90">90</a><td> });<tr><td><a name="l91" href="#l91">91</a><td> return done.promise;<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>/**<tr><td><a name="l96" href="#l96">96</a><td> * Copies the properties of one object into another.<tr><td><a name="l97" href="#l97">97</a><td> * @param {!Object} a The destination object.<tr><td><a name="l98" href="#l98">98</a><td> * @param {!Object} b The source object to apply as a mixin.<tr><td><a name="l99" href="#l99">99</a><td> */<tr><td><a name="l100" href="#l100">100</a><td>function mixin(a, b) {<tr><td><a name="l101" href="#l101">101</a><td> Object.keys(b).forEach(function(key) {<tr><td><a name="l102" href="#l102">102</a><td> a[key] = b[key];<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>/**<tr><td><a name="l108" href="#l108">108</a><td> * @param {!Object} defaults The default preferences to write. Will be<tr><td><a name="l109" href="#l109">109</a><td> * overridden by user.js preferences in the template directory and the<tr><td><a name="l110" href="#l110">110</a><td> * frozen preferences required by WebDriver.<tr><td><a name="l111" href="#l111">111</a><td> * @param {string} dir Path to the directory write the file to.<tr><td><a name="l112" href="#l112">112</a><td> * @return {!promise.Promise.<string>} A promise for the profile directory,<tr><td><a name="l113" href="#l113">113</a><td> * to be fulfilled when user preferences have been written.<tr><td><a name="l114" href="#l114">114</a><td> */<tr><td><a name="l115" href="#l115">115</a><td>function writeUserPrefs(prefs, dir) {<tr><td><a name="l116" href="#l116">116</a><td> var userPrefs = path.join(dir, 'user.js');<tr><td><a name="l117" href="#l117">117</a><td> return loadUserPrefs(userPrefs).then(function(overrides) {<tr><td><a name="l118" href="#l118">118</a><td> mixin(prefs, overrides);<tr><td><a name="l119" href="#l119">119</a><td> mixin(prefs, getDefaultPreferences()['frozen']);<tr><td><a name="l120" href="#l120">120</a><td><tr><td><a name="l121" href="#l121">121</a><td> var contents = Object.keys(prefs).map(function(key) {<tr><td><a name="l122" href="#l122">122</a><td> return 'user_pref(' + JSON.stringify(key) + ', ' +<tr><td><a name="l123" href="#l123">123</a><td> JSON.stringify(prefs[key]) + ');';<tr><td><a name="l124" href="#l124">124</a><td> }).join('\n');<tr><td><a name="l125" href="#l125">125</a><td><tr><td><a name="l126" href="#l126">126</a><td> var done = promise.defer();<tr><td><a name="l127" href="#l127">127</a><td> fs.writeFile(userPrefs, contents, function(err) {<tr><td><a name="l128" href="#l128">128</a><td> err && done.reject(err) || done.fulfill(dir);<tr><td><a name="l129" href="#l129">129</a><td> });<tr><td><a name="l130" href="#l130">130</a><td> return done.promise;<tr><td><a name="l131" href="#l131">131</a><td> });<tr><td><a name="l132" href="#l132">132</a><td>};<tr><td><a name="l133" href="#l133">133</a><td><tr><td><a name="l134" href="#l134">134</a><td><tr><td><a name="l135" href="#l135">135</a><td>/**<tr><td><a name="l136" href="#l136">136</a><td> * Installs a group of extensions in the given profile directory. If the<tr><td><a name="l137" href="#l137">137</a><td> * WebDriver extension is not included in this set, the default version<tr><td><a name="l138" href="#l138">138</a><td> * bundled with this package will be installed.<tr><td><a name="l139" href="#l139">139</a><td> * @param {!Array.<string>} extensions The extensions to install, as a<tr><td><a name="l140" href="#l140">140</a><td> * path to an unpacked extension directory or a path to a xpi file.<tr><td><a name="l141" href="#l141">141</a><td> * @param {string} dir The profile directory to install to.<tr><td><a name="l142" href="#l142">142</a><td> * @param {boolean=} opt_excludeWebDriverExt Whether to skip installation of<tr><td><a name="l143" href="#l143">143</a><td> * the default WebDriver extension.<tr><td><a name="l144" href="#l144">144</a><td> * @return {!promise.Promise.<string>} A promise for the main profile directory<tr><td><a name="l145" href="#l145">145</a><td> * once all extensions have been installed.<tr><td><a name="l146" href="#l146">146</a><td> */<tr><td><a name="l147" href="#l147">147</a><td>function installExtensions(extensions, dir, opt_excludeWebDriverExt) {<tr><td><a name="l148" href="#l148">148</a><td> var hasWebDriver = !!opt_excludeWebDriverExt;<tr><td><a name="l149" href="#l149">149</a><td> var next = 0;<tr><td><a name="l150" href="#l150">150</a><td> var extensionDir = path.join(dir, 'extensions');<tr><td><a name="l151" href="#l151">151</a><td> var done = promise.defer();<tr><td><a name="l152" href="#l152">152</a><td><tr><td><a name="l153" href="#l153">153</a><td> return io.exists(extensionDir).then(function(exists) {<tr><td><a name="l154" href="#l154">154</a><td> if (!exists) {<tr><td><a name="l155" href="#l155">155</a><td> return promise.checkedNodeCall(fs.mkdir, extensionDir);<tr><td><a name="l156" href="#l156">156</a><td> }<tr><td><a name="l157" href="#l157">157</a><td> }).then(function() {<tr><td><a name="l158" href="#l158">158</a><td> installNext();<tr><td><a name="l159" href="#l159">159</a><td> return done.promise;<tr><td><a name="l160" href="#l160">160</a><td> });<tr><td><a name="l161" href="#l161">161</a><td><tr><td><a name="l162" href="#l162">162</a><td> function installNext() {<tr><td><a name="l163" href="#l163">163</a><td> if (!done.isPending()) {<tr><td><a name="l164" href="#l164">164</a><td> return;<tr><td><a name="l165" href="#l165">165</a><td> }<tr><td><a name="l166" href="#l166">166</a><td><tr><td><a name="l167" href="#l167">167</a><td> if (next >= extensions.length) {<tr><td><a name="l168" href="#l168">168</a><td> if (hasWebDriver) {<tr><td><a name="l169" href="#l169">169</a><td> done.fulfill(dir);<tr><td><a name="l170" href="#l170">170</a><td> } else {<tr><td><a name="l171" href="#l171">171</a><td> install(WEBDRIVER_EXTENSION_PATH);<tr><td><a name="l172" href="#l172">172</a><td> }<tr><td><a name="l173" href="#l173">173</a><td> } else {<tr><td><a name="l174" href="#l174">174</a><td> install(extensions[next++]);<tr><td><a name="l175" href="#l175">175</a><td> }<tr><td><a name="l176" href="#l176">176</a><td> }<tr><td><a name="l177" href="#l177">177</a><td><tr><td><a name="l178" href="#l178">178</a><td> function install(ext) {<tr><td><a name="l179" href="#l179">179</a><td> extension.install(ext, extensionDir).then(function(id) {<tr><td><a name="l180" href="#l180">180</a><td> hasWebDriver = hasWebDriver || (id === WEBDRIVER_EXTENSION_NAME);<tr><td><a name="l181" href="#l181">181</a><td> installNext();<tr><td><a name="l182" href="#l182">182</a><td> }, done.reject);<tr><td><a name="l183" href="#l183">183</a><td> }<tr><td><a name="l184" href="#l184">184</a><td>}<tr><td><a name="l185" href="#l185">185</a><td><tr><td><a name="l186" href="#l186">186</a><td><tr><td><a name="l187" href="#l187">187</a><td>/**<tr><td><a name="l188" href="#l188">188</a><td> * Decodes a base64 encoded profile.<tr><td><a name="l189" href="#l189">189</a><td> * @param {string} data The base64 encoded string.<tr><td><a name="l190" href="#l190">190</a><td> * @return {!promise.Promise.<string>} A promise for the path to the decoded<tr><td><a name="l191" href="#l191">191</a><td> * profile directory.<tr><td><a name="l192" href="#l192">192</a><td> */<tr><td><a name="l193" href="#l193">193</a><td>function decode(data) {<tr><td><a name="l194" href="#l194">194</a><td> return io.tmpFile().then(function(file) {<tr><td><a name="l195" href="#l195">195</a><td> var buf = new Buffer(data, 'base64');<tr><td><a name="l196" href="#l196">196</a><td> return promise.checkedNodeCall(fs.writeFile, file, buf).then(function() {<tr><td><a name="l197" href="#l197">197</a><td> return io.tmpDir();<tr><td><a name="l198" href="#l198">198</a><td> }).then(function(dir) {<tr><td><a name="l199" href="#l199">199</a><td> var zip = new AdmZip(file);<tr><td><a name="l200" href="#l200">200</a><td> zip.extractAllTo(dir); // Sync only? Why?? :-(<tr><td><a name="l201" href="#l201">201</a><td> return dir;<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> * Models a Firefox proifle directory for use with the FirefoxDriver. The<tr><td><a name="l210" href="#l210">210</a><td> * {@code Proifle} directory uses an in-memory model until {@link #writeToDisk}<tr><td><a name="l211" href="#l211">211</a><td> * is called.<tr><td><a name="l212" href="#l212">212</a><td> * @param {string=} opt_dir Path to an existing Firefox profile directory to<tr><td><a name="l213" href="#l213">213</a><td> * use a template for this profile. If not specified, a blank profile will<tr><td><a name="l214" href="#l214">214</a><td> * be used.<tr><td><a name="l215" href="#l215">215</a><td> * @constructor<tr><td><a name="l216" href="#l216">216</a><td> */<tr><td><a name="l217" href="#l217">217</a><td>var Profile = function(opt_dir) {<tr><td><a name="l218" href="#l218">218</a><td> /** @private {!Object} */<tr><td><a name="l219" href="#l219">219</a><td> this.preferences_ = {};<tr><td><a name="l220" href="#l220">220</a><td><tr><td><a name="l221" href="#l221">221</a><td> mixin(this.preferences_, getDefaultPreferences()['mutable']);<tr><td><a name="l222" href="#l222">222</a><td> mixin(this.preferences_, getDefaultPreferences()['frozen']);<tr><td><a name="l223" href="#l223">223</a><td><tr><td><a name="l224" href="#l224">224</a><td> /** @private {boolean} */<tr><td><a name="l225" href="#l225">225</a><td> this.nativeEventsEnabled_ = true;<tr><td><a name="l226" href="#l226">226</a><td><tr><td><a name="l227" href="#l227">227</a><td> /** @private {(string|undefined)} */<tr><td><a name="l228" href="#l228">228</a><td> this.template_ = opt_dir;<tr><td><a name="l229" href="#l229">229</a><td><tr><td><a name="l230" href="#l230">230</a><td> /** @private {number} */<tr><td><a name="l231" href="#l231">231</a><td> this.port_ = 0;<tr><td><a name="l232" href="#l232">232</a><td><tr><td><a name="l233" href="#l233">233</a><td> /** @private {!Array.<string>} */<tr><td><a name="l234" href="#l234">234</a><td> this.extensions_ = [];<tr><td><a name="l235" href="#l235">235</a><td>};<tr><td><a name="l236" href="#l236">236</a><td><tr><td><a name="l237" href="#l237">237</a><td><tr><td><a name="l238" href="#l238">238</a><td>/**<tr><td><a name="l239" href="#l239">239</a><td> * Registers an extension to be included with this profile.<tr><td><a name="l240" href="#l240">240</a><td> * @param {string} extension Path to the extension to include, as either an<tr><td><a name="l241" href="#l241">241</a><td> * unpacked extension directory or the path to a xpi file.<tr><td><a name="l242" href="#l242">242</a><td> */<tr><td><a name="l243" href="#l243">243</a><td>Profile.prototype.addExtension = function(extension) {<tr><td><a name="l244" href="#l244">244</a><td> this.extensions_.push(extension);<tr><td><a name="l245" href="#l245">245</a><td>};<tr><td><a name="l246" href="#l246">246</a><td><tr><td><a name="l247" href="#l247">247</a><td><tr><td><a name="l248" href="#l248">248</a><td>/**<tr><td><a name="l249" href="#l249">249</a><td> * Sets a desired preference for this profile.<tr><td><a name="l250" href="#l250">250</a><td> * @param {string} key The preference key.<tr><td><a name="l251" href="#l251">251</a><td> * @param {(string|number|boolean)} value The preference value.<tr><td><a name="l252" href="#l252">252</a><td> * @throws {Error} If attempting to set a frozen preference.<tr><td><a name="l253" href="#l253">253</a><td> */<tr><td><a name="l254" href="#l254">254</a><td>Profile.prototype.setPreference = function(key, value) {<tr><td><a name="l255" href="#l255">255</a><td> var frozen = getDefaultPreferences()['frozen'];<tr><td><a name="l256" href="#l256">256</a><td> if (frozen.hasOwnProperty(key) && frozen[key] !== value) {<tr><td><a name="l257" href="#l257">257</a><td> throw Error('You may not set ' + key + '=' + JSON.stringify(value)<tr><td><a name="l258" href="#l258">258</a><td> + '; value is frozen for proper WebDriver functionality ('<tr><td><a name="l259" href="#l259">259</a><td> + key + '=' + JSON.stringify(frozen[key]) + ')');<tr><td><a name="l260" href="#l260">260</a><td> }<tr><td><a name="l261" href="#l261">261</a><td> this.preferences_[key] = value;<tr><td><a name="l262" href="#l262">262</a><td>};<tr><td><a name="l263" href="#l263">263</a><td><tr><td><a name="l264" href="#l264">264</a><td><tr><td><a name="l265" href="#l265">265</a><td>/**<tr><td><a name="l266" href="#l266">266</a><td> * Returns the currently configured value of a profile preference. This does<tr><td><a name="l267" href="#l267">267</a><td> * not include any defaults defined in the profile's template directory user.js<tr><td><a name="l268" href="#l268">268</a><td> * file (if a template were specified on construction).<tr><td><a name="l269" href="#l269">269</a><td> * @param {string} key The desired preference.<tr><td><a name="l270" href="#l270">270</a><td> * @return {(string|number|boolean|undefined)} The current value of the<tr><td><a name="l271" href="#l271">271</a><td> * requested preference.<tr><td><a name="l272" href="#l272">272</a><td> */<tr><td><a name="l273" href="#l273">273</a><td>Profile.prototype.getPreference = function(key) {<tr><td><a name="l274" href="#l274">274</a><td> return this.preferences_[key];<tr><td><a name="l275" href="#l275">275</a><td>};<tr><td><a name="l276" href="#l276">276</a><td><tr><td><a name="l277" href="#l277">277</a><td><tr><td><a name="l278" href="#l278">278</a><td>/**<tr><td><a name="l279" href="#l279">279</a><td> * @return {number} The port this profile is currently configured to use, or<tr><td><a name="l280" href="#l280">280</a><td> * 0 if the port will be selected at random when the profile is written<tr><td><a name="l281" href="#l281">281</a><td> * to disk.<tr><td><a name="l282" href="#l282">282</a><td> */<tr><td><a name="l283" href="#l283">283</a><td>Profile.prototype.getPort = function() {<tr><td><a name="l284" href="#l284">284</a><td> return this.port_;<tr><td><a name="l285" href="#l285">285</a><td>};<tr><td><a name="l286" href="#l286">286</a><td><tr><td><a name="l287" href="#l287">287</a><td><tr><td><a name="l288" href="#l288">288</a><td>/**<tr><td><a name="l289" href="#l289">289</a><td> * Sets the port to use for the WebDriver extension loaded by this profile.<tr><td><a name="l290" href="#l290">290</a><td> * @param {number} port The desired port, or 0 to use any free port.<tr><td><a name="l291" href="#l291">291</a><td> */<tr><td><a name="l292" href="#l292">292</a><td>Profile.prototype.setPort = function(port) {<tr><td><a name="l293" href="#l293">293</a><td> this.port_ = port;<tr><td><a name="l294" href="#l294">294</a><td>};<tr><td><a name="l295" href="#l295">295</a><td><tr><td><a name="l296" href="#l296">296</a><td><tr><td><a name="l297" href="#l297">297</a><td>/**<tr><td><a name="l298" href="#l298">298</a><td> * @return {boolean} Whether the FirefoxDriver is configured to automatically<tr><td><a name="l299" href="#l299">299</a><td> * accept untrusted SSL certificates.<tr><td><a name="l300" href="#l300">300</a><td> */<tr><td><a name="l301" href="#l301">301</a><td>Profile.prototype.acceptUntrustedCerts = function() {<tr><td><a name="l302" href="#l302">302</a><td> return !!this.preferences_['webdriver_accept_untrusted_certs'];<tr><td><a name="l303" href="#l303">303</a><td>};<tr><td><a name="l304" href="#l304">304</a><td><tr><td><a name="l305" href="#l305">305</a><td><tr><td><a name="l306" href="#l306">306</a><td>/**<tr><td><a name="l307" href="#l307">307</a><td> * Sets whether the FirefoxDriver should automatically accept untrusted SSL<tr><td><a name="l308" href="#l308">308</a><td> * certificates.<tr><td><a name="l309" href="#l309">309</a><td> * @param {boolean} value .<tr><td><a name="l310" href="#l310">310</a><td> */<tr><td><a name="l311" href="#l311">311</a><td>Profile.prototype.setAcceptUntrustedCerts = function(value) {<tr><td><a name="l312" href="#l312">312</a><td> this.preferences_['webdriver_accept_untrusted_certs'] = !!value;<tr><td><a name="l313" href="#l313">313</a><td>};<tr><td><a name="l314" href="#l314">314</a><td><tr><td><a name="l315" href="#l315">315</a><td><tr><td><a name="l316" href="#l316">316</a><td>/**<tr><td><a name="l317" href="#l317">317</a><td> * Sets whether to assume untrusted certificates come from untrusted issuers.<tr><td><a name="l318" href="#l318">318</a><td> * @param {boolean} value .<tr><td><a name="l319" href="#l319">319</a><td> */<tr><td><a name="l320" href="#l320">320</a><td>Profile.prototype.setAssumeUntrustedCertIssuer = function(value) {<tr><td><a name="l321" href="#l321">321</a><td> this.preferences_['webdriver_assume_untrusted_issuer'] = !!value;<tr><td><a name="l322" href="#l322">322</a><td>};<tr><td><a name="l323" href="#l323">323</a><td><tr><td><a name="l324" href="#l324">324</a><td><tr><td><a name="l325" href="#l325">325</a><td>/**<tr><td><a name="l326" href="#l326">326</a><td> * @return {boolean} Whether to assume untrusted certs come from untrusted<tr><td><a name="l327" href="#l327">327</a><td> * issuers.<tr><td><a name="l328" href="#l328">328</a><td> */<tr><td><a name="l329" href="#l329">329</a><td>Profile.prototype.assumeUntrustedCertIssuer = function() {<tr><td><a name="l330" href="#l330">330</a><td> return !!this.preferences_['webdriver_assume_untrusted_issuer'];<tr><td><a name="l331" href="#l331">331</a><td>};<tr><td><a name="l332" href="#l332">332</a><td><tr><td><a name="l333" href="#l333">333</a><td><tr><td><a name="l334" href="#l334">334</a><td>/**<tr><td><a name="l335" href="#l335">335</a><td> * Sets whether to use native events with this profile.<tr><td><a name="l336" href="#l336">336</a><td> * @param {boolean} enabled .<tr><td><a name="l337" href="#l337">337</a><td> */<tr><td><a name="l338" href="#l338">338</a><td>Profile.prototype.setNativeEventsEnabled = function(enabled) {<tr><td><a name="l339" href="#l339">339</a><td> this.nativeEventsEnabled_ = enabled;<tr><td><a name="l340" href="#l340">340</a><td>};<tr><td><a name="l341" href="#l341">341</a><td><tr><td><a name="l342" href="#l342">342</a><td><tr><td><a name="l343" href="#l343">343</a><td>/**<tr><td><a name="l344" href="#l344">344</a><td> * Returns whether native events are enabled in this profile.<tr><td><a name="l345" href="#l345">345</a><td> * @return {boolean} .<tr><td><a name="l346" href="#l346">346</a><td> */<tr><td><a name="l347" href="#l347">347</a><td>Profile.prototype.nativeEventsEnabled = function() {<tr><td><a name="l348" href="#l348">348</a><td> return this.nativeEventsEnabled_;<tr><td><a name="l349" href="#l349">349</a><td>};<tr><td><a name="l350" href="#l350">350</a><td><tr><td><a name="l351" href="#l351">351</a><td><tr><td><a name="l352" href="#l352">352</a><td>/**<tr><td><a name="l353" href="#l353">353</a><td> * Writes this profile to disk.<tr><td><a name="l354" href="#l354">354</a><td> * @param {boolean=} opt_excludeWebDriverExt Whether to exclude the WebDriver<tr><td><a name="l355" href="#l355">355</a><td> * extension from the generated profile. Used to reduce the size of an<tr><td><a name="l356" href="#l356">356</a><td> * {@link #encode() encoded profile} since the server will always install<tr><td><a name="l357" href="#l357">357</a><td> * the extension itself.<tr><td><a name="l358" href="#l358">358</a><td> * @return {!promise.Promise.<string>} A promise for the path to the new<tr><td><a name="l359" href="#l359">359</a><td> * profile directory.<tr><td><a name="l360" href="#l360">360</a><td> */<tr><td><a name="l361" href="#l361">361</a><td>Profile.prototype.writeToDisk = function(opt_excludeWebDriverExt) {<tr><td><a name="l362" href="#l362">362</a><td> var profileDir = io.tmpDir();<tr><td><a name="l363" href="#l363">363</a><td> if (this.template_) {<tr><td><a name="l364" href="#l364">364</a><td> profileDir = profileDir.then(function(dir) {<tr><td><a name="l365" href="#l365">365</a><td> return io.copyDir(<tr><td><a name="l366" href="#l366">366</a><td> this.template_, dir, /(parent\.lock|lock|\.parentlock)/);<tr><td><a name="l367" href="#l367">367</a><td> }.bind(this));<tr><td><a name="l368" href="#l368">368</a><td> }<tr><td><a name="l369" href="#l369">369</a><td><tr><td><a name="l370" href="#l370">370</a><td> // Freeze preferences for async operations.<tr><td><a name="l371" href="#l371">371</a><td> var prefs = {};<tr><td><a name="l372" href="#l372">372</a><td> mixin(prefs, this.preferences_);<tr><td><a name="l373" href="#l373">373</a><td><tr><td><a name="l374" href="#l374">374</a><td> // Freeze extensions for async operations.<tr><td><a name="l375" href="#l375">375</a><td> var extensions = this.extensions_.concat();<tr><td><a name="l376" href="#l376">376</a><td><tr><td><a name="l377" href="#l377">377</a><td> return profileDir.then(function(dir) {<tr><td><a name="l378" href="#l378">378</a><td> return writeUserPrefs(prefs, dir);<tr><td><a name="l379" href="#l379">379</a><td> }).then(function(dir) {<tr><td><a name="l380" href="#l380">380</a><td> return installExtensions(extensions, dir, !!opt_excludeWebDriverExt);<tr><td><a name="l381" href="#l381">381</a><td> });<tr><td><a name="l382" href="#l382">382</a><td>};<tr><td><a name="l383" href="#l383">383</a><td><tr><td><a name="l384" href="#l384">384</a><td><tr><td><a name="l385" href="#l385">385</a><td>/**<tr><td><a name="l386" href="#l386">386</a><td> * Encodes this profile as a zipped, base64 encoded directory.<tr><td><a name="l387" href="#l387">387</a><td> * @return {!promise.Promise.<string>} A promise for the encoded profile.<tr><td><a name="l388" href="#l388">388</a><td> */<tr><td><a name="l389" href="#l389">389</a><td>Profile.prototype.encode = function() {<tr><td><a name="l390" href="#l390">390</a><td> return this.writeToDisk(true).then(function(dir) {<tr><td><a name="l391" href="#l391">391</a><td> var zip = new AdmZip();<tr><td><a name="l392" href="#l392">392</a><td> zip.addLocalFolder(dir, '');<tr><td><a name="l393" href="#l393">393</a><td> return io.tmpFile().then(function(file) {<tr><td><a name="l394" href="#l394">394</a><td> zip.writeZip(file); // Sync! Why oh why :-(<tr><td><a name="l395" href="#l395">395</a><td> return promise.checkedNodeCall(fs.readFile, file);<tr><td><a name="l396" href="#l396">396</a><td> });<tr><td><a name="l397" href="#l397">397</a><td> }).then(function(data) {<tr><td><a name="l398" href="#l398">398</a><td> return new Buffer(data).toString('base64');<tr><td><a name="l399" href="#l399">399</a><td> });<tr><td><a name="l400" href="#l400">400</a><td>};<tr><td><a name="l401" href="#l401">401</a><td><tr><td><a name="l402" href="#l402">402</a><td><tr><td><a name="l403" href="#l403">403</a><td>// PUBLIC API<tr><td><a name="l404" href="#l404">404</a><td><tr><td><a name="l405" href="#l405">405</a><td><tr><td><a name="l406" href="#l406">406</a><td>exports.Profile = Profile;<tr><td><a name="l407" href="#l407">407</a><td>exports.decode = decode;<tr><td><a name="l408" href="#l408">408</a><td>exports.loadUserPrefs = loadUserPrefs;</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>
|