selenium-webdriver 0.1.2 → 0.1.3.dev

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 (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
data/CHANGES CHANGED
@@ -1,4 +1,21 @@
1
- 0.1.2 (2010-12-??)
1
+ 0.1.3 (???)
2
+ ============
3
+
4
+ * Screenshot support in the IE and Remote drivers.
5
+ * Fixed paths for IE DLLs on Cygwin.
6
+ * Several crashing bugs fixed in the IE driver.
7
+ * Fix #1152 by avoiding IPv6 loopback.
8
+ * Added Mouse and Keyboard classes, accessible as Driver#{mouse,keyboard}. Considered experimental (IE + HtmlUnit only at the moment).
9
+ * Automation atoms now used extensively in the IE driver.
10
+ * Firefox::Bridge is now easier to extend (i.e. with a custom launcher).
11
+ * Add S::W::Remote::Http::Persistent (currently only usable with the remote server).
12
+ * IE driver passes along options like the other remote drivers, enabling user-specified HTTP clients.
13
+ * :firefox_profile added to Remote::Capabilities, enabling passing a profile to remote Firefoxes.
14
+ * IE driver now supports launching multiple instances of the browser.
15
+ * Remove some Ruby warnings (uninitialized ivars, URI.escape).
16
+
17
+
18
+ 0.1.2 (2010-12-22)
2
19
  ============
3
20
 
4
21
  * Changed frame switching behaviour (http://groups.google.com/group/selenium-developers/browse_thread/thread/8dc7938c35bb3968)
@@ -1334,6 +1334,15 @@ module Selenium
1334
1334
  end
1335
1335
 
1336
1336
 
1337
+ # Returns the number of nodes that match the specified css selector, eg. "css=table" would give
1338
+ # the number of tables.
1339
+ #
1340
+ # 'css' is the css selector to evaluate. do NOT wrap this expression in a 'count()' function; we will do that for you.
1341
+ def get_css_count(css)
1342
+ return number_command("getCssCount", [css,])
1343
+ end
1344
+
1345
+
1337
1346
  # Temporarily sets the "id" attribute of the specified element, so you can locate it in the future
1338
1347
  # using its ID rather than a slow/complicated XPath. This ID will disappear once the page is
1339
1348
  # reloaded.
@@ -3,7 +3,7 @@ module Selenium
3
3
  module Android
4
4
  class Bridge < Remote::Bridge
5
5
 
6
- DEFAULT_URL = "http://localhost:8080/hub"
6
+ DEFAULT_URL = "http://#{Platform.localhost}:8080/hub"
7
7
 
8
8
  def initialize(opts = nil)
9
9
  if opts
@@ -37,10 +37,6 @@ module Selenium
37
37
  @launcher.quit
38
38
  end
39
39
 
40
- def getScreenshot
41
- execute :screenshot
42
- end
43
-
44
40
  def setSpeed(value)
45
41
  @speed = value
46
42
  end
@@ -46,13 +46,13 @@ module Selenium
46
46
  end
47
47
 
48
48
  def uri
49
- "http://localhost:#{port}/chromeCommandExecutor"
49
+ "http://#{Platform.localhost}:#{port}/chromeCommandExecutor"
50
50
  end
51
51
 
52
52
  private
53
53
 
54
54
  def localhost
55
- Platform.ironruby? ? "localhost" : "0.0.0.0" # yeah, weird..
55
+ Platform.ironruby? ? Platform.localhost : "0.0.0.0" # yeah, weird..
56
56
  end
57
57
 
58
58
  def start_run_loop
@@ -8,6 +8,8 @@ require "selenium/webdriver/common/socket_poller"
8
8
  require "selenium/webdriver/common/zipper"
9
9
  require "selenium/webdriver/common/wait"
10
10
  require "selenium/webdriver/common/alert"
11
+ require "selenium/webdriver/common/mouse"
12
+ require "selenium/webdriver/common/keyboard"
11
13
  require "selenium/webdriver/common/target_locator"
12
14
  require "selenium/webdriver/common/navigation"
13
15
  require "selenium/webdriver/common/timeouts"
@@ -15,6 +17,7 @@ require "selenium/webdriver/common/options"
15
17
  require "selenium/webdriver/common/find"
16
18
  require "selenium/webdriver/common/driver_extensions/takes_screenshot"
17
19
  require "selenium/webdriver/common/driver_extensions/rotatable"
20
+ require "selenium/webdriver/common/driver_extensions/has_input_devices"
18
21
  require "selenium/webdriver/common/keys"
19
22
  require "selenium/webdriver/common/bridge_helper"
20
23
  require "selenium/webdriver/common/driver"
@@ -0,0 +1,22 @@
1
+ module Selenium
2
+ module WebDriver
3
+
4
+ #
5
+ # @api private
6
+ #
7
+
8
+ module DriverExtensions
9
+ module HasInputDevices
10
+
11
+ def mouse
12
+ Mouse.new @bridge
13
+ end
14
+
15
+ def keyboard
16
+ Keyboard.new @bridge
17
+ end
18
+
19
+ end # HasInputDevices
20
+ end # DriverExtensions
21
+ end # WebDriver
22
+ end # Selenium
@@ -213,6 +213,16 @@ module Selenium
213
213
  bridge.getElementLocation @id
214
214
  end
215
215
 
216
+ #
217
+ # Determine an element's location on the screen once it has been scrolled into view.
218
+ #
219
+ # @return [WebDriver::Point]
220
+ #
221
+
222
+ def location_once_scrolled_into_view
223
+ bridge.getElementLocationOnceScrolledIntoView @id
224
+ end
225
+
216
226
  #
217
227
  # Get the size of this element
218
228
  #
@@ -0,0 +1,48 @@
1
+ module Selenium
2
+ module WebDriver
3
+ class Keyboard
4
+
5
+ def initialize(bridge)
6
+ @bridge = bridge
7
+ end
8
+
9
+ def send_keys(*keys)
10
+ @bridge.getActiveElement.send_keys(*keys)
11
+ end
12
+
13
+ #
14
+ # Release a modifier key
15
+ #
16
+ # @see Selenium::WebDriver::Keys
17
+ #
18
+
19
+ def press(key)
20
+ assert_modifier key
21
+ @bridge.sendModifierKeyToActiveElement Keys[key], true
22
+ end
23
+
24
+ #
25
+ # Release a modifier key
26
+ #
27
+ # @see Selenium::WebDriver::Keys
28
+ #
29
+
30
+ def release(key)
31
+ assert_modifier key
32
+ @bridge.sendModifierKeyToActiveElement Keys[key], false
33
+ end
34
+
35
+ private
36
+
37
+ MODIFIERS = [:control, :shift, :alt, :command, :meta]
38
+
39
+ def assert_modifier(key)
40
+ unless MODIFIERS.include? key
41
+ raise Error::UnsupportedOperationError,
42
+ "#{key.inspect} is not a modifier key, expected one of #{MODIFIERS.inspect}"
43
+ end
44
+ end
45
+
46
+ end # Keyboard
47
+ end # WebDriver
48
+ end # Selenium
@@ -0,0 +1,63 @@
1
+ module Selenium
2
+ module WebDriver
3
+ class Mouse
4
+
5
+ def initialize(bridge)
6
+ @bridge = bridge
7
+ end
8
+
9
+ def click(element = nil)
10
+ move_if_needed element
11
+ @bridge.click
12
+ end
13
+
14
+ def double_click(element = nil)
15
+ move_if_needed element
16
+ @bridge.doubleClick
17
+ end
18
+
19
+ def context_click(element = nil)
20
+ move_if_needed element
21
+ @bridge.contextClick
22
+ end
23
+
24
+ def down(element = nil)
25
+ move_if_needed element
26
+ @bridge.mouseDown
27
+ end
28
+
29
+ def up(element = nil)
30
+ move_if_needed element
31
+ @bridge.mouseUp
32
+ end
33
+
34
+ #
35
+ # Move the mouse.
36
+ #
37
+ # Examples:
38
+ #
39
+ # driver.mouse.move_to(element)
40
+ # driver.mouse.move_to(element, 5, 5)
41
+ #
42
+
43
+ def move_to(element, down_by = nil, right_by = nil)
44
+ unless element.kind_of? Element
45
+ raise TypeError, "expected #{Element}, got #{element.inspect}:#{element.class}"
46
+ end
47
+
48
+ @bridge.mouseMoveTo element.ref, down_by, right_by
49
+ end
50
+
51
+ def move_by(down_by, right_by)
52
+ @bridge.mouseMoveTo nil, down_by, right_by
53
+ end
54
+
55
+ private
56
+
57
+ def move_if_needed(element)
58
+ move_to element if element
59
+ end
60
+
61
+ end # Mouse
62
+ end # WebDriver
63
+ end # Selenium
@@ -1,4 +1,5 @@
1
1
  require "rbconfig"
2
+ require "socket"
2
3
 
3
4
  module Selenium
4
5
  module WebDriver
@@ -84,15 +85,18 @@ module Selenium
84
85
  end
85
86
 
86
87
  def cygwin?
87
- RUBY_PLATFORM =~ /cygwin/
88
+ !!(RUBY_PLATFORM =~ /cygwin/)
88
89
  end
89
90
 
90
91
  def wrap_in_quotes_if_necessary(str)
91
92
  win? && !cygwin? ? %{"#{str}"} : str
92
93
  end
93
94
 
94
- def cygwin_path(path)
95
- `cygpath "#{path}"`.strip
95
+ def cygwin_path(path, opts = {})
96
+ flags = []
97
+ opts.each { |k,v| flags << "--#{k}" if v }
98
+
99
+ `cygpath #{flags.join ' '} "#{path}"`.strip
96
100
  end
97
101
 
98
102
  def make_writable(file)
@@ -123,17 +127,28 @@ module Selenium
123
127
  nil
124
128
  end
125
129
 
130
+ def localhost
131
+ info = Socket.getaddrinfo "localhost", 80, Socket::AF_INET, Socket::SOCK_STREAM
132
+
133
+ if info.empty?
134
+ raise Error::WebDriverError, "unable to translate 'localhost' for TCP+IPv6"
135
+ end
136
+
137
+ info[0][3]
138
+ end
139
+
126
140
  end # Platform
127
141
  end # WebDriver
128
142
  end # Selenium
129
143
 
130
144
  if __FILE__ == $0
131
- p :engine => Selenium::WebDriver::Platform.engine,
132
- :os => Selenium::WebDriver::Platform.os,
133
- :ruby187? => Selenium::WebDriver::Platform.ruby187?,
134
- :ruby19? => Selenium::WebDriver::Platform.ruby19?,
135
- :jruby? => Selenium::WebDriver::Platform.jruby?,
136
- :win? => Selenium::WebDriver::Platform.win?,
137
- :home => Selenium::WebDriver::Platform.home,
138
- :bitsize => Selenium::WebDriver::Platform.bitsize
145
+ p :engine => Selenium::WebDriver::Platform.engine,
146
+ :os => Selenium::WebDriver::Platform.os,
147
+ :ruby187? => Selenium::WebDriver::Platform.ruby187?,
148
+ :ruby19? => Selenium::WebDriver::Platform.ruby19?,
149
+ :jruby? => Selenium::WebDriver::Platform.jruby?,
150
+ :win? => Selenium::WebDriver::Platform.win?,
151
+ :home => Selenium::WebDriver::Platform.home,
152
+ :bitsize => Selenium::WebDriver::Platform.bitsize,
153
+ :localhost => Selenium::WebDriver::Platform.localhost
139
154
  end
@@ -73,7 +73,7 @@ module Selenium
73
73
  raise ArgumentError, "invalid proxy type: #{type.inspect}, expected one of #{TYPES.keys.inspect}"
74
74
  end
75
75
 
76
- if @type && type != @type
76
+ if defined?(@type) && type != @type
77
77
  raise ArgumentError, "incompatible proxy type #{type.inspect} (already set to #{@type.inspect})"
78
78
  end
79
79
 
@@ -37,7 +37,6 @@ module Selenium
37
37
 
38
38
  zos.put_next_entry(entry)
39
39
  zos << File.read(file)
40
- p :added => file, :as => entry
41
40
  end
42
41
 
43
42
  zos.close
@@ -6,14 +6,12 @@ module Selenium
6
6
  class Bridge < Remote::Bridge
7
7
 
8
8
  def initialize(opts = {})
9
- @launcher = Launcher.new(
10
- Binary.new,
11
- opts.delete(:port) || DEFAULT_PORT,
12
- opts.delete(:profile)
13
- )
14
-
9
+ port = opts.delete(:port) || DEFAULT_PORT
10
+ profile = opts.delete(:profile)
15
11
  http_client = opts.delete(:http_client)
16
12
 
13
+ @launcher = create_launcher(port, profile)
14
+
17
15
  unless opts.empty?
18
16
  raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
19
17
  end
@@ -45,8 +43,10 @@ module Selenium
45
43
  nil
46
44
  end
47
45
 
48
- def getScreenshot
49
- execute :screenshot
46
+ private
47
+
48
+ def create_launcher(port, profile)
49
+ Launcher.new Binary.new, port, profile
50
50
  end
51
51
 
52
52
  end # Bridge
@@ -78,7 +78,7 @@ module Selenium
78
78
  poller = SocketPoller.new(@host, @port, STABLE_CONNECTION_TIMEOUT)
79
79
  unless poller.connected?
80
80
  @binary.quit
81
- raise Error::WebDriverError, "unable to obtain stable firefox connection in #{STABLE_CONNECTION_TIMEOUT} seconds"
81
+ raise Error::WebDriverError, "unable to obtain stable firefox connection in #{STABLE_CONNECTION_TIMEOUT} seconds (#{@host}:#{@port})"
82
82
  end
83
83
  end
84
84
 
@@ -49,14 +49,18 @@ module Selenium
49
49
  @secure_ssl = DEFAULT_SECURE_SSL
50
50
  @untrusted_issuer = DEFAULT_ASSUME_UNTRUSTED_ISSUER
51
51
  @load_no_focus_lib = DEFAULT_LOAD_NO_FOCUS_LIB
52
+
53
+ @additional_prefs = {}
52
54
  else
53
- @native_events = model_prefs[WEBDRIVER_PREFS[:native_events]] == "true"
54
- @secure_ssl = model_prefs[WEBDRIVER_PREFS[:untrusted_certs]] != "true" # FIXME: 'untrusted_certs' vs 'secure_ssl'
55
- @untrusted_issuer = model_prefs[WEBDRIVER_PREFS[:untrusted_issuer]] == "true"
56
- @load_no_focus_lib = model_prefs[WEBDRIVER_PREFS[:load_no_focus_lib]] == "true" # not stored in profile atm, so will always be false.
55
+ # TODO: clean this up
56
+ @native_events = model_prefs.delete(WEBDRIVER_PREFS[:native_events]) == "true"
57
+ @secure_ssl = model_prefs.delete(WEBDRIVER_PREFS[:untrusted_certs]) != "true"
58
+ @untrusted_issuer = model_prefs.delete(WEBDRIVER_PREFS[:untrusted_issuer]) == "true"
59
+ @load_no_focus_lib = model_prefs.delete(WEBDRIVER_PREFS[:load_no_focus_lib]) == "true" # not stored in profile atm, so will always be false.
60
+
61
+ @additional_prefs = model_prefs
57
62
  end
58
63
 
59
- @additional_prefs = {}
60
64
  @extensions = {}
61
65
  end
62
66
 
@@ -10,16 +10,6 @@ module Selenium
10
10
 
11
11
  class SocketLock
12
12
 
13
- #
14
- # Need to be really specific about what host to use
15
- #
16
- # On os x, "localhost" will resolve to 3 different addresses (see /etc/hosts).
17
- # Ruby will loop over these and happily bind to the same port on each one,
18
- # making it completely unusable for our purposes.
19
- #
20
-
21
- HOST = "127.0.0.1"
22
-
23
13
  def initialize(port, timeout)
24
14
  @port = port
25
15
  @timeout = timeout
@@ -54,7 +44,7 @@ module Selenium
54
44
  end
55
45
 
56
46
  def can_lock?
57
- @server = TCPServer.new(HOST, @port)
47
+ @server = TCPServer.new(Platform.localhost, @port)
58
48
  ChildProcess.close_on_exec @server
59
49
 
60
50
  true
@@ -7,11 +7,13 @@ module Selenium
7
7
  :win32 => "#{WebDriver.root}/selenium/webdriver/ie/native/win32/IEDriver.dll",
8
8
  :x64 => "#{WebDriver.root}/selenium/webdriver/ie/native/x64/IEDriver.dll"
9
9
  }
10
+
11
+ DLLS.each { |k,v| DLLS[k] = Platform.cygwin_path(v, :dos => true) } if Platform.cygwin?
10
12
  end
11
13
  end
12
14
  end
13
15
 
14
16
  require "ffi"
15
17
 
16
- require "selenium/webdriver/ie/lib"
18
+ require "selenium/webdriver/ie/server"
17
19
  require "selenium/webdriver/ie/bridge"