bbc-selenium-webdriver 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. data/CHANGES +473 -0
  2. data/README +31 -0
  3. data/lib/selenium-client.rb +2 -0
  4. data/lib/selenium-webdriver.rb +1 -0
  5. data/lib/selenium/client.rb +37 -0
  6. data/lib/selenium/client/base.rb +118 -0
  7. data/lib/selenium/client/driver.rb +10 -0
  8. data/lib/selenium/client/errors.rb +9 -0
  9. data/lib/selenium/client/extensions.rb +118 -0
  10. data/lib/selenium/client/idiomatic.rb +488 -0
  11. data/lib/selenium/client/javascript_expression_builder.rb +116 -0
  12. data/lib/selenium/client/javascript_frameworks/jquery.rb +13 -0
  13. data/lib/selenium/client/javascript_frameworks/prototype.rb +13 -0
  14. data/lib/selenium/client/legacy_driver.rb +1720 -0
  15. data/lib/selenium/client/protocol.rb +104 -0
  16. data/lib/selenium/client/selenium_helper.rb +34 -0
  17. data/lib/selenium/rake/server_task.rb +157 -0
  18. data/lib/selenium/server.rb +223 -0
  19. data/lib/selenium/webdriver.rb +64 -0
  20. data/lib/selenium/webdriver/android.rb +9 -0
  21. data/lib/selenium/webdriver/android/bridge.rb +51 -0
  22. data/lib/selenium/webdriver/chrome.rb +26 -0
  23. data/lib/selenium/webdriver/chrome/bridge.rb +106 -0
  24. data/lib/selenium/webdriver/chrome/profile.rb +83 -0
  25. data/lib/selenium/webdriver/chrome/service.rb +74 -0
  26. data/lib/selenium/webdriver/common.rb +30 -0
  27. data/lib/selenium/webdriver/common/action_builder.rb +352 -0
  28. data/lib/selenium/webdriver/common/alert.rb +26 -0
  29. data/lib/selenium/webdriver/common/bridge_helper.rb +67 -0
  30. data/lib/selenium/webdriver/common/core_ext/base64.rb +9 -0
  31. data/lib/selenium/webdriver/common/core_ext/dir.rb +42 -0
  32. data/lib/selenium/webdriver/common/core_ext/string.rb +5 -0
  33. data/lib/selenium/webdriver/common/driver.rb +301 -0
  34. data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +39 -0
  35. data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +44 -0
  36. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +43 -0
  37. data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +46 -0
  38. data/lib/selenium/webdriver/common/element.rb +262 -0
  39. data/lib/selenium/webdriver/common/error.rb +212 -0
  40. data/lib/selenium/webdriver/common/file_reaper.rb +47 -0
  41. data/lib/selenium/webdriver/common/keyboard.rb +52 -0
  42. data/lib/selenium/webdriver/common/keys.rb +109 -0
  43. data/lib/selenium/webdriver/common/mouse.rb +65 -0
  44. data/lib/selenium/webdriver/common/navigation.rb +43 -0
  45. data/lib/selenium/webdriver/common/options.rb +128 -0
  46. data/lib/selenium/webdriver/common/platform.rb +166 -0
  47. data/lib/selenium/webdriver/common/port_prober.rb +25 -0
  48. data/lib/selenium/webdriver/common/profile_helper.rb +67 -0
  49. data/lib/selenium/webdriver/common/proxy.rb +120 -0
  50. data/lib/selenium/webdriver/common/search_context.rb +92 -0
  51. data/lib/selenium/webdriver/common/socket_poller.rb +100 -0
  52. data/lib/selenium/webdriver/common/target_locator.rb +81 -0
  53. data/lib/selenium/webdriver/common/timeouts.rb +29 -0
  54. data/lib/selenium/webdriver/common/wait.rb +60 -0
  55. data/lib/selenium/webdriver/common/window.rb +96 -0
  56. data/lib/selenium/webdriver/common/zipper.rb +82 -0
  57. data/lib/selenium/webdriver/firefox.rb +37 -0
  58. data/lib/selenium/webdriver/firefox/binary.rb +161 -0
  59. data/lib/selenium/webdriver/firefox/bridge.rb +58 -0
  60. data/lib/selenium/webdriver/firefox/extension.rb +52 -0
  61. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  62. data/lib/selenium/webdriver/firefox/launcher.rb +104 -0
  63. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  64. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  65. data/lib/selenium/webdriver/firefox/profile.rb +315 -0
  66. data/lib/selenium/webdriver/firefox/profiles_ini.rb +62 -0
  67. data/lib/selenium/webdriver/firefox/socket_lock.rb +61 -0
  68. data/lib/selenium/webdriver/firefox/util.rb +29 -0
  69. data/lib/selenium/webdriver/ie.rb +19 -0
  70. data/lib/selenium/webdriver/ie/bridge.rb +60 -0
  71. data/lib/selenium/webdriver/ie/native/win32/IEDriver.dll +0 -0
  72. data/lib/selenium/webdriver/ie/native/x64/IEDriver.dll +0 -0
  73. data/lib/selenium/webdriver/ie/server.rb +64 -0
  74. data/lib/selenium/webdriver/iphone.rb +9 -0
  75. data/lib/selenium/webdriver/iphone/bridge.rb +50 -0
  76. data/lib/selenium/webdriver/opera.rb +24 -0
  77. data/lib/selenium/webdriver/opera/bridge.rb +113 -0
  78. data/lib/selenium/webdriver/opera/service.rb +49 -0
  79. data/lib/selenium/webdriver/remote.rb +21 -0
  80. data/lib/selenium/webdriver/remote/bridge.rb +473 -0
  81. data/lib/selenium/webdriver/remote/capabilities.rb +241 -0
  82. data/lib/selenium/webdriver/remote/commands.rb +181 -0
  83. data/lib/selenium/webdriver/remote/http/common.rb +74 -0
  84. data/lib/selenium/webdriver/remote/http/curb.rb +79 -0
  85. data/lib/selenium/webdriver/remote/http/default.rb +102 -0
  86. data/lib/selenium/webdriver/remote/http/persistent.rb +38 -0
  87. data/lib/selenium/webdriver/remote/response.rb +99 -0
  88. data/lib/selenium/webdriver/remote/server_error.rb +17 -0
  89. data/lib/selenium/webdriver/support.rb +4 -0
  90. data/lib/selenium/webdriver/support/abstract_event_listener.rb +28 -0
  91. data/lib/selenium/webdriver/support/block_event_listener.rb +17 -0
  92. data/lib/selenium/webdriver/support/event_firing_bridge.rb +112 -0
  93. data/lib/selenium/webdriver/support/select.rb +293 -0
  94. data/spec/integration/selenium/client/api/backward_compatible_api_spec.rb +22 -0
  95. data/spec/integration/selenium/client/api/browser_xpath_library_spec.rb +17 -0
  96. data/spec/integration/selenium/client/api/click_spec.rb +39 -0
  97. data/spec/integration/selenium/client/api/cookie_spec.rb +39 -0
  98. data/spec/integration/selenium/client/api/element_spec.rb +14 -0
  99. data/spec/integration/selenium/client/api/highlight_located_element_spec.rb +19 -0
  100. data/spec/integration/selenium/client/api/retrieve_last_remote_control_logs_spec.rb +33 -0
  101. data/spec/integration/selenium/client/api/screenshot_spec.rb +29 -0
  102. data/spec/integration/selenium/client/api/select_window_spec.rb +46 -0
  103. data/spec/integration/selenium/client/api/start_stop_spec.rb +9 -0
  104. data/spec/integration/selenium/client/api/wait_for_ajax_spec.rb +27 -0
  105. data/spec/integration/selenium/client/api/wait_for_element_spec.rb +56 -0
  106. data/spec/integration/selenium/client/api/wait_for_field_value_spec.rb +52 -0
  107. data/spec/integration/selenium/client/api/wait_for_text_spec.rb +98 -0
  108. data/spec/integration/selenium/client/sample-app/public/jquery-1.3.2.js +4376 -0
  109. data/spec/integration/selenium/client/sample-app/public/jquery.html +55 -0
  110. data/spec/integration/selenium/client/sample-app/public/prototype-1.6.0.3.js +4320 -0
  111. data/spec/integration/selenium/client/sample-app/public/prototype.html +59 -0
  112. data/spec/integration/selenium/client/sample-app/sample_app.rb +32 -0
  113. data/spec/integration/selenium/client/spec_helper.rb +125 -0
  114. data/spec/integration/selenium/webdriver/chrome/driver_spec.rb +28 -0
  115. data/spec/integration/selenium/webdriver/chrome/profile_spec.rb +42 -0
  116. data/spec/integration/selenium/webdriver/driver_spec.rb +253 -0
  117. data/spec/integration/selenium/webdriver/element_spec.rb +185 -0
  118. data/spec/integration/selenium/webdriver/error_spec.rb +30 -0
  119. data/spec/integration/selenium/webdriver/firefox/driver_spec.rb +21 -0
  120. data/spec/integration/selenium/webdriver/firefox/profile_spec.rb +141 -0
  121. data/spec/integration/selenium/webdriver/keyboard_spec.rb +57 -0
  122. data/spec/integration/selenium/webdriver/mouse_spec.rb +55 -0
  123. data/spec/integration/selenium/webdriver/navigation_spec.rb +44 -0
  124. data/spec/integration/selenium/webdriver/opera/driver_spec.rb +47 -0
  125. data/spec/integration/selenium/webdriver/options_spec.rb +49 -0
  126. data/spec/integration/selenium/webdriver/remote/element_spec.rb +24 -0
  127. data/spec/integration/selenium/webdriver/spec_helper.rb +44 -0
  128. data/spec/integration/selenium/webdriver/spec_support.rb +13 -0
  129. data/spec/integration/selenium/webdriver/spec_support/guards.rb +86 -0
  130. data/spec/integration/selenium/webdriver/spec_support/helpers.rb +46 -0
  131. data/spec/integration/selenium/webdriver/spec_support/jruby_test_environment.rb +29 -0
  132. data/spec/integration/selenium/webdriver/spec_support/rack_server.rb +123 -0
  133. data/spec/integration/selenium/webdriver/spec_support/test_environment.rb +199 -0
  134. data/spec/integration/selenium/webdriver/target_locator_spec.rb +170 -0
  135. data/spec/integration/selenium/webdriver/timeout_spec.rb +56 -0
  136. data/spec/integration/selenium/webdriver/window_spec.rb +56 -0
  137. data/spec/integration/selenium/webdriver/zipper_spec.rb +66 -0
  138. data/spec/unit/selenium/client/base_spec.rb +239 -0
  139. data/spec/unit/selenium/client/extensions_spec.rb +174 -0
  140. data/spec/unit/selenium/client/idiomatic_spec.rb +500 -0
  141. data/spec/unit/selenium/client/javascript_expression_builder_spec.rb +79 -0
  142. data/spec/unit/selenium/client/javascript_frameworks/jquery_spec.rb +10 -0
  143. data/spec/unit/selenium/client/javascript_frameworks/prototype_spec.rb +10 -0
  144. data/spec/unit/selenium/client/protocol_spec.rb +124 -0
  145. data/spec/unit/selenium/client/selenium_helper_spec.rb +56 -0
  146. data/spec/unit/selenium/client/spec_helper.rb +24 -0
  147. data/spec/unit/selenium/rake/task_spec.rb +79 -0
  148. data/spec/unit/selenium/server_spec.rb +131 -0
  149. data/spec/unit/selenium/webdriver/action_builder_spec.rb +90 -0
  150. data/spec/unit/selenium/webdriver/android/bridge_spec.rb +31 -0
  151. data/spec/unit/selenium/webdriver/chrome/bridge_spec.rb +94 -0
  152. data/spec/unit/selenium/webdriver/chrome/profile_spec.rb +57 -0
  153. data/spec/unit/selenium/webdriver/chrome/service_spec.rb +44 -0
  154. data/spec/unit/selenium/webdriver/error_spec.rb +41 -0
  155. data/spec/unit/selenium/webdriver/firefox/bridge_spec.rb +17 -0
  156. data/spec/unit/selenium/webdriver/iphone/bridge_spec.rb +30 -0
  157. data/spec/unit/selenium/webdriver/proxy_spec.rb +87 -0
  158. data/spec/unit/selenium/webdriver/remote/bridge_spec.rb +16 -0
  159. data/spec/unit/selenium/webdriver/remote/capabilities_spec.rb +111 -0
  160. data/spec/unit/selenium/webdriver/remote/http/common_spec.rb +24 -0
  161. data/spec/unit/selenium/webdriver/remote/http/default_spec.rb +46 -0
  162. data/spec/unit/selenium/webdriver/search_context_spec.rb +61 -0
  163. data/spec/unit/selenium/webdriver/socket_poller_spec.rb +68 -0
  164. data/spec/unit/selenium/webdriver/spec_helper.rb +6 -0
  165. data/spec/unit/selenium/webdriver/support/event_firing_spec.rb +111 -0
  166. data/spec/unit/selenium/webdriver/support/select_spec.rb +290 -0
  167. data/spec/unit/selenium/webdriver/wait_spec.rb +40 -0
  168. metadata +215 -0
@@ -0,0 +1,49 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Opera
4
+
5
+ #
6
+ # @api private
7
+ #
8
+
9
+ class Service
10
+ MISSING_TEXT = 'Unable to find the Selenium server jar. Please download the standalone server from http://code.google.com/p/selenium/downloads/list and set the SELENIUM_SERVER_JAR environmental variable to its location. More info at http://code.google.com/p/selenium/wiki/OperaDriver.'
11
+
12
+ def self.selenium_server_jar
13
+ @selenium_server_jar ||= (
14
+ ENV['SELENIUM_SERVER_JAR'] or raise Error::WebDriverError, MISSING_TEXT
15
+ )
16
+ end
17
+
18
+ def self.selenium_server_jar=(path)
19
+ Platform.assert_file path
20
+ @selenium_server_jar = path
21
+ end
22
+
23
+ def self.default_service(opts = {})
24
+ new selenium_server_jar, opts
25
+ end
26
+
27
+ def initialize(jar, opts = {})
28
+ opts.merge! :background => true, :port => PortProber.random
29
+ opts.merge! :log => !!$DEBUG if $DEBUG
30
+ @server = Selenium::Server.new File.expand_path(jar), opts
31
+ end
32
+
33
+ def uri
34
+ @server.webdriver_url
35
+ end
36
+
37
+ def start
38
+ @server.start
39
+ Platform.exit_hook { stop } # make sure we don't leave the server running
40
+ end
41
+
42
+ def stop
43
+ @server.stop
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,21 @@
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
+
11
+ module Selenium
12
+ module WebDriver
13
+
14
+ # @api private
15
+ module Remote
16
+
17
+ end
18
+ end
19
+ end
20
+
21
+
@@ -0,0 +1,473 @@
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::Default.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 ||= @capabilities.browser_name.gsub(" ", "_").to_sym
73
+ end
74
+
75
+ def driver_extensions
76
+ [
77
+ DriverExtensions::HasInputDevices,
78
+ DriverExtensions::UploadsFiles,
79
+ DriverExtensions::TakesScreenshot,
80
+ DriverExtensions::Rotatable
81
+ ]
82
+ end
83
+
84
+ #
85
+ # Returns the current session ID.
86
+ #
87
+
88
+ def session_id
89
+ @session_id || raise(Error::WebDriverError, "no current session exists")
90
+ end
91
+
92
+ def create_session(desired_capabilities)
93
+ resp = raw_execute :newSession, {}, :desiredCapabilities => desired_capabilities
94
+ @session_id = resp['sessionId'] or raise Error::WebDriverError, 'no sessionId in returned payload'
95
+
96
+ Capabilities.json_create resp['value']
97
+ end
98
+
99
+ def get(url)
100
+ execute :get, {}, :url => url
101
+ end
102
+
103
+ def getCapabilities
104
+ Capabilities.json_create execute(:getCapabilities)
105
+ end
106
+
107
+ def setImplicitWaitTimeout(milliseconds)
108
+ execute :setImplicitWaitTimeout, {}, :ms => milliseconds
109
+ end
110
+
111
+ def setScriptTimeout(milliseconds)
112
+ execute :setScriptTimeout, {}, :ms => milliseconds
113
+ end
114
+
115
+ #
116
+ # alerts
117
+ #
118
+
119
+ def getAlert
120
+ execute :getAlert
121
+ end
122
+
123
+ def acceptAlert
124
+ execute :acceptAlert
125
+ end
126
+
127
+ def dismissAlert
128
+ execute :dismissAlert
129
+ end
130
+
131
+ def setAlertValue(keys)
132
+ execute :setAlertValue, {}, :text => keys.to_s
133
+ end
134
+
135
+ def getAlertText
136
+ execute :getAlertText
137
+ end
138
+
139
+ #
140
+ # navigation
141
+ #
142
+
143
+ def goBack
144
+ execute :goBack
145
+ end
146
+
147
+ def goForward
148
+ execute :goForward
149
+ end
150
+
151
+ def getCurrentUrl
152
+ execute :getCurrentUrl
153
+ end
154
+
155
+ def getTitle
156
+ execute :getTitle
157
+ end
158
+
159
+ def getPageSource
160
+ execute :getPageSource
161
+ end
162
+
163
+ def getVisible
164
+ execute :getVisible
165
+ end
166
+
167
+ def setVisible(bool)
168
+ execute :setVisible, {}, bool
169
+ end
170
+
171
+ def switchToWindow(name)
172
+ execute :switchToWindow, {}, :name => name
173
+ end
174
+
175
+ def switchToFrame(id)
176
+ execute :switchToFrame, {}, :id => id
177
+ end
178
+
179
+ def switchToDefaultContent
180
+ execute :switchToFrame, {}, :id => nil
181
+ end
182
+
183
+ QUIT_ERRORS = [IOError]
184
+
185
+ def quit
186
+ execute :quit
187
+ http.close
188
+ rescue *QUIT_ERRORS
189
+ end
190
+
191
+ def close
192
+ execute :close
193
+ end
194
+
195
+ def refresh
196
+ execute :refresh
197
+ end
198
+
199
+ def getWindowHandles
200
+ execute :getWindowHandles
201
+ end
202
+
203
+ def getCurrentWindowHandle
204
+ execute :getCurrentWindowHandle
205
+ end
206
+
207
+ def setWindowSize(width, height, handle = :current)
208
+ execute :setWindowSize, {:window_handle => handle},
209
+ :width => width,
210
+ :height => height
211
+ end
212
+
213
+ def getWindowSize(handle = :current)
214
+ data = execute :getWindowSize, :window_handle => handle
215
+
216
+ Dimension.new data['width'], data['height']
217
+ end
218
+
219
+ def setWindowPosition(x, y, handle = :current)
220
+ execute :setWindowPosition, {:window_handle => handle},
221
+ :x => x, :y => y
222
+ end
223
+
224
+ def getWindowPosition(handle = :current)
225
+ data = execute :getWindowPosition, :window_handle => handle
226
+
227
+ Point.new data['x'], data['y']
228
+ end
229
+
230
+ def getScreenshot
231
+ execute :screenshot
232
+ end
233
+
234
+ def executeScript(script, *args)
235
+ assert_javascript_enabled
236
+
237
+ result = execute :executeScript, {}, :script => script, :args => args
238
+ unwrap_script_result result
239
+ end
240
+
241
+ def executeAsyncScript(script, *args)
242
+ assert_javascript_enabled
243
+
244
+ result = execute :executeAsyncScript, {}, :script => script, :args => args
245
+ unwrap_script_result result
246
+ end
247
+
248
+ def addCookie(cookie)
249
+ execute :addCookie, {}, :cookie => cookie
250
+ end
251
+
252
+ def deleteCookie(name)
253
+ execute :deleteCookieNamed, :name => name
254
+ end
255
+
256
+ def getAllCookies
257
+ execute :getAllCookies
258
+ end
259
+
260
+ def deleteAllCookies
261
+ execute :deleteAllCookies
262
+ end
263
+
264
+ def clickElement(element)
265
+ execute :clickElement, :id => element
266
+ end
267
+
268
+ def click
269
+ execute :click, {}, :button => 0
270
+ end
271
+
272
+ def doubleClick
273
+ execute :doubleClick
274
+ end
275
+
276
+ def contextClick
277
+ execute :click, {}, :button => 2
278
+ end
279
+
280
+ def mouseDown
281
+ execute :mouseDown
282
+ end
283
+
284
+ def mouseUp
285
+ execute :mouseUp
286
+ end
287
+
288
+ def mouseMoveTo(element, x = nil, y = nil)
289
+ params = { :element => element }
290
+
291
+ if x && y
292
+ params.merge! :xoffset => x, :yoffset => y
293
+ end
294
+
295
+ execute :mouseMoveTo, {}, params
296
+ end
297
+
298
+ def sendKeysToActiveElement(key)
299
+ execute :sendKeysToActiveElement, {}, :value => key
300
+ end
301
+
302
+ def getElementTagName(element)
303
+ execute :getElementTagName, :id => element
304
+ end
305
+
306
+ def getElementAttribute(element, name)
307
+ execute :getElementAttribute, :id => element, :name => name
308
+ end
309
+
310
+ def getElementValue(element)
311
+ execute :getElementValue, :id => element
312
+ end
313
+
314
+ def getElementText(element)
315
+ execute :getElementText, :id => element
316
+ end
317
+
318
+ def getElementLocation(element)
319
+ data = execute :getElementLocation, :id => element
320
+
321
+ Point.new data['x'], data['y']
322
+ end
323
+
324
+ def getElementLocationOnceScrolledIntoView(element)
325
+ data = execute :getElementLocationOnceScrolledIntoView, :id => element
326
+
327
+ Point.new data['x'], data['y']
328
+ end
329
+
330
+ def getElementSize(element)
331
+ data = execute :getElementSize, :id => element
332
+
333
+ Dimension.new data['width'], data['height']
334
+ end
335
+
336
+ def sendKeysToElement(element, keys)
337
+ if @file_detector && local_file = @file_detector.call(keys)
338
+ keys = upload(local_file)
339
+ end
340
+
341
+ execute :sendKeysToElement, {:id => element}, {:value => Array(keys)}
342
+ end
343
+
344
+ def upload(local_file)
345
+ unless File.file?(local_file)
346
+ raise WebDriverError::Error, "you may only upload files: #{local_file.inspect}"
347
+ end
348
+
349
+ execute :uploadFile, {}, :file => Zipper.zip_file(local_file)
350
+ end
351
+
352
+ def clearElement(element)
353
+ execute :clearElement, :id => element
354
+ end
355
+
356
+ def isElementEnabled(element)
357
+ execute :isElementEnabled, :id => element
358
+ end
359
+
360
+ def isElementSelected(element)
361
+ execute :isElementSelected, :id => element
362
+ end
363
+
364
+ def isElementDisplayed(element)
365
+ execute :isElementDisplayed, :id => element
366
+ end
367
+
368
+ def submitElement(element)
369
+ execute :submitElement, :id => element
370
+ end
371
+
372
+ def setElementSelected(element)
373
+ execute :setElementSelected, :id => element
374
+ end
375
+
376
+ def getElementValueOfCssProperty(element, prop)
377
+ execute :getElementValueOfCssProperty, :id => element, :property_name => prop
378
+ end
379
+
380
+ def getActiveElement
381
+ Element.new self, element_id_from(execute(:getActiveElement))
382
+ end
383
+ alias_method :switchToActiveElement, :getActiveElement
384
+
385
+ def dragElement(element, right_by, down_by)
386
+ execute :dragElement, {:id => element}, :x => right_by, :y => down_by
387
+ end
388
+
389
+ def elementEquals(element, other)
390
+ if element.ref == other.ref
391
+ true
392
+ else
393
+ execute :elementEquals, :id => element.ref, :other => other.ref
394
+ end
395
+ end
396
+
397
+ def find_element_by(how, what, parent = nil)
398
+ if parent
399
+ id = execute :findChildElement, {:id => parent}, {:using => how, :value => what}
400
+ else
401
+ id = execute :findElement, {}, {:using => how, :value => what}
402
+ end
403
+
404
+ Element.new self, element_id_from(id)
405
+ end
406
+
407
+ def find_elements_by(how, what, parent = nil)
408
+ if parent
409
+ ids = execute :findChildElements, {:id => parent}, {:using => how, :value => what}
410
+ else
411
+ ids = execute :findElements, {}, {:using => how, :value => what}
412
+ end
413
+
414
+ ids.map { |id| Element.new self, element_id_from(id) }
415
+ end
416
+
417
+ def setScreenOrientation(orientation)
418
+ execute :setScreenOrientation, {}, :orientation => orientation
419
+ end
420
+
421
+ def getScreenOrientation
422
+ execute :getScreenOrientation
423
+ end
424
+
425
+ private
426
+
427
+ def assert_javascript_enabled
428
+ unless capabilities.javascript_enabled?
429
+ raise Error::UnsupportedOperationError, "underlying webdriver instance does not support javascript"
430
+ end
431
+ end
432
+
433
+ #
434
+ # executes a command on the remote server via the REST / JSON API.
435
+ #
436
+ #
437
+ # Returns the 'value' of the returned payload
438
+ #
439
+
440
+ def execute(*args)
441
+ raw_execute(*args)['value']
442
+ end
443
+
444
+ #
445
+ # executes a command on the remote server via the REST / JSON API.
446
+ #
447
+ # @return [WebDriver::Remote::Response]
448
+ #
449
+
450
+ def raw_execute(command, opts = {}, command_hash = nil)
451
+ verb, path = COMMANDS[command] || raise(ArgumentError, "unknown command: #{command.inspect}")
452
+ path = path.dup
453
+
454
+ path[':session_id'] = @session_id if path.include?(":session_id")
455
+
456
+ begin
457
+ opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s) }
458
+ rescue IndexError
459
+ raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
460
+ end
461
+
462
+ puts "-> #{verb.to_s.upcase} #{path}" if $DEBUG
463
+ http.call verb, path, command_hash
464
+ end
465
+
466
+ def escaper
467
+ @escaper ||= defined?(URI::Parser) ? URI::Parser.new : URI
468
+ end
469
+
470
+ end # Bridge
471
+ end # Remote
472
+ end # WebDriver
473
+ end # Selenium