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.
- data/CHANGES +25 -0
- data/lib/selenium/webdriver.rb +6 -29
- data/lib/selenium/webdriver/chrome.rb +4 -2
- data/lib/selenium/webdriver/chrome/extension.zip +0 -0
- data/lib/selenium/webdriver/chrome/launcher.rb +15 -16
- data/lib/selenium/webdriver/common.rb +18 -0
- data/lib/selenium/webdriver/{bridge_helper.rb → common/bridge_helper.rb} +0 -0
- data/lib/selenium/webdriver/{core_ext → common/core_ext}/dir.rb +0 -0
- data/lib/selenium/webdriver/{core_ext → common/core_ext}/string.rb +0 -0
- data/lib/selenium/webdriver/{driver.rb → common/driver.rb} +19 -7
- data/lib/selenium/webdriver/{driver_extensions → common/driver_extensions}/takes_screenshot.rb +2 -2
- data/lib/selenium/webdriver/{element.rb → common/element.rb} +30 -3
- data/lib/selenium/webdriver/{error.rb → common/error.rb} +0 -0
- data/lib/selenium/webdriver/{file_reaper.rb → common/file_reaper.rb} +0 -0
- data/lib/selenium/webdriver/{find.rb → common/find.rb} +9 -1
- data/lib/selenium/webdriver/{keys.rb → common/keys.rb} +0 -0
- data/lib/selenium/webdriver/{navigation.rb → common/navigation.rb} +3 -3
- data/lib/selenium/webdriver/{options.rb → common/options.rb} +47 -5
- data/lib/selenium/webdriver/{platform.rb → common/platform.rb} +10 -0
- data/lib/selenium/webdriver/common/socket_poller.rb +47 -0
- data/lib/selenium/webdriver/{target_locator.rb → common/target_locator.rb} +11 -8
- data/lib/selenium/webdriver/{timeouts.rb → common/timeouts.rb} +0 -0
- data/lib/selenium/webdriver/common/wait.rb +60 -0
- data/lib/selenium/webdriver/common/zipper.rb +54 -0
- data/lib/selenium/webdriver/firefox.rb +6 -3
- data/lib/selenium/webdriver/firefox/binary.rb +46 -43
- data/lib/selenium/webdriver/firefox/bridge.rb +2 -10
- data/lib/selenium/webdriver/firefox/extension.rb +51 -0
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +25 -69
- data/lib/selenium/webdriver/firefox/profile.rb +123 -89
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +2 -1
- data/lib/selenium/webdriver/firefox/socket_lock.rb +77 -0
- data/lib/selenium/webdriver/ie/bridge.rb +25 -38
- data/lib/selenium/webdriver/ie/lib.rb +11 -1
- data/lib/selenium/webdriver/ie/native/win32/InternetExplorerDriver.dll +0 -0
- data/lib/selenium/webdriver/ie/native/x64/InternetExplorerDriver.dll +0 -0
- data/lib/selenium/webdriver/ie/util.rb +3 -17
- data/lib/selenium/webdriver/remote/bridge.rb +9 -1
- data/lib/selenium/webdriver/remote/capabilities.rb +53 -20
- data/lib/selenium/webdriver/remote/http/default.rb +2 -2
- metadata +52 -31
- data/lib/selenium/webdriver/child_process.rb +0 -243
- 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
|
|
data/lib/selenium/webdriver.rb
CHANGED
@@ -1,25 +1,18 @@
|
|
1
1
|
require "tmpdir"
|
2
2
|
require "fileutils"
|
3
|
+
require "date"
|
4
|
+
require "childprocess"
|
3
5
|
|
4
|
-
|
6
|
+
have_lib = lambda { |lib|
|
5
7
|
begin
|
6
|
-
require
|
8
|
+
require lib
|
7
9
|
true
|
8
10
|
rescue LoadError
|
9
11
|
false
|
10
12
|
end
|
11
13
|
}
|
12
14
|
|
13
|
-
|
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
|
Binary file
|
@@ -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.
|
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.
|
95
|
+
@process = ChildProcess.build(*args).start
|
91
96
|
end
|
92
97
|
|
93
98
|
def ext_path
|
94
|
-
@ext_path ||=
|
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"
|
File without changes
|
File without changes
|
File without changes
|
@@ -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
|
66
|
-
extend(
|
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(
|
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(
|
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(
|
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
|
data/lib/selenium/webdriver/{driver_extensions → common/driver_extensions}/takes_screenshot.rb
RENAMED
@@ -9,7 +9,7 @@ module Selenium
|
|
9
9
|
module TakesScreenshot
|
10
10
|
|
11
11
|
def save_screenshot(png_path)
|
12
|
-
File.open(png_path, '
|
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
|
-
|
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
|
File without changes
|
File without changes
|
@@ -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(
|
6
|
-
@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(
|
10
|
-
@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["
|
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
|