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,57 @@
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 STATE_START = Components.interfaces.nsIWebProgressListener.STATE_START;
20
+ var STATE_STOP = Components.interfaces.nsIWebProgressListener.STATE_STOP;
21
+
22
+ function WebLoadingListener(browser, toCall) {
23
+ var listener = this;
24
+
25
+ this.handler = {
26
+ QueryInterface: function(iid) {
27
+ if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
28
+ iid.equals(Components.interfaces.nsISupportsWeakReference) ||
29
+ iid.equals(Components.interfaces.nsISupports))
30
+ return this;
31
+ throw Components.results.NS_NOINTERFACE;
32
+ },
33
+
34
+ onStateChange: function(webProgress, request, flags, status) {
35
+ if (flags & STATE_STOP) {
36
+ if (request.URI) {
37
+ WebLoadingListener.removeListener(browser, listener);
38
+ toCall();
39
+ }
40
+ }
41
+ return 0;
42
+ },
43
+
44
+ onLocationChange: function(aProgress, aRequest, aURI) { return 0; },
45
+ onProgressChange: function() { return 0; },
46
+ onStatusChange: function() { return 0; },
47
+ onSecurityChange: function() { return 0; },
48
+ onLinkIconAvailable: function() { return 0; }
49
+ };
50
+
51
+ browser.addProgressListener(this.handler,
52
+ Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
53
+ }
54
+
55
+ WebLoadingListener.removeListener = function(browser, listener) {
56
+ browser.removeProgressListener(listener.handler);
57
+ };
@@ -0,0 +1,106 @@
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
+
20
+ function WebDriverServer() {
21
+ this.wrappedJSObject = this;
22
+ this.serverSocket =
23
+ Components.classes["@mozilla.org/network/server-socket;1"].
24
+ createInstance(Components.interfaces.nsIServerSocket);
25
+ this.generator = Utils.getService("@mozilla.org/uuid-generator;1", "nsIUUIDGenerator");
26
+ this.enableNativeEvents = null;
27
+
28
+ // Force our cert override service to be loaded - otherwise, it will not be
29
+ // loaded and cause a "too deep recursion" error.
30
+ var overrideService = Components.classes["@mozilla.org/security/certoverride;1"]
31
+ .getService(Components.interfaces.nsICertOverrideService);
32
+ }
33
+
34
+
35
+ WebDriverServer.prototype.newDriver = function(window) {
36
+ if (null == this.useNativeEvents) {
37
+ var prefs =
38
+ Utils.getService("@mozilla.org/preferences-service;1", "nsIPrefBranch");
39
+ if (!prefs.prefHasUserValue("webdriver_enable_native_events")) {
40
+ Utils.dumpn('webdriver_enable_native_events not set; defaulting to true');
41
+ }
42
+ this.enableNativeEvents =
43
+ prefs.prefHasUserValue("webdriver_enable_native_events") ?
44
+ prefs.getBoolPref("webdriver_enable_native_events") : false;
45
+ Utils.dumpn('Enable native events: ' + this.enableNativeEvents);
46
+ }
47
+ window.fxdriver = new FirefoxDriver(this, this.enableNativeEvents);
48
+ // Yuck. But it allows us to refer to it later.
49
+ window.fxdriver.window = window;
50
+
51
+ return window.fxdriver;
52
+ };
53
+
54
+
55
+ WebDriverServer.prototype.getNextId = function() {
56
+ return this.generator.generateUUID().toString();
57
+ };
58
+
59
+
60
+ WebDriverServer.prototype.onSocketAccepted = function(socket, transport) {
61
+ try {
62
+ var socketListener = new SocketListener(transport);
63
+ } catch(e) {
64
+ dump(e);
65
+ }
66
+ };
67
+
68
+
69
+ WebDriverServer.prototype.startListening = function(port) {
70
+ if (!port) {
71
+ var prefs =
72
+ Utils.getService("@mozilla.org/preferences-service;1", "nsIPrefBranch");
73
+
74
+ port = prefs.prefHasUserValue("webdriver_firefox_port") ?
75
+ prefs.getIntPref("webdriver_firefox_port") : 7055;
76
+ }
77
+
78
+ if (!this.isListening) {
79
+ this.serverSocket.init(port, true, -1);
80
+ this.serverSocket.asyncListen(this);
81
+ this.isListening = true;
82
+ }
83
+ };
84
+
85
+
86
+ WebDriverServer.prototype.onStopListening = function(socket, status)
87
+ {
88
+ };
89
+
90
+
91
+ WebDriverServer.prototype.close = function()
92
+ {
93
+ };
94
+
95
+
96
+ WebDriverServer.prototype.QueryInterface = function(aIID) {
97
+ if (!aIID.equals(nsISupports))
98
+ throw Components.results.NS_ERROR_NO_INTERFACE;
99
+ return this;
100
+ };
101
+
102
+
103
+ WebDriverServer.prototype.createInstance = function(ignore1, ignore2, ignore3) {
104
+ var port = WebDriverServer.readPort();
105
+ this.startListening(port);
106
+ };
@@ -0,0 +1,683 @@
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
+
20
+ FirefoxDriver.prototype.click = function(respond) {
21
+ var element = Utils.getElementAt(respond.elementId, respond.context);
22
+
23
+ if (!Utils.isDisplayed(element, true) && !Utils.isInHead(element)) {
24
+ respond.isError = true;
25
+ respond.response =
26
+ "Element is not currently visible and so may not be clicked";
27
+ respond.send();
28
+ return;
29
+ }
30
+
31
+ var nativeEvents = Utils.getNativeEvents();
32
+ var node = Utils.getNodeForNativeEvents(element);
33
+ var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
34
+ getService(Components.interfaces.nsIXULAppInfo);
35
+ var versionChecker = Components.
36
+ classes["@mozilla.org/xpcom/version-comparator;1"].
37
+ getService(Components.interfaces.nsIVersionComparator);
38
+
39
+ // I'm having trouble getting clicks to work on Firefox 2 on Windows. Always
40
+ // fall back for that
41
+ var useNativeClick =
42
+ versionChecker.compare(appInfo.platformVersion, "1.9") >= 0;
43
+
44
+ if (this.enableNativeEvents && nativeEvents && node && useNativeClick) {
45
+ Utils.dumpn("Using native events for click");
46
+ var loc = Utils.getLocationOnceScrolledIntoView(element);
47
+ var x = loc.x + (loc.width ? loc.width / 2 : 0);
48
+ var y = loc.y + (loc.height ? loc.height / 2 : 0);
49
+
50
+ // In Firefox 3.6 and above, there's a shared window handle. We need to calculate an offset
51
+ // to add to the x and y locations.
52
+
53
+ var appInfo = Components.classes['@mozilla.org/xre/app-info;1'].
54
+ getService(Components.interfaces.nsIXULAppInfo);
55
+ var versionChecker = Components.classes['@mozilla.org/xpcom/version-comparator;1'].
56
+ getService(Components.interfaces.nsIVersionComparator);
57
+ if (versionChecker.compare(appInfo.version, '3.6') >= 0) {
58
+ // Get the ultimate parent frame
59
+ var current = element.ownerDocument.defaultView;
60
+ var ultimateParent = element.ownerDocument.defaultView.parent;
61
+ while (ultimateParent != current) {
62
+ current = ultimateParent;
63
+ ultimateParent = current.parent;
64
+ }
65
+ var offX = element.ownerDocument.defaultView.mozInnerScreenX - ultimateParent.mozInnerScreenX;
66
+ var offY = element.ownerDocument.defaultView.mozInnerScreenY - ultimateParent.mozInnerScreenY;
67
+
68
+ x += offX;
69
+ y += offY;
70
+ }
71
+
72
+ try {
73
+ nativeEvents.mouseMove(node, this.currentX, this.currentY, x, y);
74
+ nativeEvents.click(node, x, y);
75
+ this.currentX = x;
76
+ this.currentY = y;
77
+ respond.send();
78
+ return;
79
+ } catch (e) {
80
+ // Make sure that we only fall through only if
81
+ // the error returned from the native call indicates it's not
82
+ // implemented.
83
+
84
+ Utils.dumpn("Detected error when clicking: " + e.name);
85
+
86
+ if (e.name != "NS_ERROR_NOT_IMPLEMENTED") {
87
+ respond.isError = true;
88
+ respond.response = e.toString();
89
+ respond.send();
90
+ return;
91
+ }
92
+
93
+ // Fall through to the synthesized click code.
94
+ }
95
+ }
96
+
97
+ Utils.dumpn("Falling back to synthesized click");
98
+ var currentlyActive = Utils.getActiveElement(respond.context);
99
+
100
+ Utils.fireMouseEventOn(respond.context, element, "mouseover");
101
+ Utils.fireMouseEventOn(respond.context, element, "mousemove");
102
+ Utils.fireMouseEventOn(respond.context, element, "mousedown");
103
+ if (element != currentlyActive) {
104
+ // Some elements may not have blur, focus functions - for example,
105
+ // elements under an SVG element. Call those only if they exist.
106
+ if (typeof currentlyActive.blur == 'function') {
107
+ currentlyActive.blur();
108
+ }
109
+ if (typeof element.focus == 'function') {
110
+ element.focus();
111
+ }
112
+ }
113
+
114
+ Utils.fireMouseEventOn(respond.context, element, "mouseup");
115
+ Utils.fireMouseEventOn(respond.context, element, "click");
116
+
117
+ var browser = Utils.getBrowser(respond.context);
118
+ var alreadyReplied = false;
119
+
120
+ var clickListener = new WebLoadingListener(browser, function(event) {
121
+ if (!alreadyReplied) {
122
+ alreadyReplied = true;
123
+ respond.send();
124
+ }
125
+ });
126
+
127
+ var contentWindow = browser.contentWindow;
128
+
129
+ var checkForLoad = function() {
130
+ // Returning should be handled by the click listener, unless we're not
131
+ // actually loading something. Do a check and return if we are. There's a
132
+ // race condition here, in that the click event and load may have finished
133
+ // before we get here. For now, let's pretend that doesn't happen. The other
134
+ // race condition is that we make this check before the load has begun. With
135
+ // all the javascript out there, this might actually be a bit of a problem.
136
+ var docLoaderService = browser.webProgress;
137
+ if (!docLoaderService.isLoadingDocument) {
138
+ WebLoadingListener.removeListener(browser, clickListener);
139
+ if (!alreadyReplied) {
140
+ alreadyReplied = true;
141
+ respond.send();
142
+ }
143
+ }
144
+ };
145
+
146
+
147
+ if (contentWindow.closed) {
148
+ respond.send();
149
+ return;
150
+ }
151
+ contentWindow.setTimeout(checkForLoad, 50);
152
+ };
153
+
154
+
155
+ FirefoxDriver.prototype.getText = function(respond) {
156
+ var element = Utils.getElementAt(respond.elementId, respond.context);
157
+
158
+ if (element.tagName == "TITLE") {
159
+ respond.response = Utils.getBrowser(respond.context).contentTitle;
160
+ } else {
161
+ respond.response = Utils.getText(element, true);
162
+ }
163
+
164
+ respond.send();
165
+ };
166
+
167
+
168
+ FirefoxDriver.prototype.getValue = function(respond) {
169
+ var element = Utils.getElementAt(respond.elementId, respond.context);
170
+
171
+ if (element["value"] !== undefined) {
172
+ respond.response = element.value;
173
+ respond.send();
174
+ return;
175
+ }
176
+
177
+ if (element.hasAttribute("value")) {
178
+ respond.response = element.getAttribute("value");
179
+ respond.send();
180
+ return;
181
+ }
182
+
183
+ respond.isError = true;
184
+ respond.response = "No match";
185
+ respond.send();
186
+ };
187
+
188
+
189
+ FirefoxDriver.prototype.sendKeys = function(respond, value) {
190
+ var element = Utils.getElementAt(respond.elementId, respond.context);
191
+
192
+ if (!Utils.isDisplayed(element, true) && !Utils.isInHead(element)) {
193
+ respond.isError = true;
194
+ respond.response =
195
+ "Element is not currently visible and so may not be used for typing";
196
+ respond.send();
197
+ return;
198
+ }
199
+
200
+ var currentlyActive = Utils.getActiveElement(respond.context);
201
+ if (currentlyActive != element) {
202
+ currentlyActive.blur();
203
+ element.focus();
204
+ element.ownerDocument.defaultView.focus();
205
+ }
206
+
207
+ var use = element;
208
+ var tagName = element.tagName.toLowerCase();
209
+ if (tagName == "body" && element.ownerDocument.defaultView.frameElement) {
210
+ element.ownerDocument.defaultView.focus();
211
+
212
+ // Turns out, this is what we should be using as the target
213
+ // to send events to
214
+ use = element.ownerDocument.getElementsByTagName("html")[0];
215
+ }
216
+
217
+ Utils.type(respond.context, use, value[0], this.enableNativeEvents);
218
+
219
+ respond.send();
220
+ };
221
+
222
+
223
+ FirefoxDriver.prototype.clear = function(respond) {
224
+ var element = Utils.getElementAt(respond.elementId, respond.context);
225
+
226
+ if (!Utils.isDisplayed(element, true) && !Utils.isInHead(element)) {
227
+ respond.isError = true;
228
+ respond.response =
229
+ "Element is not currently visible and so may not be cleared";
230
+ respond.send();
231
+ return;
232
+ }
233
+
234
+ var isTextField = element["value"] !== undefined;
235
+
236
+ var currentlyActive = Utils.getActiveElement(respond.context);
237
+ if (currentlyActive != element) {
238
+ currentlyActive.blur();
239
+ element.focus();
240
+ }
241
+
242
+ var currentValue = undefined;
243
+ if (element["value"] !== undefined) {
244
+ currentValue = element.value;
245
+ } else if (element.hasAttribute("value")) {
246
+ currentValue = element.getAttribute("value");
247
+ }
248
+
249
+ if (isTextField) {
250
+ element.value = "";
251
+ } else {
252
+ element.setAttribute("value", "");
253
+ }
254
+
255
+ if (currentValue !== undefined && currentValue != "") {
256
+ Utils.fireHtmlEvent(respond.context, element, "change");
257
+ }
258
+
259
+ respond.send();
260
+ };
261
+
262
+
263
+ FirefoxDriver.prototype.getTagName = function(respond) {
264
+ var element = Utils.getElementAt(respond.elementId, respond.context);
265
+
266
+ respond.response = element.tagName.toLowerCase();
267
+ respond.send();
268
+ };
269
+
270
+
271
+ FirefoxDriver.prototype.getAttribute = function(respond, value) {
272
+ var element = Utils.getElementAt(respond.elementId, respond.context);
273
+
274
+ var attributeName = value[0];
275
+
276
+ if (element.hasAttribute(attributeName)) {
277
+ respond.response = element.getAttribute(attributeName);
278
+ // Is this block necessary?
279
+ if (attributeName.toLowerCase() == "disabled") {
280
+ respond.response = element.disabled;
281
+ } else if (attributeName.toLowerCase() == "selected") {
282
+ respond.response = element.selected;
283
+ } else if (attributeName.toLowerCase() == "checked") {
284
+ respond.response = element.checked;
285
+ } else if (attributeName.toLowerCase() == "readonly") {
286
+ respond.response = element.readOnly;
287
+ }
288
+
289
+ respond.send();
290
+ return;
291
+ }
292
+
293
+ attributeName = attributeName.toLowerCase();
294
+
295
+ if (attributeName == "disabled") {
296
+ respond.response = (element.disabled === undefined ? false : element.disabled);
297
+ respond.send();
298
+ return;
299
+ } else if ((attributeName == "checked" || attributeName == "selected") &&
300
+ element.tagName.toLowerCase() == "input") {
301
+ respond.response = element.checked;
302
+ respond.send();
303
+ return;
304
+ } else if (attributeName == "selected" && element.tagName.toLowerCase()
305
+ == "option") {
306
+ respond.response = element.selected;
307
+ respond.send();
308
+ return;
309
+ } else if (attributeName == "index" && element.tagName.toLowerCase()
310
+ == "option") {
311
+ respond.response = element.index;
312
+ respond.send();
313
+ return;
314
+ }
315
+ respond.response = null;
316
+ respond.send();
317
+ };
318
+
319
+
320
+ FirefoxDriver.prototype.hover = function(respond) {
321
+ var element = Utils.getElementAt(respond.elementId, respond.context);
322
+
323
+ var events = Utils.getNativeEvents();
324
+ var node = Utils.getNodeForNativeEvents(element);
325
+
326
+ if (this.enableNativeEvents && events && node) {
327
+ var loc = Utils.getLocationOnceScrolledIntoView(element);
328
+
329
+ var x = loc.x + (loc.width ? loc.width / 2 : 0);
330
+ var y = loc.y + (loc.height ? loc.height / 2 : 0);
331
+
332
+ events.mouseMove(node, this.currentX, this.currentY, x, y);
333
+ this.currentX = x;
334
+ this.currentY = y;
335
+ } else {
336
+ respond.isError = true;
337
+ respond.response = "Unable to hover over element";
338
+ }
339
+
340
+ respond.send();
341
+ };
342
+
343
+ FirefoxDriver.prototype.submit = function(respond) {
344
+ var element = Utils.getElementAt(respond.elementId, respond.context);
345
+
346
+ if (element) {
347
+ while (element.parentNode != null && element.tagName.toLowerCase() != "form") {
348
+ element = element.parentNode;
349
+ }
350
+ if (element.tagName && element.tagName.toLowerCase() == "form") {
351
+ if (Utils.fireHtmlEvent(respond.context, element, "submit")) {
352
+ new WebLoadingListener(Utils.getBrowser(respond.context), function() {
353
+ respond.send();
354
+ });
355
+ element.submit();
356
+ return;
357
+ } else {
358
+ //Event was blocked, so don't submit
359
+ respond.send();
360
+ return;
361
+ }
362
+ } else {
363
+ respond.isError = true;
364
+ respond.response = "Element was not in a form so couldn't submit";
365
+ respond.send();
366
+ return;
367
+ }
368
+ } else {
369
+ respond.send();
370
+ return;
371
+ }
372
+ };
373
+
374
+ FirefoxDriver.prototype.isSelected = function(respond) {
375
+ var element = Utils.getElementAt(respond.elementId, respond.context);
376
+
377
+ var selected = false;
378
+
379
+ try {
380
+ var option =
381
+ element.QueryInterface(Components.interfaces.nsIDOMHTMLOptionElement);
382
+ selected = option.selected;
383
+ } catch(e) {
384
+ }
385
+
386
+ try {
387
+ var inputElement =
388
+ element.QueryInterface(Components.interfaces.nsIDOMHTMLInputElement);
389
+ if (inputElement.type == "checkbox" || inputElement.type == "radio") {
390
+ selected = inputElement.checked;
391
+ }
392
+ } catch(e) {
393
+ }
394
+
395
+ respond.response = selected;
396
+ respond.send();
397
+ };
398
+
399
+
400
+ FirefoxDriver.prototype.setSelected = function(respond) {
401
+ var element = Utils.getElementAt(respond.elementId, respond.context);
402
+
403
+ if (!Utils.isDisplayed(element, true) && !Utils.isInHead(element)) {
404
+ respond.isError = true;
405
+ respond.response =
406
+ "Element is not currently visible and so may not be selected";
407
+ respond.send();
408
+ return;
409
+ }
410
+
411
+ var wasSet = "You may not select an unselectable element";
412
+ respond.isError = true;
413
+
414
+ try {
415
+ var inputElement =
416
+ element.QueryInterface(Components.interfaces.nsIDOMHTMLInputElement);
417
+ if (inputElement.disabled) {
418
+ respond.response = "You may not select a disabled element";
419
+ respond.send();
420
+ return;
421
+ }
422
+ } catch(e) {
423
+ }
424
+
425
+ try {
426
+ var option =
427
+ element.QueryInterface(Components.interfaces.nsIDOMHTMLOptionElement);
428
+ var select = element;
429
+ while (select.parentNode != null && select.tagName.toLowerCase() != "select") {
430
+ select = select.parentNode;
431
+ }
432
+ if (select.tagName.toLowerCase() == "select") {
433
+ select = select.QueryInterface(Components.interfaces.nsIDOMHTMLSelectElement);
434
+ } else {
435
+ //If we're not within a select element, fire the event from the option, and hope that it bubbles up
436
+ Utils.dumpn("Falling back to event firing from option, not select element");
437
+ select = option;
438
+ }
439
+ respond.isError = false;
440
+ if (!option.selected) {
441
+ option.selected = true;
442
+ Utils.fireHtmlEvent(respond.context, select, "change");
443
+ }
444
+ wasSet = "";
445
+ } catch(e) {
446
+ }
447
+
448
+ try {
449
+ var checkbox =
450
+ element.QueryInterface(Components.interfaces.nsIDOMHTMLInputElement);
451
+ respond.isError = false;
452
+ if (checkbox.type == "checkbox" || checkbox.type == "radio") {
453
+ if (!checkbox.checked) {
454
+ checkbox.checked = true;
455
+ Utils.fireHtmlEvent(respond.context, checkbox, "change");
456
+ }
457
+ wasSet = "";
458
+ }
459
+ } catch(e) {
460
+ }
461
+
462
+ respond.response = wasSet;
463
+ respond.send();
464
+ };
465
+
466
+
467
+ FirefoxDriver.prototype.toggle = function(respond) {
468
+ var element = Utils.getElementAt(respond.elementId, respond.context);
469
+
470
+ if (!Utils.isDisplayed(element) && !Utils.isInHead(element)) {
471
+ respond.isError = true;
472
+ respond.response =
473
+ "Element is not currently visible and so may not be toggled";
474
+ respond.send();
475
+ return;
476
+ }
477
+
478
+ try {
479
+ var checkbox =
480
+ element.QueryInterface(Components.interfaces.nsIDOMHTMLInputElement);
481
+ if (checkbox.type == "checkbox") {
482
+ checkbox.checked = !checkbox.checked;
483
+ Utils.fireHtmlEvent(respond.context, checkbox, "change");
484
+ respond.send();
485
+ return;
486
+ }
487
+ } catch(e) {
488
+ }
489
+
490
+ try {
491
+ var option =
492
+ element.QueryInterface(Components.interfaces.nsIDOMHTMLOptionElement);
493
+
494
+ // Find our containing select and see if it allows multiple selections
495
+ var select = option.parentNode;
496
+ while (select && select.tagName != "SELECT") {
497
+ select = select.parentNode;
498
+ }
499
+
500
+ if (select && select.multiple) {
501
+ option.selected = !option.selected;
502
+ Utils.fireHtmlEvent(respond.context, option, "change");
503
+ respond.send();
504
+ return;
505
+ }
506
+ } catch(e) {
507
+ }
508
+
509
+ respond.isError = true;
510
+ respond.response =
511
+ "You may only toggle an element that is either a checkbox or an " +
512
+ "option in a select that allows multiple selections";
513
+ respond.send();
514
+ };
515
+
516
+
517
+ FirefoxDriver.prototype.isDisplayed = function(respond) {
518
+ var element = Utils.getElementAt(respond.elementId, respond.context);
519
+ respond.response = Utils.isDisplayed(element, false);
520
+ respond.send();
521
+ };
522
+
523
+
524
+ FirefoxDriver.prototype.getLocation = function(respond) {
525
+ var element = Utils.getElementAt(respond.elementId, respond.context);
526
+
527
+ var location = Utils.getElementLocation(element, respond.context);
528
+
529
+ respond.response = {
530
+ x: Math.round(location.x),
531
+ y: Math.round(location.y)
532
+ };
533
+ respond.send();
534
+ };
535
+
536
+
537
+ FirefoxDriver.prototype.getSize = function(respond) {
538
+ var element = Utils.getElementAt(respond.elementId, respond.context);
539
+
540
+ var box = Utils.getLocationOnceScrolledIntoView(element);
541
+
542
+ respond.response = {
543
+ width: Math.round(box.width),
544
+ height: Math.round(box.height)
545
+ };
546
+ respond.send();
547
+ };
548
+
549
+
550
+ FirefoxDriver.prototype.dragElement = function(respond, movementString) {
551
+ var element = Utils.getElementAt(respond.elementId, respond.context);
552
+
553
+ if (!Utils.isDisplayed(element, true) && !Utils.isInHead(element)) {
554
+ respond.isError = true;
555
+ respond.response =
556
+ "Element is not currently visible and so may not be used for drag and drop";
557
+ respond.send();
558
+ return;
559
+ }
560
+
561
+ // Scroll the first element into view
562
+ // element.scrollIntoView(true);
563
+
564
+ var clientStartXY = Utils.getElementLocation(element, respond.context);
565
+
566
+ var clientStartX = clientStartXY.x;
567
+ var clientStartY = clientStartXY.y;
568
+
569
+ var movementX = movementString[0];
570
+ var movementY = movementString[1];
571
+
572
+ var clientFinishX = ((clientStartX + movementX) < 0) ? 0 : (clientStartX
573
+ + movementX);
574
+ var clientFinishY = ((clientStartY + movementY) < 0) ? 0 : (clientStartY
575
+ + movementY);
576
+
577
+ // Restrict the desitnation into the sensible dimension
578
+ var body = element.ownerDocument.body;
579
+
580
+ if (clientFinishX > body.scrollWidth)
581
+ clientFinishX = body.scrollWidth;
582
+ if (clientFinishY > body.scrollHeight)
583
+ clientFinishY = body.scrollHeight;
584
+
585
+ var mouseSpeed = this.mouseSpeed;
586
+ var move = function(current, dest) {
587
+ if (current == dest) return current;
588
+ if (Math.abs(current - dest) < mouseSpeed) return dest;
589
+ return (current < dest) ? current + mouseSpeed : current - mouseSpeed;
590
+ };
591
+
592
+ Utils.triggerMouseEvent(element, 'mousedown', clientStartX, clientStartY);
593
+ Utils.triggerMouseEvent(element, 'mousemove', clientStartX, clientStartY);
594
+ var clientX = clientStartX;
595
+ var clientY = clientStartY;
596
+
597
+ while ((clientX != clientFinishX) || (clientY != clientFinishY)) {
598
+ clientX = move(clientX, clientFinishX);
599
+ clientY = move(clientY, clientFinishY);
600
+
601
+ Utils.triggerMouseEvent(element, 'mousemove', clientX, clientY);
602
+ }
603
+
604
+ Utils.triggerMouseEvent(element, 'mousemove', clientFinishX, clientFinishY);
605
+
606
+ // TODO(simon.m.stewart) If we can tell which element is under the cursor,
607
+ // send the mouseup to that
608
+ Utils.triggerMouseEvent(element, 'mouseup', clientFinishX, clientFinishY);
609
+
610
+ var finalLoc = Utils.getElementLocation(element, respond.context)
611
+
612
+ respond.response = finalLoc.x + "," + finalLoc.y;
613
+ respond.send();
614
+ };
615
+
616
+
617
+ FirefoxDriver.prototype.getValueOfCssProperty = function(respond,
618
+ propertyName) {
619
+ var element = Utils.getElementAt(respond.elementId, respond.context);
620
+
621
+ respond.response = Utils.getStyleProperty(element, propertyName); // Coeerce to a string
622
+ respond.send();
623
+ };
624
+
625
+
626
+ FirefoxDriver.prototype.getLocationOnceScrolledIntoView = function(respond) {
627
+ var element = Utils.getElementAt(respond.elementId, respond.context);
628
+
629
+ if (!Utils.isDisplayed(element, true)) {
630
+ respond.response = undefined;
631
+ respond.send();
632
+ return;
633
+ }
634
+
635
+ var theDoc = element.ownerDocument;
636
+ theDoc.body.focus();
637
+ element.scrollIntoView(true);
638
+
639
+ var retrieval = Utils.newInstance(
640
+ "@mozilla.org/accessibleRetrieval;1", "nsIAccessibleRetrieval");
641
+
642
+ try {
643
+ var accessible = retrieval.getAccessibleFor(element);
644
+ var x = {}, y = {}, width = {}, height = {};
645
+ accessible.getBounds(x, y, width, height);
646
+
647
+ respond.response = {
648
+ x : x.value,
649
+ y : y.value
650
+ };
651
+ respond.send();
652
+ return;
653
+ } catch(e) {
654
+ // Element doesn't have an accessibility node. Fall through
655
+ }
656
+
657
+ // If we have the box object (which is deprecated) we could try using it
658
+ if (theDoc.getBoxObjectFor) {
659
+ // Fallback. Use the (deprecated) method to find out where the element is in
660
+ // the viewport. This should be fine to use because we only fall down this
661
+ // code path on older versions of Firefox (I think!)
662
+
663
+ var box = theDoc.getBoxObjectFor(element);
664
+
665
+ respond.response = {
666
+ x : box.screenX,
667
+ y : box.screenY
668
+ };
669
+ respond.send();
670
+ }
671
+
672
+ // Fine. Come up with a good guess. This should be the element location
673
+ // added to the current window location. It'll probably be off
674
+ var x = theDoc.defaultView.screenX;
675
+ var y = theDoc.defaultView.screenY;
676
+
677
+ var rect = element.getBoundingClientRect()
678
+ respond.response = {
679
+ x : x + rect.left,
680
+ y : y + rect.top
681
+ }
682
+ respond.send();
683
+ };