selenium-webdriver 0.2.0 → 0.2.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 (35) hide show
  1. data/CHANGES +15 -0
  2. data/lib/selenium-client.rb +1 -1
  3. data/lib/selenium-webdriver.rb +1 -1
  4. data/lib/selenium/client.rb +1 -1
  5. data/lib/selenium/server.rb +3 -3
  6. data/lib/selenium/webdriver.rb +6 -6
  7. data/lib/selenium/webdriver/android.rb +1 -1
  8. data/lib/selenium/webdriver/android/bridge.rb +1 -1
  9. data/lib/selenium/webdriver/chrome.rb +2 -2
  10. data/lib/selenium/webdriver/chrome/bridge.rb +14 -3
  11. data/lib/selenium/webdriver/common.rb +26 -26
  12. data/lib/selenium/webdriver/common/action_builder.rb +11 -11
  13. data/lib/selenium/webdriver/common/driver.rb +7 -8
  14. data/lib/selenium/webdriver/common/platform.rb +2 -2
  15. data/lib/selenium/webdriver/common/search_context.rb +4 -2
  16. data/lib/selenium/webdriver/common/socket_poller.rb +42 -12
  17. data/lib/selenium/webdriver/common/timeouts.rb +2 -2
  18. data/lib/selenium/webdriver/firefox.rb +11 -11
  19. data/lib/selenium/webdriver/firefox/binary.rb +1 -1
  20. data/lib/selenium/webdriver/firefox/extension.rb +0 -2
  21. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  22. data/lib/selenium/webdriver/firefox/launcher.rb +5 -2
  23. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  24. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  25. data/lib/selenium/webdriver/firefox/profile.rb +0 -2
  26. data/lib/selenium/webdriver/firefox/socket_lock.rb +1 -1
  27. data/lib/selenium/webdriver/ie.rb +3 -3
  28. data/lib/selenium/webdriver/ie/native/win32/IEDriver.dll +0 -0
  29. data/lib/selenium/webdriver/ie/native/x64/IEDriver.dll +0 -0
  30. data/lib/selenium/webdriver/iphone.rb +1 -1
  31. data/lib/selenium/webdriver/remote.rb +8 -8
  32. data/lib/selenium/webdriver/remote/capabilities.rb +98 -51
  33. data/lib/selenium/webdriver/remote/http/default.rb +1 -1
  34. data/lib/selenium/webdriver/remote/http/persistent.rb +1 -1
  35. metadata +46 -4
data/CHANGES CHANGED
@@ -1,3 +1,18 @@
1
+ 0.2.1 (2011-06-01)
2
+ ==================
3
+
4
+ * Allow passing custom command line switches to Chrome (requires today's release of the Chrome server)
5
+ * Avoid mutating arguments to find_element (issue #1273).
6
+ * Avoid conflicts when SUT modifies Array.prototype
7
+ * Allow setting arbitrary capabilities by adding Capabilities#[]=
8
+ * The Chrome driver is extended with TakesScreenshot.
9
+ * IE driver detects bad protected mode settings.
10
+ * Firefox driver no longer considers opacity when determining visibility.
11
+ * Fix for ActionBuilder#move_by.
12
+ * Treat Errno::EBADF as an indication that we failed to grab the socket lock (issue #1611).
13
+ * Ensure Firefox launches don't hang on some Ruby versions (by improving Selenium::WebDriver::SocketPoller).
14
+ * Various internal driver improvements.
15
+
1
16
  0.2.0 (2011-04-22)
2
17
  ==================
3
18
 
@@ -1,2 +1,2 @@
1
- require "selenium/client"
1
+ require 'selenium/client'
2
2
 
@@ -1 +1 @@
1
- require "selenium/webdriver"
1
+ require 'selenium/webdriver'
@@ -1,7 +1,7 @@
1
1
  require 'net/http'
2
2
  require 'uri'
3
3
  require 'cgi'
4
- require "digest/md5"
4
+ require 'digest/md5'
5
5
  require 'fileutils'
6
6
  require 'tmpdir'
7
7
 
@@ -1,6 +1,6 @@
1
- require "childprocess"
2
- require "selenium/webdriver/common/socket_poller"
3
- require "net/http"
1
+ require 'childprocess'
2
+ require 'selenium/webdriver/common/socket_poller'
3
+ require 'net/http'
4
4
 
5
5
  module Selenium
6
6
 
@@ -1,7 +1,7 @@
1
- require "childprocess"
2
- require "tmpdir"
3
- require "fileutils"
4
- require "date"
1
+ require 'childprocess'
2
+ require 'tmpdir'
3
+ require 'fileutils'
4
+ require 'date'
5
5
  require 'base64'
6
6
 
7
7
  have_lib = lambda { |lib|
@@ -13,7 +13,7 @@ have_lib = lambda { |lib|
13
13
  end
14
14
  }
15
15
 
16
- unless have_lib["yajl/json_gem"] || have_lib["json"]
16
+ unless have_lib['yajl/json_gem'] || have_lib['json']
17
17
  raise LoadError, <<-END
18
18
 
19
19
  You need to require rubygems or install one of these gems:
@@ -26,7 +26,7 @@ unless have_lib["yajl/json_gem"] || have_lib["json"]
26
26
  END
27
27
  end
28
28
 
29
- require "selenium/webdriver/common"
29
+ require 'selenium/webdriver/common'
30
30
 
31
31
  module Selenium
32
32
  module WebDriver
@@ -6,4 +6,4 @@ module Selenium
6
6
  end # WebDriver
7
7
  end # Selenium
8
8
 
9
- require "selenium/webdriver/android/bridge"
9
+ require 'selenium/webdriver/android/bridge'
@@ -10,7 +10,7 @@ module Selenium
10
10
  super
11
11
  else
12
12
  super(
13
- :url => DEFAULT_URL,
13
+ :url => DEFAULT_URL,
14
14
  :desired_capabilities => capabilities
15
15
  )
16
16
  end
@@ -1,7 +1,7 @@
1
1
  require 'net/http'
2
2
 
3
- require "selenium/webdriver/chrome/service"
4
- require "selenium/webdriver/chrome/bridge"
3
+ require 'selenium/webdriver/chrome/service'
4
+ require 'selenium/webdriver/chrome/bridge'
5
5
 
6
6
 
7
7
  module Selenium
@@ -6,19 +6,30 @@ module Selenium
6
6
  class Bridge < Remote::Bridge
7
7
 
8
8
  def initialize(opts = {})
9
- # TODO: pass options to Chrome::Service
10
9
  http_client = opts.delete(:http_client)
10
+ switches = opts.delete(:switches)
11
11
 
12
12
  unless opts.empty?
13
13
  raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
14
14
  end
15
15
 
16
+ caps = Remote::Capabilities.chrome
17
+
18
+ if switches
19
+ unless switches.kind_of? Array
20
+ raise ArgumentError, ":switches must be an Array of Strings"
21
+ end
22
+
23
+ caps.merge! 'chrome.switches' => switches.map { |e| e.to_s }
24
+ end
25
+
26
+
16
27
  @service = Service.default_service
17
28
  @service.start
18
29
 
19
30
  remote_opts = {
20
31
  :url => @service.uri,
21
- :desired_capabilities => :chrome
32
+ :desired_capabilities => caps
22
33
  }
23
34
 
24
35
  remote_opts.merge!(:http_client => http_client) if http_client
@@ -31,7 +42,7 @@ module Selenium
31
42
  end
32
43
 
33
44
  def driver_extensions
34
- []
45
+ [DriverExtensions::TakesScreenshot]
35
46
  end
36
47
 
37
48
  def capabilities
@@ -1,26 +1,26 @@
1
- require "selenium/webdriver/common/core_ext/dir"
2
- require "selenium/webdriver/common/core_ext/string"
3
- require "selenium/webdriver/common/error"
4
- require "selenium/webdriver/common/platform"
5
- require "selenium/webdriver/common/proxy"
6
- require "selenium/webdriver/common/file_reaper"
7
- require "selenium/webdriver/common/socket_poller"
8
- require "selenium/webdriver/common/port_prober"
9
- require "selenium/webdriver/common/zipper"
10
- require "selenium/webdriver/common/wait"
11
- require "selenium/webdriver/common/alert"
12
- require "selenium/webdriver/common/mouse"
13
- require "selenium/webdriver/common/keyboard"
14
- require "selenium/webdriver/common/target_locator"
15
- require "selenium/webdriver/common/navigation"
16
- require "selenium/webdriver/common/timeouts"
17
- require "selenium/webdriver/common/options"
18
- require "selenium/webdriver/common/search_context"
19
- require "selenium/webdriver/common/action_builder"
20
- require "selenium/webdriver/common/driver_extensions/takes_screenshot"
21
- require "selenium/webdriver/common/driver_extensions/rotatable"
22
- require "selenium/webdriver/common/driver_extensions/has_input_devices"
23
- require "selenium/webdriver/common/keys"
24
- require "selenium/webdriver/common/bridge_helper"
25
- require "selenium/webdriver/common/driver"
26
- require "selenium/webdriver/common/element"
1
+ require 'selenium/webdriver/common/core_ext/dir'
2
+ require 'selenium/webdriver/common/core_ext/string'
3
+ require 'selenium/webdriver/common/error'
4
+ require 'selenium/webdriver/common/platform'
5
+ require 'selenium/webdriver/common/proxy'
6
+ require 'selenium/webdriver/common/file_reaper'
7
+ require 'selenium/webdriver/common/socket_poller'
8
+ require 'selenium/webdriver/common/port_prober'
9
+ require 'selenium/webdriver/common/zipper'
10
+ require 'selenium/webdriver/common/wait'
11
+ require 'selenium/webdriver/common/alert'
12
+ require 'selenium/webdriver/common/mouse'
13
+ require 'selenium/webdriver/common/keyboard'
14
+ require 'selenium/webdriver/common/target_locator'
15
+ require 'selenium/webdriver/common/navigation'
16
+ require 'selenium/webdriver/common/timeouts'
17
+ require 'selenium/webdriver/common/options'
18
+ require 'selenium/webdriver/common/search_context'
19
+ require 'selenium/webdriver/common/action_builder'
20
+ require 'selenium/webdriver/common/driver_extensions/takes_screenshot'
21
+ require 'selenium/webdriver/common/driver_extensions/rotatable'
22
+ require 'selenium/webdriver/common/driver_extensions/has_input_devices'
23
+ require 'selenium/webdriver/common/keys'
24
+ require 'selenium/webdriver/common/bridge_helper'
25
+ require 'selenium/webdriver/common/driver'
26
+ require 'selenium/webdriver/common/element'
@@ -13,7 +13,7 @@ module Selenium
13
13
 
14
14
  def key_down(*args)
15
15
  if args.first.kind_of? Element
16
- @actions << [:mouse, :click, args.shift]
16
+ @actions << [:mouse, :click, [args.shift]]
17
17
  end
18
18
 
19
19
  @actions << [:keyboard, :press, args]
@@ -22,7 +22,7 @@ module Selenium
22
22
 
23
23
  def key_up(*args)
24
24
  if args.first.kind_of? Element
25
- @actions << [:mouse, :click, args.shift]
25
+ @actions << [:mouse, :click, [args.shift]]
26
26
  end
27
27
 
28
28
  @actions << [:keyboard, :release, args]
@@ -31,7 +31,7 @@ module Selenium
31
31
 
32
32
  def send_keys(*args)
33
33
  if args.first.kind_of? Element
34
- @actions << [:mouse, :click, args.shift]
34
+ @actions << [:mouse, :click, [args.shift]]
35
35
  end
36
36
 
37
37
  @actions << [:keyboard, :send_keys, args]
@@ -39,42 +39,42 @@ module Selenium
39
39
  end
40
40
 
41
41
  def click_and_hold(element)
42
- @actions << [:mouse, :down, element]
42
+ @actions << [:mouse, :down, [element]]
43
43
  self
44
44
  end
45
45
 
46
46
  def release(element = nil)
47
- @actions << [:mouse, :up, element]
47
+ @actions << [:mouse, :up, [element]]
48
48
  self
49
49
  end
50
50
 
51
51
  def click(element = nil)
52
- @actions << [:mouse, :click, element]
52
+ @actions << [:mouse, :click, [element]]
53
53
  self
54
54
  end
55
55
 
56
56
  def double_click(element = nil)
57
- @actions << [:mouse, :double_click, element]
57
+ @actions << [:mouse, :double_click, [element]]
58
58
  self
59
59
  end
60
60
 
61
61
  def move_to(element, down_by = nil, right_by = nil)
62
62
  if down_by && right_by
63
- @actions << [:mouse, :move_to, element, down_by, right_by]
63
+ @actions << [:mouse, :move_to, [element, down_by, right_by]]
64
64
  else
65
- @actions << [:mouse, :move_to, element]
65
+ @actions << [:mouse, :move_to, [element]]
66
66
  end
67
67
 
68
68
  self
69
69
  end
70
70
 
71
71
  def move_by(down_by, right_by)
72
- @actions << [:mouse, :move_by, down_by, right_by]
72
+ @actions << [:mouse, :move_by, [down_by, right_by]]
73
73
  self
74
74
  end
75
75
 
76
76
  def context_click(element = nil)
77
- @actions << [:mouse, :context_click, element]
77
+ @actions << [:mouse, :context_click, [element]]
78
78
  self
79
79
  end
80
80
 
@@ -261,7 +261,14 @@ module Selenium
261
261
  find_element sel
262
262
  end
263
263
 
264
+ def browser
265
+ bridge.browser
266
+ end
264
267
 
268
+ def capabilities
269
+ bridge.capabilities
270
+ end
271
+
265
272
  #
266
273
  # @api private
267
274
  # @see SearchContext
@@ -271,14 +278,6 @@ module Selenium
271
278
  nil
272
279
  end
273
280
 
274
- def browser
275
- bridge.browser
276
- end
277
-
278
- def capabilities
279
- bridge.capabilities
280
- end
281
-
282
281
  private
283
282
 
284
283
  def bridge
@@ -1,5 +1,5 @@
1
- require "rbconfig"
2
- require "socket"
1
+ require 'rbconfig'
2
+ require 'socket'
3
3
 
4
4
  module Selenium
5
5
  module WebDriver
@@ -20,7 +20,7 @@ module Selenium
20
20
  #
21
21
  # When using Element#find_element with :xpath, be aware that webdriver
22
22
  # follows standard conventions: a search prefixed with "//" will search
23
- # the entire document, not just the children of this current node. Use
23
+ # the entire document, not just the children of this current node. Use
24
24
  # ".//" to limit your search to the children of the receiving Element.
25
25
  #
26
26
  # @param [:class, :class_name, :id, :link_text, :link, :partial_link_text, :name, :tag_name, :xpath] how
@@ -75,11 +75,13 @@ module Selenium
75
75
  args
76
76
  when 1
77
77
  arg = args.first
78
+
78
79
  unless arg.respond_to?(:shift)
79
80
  raise ArgumentError, "expected #{arg.inspect}:#{arg.class} to respond to #shift"
80
81
  end
81
82
 
82
- arr = arg.shift
83
+ # this will be a single-entry hash, so use #shift over #first or #[]
84
+ arr = arg.dup.shift
83
85
  unless arr.size == 2
84
86
  raise ArgumentError, "expected #{arr.inspect} to have 2 elements"
85
87
  end
@@ -1,5 +1,5 @@
1
- require "selenium/webdriver/common/platform"
2
- require "socket"
1
+ require 'selenium/webdriver/common/platform'
2
+ require 'socket'
3
3
 
4
4
  module Selenium
5
5
  module WebDriver
@@ -36,17 +36,47 @@ module Selenium
36
36
 
37
37
  private
38
38
 
39
- SOCKET_ERRORS = [Errno::ECONNREFUSED, Errno::ENOTCONN, SocketError]
40
- SOCKET_ERRORS << Errno::EPERM if Platform.cygwin?
39
+ CONNECT_TIMEOUT = 5
41
40
 
42
- def listening?
43
- # There's a bug in 1.9.1 on Windows where this will succeed even if no
44
- # one is listening. Users who hit that should upgrade their Ruby.
45
- TCPSocket.new(@host, @port).close
46
- true
47
- rescue *SOCKET_ERRORS => e
48
- $stderr.puts [@host, @port].inspect if $DEBUG
49
- false
41
+ NOT_CONNECTED_ERRORS = [Errno::ECONNREFUSED, Errno::ENOTCONN, SocketError]
42
+ NOT_CONNECTED_ERRORS << Errno::EPERM if Platform.cygwin?
43
+
44
+ CONNECTED_ERRORS = [Errno::EISCONN]
45
+ CONNECTED_ERRORS << Errno::EINVAL if Platform.win?
46
+
47
+ if Platform.jruby?
48
+ # we use a plain TCPSocket here since JRuby has issues select()ing on a connecting socket
49
+ # see http://jira.codehaus.org/browse/JRUBY-5165
50
+ def listening?
51
+ TCPSocket.new(@host, @port).close
52
+ true
53
+ rescue *NOT_CONNECTED_ERRORS
54
+ false
55
+ end
56
+ else
57
+ def listening?
58
+ addr = Socket.getaddrinfo(@host, @port, Socket::AF_INET, Socket::SOCK_STREAM)
59
+ sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
60
+ sockaddr = Socket.pack_sockaddr_in(@port, addr[0][3])
61
+
62
+ begin
63
+ sock.connect_nonblock sockaddr
64
+ rescue Errno::EINPROGRESS
65
+ if IO.select(nil, [sock], nil, CONNECT_TIMEOUT)
66
+ retry
67
+ else
68
+ raise Errno::ECONNREFUSED
69
+ end
70
+ rescue *CONNECTED_ERRORS
71
+ # yay!
72
+ end
73
+
74
+ sock.close
75
+ true
76
+ rescue *NOT_CONNECTED_ERRORS => e
77
+ $stderr.puts [@host, @port].inspect if $DEBUG
78
+ false
79
+ end
50
80
  end
51
81
 
52
82
  def with_timeout(&blk)
@@ -11,7 +11,7 @@ module Selenium
11
11
  #
12
12
 
13
13
  def implicit_wait=(seconds)
14
- @bridge.setImplicitWaitTimeout seconds * 1000
14
+ @bridge.setImplicitWaitTimeout Integer(seconds * 1000)
15
15
  end
16
16
 
17
17
  #
@@ -21,7 +21,7 @@ module Selenium
21
21
  #
22
22
 
23
23
  def script_timeout=(seconds)
24
- @bridge.setScriptTimeout seconds * 1000
24
+ @bridge.setScriptTimeout Integer(seconds * 1000)
25
25
  end
26
26
 
27
27
  end # Timeouts
@@ -1,15 +1,15 @@
1
- require "timeout"
2
- require "socket"
3
- require "rexml/document"
1
+ require 'timeout'
2
+ require 'socket'
3
+ require 'rexml/document'
4
4
 
5
- require "selenium/webdriver/firefox/util"
6
- require "selenium/webdriver/firefox/extension"
7
- require "selenium/webdriver/firefox/socket_lock"
8
- require "selenium/webdriver/firefox/binary"
9
- require "selenium/webdriver/firefox/profiles_ini"
10
- require "selenium/webdriver/firefox/profile"
11
- require "selenium/webdriver/firefox/launcher"
12
- require "selenium/webdriver/firefox/bridge"
5
+ require 'selenium/webdriver/firefox/util'
6
+ require 'selenium/webdriver/firefox/extension'
7
+ require 'selenium/webdriver/firefox/socket_lock'
8
+ require 'selenium/webdriver/firefox/binary'
9
+ require 'selenium/webdriver/firefox/profiles_ini'
10
+ require 'selenium/webdriver/firefox/profile'
11
+ require 'selenium/webdriver/firefox/launcher'
12
+ require 'selenium/webdriver/firefox/bridge'
13
13
 
14
14
  module Selenium
15
15
  module WebDriver
@@ -133,7 +133,7 @@ module Selenium
133
133
  end
134
134
 
135
135
  def windows_registry_path
136
- require "win32/registry"
136
+ require 'win32/registry'
137
137
 
138
138
  lm = Win32::Registry::HKEY_LOCAL_MACHINE
139
139
  lm.open("SOFTWARE\\Mozilla\\Mozilla Firefox") do |reg|
@@ -4,8 +4,6 @@ module Selenium
4
4
 
5
5
  # @api private
6
6
  class Extension
7
- EM_NAMESPACE_URI = "http://www.mozilla.org/2004/em-rdf#" # not used?
8
-
9
7
  def initialize(path)
10
8
  unless File.exist?(path)
11
9
  raise Error::WebDriverError, "could not find extension at #{path.inspect}"
@@ -50,7 +50,7 @@ module Selenium
50
50
  end
51
51
 
52
52
  def create_profile
53
- fetch_profile if @profile.nil?
53
+ fetch_profile unless @profile
54
54
 
55
55
  @profile.add_webdriver_extension
56
56
  @profile.port = @port
@@ -64,12 +64,14 @@ module Selenium
64
64
 
65
65
  def start_silent_and_wait
66
66
  assert_profile
67
+
67
68
  @binary.start_with @profile, @profile_dir, "-silent"
68
69
  @binary.wait
69
70
  end
70
71
 
71
72
  def connect_until_stable
72
73
  poller = SocketPoller.new(@host, @port, STABLE_CONNECTION_TIMEOUT)
74
+
73
75
  unless poller.connected?
74
76
  @binary.quit
75
77
  raise Error::WebDriverError, "unable to obtain stable firefox connection in #{STABLE_CONNECTION_TIMEOUT} seconds (#{@host}:#{@port})"
@@ -79,7 +81,8 @@ module Selenium
79
81
  def fetch_profile
80
82
  if @profile_name
81
83
  @profile = Profile.from_name @profile_name
82
- if @profile.nil?
84
+
85
+ unless @profile
83
86
  raise Error::WebDriverError, "unable to find profile named: #{@profile_name.inspect}"
84
87
  end
85
88
  else
@@ -3,8 +3,6 @@ module Selenium
3
3
  module Firefox
4
4
  class Profile
5
5
 
6
- ANONYMOUS_PROFILE_NAME = "WEBDRIVER_ANONYMOUS_PROFILE"
7
- EXTENSION_NAME = "fxdriver@googlecode.com"
8
6
  WEBDRIVER_EXTENSION_PATH = File.expand_path("#{WebDriver.root}/selenium/webdriver/firefox/extension/webdriver.xpi")
9
7
  WEBDRIVER_PREFS = {
10
8
  :native_events => 'webdriver_enable_native_events',
@@ -46,7 +46,7 @@ module Selenium
46
46
  ChildProcess.close_on_exec @server
47
47
 
48
48
  true
49
- rescue SocketError, Errno::EADDRINUSE => ex
49
+ rescue SocketError, Errno::EADDRINUSE, Errno::EBADF => ex
50
50
  $stderr.puts "#{self}: #{ex.message}" if $DEBUG
51
51
  false
52
52
  end
@@ -13,7 +13,7 @@ module Selenium
13
13
  end
14
14
  end
15
15
 
16
- require "ffi"
16
+ require 'ffi'
17
17
 
18
- require "selenium/webdriver/ie/server"
19
- require "selenium/webdriver/ie/bridge"
18
+ require 'selenium/webdriver/ie/server'
19
+ require 'selenium/webdriver/ie/bridge'
@@ -6,4 +6,4 @@ module Selenium
6
6
  end # WebDriver
7
7
  end # Selenium
8
8
 
9
- require "selenium/webdriver/iphone/bridge"
9
+ require 'selenium/webdriver/iphone/bridge'
@@ -1,12 +1,12 @@
1
- require "uri"
1
+ require 'uri'
2
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"
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
10
 
11
11
  module Selenium
12
12
  module WebDriver
@@ -7,17 +7,28 @@ module Selenium
7
7
  #
8
8
  class Capabilities
9
9
 
10
- attr_reader :proxy
11
-
12
- attr_accessor :css_selectors_enabled,
13
- :javascript_enabled,
14
- :native_events,
15
- :platform,
16
- :takes_screenshot,
17
- :rotatable,
18
- :version,
19
- :browser_name,
20
- :firefox_profile
10
+ DEFAULTS = {
11
+ :browser_name => "",
12
+ :version => "",
13
+ :platform => :any,
14
+ :javascript_enabled => false,
15
+ :css_selectors_enabled => false,
16
+ :takes_screenshot => false,
17
+ :native_events => false,
18
+ :rotatable => false,
19
+ :firefox_profile => nil,
20
+ :proxy => nil
21
+ }
22
+
23
+ DEFAULTS.each_key do |key|
24
+ define_method key do
25
+ @capabilities.fetch(key)
26
+ end
27
+
28
+ define_method "#{key}=" do |value|
29
+ @capabilities[key] = value
30
+ end
31
+ end
21
32
 
22
33
  alias_method :css_selectors_enabled?, :css_selectors_enabled
23
34
  alias_method :javascript_enabled? , :javascript_enabled
@@ -92,17 +103,23 @@ module Selenium
92
103
  #
93
104
 
94
105
  def json_create(data)
95
- new(
96
- :browser_name => data["browserName"],
97
- :version => data["version"],
98
- :platform => data["platform"].downcase.to_sym,
99
- :javascript_enabled => data["javascriptEnabled"],
100
- :css_selectors_enabled => data["cssSelectorsEnabled"],
101
- :takes_screenshot => data["takesScreenshot"],
102
- :native_events => data["nativeEvents"],
103
- :rotatable => data["rotatable"],
104
- :proxy => (Proxy.json_create(data['proxy']) if data['proxy'])
105
- )
106
+ data = data.dup
107
+
108
+ caps = new
109
+ caps.browser_name = data.delete("browserName")
110
+ caps.version = data.delete("version")
111
+ caps.platform = data.delete("platform").downcase.to_sym
112
+ caps.javascript_enabled = data.delete("javascriptEnabled")
113
+ caps.css_selectors_enabled = data.delete("cssSelectorsEnabled")
114
+ caps.takes_screenshot = data.delete("takesScreenshot")
115
+ caps.native_events = data.delete("nativeEvents")
116
+ caps.rotatable = data.delete("rotatable")
117
+ caps.proxy = Proxy.json_create(data['proxy']) if data.has_key?('proxy')
118
+
119
+ # any remaining pairs will be added as is, with no conversion
120
+ caps.merge!(data)
121
+
122
+ caps
106
123
  end
107
124
  end
108
125
 
@@ -112,36 +129,49 @@ module Selenium
112
129
  # @option :javascript_enabled [Boolean] does the driver have javascript enabled?
113
130
  # @option :css_selectors_enabled [Boolean] does the driver support CSS selectors?
114
131
  # @option :takes_screenshot [Boolean] can this driver take screenshots?
115
- # @option :native_events [Boolean] does this driver use native events?
116
- # @option :proxy [Selenium::WebDriver::Proxy, Hash] proxy configuration
132
+ # @option :native_events [Boolean] does this driver use native events?
133
+ # @option :proxy [Selenium::WebDriver::Proxy, Hash] proxy configuration
117
134
  #
118
135
  # Firefox-specific options:
119
136
  #
120
- # @option :firefox_profile [Selenium::WebDriver::Firefox::Profile] the firefox profile to use
137
+ # @option :firefox_profile [Selenium::WebDriver::Firefox::Profile] the firefox profile to use
121
138
  #
122
139
  # @api public
123
140
  #
124
141
 
125
142
  def initialize(opts = {})
126
- @browser_name = opts[:browser_name] || ""
127
- @version = opts[:version] || ""
128
- @platform = opts[:platform] || :any
129
- @javascript_enabled = opts[:javascript_enabled] || false
130
- @css_selectors_enabled = opts[:css_selectors_enabled] || false
131
- @takes_screenshot = opts[:takes_screenshot] || false
132
- @native_events = opts[:native_events] || false
133
- @rotatable = opts[:rotatable] || false
134
- @firefox_profile = opts[:firefox_profile]
135
-
136
- self.proxy = opts[:proxy]
143
+ @capabilities = DEFAULTS.merge(opts)
144
+ self.proxy = opts.delete(:proxy)
145
+ end
146
+
147
+ #
148
+ # Allows setting arbitrary capabilities.
149
+ #
150
+
151
+ def []=(key, value)
152
+ @capabilities[key] = value
153
+ end
154
+
155
+ def [](key)
156
+ @capabilities[key]
157
+ end
158
+
159
+ def merge!(other)
160
+ if other.respond_to?(:capabilities) && other.capabilities.kind_of?(Hash)
161
+ @capabilities.merge! other.capabilities
162
+ elsif other.kind_of? Hash
163
+ @capabilities.merge! other
164
+ else
165
+ raise ArgumentError, "argument should be a Hash or implement #capabilities"
166
+ end
137
167
  end
138
168
 
139
169
  def proxy=(proxy)
140
170
  case proxy
141
171
  when Hash
142
- @proxy = Proxy.new(proxy)
172
+ @capabilities[:proxy] = Proxy.new(proxy)
143
173
  when Proxy, nil
144
- @proxy = proxy
174
+ @capabilities[:proxy] = proxy
145
175
  else
146
176
  raise TypeError, "expected Hash or #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}"
147
177
  end
@@ -151,19 +181,24 @@ module Selenium
151
181
  #
152
182
 
153
183
  def as_json(opts = nil)
154
- hash = {
155
- "browserName" => browser_name,
156
- "version" => version,
157
- "platform" => platform.to_s.upcase,
158
- "javascriptEnabled" => javascript_enabled?,
159
- "cssSelectorsEnabled" => css_selectors_enabled?,
160
- "takesScreenshot" => takes_screenshot?,
161
- "nativeEvents" => native_events?,
162
- "rotatable" => rotatable?,
163
- }
164
-
165
- hash["proxy"] = proxy.as_json if proxy
166
- hash['firefox_profile'] = firefox_profile.as_json['zip'] if firefox_profile
184
+ hash = {}
185
+
186
+ @capabilities.each do |key, value|
187
+ case key
188
+ when :platform
189
+ hash['platform'] = value.to_s.upcase
190
+ when :firefox_profile
191
+ hash['firefox_profile'] = value.as_json['zip'] if value
192
+ when :proxy
193
+ hash['proxy'] = value.as_json if value
194
+ when String
195
+ hash[key] = value
196
+ when Symbol
197
+ hash[camel_case(key.to_s)] = value
198
+ else
199
+ raise TypeError, "expected String or Symbol, got #{key.inspect}:#{key.class} / #{value.inspect}"
200
+ end
201
+ end
167
202
 
168
203
  hash
169
204
  end
@@ -178,6 +213,18 @@ module Selenium
178
213
  end
179
214
  alias_method :eql?, :==
180
215
 
216
+ protected
217
+
218
+ def capabilities
219
+ @capabilities
220
+ end
221
+
222
+ private
223
+
224
+ def camel_case(str)
225
+ str.gsub(/_([a-z])/) { $1.upcase }
226
+ end
227
+
181
228
  end # Capabilities
182
229
  end # Remote
183
230
  end # WebDriver
@@ -1,4 +1,4 @@
1
- require "net/https"
1
+ require 'net/https'
2
2
 
3
3
  module Selenium
4
4
  module WebDriver
@@ -1,4 +1,4 @@
1
- require "net/http/persistent"
1
+ require 'net/http/persistent'
2
2
 
3
3
  module Selenium
4
4
  module WebDriver
metadata CHANGED
@@ -1,8 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selenium-webdriver
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.2.0
4
+ hash: 21
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 1
10
+ version: 0.2.1
6
11
  platform: ruby
7
12
  authors:
8
13
  - Jari Bakken
@@ -10,7 +15,8 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2011-04-22 00:00:00 Z
18
+ date: 2011-06-01 00:00:00 +02:00
19
+ default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: json_pure
@@ -20,6 +26,9 @@ dependencies:
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
23
32
  version: "0"
24
33
  type: :runtime
25
34
  version_requirements: *id001
@@ -31,6 +40,9 @@ dependencies:
31
40
  requirements:
32
41
  - - ">="
33
42
  - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
34
46
  version: "0"
35
47
  type: :runtime
36
48
  version_requirements: *id002
@@ -42,6 +54,11 @@ dependencies:
42
54
  requirements:
43
55
  - - ">="
44
56
  - !ruby/object:Gem::Version
57
+ hash: 21
58
+ segments:
59
+ - 0
60
+ - 1
61
+ - 7
45
62
  version: 0.1.7
46
63
  type: :runtime
47
64
  version_requirements: *id003
@@ -53,6 +70,11 @@ dependencies:
53
70
  requirements:
54
71
  - - ">="
55
72
  - !ruby/object:Gem::Version
73
+ hash: 25
74
+ segments:
75
+ - 1
76
+ - 0
77
+ - 7
56
78
  version: 1.0.7
57
79
  type: :runtime
58
80
  version_requirements: *id004
@@ -64,6 +86,10 @@ dependencies:
64
86
  requirements:
65
87
  - - ~>
66
88
  - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 2
92
+ - 0
67
93
  version: "2.0"
68
94
  type: :development
69
95
  version_requirements: *id005
@@ -75,6 +101,10 @@ dependencies:
75
101
  requirements:
76
102
  - - ~>
77
103
  - !ruby/object:Gem::Version
104
+ hash: 15
105
+ segments:
106
+ - 1
107
+ - 0
78
108
  version: "1.0"
79
109
  type: :development
80
110
  version_requirements: *id006
@@ -86,6 +116,11 @@ dependencies:
86
116
  requirements:
87
117
  - - ~>
88
118
  - !ruby/object:Gem::Version
119
+ hash: 11
120
+ segments:
121
+ - 1
122
+ - 6
123
+ - 2
89
124
  version: 1.6.2
90
125
  type: :development
91
126
  version_requirements: *id007
@@ -178,6 +213,7 @@ files:
178
213
  - lib/selenium-webdriver.rb
179
214
  - CHANGES
180
215
  - README
216
+ has_rdoc: true
181
217
  homepage: http://selenium.googlecode.com
182
218
  licenses: []
183
219
 
@@ -191,17 +227,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
191
227
  requirements:
192
228
  - - ">="
193
229
  - !ruby/object:Gem::Version
230
+ hash: 3
231
+ segments:
232
+ - 0
194
233
  version: "0"
195
234
  required_rubygems_version: !ruby/object:Gem::Requirement
196
235
  none: false
197
236
  requirements:
198
237
  - - ">="
199
238
  - !ruby/object:Gem::Version
239
+ hash: 3
240
+ segments:
241
+ - 0
200
242
  version: "0"
201
243
  requirements: []
202
244
 
203
245
  rubyforge_project:
204
- rubygems_version: 1.7.2
246
+ rubygems_version: 1.3.7
205
247
  signing_key:
206
248
  specification_version: 3
207
249
  summary: The next generation developer focused tool for automated testing of webapps