selenium-webdriver 0.1.2 → 0.1.3.dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/CHANGES +18 -1
  2. data/lib/selenium/client/legacy_driver.rb +9 -0
  3. data/lib/selenium/webdriver/android/bridge.rb +1 -1
  4. data/lib/selenium/webdriver/chrome/bridge.rb +0 -4
  5. data/lib/selenium/webdriver/chrome/command_executor.rb +2 -2
  6. data/lib/selenium/webdriver/chrome/extension.zip +0 -0
  7. data/lib/selenium/webdriver/common.rb +3 -0
  8. data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +22 -0
  9. data/lib/selenium/webdriver/common/element.rb +10 -0
  10. data/lib/selenium/webdriver/common/keyboard.rb +48 -0
  11. data/lib/selenium/webdriver/common/mouse.rb +63 -0
  12. data/lib/selenium/webdriver/common/platform.rb +26 -11
  13. data/lib/selenium/webdriver/common/proxy.rb +1 -1
  14. data/lib/selenium/webdriver/common/zipper.rb +0 -1
  15. data/lib/selenium/webdriver/firefox/bridge.rb +8 -8
  16. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  17. data/lib/selenium/webdriver/firefox/launcher.rb +1 -1
  18. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  19. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  20. data/lib/selenium/webdriver/firefox/profile.rb +9 -5
  21. data/lib/selenium/webdriver/firefox/socket_lock.rb +1 -11
  22. data/lib/selenium/webdriver/ie.rb +3 -1
  23. data/lib/selenium/webdriver/ie/bridge.rb +23 -12
  24. data/lib/selenium/webdriver/ie/native/win32/IEDriver.dll +0 -0
  25. data/lib/selenium/webdriver/ie/native/x64/IEDriver.dll +0 -0
  26. data/lib/selenium/webdriver/ie/server.rb +64 -0
  27. data/lib/selenium/webdriver/iphone/bridge.rb +1 -1
  28. data/lib/selenium/webdriver/remote/bridge.rb +62 -8
  29. data/lib/selenium/webdriver/remote/capabilities.rb +10 -3
  30. data/lib/selenium/webdriver/remote/commands.rb +67 -59
  31. data/lib/selenium/webdriver/remote/http/common.rb +4 -0
  32. data/lib/selenium/webdriver/remote/http/default.rb +10 -4
  33. data/lib/selenium/webdriver/remote/http/persistent.rb +34 -0
  34. metadata +169 -196
  35. data/lib/selenium/webdriver/ie/lib.rb +0 -26
@@ -8,24 +8,35 @@ module Selenium
8
8
 
9
9
  class Bridge < Remote::Bridge
10
10
 
11
- HOST = "localhost"
12
-
11
+ HOST = Platform.localhost
13
12
  DEFAULT_PORT = 5555
14
13
  DEFAULT_TIMEOUT = 30
15
14
 
16
15
  def initialize(opts = {})
17
- timeout = opts[:timeout] || DEFAULT_TIMEOUT
18
- @port = opts[:port] || DEFAULT_PORT
19
- @speed = opts[:speed] || :fast
16
+ timeout = opts.delete(:timeout) { DEFAULT_TIMEOUT }
17
+ port = opts.delete(:port) { DEFAULT_PORT }
18
+ http_client = opts.delete(:http_client)
19
+
20
+ unless opts.empty?
21
+ raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
22
+ end
20
23
 
21
- @server_pointer = Lib.start_server @port
24
+ @server = Server.new
25
+ @port = @server.start Integer(port)
22
26
 
23
- unless SocketPoller.new(HOST, @port, timeout).connected?
24
- raise "unable to connect to IE server within #{timeout} seconds"
27
+ host = Platform.localhost
28
+ unless SocketPoller.new(host, @port, timeout).connected?
29
+ raise Error::WebDriverError, "unable to connect to IE server within #{timeout} seconds"
25
30
  end
26
31
 
27
- super(:url => "http://#{HOST}:#{@port}",
28
- :desired_capabilities => :internet_explorer)
32
+ remote_opts = {
33
+ :url => "http://#{host}:#{@port}",
34
+ :desired_capabilities => :firefox
35
+ }
36
+
37
+ remote_opts.merge!(:http_client => http_client) if http_client
38
+
39
+ super(remote_opts)
29
40
  end
30
41
 
31
42
  def browser
@@ -33,12 +44,12 @@ module Selenium
33
44
  end
34
45
 
35
46
  def driver_extensions
36
- []
47
+ [DriverExtensions::TakesScreenshot, DriverExtensions::HasInputDevices]
37
48
  end
38
49
 
39
50
  def quit
40
51
  super
41
- Lib.stop_server(@server_pointer)
52
+ @server.stop
42
53
 
43
54
  nil
44
55
  end
@@ -0,0 +1,64 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module IE
4
+
5
+ #
6
+ # @api private
7
+ #
8
+
9
+ class Server
10
+ extend FFI::Library
11
+
12
+ if Platform.bitsize == 64
13
+ ffi_lib WebDriver::IE::DLLS[:x64]
14
+ else
15
+ ffi_lib WebDriver::IE::DLLS[:win32]
16
+ end
17
+
18
+ ffi_convention :stdcall
19
+
20
+ attach_function :start_server, :StartServer, [:int], :pointer
21
+ attach_function :stop_server, :StopServer, [:pointer], :void
22
+ attach_function :session_count, :GetServerSessionCount, [], :int
23
+ attach_function :current_port, :GetServerPort, [], :int
24
+ attach_function :is_running, :ServerIsRunning, [], :bool
25
+
26
+ def initialize
27
+ @handle = nil
28
+ end
29
+
30
+ #
31
+ # Starts the server, communicating on the specified port, if it is not already running
32
+ #
33
+
34
+ def start(start_port)
35
+ return port if running?
36
+ @handle = self.class.start_server(start_port)
37
+
38
+ start_port
39
+ end
40
+
41
+ def stop
42
+ return unless session_count == 0
43
+ self.class.stop_server @handle
44
+ @handle = nil
45
+ end
46
+
47
+ def running?
48
+ self.class.is_running
49
+ end
50
+
51
+ def port
52
+ self.class.current_port
53
+ end
54
+
55
+ private
56
+
57
+ def session_count
58
+ self.class.session_count
59
+ end
60
+
61
+ end # Server
62
+ end # IE
63
+ end # WebDriver
64
+ end # Selenium
@@ -3,7 +3,7 @@ module Selenium
3
3
  module IPhone
4
4
  class Bridge < Remote::Bridge
5
5
 
6
- DEFAULT_URL = "http://localhost:3001/hub/"
6
+ DEFAULT_URL = "http://#{Platform.localhost}:3001/hub/"
7
7
 
8
8
  def initialize(opts = nil)
9
9
  if opts
@@ -46,7 +46,7 @@ module Selenium
46
46
 
47
47
  http_client = opts.delete(:http_client) { Http::Default.new }
48
48
  desired_capabilities = opts.delete(:desired_capabilities) { Capabilities.firefox }
49
- url = opts.delete(:url) { "http://localhost:4444/wd/hub" }
49
+ url = opts.delete(:url) { "http://#{Platform.localhost}:4444/wd/hub" }
50
50
 
51
51
  unless opts.empty?
52
52
  raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
@@ -74,7 +74,7 @@ module Selenium
74
74
  end
75
75
 
76
76
  def driver_extensions
77
- []
77
+ [DriverExtensions::HasInputDevices, DriverExtensions::TakesScreenshot]
78
78
  end
79
79
 
80
80
  #
@@ -108,6 +108,10 @@ module Selenium
108
108
  execute :setScriptTimeout, {}, :ms => milliseconds
109
109
  end
110
110
 
111
+ #
112
+ # alerts
113
+ #
114
+
111
115
  def acceptAlert
112
116
  execute :acceptAlert
113
117
  end
@@ -124,6 +128,10 @@ module Selenium
124
128
  execute :getAlertText
125
129
  end
126
130
 
131
+ #
132
+ # navigation
133
+ #
134
+
127
135
  def goBack
128
136
  execute :goBack
129
137
  end
@@ -195,6 +203,10 @@ module Selenium
195
203
  execute :getSpeed
196
204
  end
197
205
 
206
+ def getScreenshot
207
+ execute :screenshot
208
+ end
209
+
198
210
  def executeScript(script, *args)
199
211
  unless capabilities.javascript_enabled?
200
212
  raise Error::UnsupportedOperationError, "underlying webdriver instance does not support javascript"
@@ -220,6 +232,8 @@ module Selenium
220
232
  execute :deleteAllCookies
221
233
  end
222
234
 
235
+ # finding elements
236
+
223
237
  def findElementByClassName(parent, class_name)
224
238
  find_element_by 'class name', class_name, parent
225
239
  end
@@ -284,14 +298,44 @@ module Selenium
284
298
  find_elements_by 'xpath', xpath, parent
285
299
  end
286
300
 
287
- #
288
- # Element functions
289
- #
290
-
291
301
  def clickElement(element)
292
302
  execute :clickElement, :id => element
293
303
  end
294
304
 
305
+ def click
306
+ execute :click, {}, :button => 0
307
+ end
308
+
309
+ def doubleClick
310
+ execute :doubleClick
311
+ end
312
+
313
+ def contextClick
314
+ execute :click, {}, :button => 2
315
+ end
316
+
317
+ def mouseDown
318
+ execute :mouseDown
319
+ end
320
+
321
+ def mouseUp
322
+ execute :mouseUp
323
+ end
324
+
325
+ def mouseMoveTo(element, x = nil, y = nil)
326
+ params = { :element => element }
327
+
328
+ if x && y
329
+ params.merge!(:xoffset => x, :yoffset => y)
330
+ end
331
+
332
+ execute :mouseMoveTo, {}, params
333
+ end
334
+
335
+ def sendModifierKeyToActiveElement(key, down)
336
+ execute :sendModifierKeyToActiveElement, {}, :value => key, :isdown => down
337
+ end
338
+
295
339
  def getElementTagName(element)
296
340
  execute :getElementTagName, :id => element
297
341
  end
@@ -314,6 +358,12 @@ module Selenium
314
358
  Point.new data['x'], data['y']
315
359
  end
316
360
 
361
+ def getElementLocationOnceScrolledIntoView(element)
362
+ data = execute :getElementLocationOnceScrolledIntoView, :id => element
363
+
364
+ Point.new data['x'], data['y']
365
+ end
366
+
317
367
  def getElementSize(element)
318
368
  data = execute :getElementSize, :id => element
319
369
 
@@ -410,7 +460,7 @@ module Selenium
410
460
  #
411
461
  # executes a command on the remote server via the REST / JSON API.
412
462
  #
413
- # Returns a WebDriver::Remote::Response instance
463
+ # @return [WebDriver::Remote::Response]
414
464
  #
415
465
 
416
466
  def raw_execute(command, opts = {}, command_hash = nil)
@@ -420,7 +470,7 @@ module Selenium
420
470
  path[':session_id'] = @session_id if path.include?(":session_id")
421
471
 
422
472
  begin
423
- opts.each { |key, value| path[key.inspect] = URI.escape(value.to_s)}
473
+ opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s)}
424
474
  rescue IndexError
425
475
  raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
426
476
  end
@@ -429,6 +479,10 @@ module Selenium
429
479
  http.call verb, path, command_hash
430
480
  end
431
481
 
482
+ def escaper
483
+ @escaper ||= defined?(URI::Parser) ? URI::Parser.new : URI
484
+ end
485
+
432
486
  end # Bridge
433
487
  end # Remote
434
488
  end # WebDriver
@@ -16,7 +16,8 @@ module Selenium
16
16
  :takes_screenshot,
17
17
  :rotatable,
18
18
  :version,
19
- :browser_name
19
+ :browser_name,
20
+ :firefox_profile
20
21
 
21
22
  alias_method :css_selectors_enabled?, :css_selectors_enabled
22
23
  alias_method :javascript_enabled? , :javascript_enabled
@@ -108,6 +109,10 @@ module Selenium
108
109
  # @option :native_events [Boolean] does this driver use native events?
109
110
  # @option :proxy [Selenium::WebDriver::Proxy, Hash] proxy configuration
110
111
  #
112
+ # Firefox-specific options:
113
+ #
114
+ # @option :firefox_profile [Selenium::WebDriver::Firefox::Profile] the firefox profile to use
115
+ #
111
116
  # @api public
112
117
  #
113
118
 
@@ -120,6 +125,7 @@ module Selenium
120
125
  @takes_screenshot = opts[:takes_screenshot] || false
121
126
  @native_events = opts[:native_events] || false
122
127
  @rotatable = opts[:rotatable] || false
128
+ @firefox_profile = opts[:firefox_profile]
123
129
 
124
130
  self.proxy = opts[:proxy]
125
131
  end
@@ -147,10 +153,11 @@ module Selenium
147
153
  "cssSelectorsEnabled" => css_selectors_enabled?,
148
154
  "takesScreenshot" => takes_screenshot?,
149
155
  "nativeEvents" => native_events?,
150
- "rotatable" => rotatable?
156
+ "rotatable" => rotatable?,
151
157
  }
152
158
 
153
- hash["proxy"] = proxy.as_json if proxy
159
+ hash["proxy"] = proxy.as_json if proxy
160
+ hash['firefox_profile'] = firefox_profile.as_json['zip'] if firefox_profile
154
161
 
155
162
  hash
156
163
  end
@@ -5,63 +5,71 @@ class Selenium::WebDriver::Remote::Bridge
5
5
  # http://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference
6
6
  #
7
7
 
8
- command :newSession, :post, "session"
9
- command :getCapabilities, :get, "session/:session_id"
10
- command :quit, :delete, "session/:session_id"
11
- command :setImplicitWaitTimeout, :post, "session/:session_id/timeouts/implicit_wait"
12
- command :setScriptTimeout, :post, "session/:session_id/timeouts/async_script"
13
- command :getCurrentWindowHandle, :get, "session/:session_id/window_handle"
14
- command :getWindowHandles, :get, "session/:session_id/window_handles"
15
- command :getCurrentUrl, :get, "session/:session_id/url"
16
- command :get, :post, "session/:session_id/url"
17
- command :dismissAlert, :post, "session/:session_id/dismiss_alert"
18
- command :acceptAlert, :post, "session/:session_id/accept_alert"
19
- command :getAlertText, :get, "session/:session_id/alert_text"
20
- command :setAlertValue, :post, "session/:session_id/alert_text"
21
- command :goForward, :post, "session/:session_id/forward"
22
- command :goBack, :post, "session/:session_id/back"
23
- command :refresh, :post, "session/:session_id/refresh"
24
- command :executeScript, :post, "session/:session_id/execute"
25
- command :screenshot, :get, "session/:session_id/screenshot"
26
- command :switchToFrame, :post, "session/:session_id/frame"
27
- command :switchToWindow, :post, "session/:session_id/window"
28
- command :getSpeed, :get, "session/:session_id/speed"
29
- command :setSpeed, :post, "session/:session_id/speed"
30
- command :getAllCookies, :get, "session/:session_id/cookie"
31
- command :addCookie, :post, "session/:session_id/cookie"
32
- command :deleteAllCookies, :delete, "session/:session_id/cookie"
33
- command :deleteCookieNamed, :delete, "session/:session_id/cookie/:name"
34
- command :getPageSource, :get, "session/:session_id/source"
35
- command :getTitle, :get, "session/:session_id/title"
36
- command :findElement, :post, "session/:session_id/element"
37
- command :findElements, :post, "session/:session_id/elements"
38
- command :getActiveElement, :post, "session/:session_id/element/active"
39
- command :describeElement, :get, "session/:session_id/element/:id"
40
- command :findChildElement, :post, "session/:session_id/element/:id/element"
41
- command :findChildElements, :post, "session/:session_id/element/:id/elements"
42
- command :clickElement, :post, "session/:session_id/element/:id/click"
43
- command :submitElement, :post, "session/:session_id/element/:id/submit"
44
- command :getElementValue, :get, "session/:session_id/element/:id/value"
45
- command :sendKeysToElement, :post, "session/:session_id/element/:id/value"
46
- command :getElementTagName, :get, "session/:session_id/element/:id/name"
47
- command :clearElement, :post, "session/:session_id/element/:id/clear"
48
- command :isElementSelected, :get, "session/:session_id/element/:id/selected"
49
- command :setElementSelected, :post, "session/:session_id/element/:id/selected"
50
- command :toggleElement, :post, "session/:session_id/element/:id/toggle"
51
- command :isElementEnabled, :get, "session/:session_id/element/:id/enabled"
52
- command :getElementAttribute, :get, "session/:session_id/element/:id/attribute/:name"
53
- command :elementEquals, :get, "session/:session_id/element/:id/equals/:other"
54
- command :isElementDisplayed, :get, "session/:session_id/element/:id/displayed"
55
- command :getElementLocation, :get, "session/:session_id/element/:id/location"
56
- command :getElementLocationInView, :get, "session/:session_id/element/:id/location_in_view"
57
- command :getElementSize, :get, "session/:session_id/element/:id/size"
58
- command :hoverOverElement, :post, "session/:session_id/element/:id/hover"
59
- command :dragElement, :post, "session/:session_id/element/:id/drag"
60
- command :getElementValueOfCssProperty, :get, "session/:session_id/element/:id/css/:property_name"
61
- command :close, :delete, "session/:session_id/window"
62
- command :getElementText, :get, "session/:session_id/element/:id/text"
63
- command :getVisible, :get, "session/:session_id/visible"
64
- command :setVisible, :post, "session/:session_id/visible"
65
- command :getScreenOrientation, :get, "session/:session_id/orientation"
66
- command :setScreenOrientation, :post, "session/:session_id/orientation"
8
+ command :newSession, :post, "session"
9
+ command :getCapabilities, :get, "session/:session_id"
10
+ command :quit, :delete, "session/:session_id"
11
+ command :setImplicitWaitTimeout, :post, "session/:session_id/timeouts/implicit_wait"
12
+ command :setScriptTimeout, :post, "session/:session_id/timeouts/async_script"
13
+ command :getCurrentWindowHandle, :get, "session/:session_id/window_handle"
14
+ command :getWindowHandles, :get, "session/:session_id/window_handles"
15
+ command :getCurrentUrl, :get, "session/:session_id/url"
16
+ command :get, :post, "session/:session_id/url"
17
+ command :dismissAlert, :post, "session/:session_id/dismiss_alert"
18
+ command :acceptAlert, :post, "session/:session_id/accept_alert"
19
+ command :getAlertText, :get, "session/:session_id/alert_text"
20
+ command :setAlertValue, :post, "session/:session_id/alert_text"
21
+ command :goForward, :post, "session/:session_id/forward"
22
+ command :goBack, :post, "session/:session_id/back"
23
+ command :refresh, :post, "session/:session_id/refresh"
24
+ command :executeScript, :post, "session/:session_id/execute"
25
+ command :screenshot, :get, "session/:session_id/screenshot"
26
+ command :switchToFrame, :post, "session/:session_id/frame"
27
+ command :switchToWindow, :post, "session/:session_id/window"
28
+ command :getSpeed, :get, "session/:session_id/speed"
29
+ command :setSpeed, :post, "session/:session_id/speed"
30
+ command :getAllCookies, :get, "session/:session_id/cookie"
31
+ command :addCookie, :post, "session/:session_id/cookie"
32
+ command :deleteAllCookies, :delete, "session/:session_id/cookie"
33
+ command :deleteCookieNamed, :delete, "session/:session_id/cookie/:name"
34
+ command :getPageSource, :get, "session/:session_id/source"
35
+ command :getTitle, :get, "session/:session_id/title"
36
+ command :findElement, :post, "session/:session_id/element"
37
+ command :findElements, :post, "session/:session_id/elements"
38
+ command :getActiveElement, :post, "session/:session_id/element/active"
39
+ command :describeElement, :get, "session/:session_id/element/:id"
40
+ command :findChildElement, :post, "session/:session_id/element/:id/element"
41
+ command :findChildElements, :post, "session/:session_id/element/:id/elements"
42
+ command :clickElement, :post, "session/:session_id/element/:id/click"
43
+ command :submitElement, :post, "session/:session_id/element/:id/submit"
44
+ command :getElementValue, :get, "session/:session_id/element/:id/value"
45
+ command :sendKeysToElement, :post, "session/:session_id/element/:id/value"
46
+ command :getElementTagName, :get, "session/:session_id/element/:id/name"
47
+ command :clearElement, :post, "session/:session_id/element/:id/clear"
48
+ command :isElementSelected, :get, "session/:session_id/element/:id/selected"
49
+ command :setElementSelected, :post, "session/:session_id/element/:id/selected"
50
+ command :toggleElement, :post, "session/:session_id/element/:id/toggle"
51
+ command :isElementEnabled, :get, "session/:session_id/element/:id/enabled"
52
+ command :getElementAttribute, :get, "session/:session_id/element/:id/attribute/:name"
53
+ command :elementEquals, :get, "session/:session_id/element/:id/equals/:other"
54
+ command :isElementDisplayed, :get, "session/:session_id/element/:id/displayed"
55
+ command :getElementLocation, :get, "session/:session_id/element/:id/location"
56
+ command :getElementLocationOnceScrolledIntoView, :get, "session/:session_id/element/:id/location_in_view"
57
+ command :getElementSize, :get, "session/:session_id/element/:id/size"
58
+ command :hoverOverElement, :post, "session/:session_id/element/:id/hover"
59
+ command :dragElement, :post, "session/:session_id/element/:id/drag"
60
+ command :getElementValueOfCssProperty, :get, "session/:session_id/element/:id/css/:property_name"
61
+ command :close, :delete, "session/:session_id/window"
62
+ command :getElementText, :get, "session/:session_id/element/:id/text"
63
+ command :getVisible, :get, "session/:session_id/visible"
64
+ command :setVisible, :post, "session/:session_id/visible"
65
+ command :getScreenOrientation, :get, "session/:session_id/orientation"
66
+ command :setScreenOrientation, :post, "session/:session_id/orientation"
67
+
68
+ # interactions API
69
+ command :click, :post, "session/:session_id/click"
70
+ command :doubleClick, :post, "session/:session_id/doubleclick"
71
+ command :mouseDown, :post, "session/:session_id/buttondown"
72
+ command :mouseUp, :post, "session/:session_id/buttonup"
73
+ command :mouseMoveTo, :post, "session/:session_id/moveto"
74
+ command :sendModifierKeyToActiveElement, :post, "session/:session_id/modifier"
67
75
  end