rainux-selenium-webdriver 0.0.17

Sign up to get free protection for your applications and to get access to all the features.
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