rainux-selenium-webdriver 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. data/COPYING +204 -0
  2. data/chrome/prebuilt/Win32/Release/npchromedriver.dll +0 -0
  3. data/chrome/prebuilt/x64/Release/npchromedriver.dll +0 -0
  4. data/chrome/src/extension/background.html +9 -0
  5. data/chrome/src/extension/background.js +995 -0
  6. data/chrome/src/extension/content_script.js +1321 -0
  7. data/chrome/src/extension/icons/busy.png +0 -0
  8. data/chrome/src/extension/icons/free.png +0 -0
  9. data/chrome/src/extension/manifest-nonwin.json +19 -0
  10. data/chrome/src/extension/manifest-win.json +20 -0
  11. data/chrome/src/extension/utils.js +231 -0
  12. data/chrome/src/rb/lib/selenium/webdriver/chrome.rb +8 -0
  13. data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +358 -0
  14. data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +124 -0
  15. data/chrome/src/rb/lib/selenium/webdriver/chrome/launcher.rb +135 -0
  16. data/common/src/js/abstractcommandprocessor.js +134 -0
  17. data/common/src/js/asserts.js +296 -0
  18. data/common/src/js/by.js +149 -0
  19. data/common/src/js/command.js +304 -0
  20. data/common/src/js/context.js +58 -0
  21. data/common/src/js/core/Blank.html +7 -0
  22. data/common/src/js/core/InjectedRemoteRunner.html +8 -0
  23. data/common/src/js/core/RemoteRunner.html +101 -0
  24. data/common/src/js/core/SeleniumLog.html +109 -0
  25. data/common/src/js/core/TestPrompt.html +145 -0
  26. data/common/src/js/core/TestRunner-splash.html +55 -0
  27. data/common/src/js/core/TestRunner.html +165 -0
  28. data/common/src/js/core/icons/all.png +0 -0
  29. data/common/src/js/core/icons/continue.png +0 -0
  30. data/common/src/js/core/icons/continue_disabled.png +0 -0
  31. data/common/src/js/core/icons/pause.png +0 -0
  32. data/common/src/js/core/icons/pause_disabled.png +0 -0
  33. data/common/src/js/core/icons/selected.png +0 -0
  34. data/common/src/js/core/icons/step.png +0 -0
  35. data/common/src/js/core/icons/step_disabled.png +0 -0
  36. data/common/src/js/core/lib/cssQuery/cssQuery-p.js +6 -0
  37. data/common/src/js/core/lib/cssQuery/src/cssQuery-level2.js +142 -0
  38. data/common/src/js/core/lib/cssQuery/src/cssQuery-level3.js +150 -0
  39. data/common/src/js/core/lib/cssQuery/src/cssQuery-standard.js +53 -0
  40. data/common/src/js/core/lib/cssQuery/src/cssQuery.js +356 -0
  41. data/common/src/js/core/lib/prototype.js +2006 -0
  42. data/common/src/js/core/lib/scriptaculous/builder.js +101 -0
  43. data/common/src/js/core/lib/scriptaculous/controls.js +815 -0
  44. data/common/src/js/core/lib/scriptaculous/dragdrop.js +915 -0
  45. data/common/src/js/core/lib/scriptaculous/effects.js +958 -0
  46. data/common/src/js/core/lib/scriptaculous/scriptaculous.js +47 -0
  47. data/common/src/js/core/lib/scriptaculous/slider.js +283 -0
  48. data/common/src/js/core/lib/scriptaculous/unittest.js +383 -0
  49. data/common/src/js/core/lib/snapsie.js +91 -0
  50. data/common/src/js/core/scripts/find_matching_child.js +69 -0
  51. data/common/src/js/core/scripts/htmlutils.js +8716 -0
  52. data/common/src/js/core/scripts/injection.html +72 -0
  53. data/common/src/js/core/scripts/selenium-api.js +3291 -0
  54. data/common/src/js/core/scripts/selenium-browserbot.js +2457 -0
  55. data/common/src/js/core/scripts/selenium-browserdetect.js +153 -0
  56. data/common/src/js/core/scripts/selenium-commandhandlers.js +379 -0
  57. data/common/src/js/core/scripts/selenium-executionloop.js +175 -0
  58. data/common/src/js/core/scripts/selenium-logging.js +148 -0
  59. data/common/src/js/core/scripts/selenium-remoterunner.js +695 -0
  60. data/common/src/js/core/scripts/selenium-testrunner.js +1362 -0
  61. data/common/src/js/core/scripts/selenium-version.js +5 -0
  62. data/common/src/js/core/scripts/ui-doc.html +808 -0
  63. data/common/src/js/core/scripts/ui-element.js +1644 -0
  64. data/common/src/js/core/scripts/ui-map-sample.js +979 -0
  65. data/common/src/js/core/scripts/user-extensions.js +3 -0
  66. data/common/src/js/core/scripts/user-extensions.js.sample +75 -0
  67. data/common/src/js/core/scripts/xmlextras.js +153 -0
  68. data/common/src/js/core/selenium-logo.png +0 -0
  69. data/common/src/js/core/selenium-test.css +43 -0
  70. data/common/src/js/core/selenium.css +316 -0
  71. data/common/src/js/core/xpath/dom.js +566 -0
  72. data/common/src/js/core/xpath/javascript-xpath-0.1.11.js +2816 -0
  73. data/common/src/js/core/xpath/util.js +549 -0
  74. data/common/src/js/core/xpath/xmltoken.js +149 -0
  75. data/common/src/js/core/xpath/xpath.js +2481 -0
  76. data/common/src/js/extension/README +2 -0
  77. data/common/src/js/extension/dommessenger.js +152 -0
  78. data/common/src/js/factory.js +55 -0
  79. data/common/src/js/future.js +141 -0
  80. data/common/src/js/jsunit.js +40 -0
  81. data/common/src/js/jsunit/app/css/jsUnitStyle.css +50 -0
  82. data/common/src/js/jsunit/app/css/readme +10 -0
  83. data/common/src/js/jsunit/app/emptyPage.html +11 -0
  84. data/common/src/js/jsunit/app/jsUnitCore.js +534 -0
  85. data/common/src/js/jsunit/app/jsUnitMockTimeout.js +81 -0
  86. data/common/src/js/jsunit/app/jsUnitTestManager.js +705 -0
  87. data/common/src/js/jsunit/app/jsUnitTestSuite.js +44 -0
  88. data/common/src/js/jsunit/app/jsUnitTracer.js +102 -0
  89. data/common/src/js/jsunit/app/jsUnitVersionCheck.js +59 -0
  90. data/common/src/js/jsunit/app/main-counts-errors.html +12 -0
  91. data/common/src/js/jsunit/app/main-counts-failures.html +13 -0
  92. data/common/src/js/jsunit/app/main-counts-runs.html +13 -0
  93. data/common/src/js/jsunit/app/main-counts.html +21 -0
  94. data/common/src/js/jsunit/app/main-data.html +178 -0
  95. data/common/src/js/jsunit/app/main-errors.html +23 -0
  96. data/common/src/js/jsunit/app/main-frame.html +19 -0
  97. data/common/src/js/jsunit/app/main-loader.html +45 -0
  98. data/common/src/js/jsunit/app/main-progress.html +25 -0
  99. data/common/src/js/jsunit/app/main-results.html +67 -0
  100. data/common/src/js/jsunit/app/main-status.html +13 -0
  101. data/common/src/js/jsunit/app/testContainer.html +16 -0
  102. data/common/src/js/jsunit/app/testContainerController.html +77 -0
  103. data/common/src/js/jsunit/app/xbDebug.js +306 -0
  104. data/common/src/js/jsunit/changelog.txt +60 -0
  105. data/common/src/js/jsunit/css/jsUnitStyle.css +83 -0
  106. data/common/src/js/jsunit/images/green.gif +0 -0
  107. data/common/src/js/jsunit/images/logo_jsunit.gif +0 -0
  108. data/common/src/js/jsunit/images/powerby-transparent.gif +0 -0
  109. data/common/src/js/jsunit/images/red.gif +0 -0
  110. data/common/src/js/jsunit/licenses/JDOM_license.txt +56 -0
  111. data/common/src/js/jsunit/licenses/Jetty_license.html +213 -0
  112. data/common/src/js/jsunit/licenses/MPL-1.1.txt +470 -0
  113. data/common/src/js/jsunit/licenses/gpl-2.txt +340 -0
  114. data/common/src/js/jsunit/licenses/index.html +141 -0
  115. data/common/src/js/jsunit/licenses/lgpl-2.1.txt +504 -0
  116. data/common/src/js/jsunit/licenses/mpl-tri-license-c.txt +35 -0
  117. data/common/src/js/jsunit/licenses/mpl-tri-license-html.txt +35 -0
  118. data/common/src/js/jsunit/readme.txt +19 -0
  119. data/common/src/js/jsunit/testRunner.html +167 -0
  120. data/common/src/js/jsunit/version.txt +1 -0
  121. data/common/src/js/key.js +117 -0
  122. data/common/src/js/localcommandprocessor.js +185 -0
  123. data/common/src/js/testcase.js +217 -0
  124. data/common/src/js/timing.js +89 -0
  125. data/common/src/js/webdriver.js +890 -0
  126. data/common/src/js/webelement.js +485 -0
  127. data/common/src/rb/README +30 -0
  128. data/common/src/rb/lib/selenium-webdriver.rb +1 -0
  129. data/common/src/rb/lib/selenium/webdriver.rb +67 -0
  130. data/common/src/rb/lib/selenium/webdriver/bridge_helper.rb +91 -0
  131. data/common/src/rb/lib/selenium/webdriver/child_process.rb +180 -0
  132. data/common/src/rb/lib/selenium/webdriver/core_ext/dir.rb +41 -0
  133. data/common/src/rb/lib/selenium/webdriver/driver.rb +252 -0
  134. data/common/src/rb/lib/selenium/webdriver/driver_extensions/takes_screenshot.rb +24 -0
  135. data/common/src/rb/lib/selenium/webdriver/element.rb +262 -0
  136. data/common/src/rb/lib/selenium/webdriver/error.rb +67 -0
  137. data/common/src/rb/lib/selenium/webdriver/find.rb +89 -0
  138. data/common/src/rb/lib/selenium/webdriver/keys.rb +84 -0
  139. data/common/src/rb/lib/selenium/webdriver/navigation.rb +27 -0
  140. data/common/src/rb/lib/selenium/webdriver/options.rb +50 -0
  141. data/common/src/rb/lib/selenium/webdriver/platform.rb +86 -0
  142. data/common/src/rb/lib/selenium/webdriver/target_locator.rb +70 -0
  143. data/firefox/prebuilt/Win32/Release/webdriver-firefox.dll +0 -0
  144. data/firefox/prebuilt/linux/Release/libwebdriver-firefox.so +0 -0
  145. data/firefox/prebuilt/linux/Release/x_ignore_nofocus.so +0 -0
  146. data/firefox/prebuilt/linux64/Release/libwebdriver-firefox.so +0 -0
  147. data/firefox/prebuilt/linux64/Release/x_ignore_nofocus.so +0 -0
  148. data/firefox/prebuilt/nsICommandProcessor.xpt +0 -0
  149. data/firefox/prebuilt/nsINativeEvents.xpt +0 -0
  150. data/firefox/prebuilt/nsIResponseHandler.xpt +0 -0
  151. data/firefox/src/extension/chrome.manifest +3 -0
  152. data/firefox/src/extension/components/badCertListener.js +294 -0
  153. data/firefox/src/extension/components/context.js +37 -0
  154. data/firefox/src/extension/components/driver-component.js +127 -0
  155. data/firefox/src/extension/components/firefoxDriver.js +810 -0
  156. data/firefox/src/extension/components/json2.js +273 -0
  157. data/firefox/src/extension/components/keytest.html +554 -0
  158. data/firefox/src/extension/components/nsCommandProcessor.js +643 -0
  159. data/firefox/src/extension/components/promptService.js +208 -0
  160. data/firefox/src/extension/components/screenshooter.js +81 -0
  161. data/firefox/src/extension/components/socketListener.js +185 -0
  162. data/firefox/src/extension/components/utils.js +1263 -0
  163. data/firefox/src/extension/components/webLoadingListener.js +57 -0
  164. data/firefox/src/extension/components/webdriverserver.js +106 -0
  165. data/firefox/src/extension/components/wrappedElement.js +683 -0
  166. data/firefox/src/extension/content/fxdriver.xul +30 -0
  167. data/firefox/src/extension/content/server.js +95 -0
  168. data/firefox/src/extension/idl/nsICommandProcessor.idl +38 -0
  169. data/firefox/src/extension/idl/nsIResponseHandler.idl +34 -0
  170. data/firefox/src/extension/install.rdf +29 -0
  171. data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +31 -0
  172. data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +107 -0
  173. data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +484 -0
  174. data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +90 -0
  175. data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +155 -0
  176. data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +233 -0
  177. data/firefox/src/rb/lib/selenium/webdriver/firefox/profiles_ini.rb +59 -0
  178. data/firefox/src/rb/lib/selenium/webdriver/firefox/util.rb +23 -0
  179. data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
  180. data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
  181. data/jobbie/src/rb/lib/selenium/webdriver/ie.rb +14 -0
  182. data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +565 -0
  183. data/jobbie/src/rb/lib/selenium/webdriver/ie/lib.rb +99 -0
  184. data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +147 -0
  185. data/remote/client/src/rb/lib/selenium/webdriver/remote.rb +16 -0
  186. data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +408 -0
  187. data/remote/client/src/rb/lib/selenium/webdriver/remote/capabilities.rb +105 -0
  188. data/remote/client/src/rb/lib/selenium/webdriver/remote/commands.rb +53 -0
  189. data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +71 -0
  190. data/remote/client/src/rb/lib/selenium/webdriver/remote/response.rb +49 -0
  191. data/remote/client/src/rb/lib/selenium/webdriver/remote/server_error.rb +32 -0
  192. metadata +303 -0
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0"?>
2
+
3
+ <!--
4
+ Copyright 2007-2009 WebDriver committers
5
+ Copyright 2007-2009 Google Inc.
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
18
+ -->
19
+
20
+ <overlay id="fxdriver-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
21
+ <script src="dommessenger.js" />
22
+ <script src="server.js" />
23
+ <statusbar id="status-bar">
24
+ <statusbarpanel>
25
+ <hbox>
26
+ <label id="fxdriver-label" value="WebDriver" tooltiptext="This Firefox can be remote controlled with WebDriver." />
27
+ </hbox>
28
+ </statusbarpanel>
29
+ </statusbar>
30
+ </overlay>
@@ -0,0 +1,95 @@
1
+ /*
2
+ Copyright 2007-2009 WebDriver committers
3
+ Copyright 2007-2009 Google Inc.
4
+ Portions copyright 2007 ThoughtWorks, Inc
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ */
18
+
19
+ var driver = false;
20
+ var domMessenger = null;
21
+
22
+ // This will configure a FirefoxDriver and DomMessenger for each
23
+ // _browser window_ (not chrome window). Multiple tabs in the same window will
24
+ // share a FirefoxDriver and DomMessenger instance.
25
+ window.addEventListener("load", function(e) {
26
+ handle = Components.classes["@googlecode.com/webdriver/fxdriver;1"].createInstance(Components.interfaces.nsISupports);
27
+ var server = handle.wrappedJSObject;
28
+
29
+ if (!domMessenger) {
30
+ var appcontent = document.getElementById('appcontent');
31
+ if (appcontent) {
32
+ try {
33
+ var commandProcessor = Components.
34
+ classes['@googlecode.com/webdriver/command-processor;1'].
35
+ getService(Components.interfaces.nsICommandProcessor);
36
+ domMessenger = new DomMessenger(commandProcessor);
37
+ appcontent.addEventListener('DOMContentLoaded',
38
+ function(e) {
39
+ domMessenger.onPageLoad(e);
40
+ }, true);
41
+ appcontent.addEventListener('pagehide',
42
+ function(e) {
43
+ domMessenger.onPageUnload(e);
44
+ }, true);
45
+ } catch (ex) {
46
+ // Not catching this can really mess things up and lead to inexplicable
47
+ // and hard to debug behavior.
48
+ Components.utils.reportError(ex);
49
+ }
50
+ }
51
+ }
52
+
53
+ if (!driver) {
54
+ driver = server.newDriver(window);
55
+ } else {
56
+ if (window.content)
57
+ var frames = window.content.frames;
58
+
59
+ // If we are already focused on a frame, try and stay focused
60
+ if (driver.context.frameId !== undefined && frames) {
61
+ if (frames && frames.length > driver.context.frameId) {
62
+ // do nothing
63
+ } else {
64
+ if (frames && frames.length && "FRAME" == frames[0].frameElement.tagName) {
65
+ if (!frames[driver.context.frameId]) {
66
+ driver.context.frameId = 0;
67
+ }
68
+ } else {
69
+ driver.context.frameId = undefined;
70
+ }
71
+
72
+ }
73
+ } else {
74
+ // Other use a sensible default
75
+ if (frames && frames.length && "FRAME" == frames[0].frameElement.tagName) {
76
+ if (!frames[driver.context.frameId]) {
77
+ driver.context.frameId = 0;
78
+ }
79
+ } else {
80
+ driver.context.frameId = undefined;
81
+ }
82
+ }
83
+ }
84
+
85
+ server.startListening();
86
+
87
+ }, true);
88
+
89
+ //window.addEventListener("focus", function(e) {
90
+ // var active = e.originalTarget;
91
+ // var doc = gBrowser.selectedBrowser.contentDocument;
92
+ // if (active.ownerDocument == doc) {
93
+ // driver.activeElement = active;
94
+ // }
95
+ //}, true);
@@ -0,0 +1,38 @@
1
+ /*
2
+ Copyright 2007-2009 WebDriver committers
3
+ Copyright 2007-2009 Google Inc.
4
+ Portions copyright 2007 ThoughtWorks, Inc
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ */
18
+
19
+ #include "nsISupports.idl"
20
+ #include "nsIResponseHandler.idl"
21
+
22
+ /**
23
+ * Defines a single method for executing commands specified as a JSON string.
24
+ */
25
+ [scriptable, uuid(4427729b-441e-47c3-8380-df0350cac636)]
26
+ interface nsICommandProcessor : nsISupports {
27
+
28
+ /**
29
+ * Executes the given command specified in a JSON string. When the command
30
+ * is fully processed, the response will be sent to the given
31
+ * {@code nsIResponseHandler} callback as a JSON string.
32
+ *
33
+ * @param jsonCommandString The command to execute, specified in JSON format.
34
+ * @param responseHandler The callback to send the command response to.
35
+ */
36
+ void execute(in AUTF8String jsonCommandString,
37
+ in nsIResponseHandler responseHandler);
38
+ };
@@ -0,0 +1,34 @@
1
+ /*
2
+ Copyright 2007-2009 WebDriver committers
3
+ Copyright 2007-2009 Google Inc.
4
+ Portions copyright 2007 ThoughtWorks, Inc
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ */
18
+
19
+ #include "nsISupports.idl"
20
+
21
+ /**
22
+ * Defines a callback used to process the response to a command sent to the
23
+ * {@code nsICommandProcessor}.
24
+ */
25
+ [scriptable, function, uuid(0539a68f-b4a8-4543-bf2a-031cef89aff1)]
26
+ interface nsIResponseHandler : nsISupports {
27
+
28
+ /**
29
+ * Handle a response from the {@code nsICommandProcessor}.
30
+ *
31
+ * @param jsonResponseString The command response as a string.
32
+ */
33
+ void handleResponse(in AUTF8String jsonResponseString);
34
+ };
@@ -0,0 +1,29 @@
1
+ <?xml version="1.0"?>
2
+ <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
3
+
4
+ <Description about="urn:mozilla:install-manifest">
5
+ <em:id>fxdriver@googlecode.com</em:id>
6
+ <em:name>Firefox WebDriver</em:name>
7
+ <em:version>2.0a2</em:version>
8
+ <em:description>WebDriver implementation for Firefox</em:description>
9
+ <em:creator>Simon Stewart</em:creator>
10
+
11
+ <!-- Firefox -->
12
+ <em:targetApplication>
13
+ <Description>
14
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
15
+ <em:minVersion>2.0</em:minVersion>
16
+ <em:maxVersion>3.*</em:maxVersion>
17
+ </Description>
18
+ </em:targetApplication>
19
+
20
+ <!-- Platforms where we're not compiling the native events -->
21
+ <em:targetPlatform>Darwin</em:targetPlatform>
22
+ <em:targetPlatform>Linux</em:targetPlatform>
23
+ <!-- Platforms where we are -->
24
+ <em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
25
+
26
+ <!-- We're probably missing lots of platforms here -->
27
+ </Description>
28
+
29
+ </RDF>
@@ -0,0 +1,31 @@
1
+ require "timeout"
2
+ require "socket"
3
+
4
+ require "selenium/webdriver/firefox/util"
5
+ require "selenium/webdriver/firefox/binary"
6
+ require "selenium/webdriver/firefox/profiles_ini"
7
+ require "selenium/webdriver/firefox/profile"
8
+ require "selenium/webdriver/firefox/extension_connection"
9
+ require "selenium/webdriver/firefox/launcher"
10
+ require "selenium/webdriver/firefox/bridge"
11
+
12
+ module Selenium
13
+ module WebDriver
14
+ module Firefox
15
+
16
+ DEFAULT_PROFILE_NAME = "WebDriver".freeze
17
+ DEFAULT_PORT = 7055
18
+ DEFAULT_ENABLE_NATIVE_EVENTS = [:windows, :linux].include? Platform.os
19
+ DEFAULT_SECURE_SSL = false
20
+ DEFAULT_LOAD_NO_FOCUS_LIB = Platform.os == :linux
21
+
22
+ end
23
+ end
24
+ end
25
+
26
+
27
+ # SocketError was added in Ruby 1.8.7.
28
+ # If it's not defined, we add it here so it can be used in rescues.
29
+ unless defined? SocketError
30
+ class SocketError < IOError; end
31
+ end
@@ -0,0 +1,107 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Firefox
4
+ class Binary
5
+
6
+ def initialize
7
+ ENV['MOZ_NO_REMOTE'] = '1' # able to launch multiple instances
8
+ check_binary_exists
9
+ end
10
+
11
+ def create_base_profile(name)
12
+ execute("-CreateProfile", name)
13
+
14
+ status = nil
15
+ Timeout.timeout(15, Error::TimeOutError) do
16
+ _, status = wait
17
+ end
18
+
19
+
20
+ if status && status.to_i != 0
21
+ raise Error::WebDriverError, "could not create base profile: (exit status: #{status})"
22
+ end
23
+ end
24
+
25
+ def start_with(profile, *args)
26
+ ENV['XRE_PROFILE_PATH'] = profile.absolute_path
27
+ execute(*args)
28
+ cope_with_mac_strangeness(args) if Platform.mac?
29
+ end
30
+
31
+ def execute(*extra_args)
32
+ args = [path, "-no-remote", "--verbose"] + extra_args
33
+ @process = ChildProcess.new(*args).start
34
+ end
35
+
36
+ def cope_with_mac_strangeness(args)
37
+ sleep 0.3
38
+
39
+ if @process.ugly_death?
40
+ # process crashed, trying a restart. sleeping 5 seconds shorter than the java driver
41
+ sleep 5
42
+ execute(*args)
43
+ end
44
+
45
+ # ensure we're ok
46
+ sleep 0.3
47
+ if @process.ugly_death?
48
+ raise Error::WebDriverError, "unable to start Firefox cleanly, args: #{args.inspect}"
49
+ end
50
+ end
51
+
52
+ def kill
53
+ @process.kill if @process
54
+ end
55
+
56
+ def wait
57
+ @process.wait if @process
58
+ end
59
+
60
+ def pid
61
+ @process.pid if @process
62
+ end
63
+
64
+ private
65
+
66
+ def path
67
+ @path ||= case Platform.os
68
+ when :macosx
69
+ "/Applications/Firefox.app/Contents/MacOS/firefox-bin"
70
+ when :windows
71
+ windows_path
72
+ when :linux, :unix
73
+ "/usr/bin/firefox"
74
+ else
75
+ raise "Unknown platform: #{Platform.os}"
76
+ end
77
+ end
78
+
79
+ def check_binary_exists
80
+ unless File.file?(path)
81
+ raise Error::WebDriverError, "Could not find Firefox binary. Make sure Firefox is installed (OS: #{Platform.os})"
82
+ end
83
+ end
84
+
85
+ def windows_path
86
+ windows_registry_path || (ENV['PROGRAMFILES'] || "\\Program Files") + "\\Mozilla Firefox\\firefox.exe"
87
+ end
88
+
89
+ def windows_registry_path
90
+ return if Platform.jruby? || Platform.ironruby?
91
+ require "win32/registry"
92
+
93
+ lm = Win32::Registry::HKEY_LOCAL_MACHINE
94
+ lm.open("SOFTWARE\\Mozilla\\Mozilla Firefox") do |reg|
95
+ main = lm.open("SOFTWARE\\Mozilla\\Mozilla Firefox\\#{reg.keys[0]}\\Main")
96
+ if entry = main.find {|key, type, data| key =~ /pathtoexe/i}
97
+ return entry.last
98
+ end
99
+ end
100
+ rescue Win32::Registry::Error
101
+ raise Error::WebDriverError, "Firefox not found in Windows registry, please make sure you have it installed."
102
+ end
103
+
104
+ end # Binary
105
+ end # Firefox
106
+ end # WebDriver
107
+ end # Selenium
@@ -0,0 +1,484 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Firefox
4
+ class Bridge
5
+ include BridgeHelper
6
+
7
+ def initialize(opts = {})
8
+ @binary = Binary.new
9
+ @launcher = Launcher.new(
10
+ @binary,
11
+ opts.delete(:port) || DEFAULT_PORT,
12
+ opts.delete(:profile) || DEFAULT_PROFILE_NAME
13
+ )
14
+
15
+ unless opts.empty?
16
+ raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
17
+ end
18
+
19
+ @launcher.launch
20
+ @connection = @launcher.connection
21
+ @context = newSession
22
+ end
23
+
24
+ def browser
25
+ :firefox
26
+ end
27
+
28
+ def driver_extensions
29
+ [DriverExtensions::TakesScreenshot]
30
+ end
31
+
32
+ def quit
33
+ @connection.quit
34
+ @binary.wait rescue nil # might raise on windows
35
+
36
+ nil
37
+ end
38
+
39
+ def getPageSource
40
+ execute :getPageSource
41
+ end
42
+
43
+ def refresh
44
+ execute :refresh
45
+ end
46
+
47
+ def getWindowHandles
48
+ execute :getWindowHandles
49
+ end
50
+
51
+ def getCurrentWindowHandle
52
+ execute :getCurrentWindowHandle
53
+ end
54
+
55
+ def getScreenshotAsBase64
56
+ execute :getScreenshotAsBase64
57
+ end
58
+
59
+ def get(url)
60
+ execute :get,
61
+ :parameters => [url]
62
+ end
63
+
64
+ def close
65
+ execute :close
66
+ # TODO: rescue ?
67
+ end
68
+
69
+ def goBack
70
+ execute :goBack
71
+ end
72
+
73
+ def goForward
74
+ execute :goForward
75
+ end
76
+
77
+ def getCurrentUrl
78
+ execute :getCurrentUrl
79
+ end
80
+
81
+ def getTitle
82
+ execute :title
83
+ end
84
+
85
+ def executeScript(string, *args)
86
+ typed_args = args.map { |e| wrap_script_argument(e) }
87
+
88
+ resp = raw_execute :executeScript, :parameters => [string, typed_args]
89
+ raise TypeError, "expected Hash" unless resp.kind_of? Hash
90
+
91
+ unwrap_script_argument resp["response"]
92
+ end
93
+
94
+ #
95
+ # Finders - TODO: should be shared with Chrome::Bridge
96
+ #
97
+
98
+ def findElementByClassName(parent, class_name)
99
+ find_element_by 'class name', class_name, parent
100
+ end
101
+
102
+ def findElementsByClassName(parent, class_name)
103
+ find_elements_by 'class name', class_name, parent
104
+ end
105
+
106
+ def findElementById(parent, id)
107
+ find_element_by 'id', id, parent
108
+ end
109
+
110
+ def findElementsById(parent, id)
111
+ find_elements_by 'id', id, parent
112
+ end
113
+
114
+ def findElementByLinkText(parent, link_text)
115
+ find_element_by 'link text', link_text, parent
116
+ end
117
+
118
+ def findElementsByLinkText(parent, link_text)
119
+ find_elements_by 'link text', link_text, parent
120
+ end
121
+
122
+ def findElementByPartialLinkText(parent, link_text)
123
+ find_element_by 'partial link text', link_text, parent
124
+ end
125
+
126
+ def findElementsByPartialLinkText(parent, link_text)
127
+ find_elements_by 'partial link text', link_text, parent
128
+ end
129
+
130
+ def findElementByName(parent, name)
131
+ find_element_by 'name', name, parent
132
+ end
133
+
134
+ def findElementsByName(parent, name)
135
+ find_elements_by 'name', name, parent
136
+ end
137
+
138
+ def findElementByTagName(parent, tag_name)
139
+ find_element_by 'tag name', tag_name, parent
140
+ end
141
+
142
+ def findElementsByTagName(parent, tag_name)
143
+ find_elements_by 'tag name', tag_name, parent
144
+ end
145
+
146
+ def findElementByXpath(parent, xpath)
147
+ find_element_by 'xpath', xpath, parent
148
+ end
149
+
150
+ def findElementsByXpath(parent, xpath)
151
+ find_elements_by 'xpath', xpath, parent
152
+ end
153
+
154
+ def findElementByCssSelector(parent, selector)
155
+ find_element_by 'css selector', selector, parent
156
+ end
157
+
158
+ def findElementsByCssSelector(parent, selector)
159
+ find_elements_by 'css selector', selector, parent
160
+ end
161
+
162
+ def findElementByJsExpr(parent, js_expr)
163
+ find_element_by 'js expr', js_expr, parent
164
+ end
165
+
166
+ def findElementsByJsExpr(parent, js_expr)
167
+ find_elements_by 'js expr', js_expr, parent
168
+ end
169
+
170
+ def findElementByJavascript(parent, javascript)
171
+ find_element_by 'javascript', javascript, parent
172
+ end
173
+
174
+ def findElementsByJavascript(parent, javascript)
175
+ find_elements_by 'javascript', javascript, parent
176
+ end
177
+
178
+ #
179
+ # Element functions
180
+ #
181
+
182
+ def clickElement(element)
183
+ # execute :clickElement, :element_id => element
184
+ execute :click,
185
+ :element_id => element
186
+ end
187
+
188
+ def getElementTagName(element)
189
+ # execute :getElementTagName, :element_id => element
190
+ execute :getTagName,
191
+ :element_id => element
192
+ end
193
+
194
+ def getElementAttribute(element, name)
195
+ # execute :getElementAttribute, :element_id => element, :parameters => [name]
196
+ execute :getAttribute,
197
+ :element_id => element,
198
+ :parameters => [name]
199
+ end
200
+
201
+ def getElementValue(element)
202
+ # execute :getElementValue, :element_id => element
203
+ execute :getValue,
204
+ :element_id => element
205
+ end
206
+
207
+ def getElementText(element)
208
+ # execute :getElementText, :element_id => element
209
+ execute :getText,
210
+ :element_id => element
211
+ end
212
+
213
+ def getElementLocation(element)
214
+ # data = execute :getElementLocation, :element_id => element
215
+ data = execute :getLocation,
216
+ :element_id => element
217
+
218
+ Point.new data["x"], data["y"]
219
+ end
220
+
221
+ def getElementSize(element)
222
+ # execute :getElementSize, :element_id => element
223
+ data = execute :getSize,
224
+ :element_id => element
225
+
226
+ Dimension.new data['width'], data['height']
227
+ end
228
+
229
+ def sendKeysToElement(element, string)
230
+ # execute :sendKeysToElement, :element_id => element, :parameters => [string.split(//u)]
231
+ execute :sendKeys,
232
+ :element_id => element,
233
+ :parameters => [string.to_s]
234
+ end
235
+
236
+ def clearElement(element)
237
+ # execute :clearElement, :element_id => element
238
+ execute :clear,
239
+ :element_id => element
240
+ end
241
+
242
+ def isElementEnabled(element)
243
+ # execute :isElementEnabled, :element_id => element
244
+ !getElementAttribute(element, "disabled")
245
+ end
246
+
247
+ def isElementSelected(element)
248
+ # execute :isElementSelected, :element_id => element
249
+ execute :isSelected,
250
+ :element_id => element
251
+ end
252
+
253
+ def isElementDisplayed(element)
254
+ # execute :isElementDisplayed, :element_id => element
255
+ execute :isDisplayed,
256
+ :element_id => element
257
+ end
258
+
259
+ def submitElement(element)
260
+ # execute :submitElement, :element_id => element
261
+ execute :submit,
262
+ :element_id => element
263
+ end
264
+
265
+ def toggleElement(element)
266
+ # execute :toggleElement, :element_id => element
267
+ execute :toggle,
268
+ :element_id => element
269
+ end
270
+
271
+ def setElementSelected(element)
272
+ # execute :setElementSelected, :element_id => element
273
+ execute :setSelected,
274
+ :element_id => element
275
+ end
276
+
277
+ def getElementValueOfCssProperty(element, prop)
278
+ # execute :getElementValueOfCssProperty, :element_id => element, :parameters => [prop]
279
+ execute :getValueOfCssProperty,
280
+ :element_id => element,
281
+ :parameters => [prop]
282
+ end
283
+
284
+ def hoverOverElement(element)
285
+ execute :hover,
286
+ :element_id => element
287
+ # execute :hoverOverElement, :element_id => element
288
+ end
289
+
290
+ def dragElement(element, rigth_by, down_by)
291
+ execute :dragElement,
292
+ :element_id => element,
293
+ :parameters => [rigth_by, down_by]
294
+ end
295
+
296
+
297
+ def setSpeed(speed)
298
+ pixel_speed = case speed
299
+ when "SLOW" then '1'
300
+ when "MEDIUM" then '10'
301
+ when "FAST" then '100'
302
+ else
303
+ raise ArgumentError, "unknown speed: #{speed.inspect}"
304
+ end
305
+
306
+ execute :setMouseSpeed,
307
+ :parameters => [pixel_speed]
308
+ end
309
+
310
+ def getSpeed
311
+ case execute(:getMouseSpeed)
312
+ when '1' then "SLOW"
313
+ when '10' then "MEDIUM"
314
+ when '100' then "FAST"
315
+ else
316
+ "FAST"
317
+ end
318
+ end
319
+
320
+ def addCookie(cookie)
321
+ execute :addCookie,
322
+ :parameters => [cookie.to_json] # uhm, sending text instead of data
323
+ end
324
+
325
+ def deleteCookie(name)
326
+ execute :deleteCookie,
327
+ :parameters => [{:name => name}.to_json] # ditto
328
+ end
329
+
330
+ def getAllCookies
331
+ data = execute :getCookie
332
+ data.map do |c|
333
+ parse_cookie_string(c) unless c.strip.empty?
334
+ end.compact
335
+ end
336
+
337
+ #
338
+ # FF-specific?
339
+ #
340
+
341
+ def deleteAllCookies
342
+ execute :deleteAllCookies
343
+ end
344
+
345
+ def getCookieNamed(name)
346
+ getCookies.find { |c| c['name'] == name }
347
+ end
348
+
349
+ def switchToFrame(name)
350
+ execute :switchToFrame,
351
+ :parameters => [name.to_s]
352
+ end
353
+
354
+ def switchToDefaultContent
355
+ execute :switchToDefaultContent
356
+ end
357
+
358
+ def switchToWindow(name)
359
+ @context = execute :switchToWindow,
360
+ :parameters => [name.to_s]
361
+ end
362
+
363
+ def switchToActiveElement
364
+ Element.new self, element_id_from(execute(:switchToActiveElement))
365
+ end
366
+ alias_method :getActiveElement, :switchToActiveElement
367
+
368
+ private
369
+
370
+ def find_element_by(how, what, parent = nil)
371
+ if parent
372
+ id = execute :findChildElement,
373
+ :parameters => [{:id => parent, :using => how, :value => what}]
374
+ else
375
+ id = execute :findElement,
376
+ :parameters => [how, what]
377
+ end
378
+
379
+ Element.new self, element_id_from(id)
380
+ end
381
+
382
+ def find_elements_by(how, what, parent = nil)
383
+ if parent
384
+ id_string = execute :findChildElements,
385
+ :parameters => [{:id => parent, :using => how, :value => what}]
386
+ else
387
+ id_string = execute :findElements,
388
+ :parameters => [how, what]
389
+ end
390
+
391
+ id_string.map { |id| Element.new self, element_id_from(id) }
392
+ end
393
+
394
+ def newSession
395
+ execute :newSession
396
+ end
397
+
398
+ def execute(*args)
399
+ raw_execute(*args)['response']
400
+ end
401
+
402
+ def raw_execute(command, opts = {})
403
+ request = {:commandName => command, :context => @context.to_s}
404
+
405
+ if eid = opts[:element_id]
406
+ request[:elementId] = eid
407
+ end
408
+
409
+ if params = opts[:parameters]
410
+ request[:parameters] = params
411
+ end
412
+
413
+ puts "--> #{request.inspect}" if $DEBUG
414
+
415
+ @connection.send_string request.to_json
416
+ resp = @connection.read_response
417
+
418
+ puts "<-- #{resp.inspect}" if $DEBUG
419
+
420
+ if resp['isError']
421
+ case resp['response']
422
+ when String
423
+ msg = resp['response']
424
+ when Hash
425
+ msg = resp['response']['message']
426
+ end
427
+
428
+ msg ||= resp.inspect
429
+ raise Error::WebDriverError, msg
430
+ end
431
+
432
+ if ctx = resp['context']
433
+ @context = ctx
434
+ end
435
+
436
+ resp
437
+ end
438
+
439
+ #
440
+ # wrap/unwrap will be shared with Chrome (overrides BridgeHelper for now)
441
+ #
442
+
443
+ def wrap_script_argument(arg)
444
+ case arg
445
+ when Integer, Float
446
+ { :type => "NUMBER", :value => arg }
447
+ when TrueClass, FalseClass, NilClass
448
+ { :type => "BOOLEAN", :value => !!arg }
449
+ when Element
450
+ { :type => "ELEMENT", :value => arg.ref }
451
+ when String
452
+ { :type => "STRING", :value => arg.to_s }
453
+ when Array # Enumerable?
454
+ arg.map { |e| wrap_script_argument(e) }
455
+ else
456
+ raise TypeError, "Parameter is not of recognized type: #{arg.inspect}:#{arg.class}"
457
+ end
458
+ end
459
+
460
+ def unwrap_script_argument(arg)
461
+ raise TypeError, "expected Hash" unless arg.kind_of? Hash
462
+ case arg["type"]
463
+ when "NULL"
464
+ nil
465
+ when "ELEMENT"
466
+ Element.new self, element_id_from(arg["value"])
467
+ when "ARRAY"
468
+ arg['value'].map { |e| unwrap_script_argument(e) }
469
+ # when "POINT"
470
+ # Point.new arg['x'], arg['y']
471
+ # when "DIMENSION"
472
+ # Dimension.new arg['width'], arg['height']
473
+ # when "COOKIE"
474
+ # {:name => arg['name'], :value => arg['value']}
475
+ else
476
+ arg["value"]
477
+ end
478
+ end
479
+
480
+
481
+ end # Bridge
482
+ end # Firefox
483
+ end # WebDriver
484
+ end # Selenium