browserstack-webdriver 0.0.1

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 (202) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +791 -0
  3. data/README.md +31 -0
  4. data/build.desc +334 -0
  5. data/lib/selenium-client.rb +2 -0
  6. data/lib/selenium-webdriver.rb +1 -0
  7. data/lib/selenium/client.rb +37 -0
  8. data/lib/selenium/client/base.rb +132 -0
  9. data/lib/selenium/client/driver.rb +10 -0
  10. data/lib/selenium/client/errors.rb +9 -0
  11. data/lib/selenium/client/extensions.rb +118 -0
  12. data/lib/selenium/client/idiomatic.rb +488 -0
  13. data/lib/selenium/client/javascript_expression_builder.rb +116 -0
  14. data/lib/selenium/client/javascript_frameworks/jquery.rb +13 -0
  15. data/lib/selenium/client/javascript_frameworks/prototype.rb +13 -0
  16. data/lib/selenium/client/legacy_driver.rb +1720 -0
  17. data/lib/selenium/client/protocol.rb +104 -0
  18. data/lib/selenium/client/selenium_helper.rb +34 -0
  19. data/lib/selenium/rake/server_task.rb +157 -0
  20. data/lib/selenium/server.rb +248 -0
  21. data/lib/selenium/webdriver.rb +71 -0
  22. data/lib/selenium/webdriver/android.rb +9 -0
  23. data/lib/selenium/webdriver/android/bridge.rb +47 -0
  24. data/lib/selenium/webdriver/chrome.rb +26 -0
  25. data/lib/selenium/webdriver/chrome/bridge.rb +120 -0
  26. data/lib/selenium/webdriver/chrome/profile.rb +90 -0
  27. data/lib/selenium/webdriver/chrome/service.rb +75 -0
  28. data/lib/selenium/webdriver/common.rb +44 -0
  29. data/lib/selenium/webdriver/common/action_builder.rb +352 -0
  30. data/lib/selenium/webdriver/common/alert.rb +30 -0
  31. data/lib/selenium/webdriver/common/bridge_helper.rb +67 -0
  32. data/lib/selenium/webdriver/common/core_ext/base64.rb +9 -0
  33. data/lib/selenium/webdriver/common/core_ext/dir.rb +42 -0
  34. data/lib/selenium/webdriver/common/core_ext/string.rb +5 -0
  35. data/lib/selenium/webdriver/common/driver.rb +301 -0
  36. data/lib/selenium/webdriver/common/driver_extensions/has_browser_connection.rb +17 -0
  37. data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +39 -0
  38. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +25 -0
  39. data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +13 -0
  40. data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +22 -0
  41. data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +19 -0
  42. data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +22 -0
  43. data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +45 -0
  44. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +43 -0
  45. data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +46 -0
  46. data/lib/selenium/webdriver/common/element.rb +293 -0
  47. data/lib/selenium/webdriver/common/error.rb +207 -0
  48. data/lib/selenium/webdriver/common/file_reaper.rb +47 -0
  49. data/lib/selenium/webdriver/common/html5/local_storage.rb +42 -0
  50. data/lib/selenium/webdriver/common/html5/location.rb +0 -0
  51. data/lib/selenium/webdriver/common/html5/session_storage.rb +44 -0
  52. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +42 -0
  53. data/lib/selenium/webdriver/common/json_helper.rb +34 -0
  54. data/lib/selenium/webdriver/common/keyboard.rb +55 -0
  55. data/lib/selenium/webdriver/common/keys.rb +109 -0
  56. data/lib/selenium/webdriver/common/log_entry.rb +29 -0
  57. data/lib/selenium/webdriver/common/logs.rb +23 -0
  58. data/lib/selenium/webdriver/common/mouse.rb +72 -0
  59. data/lib/selenium/webdriver/common/navigation.rb +43 -0
  60. data/lib/selenium/webdriver/common/options.rb +136 -0
  61. data/lib/selenium/webdriver/common/platform.rb +218 -0
  62. data/lib/selenium/webdriver/common/port_prober.rb +42 -0
  63. data/lib/selenium/webdriver/common/profile_helper.rb +67 -0
  64. data/lib/selenium/webdriver/common/proxy.rb +149 -0
  65. data/lib/selenium/webdriver/common/search_context.rb +92 -0
  66. data/lib/selenium/webdriver/common/socket_poller.rb +105 -0
  67. data/lib/selenium/webdriver/common/target_locator.rb +81 -0
  68. data/lib/selenium/webdriver/common/timeouts.rb +38 -0
  69. data/lib/selenium/webdriver/common/touch_action_builder.rb +64 -0
  70. data/lib/selenium/webdriver/common/touch_screen.rb +105 -0
  71. data/lib/selenium/webdriver/common/wait.rb +63 -0
  72. data/lib/selenium/webdriver/common/window.rb +104 -0
  73. data/lib/selenium/webdriver/common/zipper.rb +82 -0
  74. data/lib/selenium/webdriver/firefox.rb +37 -0
  75. data/lib/selenium/webdriver/firefox/binary.rb +158 -0
  76. data/lib/selenium/webdriver/firefox/bridge.rb +70 -0
  77. data/lib/selenium/webdriver/firefox/extension.rb +52 -0
  78. data/lib/selenium/webdriver/firefox/launcher.rb +106 -0
  79. data/lib/selenium/webdriver/firefox/profile.rb +263 -0
  80. data/lib/selenium/webdriver/firefox/profiles_ini.rb +62 -0
  81. data/lib/selenium/webdriver/firefox/socket_lock.rb +61 -0
  82. data/lib/selenium/webdriver/firefox/util.rb +29 -0
  83. data/lib/selenium/webdriver/ie.rb +19 -0
  84. data/lib/selenium/webdriver/ie/bridge.rb +68 -0
  85. data/lib/selenium/webdriver/ie/server.rb +86 -0
  86. data/lib/selenium/webdriver/iphone.rb +9 -0
  87. data/lib/selenium/webdriver/iphone/bridge.rb +45 -0
  88. data/lib/selenium/webdriver/opera.rb +24 -0
  89. data/lib/selenium/webdriver/opera/bridge.rb +112 -0
  90. data/lib/selenium/webdriver/opera/service.rb +49 -0
  91. data/lib/selenium/webdriver/phantomjs.rb +22 -0
  92. data/lib/selenium/webdriver/phantomjs/bridge.rb +59 -0
  93. data/lib/selenium/webdriver/phantomjs/service.rb +90 -0
  94. data/lib/selenium/webdriver/remote.rb +22 -0
  95. data/lib/selenium/webdriver/remote/bridge.rb +644 -0
  96. data/lib/selenium/webdriver/remote/capabilities.rb +267 -0
  97. data/lib/selenium/webdriver/remote/commands.rb +193 -0
  98. data/lib/selenium/webdriver/remote/http/common.rb +74 -0
  99. data/lib/selenium/webdriver/remote/http/curb.rb +79 -0
  100. data/lib/selenium/webdriver/remote/http/default.rb +139 -0
  101. data/lib/selenium/webdriver/remote/http/persistent.rb +38 -0
  102. data/lib/selenium/webdriver/remote/response.rb +97 -0
  103. data/lib/selenium/webdriver/remote/server_error.rb +17 -0
  104. data/lib/selenium/webdriver/safari.rb +46 -0
  105. data/lib/selenium/webdriver/safari/bridge.rb +110 -0
  106. data/lib/selenium/webdriver/safari/browser.rb +20 -0
  107. data/lib/selenium/webdriver/safari/extension.rb +120 -0
  108. data/lib/selenium/webdriver/safari/server.rb +145 -0
  109. data/lib/selenium/webdriver/support.rb +5 -0
  110. data/lib/selenium/webdriver/support/abstract_event_listener.rb +28 -0
  111. data/lib/selenium/webdriver/support/block_event_listener.rb +17 -0
  112. data/lib/selenium/webdriver/support/color.rb +110 -0
  113. data/lib/selenium/webdriver/support/event_firing_bridge.rb +112 -0
  114. data/lib/selenium/webdriver/support/select.rb +293 -0
  115. data/ruby.iml +13 -0
  116. data/spec/integration/selenium/client/api/backward_compatible_api_spec.rb +22 -0
  117. data/spec/integration/selenium/client/api/browser_xpath_library_spec.rb +17 -0
  118. data/spec/integration/selenium/client/api/click_spec.rb +39 -0
  119. data/spec/integration/selenium/client/api/cookie_spec.rb +39 -0
  120. data/spec/integration/selenium/client/api/element_spec.rb +14 -0
  121. data/spec/integration/selenium/client/api/highlight_located_element_spec.rb +19 -0
  122. data/spec/integration/selenium/client/api/retrieve_last_remote_control_logs_spec.rb +33 -0
  123. data/spec/integration/selenium/client/api/screenshot_spec.rb +31 -0
  124. data/spec/integration/selenium/client/api/select_window_spec.rb +46 -0
  125. data/spec/integration/selenium/client/api/start_stop_spec.rb +9 -0
  126. data/spec/integration/selenium/client/api/wait_for_ajax_spec.rb +27 -0
  127. data/spec/integration/selenium/client/api/wait_for_element_spec.rb +56 -0
  128. data/spec/integration/selenium/client/api/wait_for_field_value_spec.rb +52 -0
  129. data/spec/integration/selenium/client/api/wait_for_text_spec.rb +98 -0
  130. data/spec/integration/selenium/client/api/webdriver_backed_spec.rb +21 -0
  131. data/spec/integration/selenium/client/sample-app/public/jquery-1.3.2.js +4376 -0
  132. data/spec/integration/selenium/client/sample-app/public/jquery.html +55 -0
  133. data/spec/integration/selenium/client/sample-app/public/prototype-1.6.0.3.js +4320 -0
  134. data/spec/integration/selenium/client/sample-app/public/prototype.html +59 -0
  135. data/spec/integration/selenium/client/sample-app/sample_app.rb +32 -0
  136. data/spec/integration/selenium/client/spec_helper.rb +139 -0
  137. data/spec/integration/selenium/webdriver/app_cache_spec.rb +47 -0
  138. data/spec/integration/selenium/webdriver/browser_connection_spec.rb +20 -0
  139. data/spec/integration/selenium/webdriver/chrome/driver_spec.rb +28 -0
  140. data/spec/integration/selenium/webdriver/chrome/profile_spec.rb +63 -0
  141. data/spec/integration/selenium/webdriver/driver_spec.rb +266 -0
  142. data/spec/integration/selenium/webdriver/element_spec.rb +191 -0
  143. data/spec/integration/selenium/webdriver/error_spec.rb +30 -0
  144. data/spec/integration/selenium/webdriver/firefox/driver_spec.rb +21 -0
  145. data/spec/integration/selenium/webdriver/firefox/profile_spec.rb +141 -0
  146. data/spec/integration/selenium/webdriver/keyboard_spec.rb +57 -0
  147. data/spec/integration/selenium/webdriver/location_spec.rb +29 -0
  148. data/spec/integration/selenium/webdriver/mouse_spec.rb +57 -0
  149. data/spec/integration/selenium/webdriver/navigation_spec.rb +46 -0
  150. data/spec/integration/selenium/webdriver/opera/driver_spec.rb +47 -0
  151. data/spec/integration/selenium/webdriver/options_spec.rb +77 -0
  152. data/spec/integration/selenium/webdriver/remote/driver_spec.rb +19 -0
  153. data/spec/integration/selenium/webdriver/remote/element_spec.rb +26 -0
  154. data/spec/integration/selenium/webdriver/spec_helper.rb +36 -0
  155. data/spec/integration/selenium/webdriver/spec_support.rb +12 -0
  156. data/spec/integration/selenium/webdriver/spec_support/guards.rb +110 -0
  157. data/spec/integration/selenium/webdriver/spec_support/helpers.rb +51 -0
  158. data/spec/integration/selenium/webdriver/spec_support/rack_server.rb +123 -0
  159. data/spec/integration/selenium/webdriver/spec_support/test_environment.rb +239 -0
  160. data/spec/integration/selenium/webdriver/sql_database_spec.rb +59 -0
  161. data/spec/integration/selenium/webdriver/storage_spec.rb +96 -0
  162. data/spec/integration/selenium/webdriver/target_locator_spec.rb +186 -0
  163. data/spec/integration/selenium/webdriver/timeout_spec.rb +69 -0
  164. data/spec/integration/selenium/webdriver/touch_spec.rb +176 -0
  165. data/spec/integration/selenium/webdriver/window_spec.rb +70 -0
  166. data/spec/integration/selenium/webdriver/zipper_spec.rb +66 -0
  167. data/spec/unit/selenium/client/base_spec.rb +239 -0
  168. data/spec/unit/selenium/client/extensions_spec.rb +174 -0
  169. data/spec/unit/selenium/client/idiomatic_spec.rb +500 -0
  170. data/spec/unit/selenium/client/javascript_expression_builder_spec.rb +79 -0
  171. data/spec/unit/selenium/client/javascript_frameworks/jquery_spec.rb +10 -0
  172. data/spec/unit/selenium/client/javascript_frameworks/prototype_spec.rb +10 -0
  173. data/spec/unit/selenium/client/protocol_spec.rb +124 -0
  174. data/spec/unit/selenium/client/selenium_helper_spec.rb +56 -0
  175. data/spec/unit/selenium/client/spec_helper.rb +24 -0
  176. data/spec/unit/selenium/rake/task_spec.rb +79 -0
  177. data/spec/unit/selenium/server_spec.rb +150 -0
  178. data/spec/unit/selenium/webdriver/action_builder_spec.rb +97 -0
  179. data/spec/unit/selenium/webdriver/android/bridge_spec.rb +43 -0
  180. data/spec/unit/selenium/webdriver/chrome/bridge_spec.rb +137 -0
  181. data/spec/unit/selenium/webdriver/chrome/profile_spec.rb +57 -0
  182. data/spec/unit/selenium/webdriver/chrome/service_spec.rb +44 -0
  183. data/spec/unit/selenium/webdriver/error_spec.rb +41 -0
  184. data/spec/unit/selenium/webdriver/firefox/bridge_spec.rb +47 -0
  185. data/spec/unit/selenium/webdriver/ie/bridge_spec.rb +91 -0
  186. data/spec/unit/selenium/webdriver/iphone/bridge_spec.rb +42 -0
  187. data/spec/unit/selenium/webdriver/log_entry_spec.rb +11 -0
  188. data/spec/unit/selenium/webdriver/opera/bridge_spec.rb +44 -0
  189. data/spec/unit/selenium/webdriver/phantomjs/bridge_spec.rb +55 -0
  190. data/spec/unit/selenium/webdriver/proxy_spec.rb +106 -0
  191. data/spec/unit/selenium/webdriver/remote/bridge_spec.rb +16 -0
  192. data/spec/unit/selenium/webdriver/remote/capabilities_spec.rb +115 -0
  193. data/spec/unit/selenium/webdriver/remote/http/common_spec.rb +24 -0
  194. data/spec/unit/selenium/webdriver/remote/http/default_spec.rb +124 -0
  195. data/spec/unit/selenium/webdriver/search_context_spec.rb +61 -0
  196. data/spec/unit/selenium/webdriver/socket_poller_spec.rb +68 -0
  197. data/spec/unit/selenium/webdriver/spec_helper.rb +27 -0
  198. data/spec/unit/selenium/webdriver/support/color_spec.rb +119 -0
  199. data/spec/unit/selenium/webdriver/support/event_firing_spec.rb +111 -0
  200. data/spec/unit/selenium/webdriver/support/select_spec.rb +290 -0
  201. data/spec/unit/selenium/webdriver/wait_spec.rb +49 -0
  202. metadata +370 -0
@@ -0,0 +1,22 @@
1
+ require 'uri'
2
+
3
+ require 'selenium/webdriver/remote/capabilities'
4
+ require 'selenium/webdriver/remote/bridge'
5
+ require 'selenium/webdriver/remote/server_error'
6
+ require 'selenium/webdriver/remote/response'
7
+ require 'selenium/webdriver/remote/commands'
8
+ require 'selenium/webdriver/remote/http/common'
9
+ require 'selenium/webdriver/remote/http/default'
10
+ require 'selenium/webdriver/remote/http/curb'
11
+
12
+ module Selenium
13
+ module WebDriver
14
+
15
+ # @api private
16
+ module Remote
17
+
18
+ end
19
+ end
20
+ end
21
+
22
+
@@ -0,0 +1,644 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Remote
4
+
5
+ COMMANDS = {}
6
+
7
+ #
8
+ # Low level bridge to the remote server, through which the rest of the API works.
9
+ #
10
+ # @api private
11
+ #
12
+
13
+ class Bridge
14
+ include BridgeHelper
15
+
16
+ #
17
+ # Defines a wrapper method for a command, which ultimately calls #execute.
18
+ #
19
+ # @param name [Symbol]
20
+ # name of the resulting method
21
+ # @param url [String]
22
+ # a URL template, which can include some arguments, much like the definitions on the server.
23
+ # the :session_id parameter is implicitly handled, but the remainder will become required method arguments.
24
+ # @param verb [Symbol]
25
+ # the appropriate http verb, such as :get, :post, or :delete
26
+ #
27
+
28
+ def self.command(name, verb, url)
29
+ COMMANDS[name] = [verb, url.freeze]
30
+ end
31
+
32
+ attr_accessor :context, :http, :file_detector
33
+ attr_reader :capabilities
34
+
35
+ #
36
+ # Initializes the bridge with the given server URL.
37
+ #
38
+ # @param url [String] url for the remote server
39
+ # @param http_client [Object] an HTTP client instance that implements the same protocol as Http::Default
40
+ # @param desired_capabilities [Capabilities] an instance of Remote::Capabilities describing the capabilities you want
41
+ #
42
+
43
+ def initialize(opts = {})
44
+ opts = opts.dup
45
+
46
+ http_client = opts.delete(:http_client) { Http::Curb.new }
47
+ desired_capabilities = opts.delete(:desired_capabilities) { Capabilities.firefox }
48
+ url = opts.delete(:url) { "http://#{Platform.localhost}:4444/wd/hub" }
49
+
50
+ unless opts.empty?
51
+ raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
52
+ end
53
+
54
+ if desired_capabilities.kind_of?(Symbol)
55
+ unless Capabilities.respond_to?(desired_capabilities)
56
+ raise Error::WebDriverError, "invalid desired capability: #{desired_capabilities.inspect}"
57
+ end
58
+
59
+ desired_capabilities = Capabilities.send(desired_capabilities)
60
+ end
61
+
62
+ uri = url.kind_of?(URI) ? url : URI.parse(url)
63
+ uri.path += "/" unless uri.path =~ /\/$/
64
+
65
+ http_client.server_url = uri
66
+
67
+ @http = http_client
68
+ @capabilities = create_session(desired_capabilities)
69
+ end
70
+
71
+ def browser
72
+ @browser ||= (
73
+ name = @capabilities.browser_name
74
+ name ? name.gsub(" ", "_").to_sym : 'unknown'
75
+ )
76
+ end
77
+
78
+ def driver_extensions
79
+ [
80
+ DriverExtensions::HasInputDevices,
81
+ DriverExtensions::UploadsFiles,
82
+ DriverExtensions::TakesScreenshot,
83
+ DriverExtensions::HasSessionId,
84
+ DriverExtensions::Rotatable,
85
+ DriverExtensions::HasTouchScreen,
86
+ DriverExtensions::HasRemoteStatus
87
+ ]
88
+ end
89
+
90
+ #
91
+ # Returns the current session ID.
92
+ #
93
+
94
+ def session_id
95
+ @session_id || raise(Error::WebDriverError, "no current session exists")
96
+ end
97
+
98
+ def create_session(desired_capabilities)
99
+ resp = raw_execute :newSession, {}, :desiredCapabilities => desired_capabilities
100
+ @session_id = resp['sessionId'] or raise Error::WebDriverError, 'no sessionId in returned payload'
101
+
102
+ Capabilities.json_create resp['value']
103
+ end
104
+
105
+ def status
106
+ execute :status
107
+ end
108
+
109
+ def get(url)
110
+ execute :get, {}, :url => url
111
+ end
112
+
113
+ def getCapabilities
114
+ Capabilities.json_create execute(:getCapabilities)
115
+ end
116
+
117
+ def setImplicitWaitTimeout(milliseconds)
118
+ execute :implicitlyWait, {}, :ms => milliseconds
119
+ end
120
+
121
+ def setScriptTimeout(milliseconds)
122
+ execute :setScriptTimeout, {}, :ms => milliseconds
123
+ end
124
+
125
+ def setTimeout(type, milliseconds)
126
+ execute :setTimeout, {}, :type => type, :ms => milliseconds
127
+ end
128
+
129
+ #
130
+ # alerts
131
+ #
132
+
133
+ def getAlert
134
+ execute :getAlert
135
+ end
136
+
137
+ def acceptAlert
138
+ execute :acceptAlert
139
+ end
140
+
141
+ def dismissAlert
142
+ execute :dismissAlert
143
+ end
144
+
145
+ def setAlertValue(keys)
146
+ execute :setAlertValue, {}, :text => keys.to_s
147
+ end
148
+
149
+ def getAlertText
150
+ execute :getAlertText
151
+ end
152
+
153
+ #
154
+ # navigation
155
+ #
156
+
157
+ def goBack
158
+ execute :goBack
159
+ end
160
+
161
+ def goForward
162
+ execute :goForward
163
+ end
164
+
165
+ def getCurrentUrl
166
+ execute :getCurrentUrl
167
+ end
168
+
169
+ def getTitle
170
+ execute :getTitle
171
+ end
172
+
173
+ def getPageSource
174
+ execute :getPageSource
175
+ end
176
+
177
+ def getVisible
178
+ execute :getVisible
179
+ end
180
+
181
+ def setVisible(bool)
182
+ execute :setVisible, {}, bool
183
+ end
184
+
185
+ def switchToWindow(name)
186
+ execute :switchToWindow, {}, :name => name
187
+ end
188
+
189
+ def switchToFrame(id)
190
+ execute :switchToFrame, {}, :id => id
191
+ end
192
+
193
+ def switchToDefaultContent
194
+ execute :switchToFrame, {}, :id => nil
195
+ end
196
+
197
+ QUIT_ERRORS = [IOError]
198
+
199
+ def quit
200
+ execute :quit
201
+ http.close
202
+ rescue *QUIT_ERRORS
203
+ end
204
+
205
+ def close
206
+ execute :close
207
+ end
208
+
209
+ def refresh
210
+ execute :refresh
211
+ end
212
+
213
+ #
214
+ # window handling
215
+ #
216
+
217
+ def getWindowHandles
218
+ execute :getWindowHandles
219
+ end
220
+
221
+ def getCurrentWindowHandle
222
+ execute :getCurrentWindowHandle
223
+ end
224
+
225
+ def setWindowSize(width, height, handle = :current)
226
+ execute :setWindowSize, {:window_handle => handle},
227
+ :width => width,
228
+ :height => height
229
+ end
230
+
231
+ def maximizeWindow(handle = :current)
232
+ execute :maximizeWindow, :window_handle => handle
233
+ end
234
+
235
+ def getWindowSize(handle = :current)
236
+ data = execute :getWindowSize, :window_handle => handle
237
+
238
+ Dimension.new data['width'], data['height']
239
+ end
240
+
241
+ def setWindowPosition(x, y, handle = :current)
242
+ execute :setWindowPosition, {:window_handle => handle},
243
+ :x => x, :y => y
244
+ end
245
+
246
+ def getWindowPosition(handle = :current)
247
+ data = execute :getWindowPosition, :window_handle => handle
248
+
249
+ Point.new data['x'], data['y']
250
+ end
251
+
252
+ def getScreenshot
253
+ execute :screenshot
254
+ end
255
+
256
+ #
257
+ # HTML 5
258
+ #
259
+
260
+ def getLocalStorageItem(key)
261
+ execute :getLocalStorageItem, :key => key
262
+ end
263
+
264
+ def removeLocalStorageItem(key)
265
+ execute :removeLocalStorageItem, :key => key
266
+ end
267
+
268
+ def getLocalStorageKeys
269
+ execute :getLocalStorageKeys
270
+ end
271
+
272
+ def setLocalStorageItem(key, value)
273
+ execute :setLocalStorageItem, {}, :key => key, :value => value
274
+ end
275
+
276
+ def clearLocalStorage
277
+ execute :clearLocalStorage
278
+ end
279
+
280
+ def getLocalStorageSize
281
+ execute :getLocalStorageSize
282
+ end
283
+
284
+ def getSessionStorageItem(key)
285
+ execute :getSessionStorageItem, :key => key
286
+ end
287
+
288
+ def removeSessionStorageItem(key)
289
+ execute :removeSessionStorageItem, :key => key
290
+ end
291
+
292
+ def getSessionStorageKeys
293
+ execute :getSessionStorageKeys
294
+ end
295
+
296
+ def setSessionStorageItem(key, value)
297
+ execute :setSessionStorageItem, {}, :key => key, :value => value
298
+ end
299
+
300
+ def clearSessionStorage
301
+ execute :clearSessionStorage
302
+ end
303
+
304
+ def getSessionStorageSize
305
+ execute :getSessionStorageSize
306
+ end
307
+
308
+ def getLocation
309
+ obj = execute(:getLocation) || {} # android returns null
310
+ Location.new obj['latitude'], obj['longitude'], obj['altitude']
311
+ end
312
+
313
+ def setLocation(lat, lon, alt)
314
+ loc = {:latitude => lat, :longitude => lon, :altitude => alt}
315
+ execute :setLocation, {}, :location => loc
316
+ end
317
+
318
+ def isBrowserOnline
319
+ execute :isBrowserOnline
320
+ end
321
+
322
+ def setBrowserOnline(bool)
323
+ execute :setBrowserOnline, {}, :state => bool
324
+ end
325
+
326
+ #
327
+ # javascript execution
328
+ #
329
+
330
+ def executeScript(script, *args)
331
+ assert_javascript_enabled
332
+
333
+ result = execute :executeScript, {}, :script => script, :args => args
334
+ unwrap_script_result result
335
+ end
336
+
337
+ def executeAsyncScript(script, *args)
338
+ assert_javascript_enabled
339
+
340
+ result = execute :executeAsyncScript, {}, :script => script, :args => args
341
+ unwrap_script_result result
342
+ end
343
+
344
+ #
345
+ # cookies
346
+ #
347
+
348
+ def addCookie(cookie)
349
+ execute :addCookie, {}, :cookie => cookie
350
+ end
351
+
352
+ def deleteCookie(name)
353
+ execute :deleteCookie, :name => name
354
+ end
355
+
356
+ def getAllCookies
357
+ execute :getCookies
358
+ end
359
+
360
+ def deleteAllCookies
361
+ execute :deleteAllCookies
362
+ end
363
+
364
+ #
365
+ # actions
366
+ #
367
+
368
+ def clickElement(element)
369
+ execute :clickElement, :id => element
370
+ end
371
+
372
+ def click
373
+ execute :click, {}, :button => 0
374
+ end
375
+
376
+ def doubleClick
377
+ execute :doubleClick
378
+ end
379
+
380
+ def contextClick
381
+ execute :click, {}, :button => 2
382
+ end
383
+
384
+ def mouseDown
385
+ execute :mouseDown
386
+ end
387
+
388
+ def mouseUp
389
+ execute :mouseUp
390
+ end
391
+
392
+ def mouseMoveTo(element, x = nil, y = nil)
393
+ params = { :element => element }
394
+
395
+ if x && y
396
+ params.merge! :xoffset => x, :yoffset => y
397
+ end
398
+
399
+ execute :mouseMoveTo, {}, params
400
+ end
401
+
402
+ def sendKeysToActiveElement(key)
403
+ execute :sendKeysToActiveElement, {}, :value => key
404
+ end
405
+
406
+ def sendKeysToElement(element, keys)
407
+ if @file_detector && local_file = @file_detector.call(keys)
408
+ keys = upload(local_file)
409
+ end
410
+
411
+ execute :sendKeysToElement, {:id => element}, {:value => Array(keys)}
412
+ end
413
+
414
+ def upload(local_file)
415
+ unless File.file?(local_file)
416
+ raise WebDriverError::Error, "you may only upload files: #{local_file.inspect}"
417
+ end
418
+
419
+ execute :uploadFile, {}, :file => Zipper.zip_file(local_file)
420
+ end
421
+
422
+ def clearElement(element)
423
+ execute :clearElement, :id => element
424
+ end
425
+
426
+
427
+ def submitElement(element)
428
+ execute :submitElement, :id => element
429
+ end
430
+
431
+ def dragElement(element, right_by, down_by)
432
+ execute :dragElement, {:id => element}, :x => right_by, :y => down_by
433
+ end
434
+
435
+ def touchSingleTap(element)
436
+ execute :touchSingleTap, {}, :element => element
437
+ end
438
+
439
+ def touchDoubleTap(element)
440
+ execute :touchDoubleTap, {}, :element => element
441
+ end
442
+
443
+ def touchLongPress(element)
444
+ execute :touchLongPress, {}, :element => element
445
+ end
446
+
447
+ def touchDown(x, y)
448
+ execute :touchDown, {}, :x => x, :y => y
449
+ end
450
+
451
+ def touchUp(x, y)
452
+ execute :touchUp, {}, :x => x, :y => y
453
+ end
454
+
455
+ def touchMove(x, y)
456
+ execute :touchMove, {}, :x => x, :y => y
457
+ end
458
+
459
+ def touchScroll(element, x, y)
460
+ if element
461
+ execute :touchScroll, {}, :element => element,
462
+ :xoffset => x,
463
+ :yoffset => y
464
+ else
465
+ execute :touchScroll, {}, :xoffset => x, :yoffset => y
466
+ end
467
+ end
468
+
469
+ def touchFlick(xspeed, yspeed)
470
+ execute :touchFlick, {}, :xspeed => xspeed, :yspeed => yspeed
471
+ end
472
+
473
+ def touchElementFlick(element, right_by, down_by, speed)
474
+ execute :touchFlick, {}, :element => element,
475
+ :xoffset => right_by,
476
+ :yoffset => down_by,
477
+ :speed => speed
478
+
479
+ end
480
+
481
+ def setScreenOrientation(orientation)
482
+ execute :setScreenOrientation, {}, :orientation => orientation
483
+ end
484
+
485
+ def getScreenOrientation
486
+ execute :getScreenOrientation
487
+ end
488
+
489
+ #
490
+ # logs
491
+ #
492
+
493
+ def getAvailableLogTypes
494
+ types = execute :getAvailableLogTypes
495
+ Array(types).map { |e| e.to_sym }
496
+ end
497
+
498
+ def getLog(type)
499
+ data = execute :getLog, {}, :type => type.to_s
500
+
501
+ Array(data).map do |l|
502
+ LogEntry.new l.fetch('level'), l.fetch('timestamp'), l.fetch('message')
503
+ end
504
+ end
505
+
506
+ #
507
+ # element properties
508
+ #
509
+
510
+ def getElementTagName(element)
511
+ execute :getElementTagName, :id => element
512
+ end
513
+
514
+ def getElementAttribute(element, name)
515
+ execute :getElementAttribute, :id => element, :name => name
516
+ end
517
+
518
+ def getElementValue(element)
519
+ execute :getElementValue, :id => element
520
+ end
521
+
522
+ def getElementText(element)
523
+ execute :getElementText, :id => element
524
+ end
525
+
526
+ def getElementLocation(element)
527
+ data = execute :getElementLocation, :id => element
528
+
529
+ Point.new data['x'], data['y']
530
+ end
531
+
532
+ def getElementLocationOnceScrolledIntoView(element)
533
+ data = execute :getElementLocationOnceScrolledIntoView, :id => element
534
+
535
+ Point.new data['x'], data['y']
536
+ end
537
+
538
+ def getElementSize(element)
539
+ data = execute :getElementSize, :id => element
540
+
541
+ Dimension.new data['width'], data['height']
542
+ end
543
+
544
+ def isElementEnabled(element)
545
+ execute :isElementEnabled, :id => element
546
+ end
547
+
548
+ def isElementSelected(element)
549
+ execute :isElementSelected, :id => element
550
+ end
551
+
552
+ def isElementDisplayed(element)
553
+ execute :isElementDisplayed, :id => element
554
+ end
555
+ def getElementValueOfCssProperty(element, prop)
556
+ execute :getElementValueOfCssProperty, :id => element, :property_name => prop
557
+ end
558
+
559
+ def elementEquals(element, other)
560
+ if element.ref == other.ref
561
+ true
562
+ else
563
+ execute :elementEquals, :id => element.ref, :other => other.ref
564
+ end
565
+ end
566
+
567
+ #
568
+ # finding elements
569
+ #
570
+
571
+ def getActiveElement
572
+ Element.new self, element_id_from(execute(:getActiveElement))
573
+ end
574
+ alias_method :switchToActiveElement, :getActiveElement
575
+
576
+ def find_element_by(how, what, parent = nil)
577
+ if parent
578
+ id = execute :findChildElement, {:id => parent}, {:using => how, :value => what}
579
+ else
580
+ id = execute :findElement, {}, {:using => how, :value => what}
581
+ end
582
+
583
+ Element.new self, element_id_from(id)
584
+ end
585
+
586
+ def find_elements_by(how, what, parent = nil)
587
+ if parent
588
+ ids = execute :findChildElements, {:id => parent}, {:using => how, :value => what}
589
+ else
590
+ ids = execute :findElements, {}, {:using => how, :value => what}
591
+ end
592
+
593
+ ids.map { |id| Element.new self, element_id_from(id) }
594
+ end
595
+
596
+ private
597
+
598
+ def assert_javascript_enabled
599
+ unless capabilities.javascript_enabled?
600
+ raise Error::UnsupportedOperationError, "underlying webdriver instance does not support javascript"
601
+ end
602
+ end
603
+
604
+ #
605
+ # executes a command on the remote server.
606
+ #
607
+ #
608
+ # Returns the 'value' of the returned payload
609
+ #
610
+
611
+ def execute(*args)
612
+ raw_execute(*args)['value']
613
+ end
614
+
615
+ #
616
+ # executes a command on the remote server.
617
+ #
618
+ # @return [WebDriver::Remote::Response]
619
+ #
620
+
621
+ def raw_execute(command, opts = {}, command_hash = nil)
622
+ verb, path = COMMANDS[command] || raise(ArgumentError, "unknown command: #{command.inspect}")
623
+ path = path.dup
624
+
625
+ path[':session_id'] = @session_id if path.include?(":session_id")
626
+
627
+ begin
628
+ opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s) }
629
+ rescue IndexError
630
+ raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
631
+ end
632
+
633
+ puts "-> #{verb.to_s.upcase} #{path}" if $DEBUG
634
+ http.call verb, path, command_hash
635
+ end
636
+
637
+ def escaper
638
+ @escaper ||= defined?(URI::Parser) ? URI::Parser.new : URI
639
+ end
640
+
641
+ end # Bridge
642
+ end # Remote
643
+ end # WebDriver
644
+ end # Selenium