selenium-webdriver 0.0.28 → 0.0.29

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 (44) hide show
  1. data/CHANGES +25 -0
  2. data/lib/selenium/webdriver.rb +6 -29
  3. data/lib/selenium/webdriver/chrome.rb +4 -2
  4. data/lib/selenium/webdriver/chrome/extension.zip +0 -0
  5. data/lib/selenium/webdriver/chrome/launcher.rb +15 -16
  6. data/lib/selenium/webdriver/common.rb +18 -0
  7. data/lib/selenium/webdriver/{bridge_helper.rb → common/bridge_helper.rb} +0 -0
  8. data/lib/selenium/webdriver/{core_ext → common/core_ext}/dir.rb +0 -0
  9. data/lib/selenium/webdriver/{core_ext → common/core_ext}/string.rb +0 -0
  10. data/lib/selenium/webdriver/{driver.rb → common/driver.rb} +19 -7
  11. data/lib/selenium/webdriver/{driver_extensions → common/driver_extensions}/takes_screenshot.rb +2 -2
  12. data/lib/selenium/webdriver/{element.rb → common/element.rb} +30 -3
  13. data/lib/selenium/webdriver/{error.rb → common/error.rb} +0 -0
  14. data/lib/selenium/webdriver/{file_reaper.rb → common/file_reaper.rb} +0 -0
  15. data/lib/selenium/webdriver/{find.rb → common/find.rb} +9 -1
  16. data/lib/selenium/webdriver/{keys.rb → common/keys.rb} +0 -0
  17. data/lib/selenium/webdriver/{navigation.rb → common/navigation.rb} +3 -3
  18. data/lib/selenium/webdriver/{options.rb → common/options.rb} +47 -5
  19. data/lib/selenium/webdriver/{platform.rb → common/platform.rb} +10 -0
  20. data/lib/selenium/webdriver/common/socket_poller.rb +47 -0
  21. data/lib/selenium/webdriver/{target_locator.rb → common/target_locator.rb} +11 -8
  22. data/lib/selenium/webdriver/{timeouts.rb → common/timeouts.rb} +0 -0
  23. data/lib/selenium/webdriver/common/wait.rb +60 -0
  24. data/lib/selenium/webdriver/common/zipper.rb +54 -0
  25. data/lib/selenium/webdriver/firefox.rb +6 -3
  26. data/lib/selenium/webdriver/firefox/binary.rb +46 -43
  27. data/lib/selenium/webdriver/firefox/bridge.rb +2 -10
  28. data/lib/selenium/webdriver/firefox/extension.rb +51 -0
  29. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  30. data/lib/selenium/webdriver/firefox/launcher.rb +25 -69
  31. data/lib/selenium/webdriver/firefox/profile.rb +123 -89
  32. data/lib/selenium/webdriver/firefox/profiles_ini.rb +2 -1
  33. data/lib/selenium/webdriver/firefox/socket_lock.rb +77 -0
  34. data/lib/selenium/webdriver/ie/bridge.rb +25 -38
  35. data/lib/selenium/webdriver/ie/lib.rb +11 -1
  36. data/lib/selenium/webdriver/ie/native/win32/InternetExplorerDriver.dll +0 -0
  37. data/lib/selenium/webdriver/ie/native/x64/InternetExplorerDriver.dll +0 -0
  38. data/lib/selenium/webdriver/ie/util.rb +3 -17
  39. data/lib/selenium/webdriver/remote/bridge.rb +9 -1
  40. data/lib/selenium/webdriver/remote/capabilities.rb +53 -20
  41. data/lib/selenium/webdriver/remote/http/default.rb +2 -2
  42. metadata +52 -31
  43. data/lib/selenium/webdriver/child_process.rb +0 -243
  44. data/lib/selenium/webdriver/zip_helper.rb +0 -27
data/CHANGES CHANGED
@@ -1,3 +1,28 @@
1
+ 0.0.29 (2010-10-09)
2
+ ===================
3
+
4
+ * Element#find_element with :xpath follows the XPath spec (i.e. results are not limited to the receiver's subtree).
5
+ * Element#attribute(attribute) now returns "false" instead of nil.
6
+ * Firefox::Profile instances can now be reused for multiple drivers.
7
+ * Redirect Firefox console logs to a file with Firefox::Profile.log_file=
8
+ * Added a simple Wait class, based on WebDriverWait in Java.
9
+ * Search PATH for Firefox executable on Windows also.
10
+ * Added Capabilities.android
11
+ * Fix saving of screenshots on Windows and Ruby 1.9 (using "wb" mode string)
12
+ * CSS selector support in the remote driver
13
+ * CSS selector support for IE (using querySelector when available, Sizzle elsewhere)
14
+ * CSS selector support for older versions of Firefox (through Sizzle)
15
+ * Cookie expiration dates are now handled correctly (#730)
16
+ * Make Driver#bridge private, since this seems to be a common cause of confusion.
17
+ * Add {Element,Remote::Capabilities}#as_json for Rails 3 (http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/)
18
+ * User can configure path to exectuables with {Firefox,Chrome}.path = "/some/path"
19
+ * Added "chromium" as a possible name for the Chrome binary (#769)
20
+ * Correctly set the HTTP client timeout (#768)
21
+ * switch_to.window with block now handles exceptions and non-local returns.
22
+ * switch_to.window with block returns the result of the block.
23
+ * Extracted handling of child processes to a separate gem: http://github.com/jarib/childprocess
24
+
25
+
1
26
  0.0.28 (2010-08-23)
2
27
  ===================
3
28
 
@@ -1,25 +1,18 @@
1
1
  require "tmpdir"
2
2
  require "fileutils"
3
+ require "date"
4
+ require "childprocess"
3
5
 
4
- have_yajl = lambda {
6
+ have_lib = lambda { |lib|
5
7
  begin
6
- require "yajl/json_gem"
8
+ require lib
7
9
  true
8
10
  rescue LoadError
9
11
  false
10
12
  end
11
13
  }
12
14
 
13
- have_json = lambda {
14
- begin
15
- require "json"
16
- true
17
- rescue LoadError
18
- false
19
- end
20
- }
21
-
22
- unless have_yajl.call || have_json.call
15
+ unless have_lib["yajl/json_gem"] || have_lib["json"]
23
16
  raise LoadError, <<-END
24
17
 
25
18
  You need to require rubygems or install one of these gems:
@@ -32,24 +25,8 @@ unless have_yajl.call || have_json.call
32
25
  END
33
26
  end
34
27
 
28
+ require "selenium/webdriver/common"
35
29
 
36
- require "selenium/webdriver/core_ext/dir"
37
- require "selenium/webdriver/core_ext/string"
38
- require "selenium/webdriver/error"
39
- require "selenium/webdriver/platform"
40
- require "selenium/webdriver/child_process"
41
- require "selenium/webdriver/file_reaper"
42
- require "selenium/webdriver/zip_helper"
43
- require "selenium/webdriver/target_locator"
44
- require "selenium/webdriver/navigation"
45
- require "selenium/webdriver/timeouts"
46
- require "selenium/webdriver/options"
47
- require "selenium/webdriver/find"
48
- require "selenium/webdriver/driver_extensions/takes_screenshot"
49
- require "selenium/webdriver/keys"
50
- require "selenium/webdriver/bridge_helper"
51
- require "selenium/webdriver/driver"
52
- require "selenium/webdriver/element"
53
30
 
54
31
  module Selenium
55
32
  module WebDriver
@@ -9,9 +9,11 @@ require "socket"
9
9
  module Selenium
10
10
  module WebDriver
11
11
 
12
- # @private
13
12
  module Chrome
13
+ def self.path=(path)
14
+ Launcher.binary_path = path
15
+ end
14
16
  end
15
17
 
16
18
  end
17
- end
19
+ end
@@ -35,6 +35,17 @@ module Selenium
35
35
  )
36
36
  end
37
37
 
38
+ #
39
+ # @private
40
+ #
41
+ # @see Chrome.path=
42
+ #
43
+
44
+ def self.binary_path=(path)
45
+ Platform.assert_executable(path)
46
+ @binary_path = path
47
+ end
48
+
38
49
  def launch(server_url)
39
50
  create_extension
40
51
  create_profile
@@ -44,7 +55,7 @@ module Selenium
44
55
  end
45
56
 
46
57
  def quit
47
- @process.ensure_death
58
+ @process.stop
48
59
  end
49
60
 
50
61
  private
@@ -54,12 +65,6 @@ module Selenium
54
65
  rm_rf tmp_extension_dir
55
66
  mkdir_p File.dirname(tmp_extension_dir), :mode => 0700
56
67
  cp_r ext_path, tmp_extension_dir
57
-
58
- if Platform.win?
59
- mv "#{tmp_extension_dir}/manifest-win.json", "#{tmp_extension_dir}/manifest.json"
60
- else
61
- mv "#{tmp_extension_dir}/manifest-nonwin.json", "#{tmp_extension_dir}/manifest.json"
62
- end
63
68
  end
64
69
 
65
70
  def create_profile
@@ -87,11 +92,11 @@ module Selenium
87
92
 
88
93
  args << server_url
89
94
 
90
- @process = ChildProcess.new(*args).start
95
+ @process = ChildProcess.build(*args).start
91
96
  end
92
97
 
93
98
  def ext_path
94
- @ext_path ||= ZipHelper.unzip("#{WebDriver.root}/selenium/webdriver/chrome/extension.zip")
99
+ @ext_path ||= Zipper.unzip("#{WebDriver.root}/selenium/webdriver/chrome/extension.zip")
95
100
  end
96
101
 
97
102
  def tmp_extension_dir
@@ -136,17 +141,11 @@ module Selenium
136
141
  rescue Win32::Registry::Error
137
142
  nil
138
143
  end
139
-
140
- def quit
141
- # looks like we need a kill right away on Windows + MRI
142
- @process.kill if Platform.engine == :ruby
143
- super
144
- end
145
144
  end
146
145
 
147
146
  class UnixLauncher < Launcher
148
147
  def self.possible_paths
149
- [Platform.find_binary("google-chrome"), "/usr/bin/google-chrome"].compact
148
+ [Platform.find_binary("google-chrome"), Platform.find_binary("chromium"), "/usr/bin/google-chrome"].compact
150
149
  end
151
150
 
152
151
  end
@@ -0,0 +1,18 @@
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/file_reaper"
6
+ require "selenium/webdriver/common/socket_poller"
7
+ require "selenium/webdriver/common/zipper"
8
+ require "selenium/webdriver/common/wait"
9
+ require "selenium/webdriver/common/target_locator"
10
+ require "selenium/webdriver/common/navigation"
11
+ require "selenium/webdriver/common/timeouts"
12
+ require "selenium/webdriver/common/options"
13
+ require "selenium/webdriver/common/find"
14
+ require "selenium/webdriver/common/driver_extensions/takes_screenshot"
15
+ require "selenium/webdriver/common/keys"
16
+ require "selenium/webdriver/common/bridge_helper"
17
+ require "selenium/webdriver/common/driver"
18
+ require "selenium/webdriver/common/element"
@@ -13,8 +13,6 @@ module Selenium
13
13
  class Driver
14
14
  include Find
15
15
 
16
- attr_reader :bridge
17
-
18
16
  class << self
19
17
 
20
18
  #
@@ -62,8 +60,8 @@ module Selenium
62
60
  @bridge = bridge
63
61
 
64
62
  # TODO: refactor this away
65
- unless @bridge.driver_extensions.empty?
66
- extend(*@bridge.driver_extensions)
63
+ unless bridge.driver_extensions.empty?
64
+ extend(*bridge.driver_extensions)
67
65
  end
68
66
  end
69
67
 
@@ -77,7 +75,7 @@ module Selenium
77
75
  #
78
76
 
79
77
  def navigate
80
- @navigate ||= WebDriver::Navigation.new(self)
78
+ @navigate ||= WebDriver::Navigation.new(bridge)
81
79
  end
82
80
 
83
81
  #
@@ -86,7 +84,7 @@ module Selenium
86
84
  #
87
85
 
88
86
  def switch_to
89
- @switch_to ||= WebDriver::TargetLocator.new(self)
87
+ @switch_to ||= WebDriver::TargetLocator.new(bridge)
90
88
  end
91
89
 
92
90
  #
@@ -95,7 +93,7 @@ module Selenium
95
93
  #
96
94
 
97
95
  def manage
98
- @manage ||= WebDriver::Options.new(self)
96
+ @manage ||= WebDriver::Options.new(bridge)
99
97
  end
100
98
 
101
99
  #
@@ -258,6 +256,20 @@ module Selenium
258
256
  nil
259
257
  end
260
258
 
259
+ def browser
260
+ bridge.browser
261
+ end
262
+
263
+ def capabilities
264
+ bridge.capabilities
265
+ end
266
+
267
+ private
268
+
269
+ def bridge
270
+ @bridge
271
+ end
272
+
261
273
  end # Driver
262
274
  end # WebDriver
263
275
  end # Selenium
@@ -9,7 +9,7 @@ module Selenium
9
9
  module TakesScreenshot
10
10
 
11
11
  def save_screenshot(png_path)
12
- File.open(png_path, 'w') { |f| f << screenshot_as(:png) }
12
+ File.open(png_path, 'wb') { |f| f << screenshot_as(:png) }
13
13
  end
14
14
 
15
15
  def screenshot_as(format)
@@ -26,4 +26,4 @@ module Selenium
26
26
  end # TakesScreenshot
27
27
  end # DriverExtensions
28
28
  end # WebDriver
29
- end # Selenium
29
+ end # Selenium
@@ -57,7 +57,24 @@ module Selenium
57
57
  end
58
58
 
59
59
  #
60
- # Get the value of the given attribute
60
+ # Get the value of a the given attribute of the element. Will return the current value, even if
61
+ # this has been modified after the page has been loaded. More exactly, this method will return
62
+ # the value of the given attribute, unless that attribute is not present, in which case the
63
+ # value of the property with the same name is returned. If neither value is set, nil is
64
+ # returned. The "style" attribute is converted as best can be to a text representation with a
65
+ # trailing semi-colon. The following are deemed to be "boolean" attributes, and will
66
+ # return either "true" or "false":
67
+ #
68
+ # async, autofocus, autoplay, checked, compact, complete, controls, declare, defaultchecked,
69
+ # defaultselected, defer, disabled, draggable, ended, formnovalidate, hidden, indeterminate,
70
+ # iscontenteditable, ismap, itemscope, loop, multiple, muted, nohref, noresize, noshade, novalidate,
71
+ # nowrap, open, paused, pubdate, readonly, required, reversed, scoped, seamless, seeking,
72
+ # selected, spellcheck, truespeed, willvalidate
73
+ #
74
+ # Finally, the following commonly mis-capitalized attribute/property names are evaluated as
75
+ # expected:
76
+ #
77
+ # class, readonly
61
78
  #
62
79
  # @param [String]
63
80
  # attribute name
@@ -272,9 +289,19 @@ module Selenium
272
289
  #
273
290
 
274
291
  def to_json(*args)
275
- { :ELEMENT => @id }.to_json(*args)
292
+ as_json.to_json(*args)
293
+ end
294
+
295
+ #
296
+ # For Rails 3 - http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/
297
+ #
298
+ # @private
299
+ #
300
+
301
+ def as_json(opts = nil)
302
+ { :ELEMENT => @id }
276
303
  end
277
304
 
278
305
  end # Element
279
306
  end # WebDriver
280
- end # Selenium
307
+ end # Selenium
@@ -18,12 +18,18 @@ module Selenium
18
18
  #
19
19
  # Find the first element matching the given arguments.
20
20
  #
21
+ # When using Element#find_element with :xpath, be aware that webdriver
22
+ # follows standard conventions: a search prefixed with "//" will search
23
+ # the entire document, not just the children of this current node. Use
24
+ # ".//" to limit your search to the children of the receiving Element.
25
+ #
21
26
  # @param [:class, :class_name, :id, :link_text, :link, :partial_link_text, :name, :tag_name, :xpath] how
22
27
  # @param [String] what
23
28
  # @return [WebDriver::Element]
24
29
  #
25
30
  # @raise [NoSuchElementError] if the element doesn't exist
26
31
  #
32
+ #
27
33
 
28
34
  def find_element(*args)
29
35
  how, what = extract_args(args)
@@ -41,6 +47,8 @@ module Selenium
41
47
  #
42
48
  # Find all elements matching the given arguments
43
49
  #
50
+ # @see Find#find_element
51
+ #
44
52
  # @param [:class, :class_name, :id, :link_text, :link, :partial_link_text, :name, :tag_name, :xpath] how
45
53
  # @param [String] what
46
54
  # @return [Array<WebDriver::Element>]
@@ -84,4 +92,4 @@ module Selenium
84
92
 
85
93
  end # Find
86
94
  end # WebDriver
87
- end # Selenium
95
+ end # Selenium
File without changes
@@ -2,8 +2,8 @@ module Selenium
2
2
  module WebDriver
3
3
  class Navigation
4
4
 
5
- def initialize(driver)
6
- @bridge = driver.bridge
5
+ def initialize(bridge)
6
+ @bridge = bridge
7
7
  end
8
8
 
9
9
  #
@@ -40,4 +40,4 @@ module Selenium
40
40
 
41
41
  end # Navigation
42
42
  end # WebDriver
43
- end # Selenium
43
+ end # Selenium
@@ -6,8 +6,8 @@ module Selenium
6
6
  # @private
7
7
  #
8
8
 
9
- def initialize(driver)
10
- @bridge = driver.bridge
9
+ def initialize(bridge)
10
+ @bridge = bridge
11
11
  end
12
12
 
13
13
  #
@@ -18,6 +18,7 @@ module Selenium
18
18
  # @option opts [String] :value A value
19
19
  # @option opts [String] :path ('/') A path
20
20
  # @option opts [String] :secure (false) A boolean
21
+ # @option opts [Time,DateTime,Numeric,nil] :expires (nil) Expiry date, either as a Time, DateTime, or seconds since epoch.
21
22
  #
22
23
  # @raise [ArgumentError] if :name or :value is not specified
23
24
  #
@@ -29,9 +30,25 @@ module Selenium
29
30
  opts[:path] ||= "/"
30
31
  opts[:secure] ||= false
31
32
 
33
+ if obj = opts[:expires]
34
+ opts[:expiry] = seconds_from(obj)
35
+ end
36
+
37
+
32
38
  @bridge.addCookie opts
33
39
  end
34
40
 
41
+ #
42
+ # Get the cookie with the given name
43
+ #
44
+ # @param [String] name the name of the cookie
45
+ # @return [Hash, nil] the cookie, or nil if it wasn't found.
46
+ #
47
+
48
+ def cookie_named(name)
49
+ all_cookies.find { |c| c[:name] == name }
50
+ end
51
+
35
52
  #
36
53
  # Delete the cookie with the given name
37
54
  #
@@ -62,8 +79,8 @@ module Selenium
62
79
  :name => cookie["name"],
63
80
  :value => cookie["value"],
64
81
  :path => cookie["path"],
65
- :domain => cookie["domain"],
66
- :expires => cookie["expires"],
82
+ :domain => strip_port(cookie["domain"]),
83
+ :expires => cookie["expiry"] && datetime_at(cookie['expiry']),
67
84
  :secure => cookie["secure"]
68
85
  }
69
86
  end
@@ -81,6 +98,31 @@ module Selenium
81
98
  @timeouts ||= Timeouts.new(@bridge)
82
99
  end
83
100
 
101
+ private
102
+
103
+ SECONDS_PER_DAY = 86_400.0
104
+
105
+ def datetime_at(int)
106
+ DateTime.civil(1970) + (int / SECONDS_PER_DAY)
107
+ end
108
+
109
+ def seconds_from(obj)
110
+ case obj
111
+ when Time
112
+ obj.to_f
113
+ when DateTime
114
+ (obj - DateTime.civil(1970)) * SECONDS_PER_DAY
115
+ when Numeric
116
+ obj
117
+ else
118
+ raise ArgumentError, "invalid value for expiration date: #{obj.inspect}"
119
+ end
120
+ end
121
+
122
+ def strip_port(str)
123
+ str.split(":", 2).first
124
+ end
125
+
84
126
  end # Options
85
127
  end # WebDriver
86
- end # Selenium
128
+ end # Selenium