selenium-webdriver 0.1.1 → 0.1.2
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 +10 -0
- data/lib/selenium/webdriver.rb +23 -1
- data/lib/selenium/webdriver/chrome/bridge.rb +5 -1
- data/lib/selenium/webdriver/chrome/command_executor.rb +1 -1
- data/lib/selenium/webdriver/chrome/extension.zip +0 -0
- data/lib/selenium/webdriver/chrome/launcher.rb +10 -4
- data/lib/selenium/webdriver/common.rb +1 -0
- data/lib/selenium/webdriver/common/alert.rb +27 -0
- data/lib/selenium/webdriver/common/bridge_helper.rb +10 -7
- data/lib/selenium/webdriver/common/core_ext/dir.rb +1 -1
- data/lib/selenium/webdriver/common/driver.rb +8 -16
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +1 -1
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +1 -1
- data/lib/selenium/webdriver/common/element.rb +4 -4
- data/lib/selenium/webdriver/common/keys.rb +3 -1
- data/lib/selenium/webdriver/common/options.rb +2 -2
- data/lib/selenium/webdriver/common/platform.rb +11 -3
- data/lib/selenium/webdriver/common/socket_poller.rb +5 -1
- data/lib/selenium/webdriver/common/target_locator.rb +11 -3
- data/lib/selenium/webdriver/common/timeouts.rb +10 -0
- data/lib/selenium/webdriver/firefox/binary.rb +4 -2
- data/lib/selenium/webdriver/firefox/bridge.rb +1 -1
- data/lib/selenium/webdriver/firefox/extension.rb +2 -2
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +1 -1
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +2 -2
- data/lib/selenium/webdriver/firefox/socket_lock.rb +1 -1
- data/lib/selenium/webdriver/firefox/util.rb +2 -2
- data/lib/selenium/webdriver/ie.rb +3 -4
- data/lib/selenium/webdriver/ie/bridge.rb +20 -565
- data/lib/selenium/webdriver/ie/lib.rb +4 -99
- data/lib/selenium/webdriver/ie/native/win32/IEDriver.dll +0 -0
- data/lib/selenium/webdriver/ie/native/x64/IEDriver.dll +0 -0
- data/lib/selenium/webdriver/remote.rb +1 -1
- data/lib/selenium/webdriver/remote/bridge.rb +21 -1
- data/lib/selenium/webdriver/remote/commands.rb +6 -1
- data/lib/selenium/webdriver/remote/http/default.rb +2 -1
- data/lib/selenium/webdriver/remote/response.rb +1 -1
- metadata +19 -10
- 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 +0 -138
data/CHANGES
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
0.1.2 (2010-12-??)
|
2
|
+
============
|
3
|
+
|
4
|
+
* Changed frame switching behaviour (http://groups.google.com/group/selenium-developers/browse_thread/thread/8dc7938c35bb3968)
|
5
|
+
* IE driver rewrite landed.
|
6
|
+
* Initial support for alerts/prompts (in Firefox).
|
7
|
+
* Cygwin support.
|
8
|
+
* Driver#execute_script now properly wraps elements inside Hashes.
|
9
|
+
* Various fixes for Firefox 4.
|
10
|
+
|
1
11
|
0.1.1 (2010-11-29)
|
2
12
|
==================
|
3
13
|
|
data/lib/selenium/webdriver.rb
CHANGED
@@ -39,12 +39,34 @@ module Selenium
|
|
39
39
|
autoload :Remote, 'selenium/webdriver/remote'
|
40
40
|
autoload :Firefox, 'selenium/webdriver/firefox'
|
41
41
|
|
42
|
+
# @api private
|
43
|
+
|
42
44
|
def self.root
|
43
45
|
@root ||= File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
44
46
|
end
|
45
47
|
|
46
48
|
#
|
47
|
-
#
|
49
|
+
# Create a new Driver instance with the correct bridge for the given browser
|
50
|
+
#
|
51
|
+
# @param browser [:ie, :internet_explorer, :remote, :chrome, :firefox, :ff, :android, :iphone]
|
52
|
+
# the driver type to use
|
53
|
+
# @param *rest
|
54
|
+
# arguments passed to Bridge.new
|
55
|
+
#
|
56
|
+
# @return [Driver]
|
57
|
+
#
|
58
|
+
# @see Selenium::WebDriver::Remote::Bridge
|
59
|
+
# @see Selenium::WebDriver::Firefox::Bridge
|
60
|
+
# @see Selenium::WebDriver::IE::Bridge
|
61
|
+
# @see Selenium::WebDriver::Chrome::Bridge
|
62
|
+
# @see Selenium::WebDriver::Android::Bridge
|
63
|
+
# @see Selenium::WebDriver::IPhone::Bridge
|
64
|
+
#
|
65
|
+
# @example
|
66
|
+
#
|
67
|
+
# WebDriver.for :firefox, :profile => "some-profile"
|
68
|
+
# WebDriver.for :firefox, :profile => Profile.new
|
69
|
+
# WebDriver.for :remote, :url => "http://localhost:4444/wd/hub", :desired_capabilities => caps
|
48
70
|
#
|
49
71
|
|
50
72
|
def self.for(*args)
|
@@ -2,7 +2,7 @@ module Selenium
|
|
2
2
|
module WebDriver
|
3
3
|
module Chrome
|
4
4
|
|
5
|
-
# @private
|
5
|
+
# @api private
|
6
6
|
class Bridge < Remote::Bridge
|
7
7
|
|
8
8
|
def initialize(opts = {})
|
@@ -73,6 +73,10 @@ module Selenium
|
|
73
73
|
element.ref == other.ref
|
74
74
|
end
|
75
75
|
|
76
|
+
%w[acceptAlert dismissAlert setAlertValue getAlertText].each do |m|
|
77
|
+
define_method(m) { |*args| raise NotImplementedError }
|
78
|
+
end
|
79
|
+
|
76
80
|
private
|
77
81
|
|
78
82
|
def execute(command_name, opts = {}, args = nil)
|
@@ -2,7 +2,7 @@ module Selenium
|
|
2
2
|
module WebDriver
|
3
3
|
module Chrome
|
4
4
|
|
5
|
-
# @private
|
5
|
+
# @api private
|
6
6
|
class CommandExecutor
|
7
7
|
HTML_TEMPLATE = "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n%s"
|
8
8
|
JSON_TEMPLATE = "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n%s"
|
Binary file
|
@@ -2,7 +2,7 @@ module Selenium
|
|
2
2
|
module WebDriver
|
3
3
|
module Chrome
|
4
4
|
|
5
|
-
# @private
|
5
|
+
# @api private
|
6
6
|
class Launcher
|
7
7
|
include FileUtils
|
8
8
|
|
@@ -21,7 +21,7 @@ module Selenium
|
|
21
21
|
end
|
22
22
|
|
23
23
|
#
|
24
|
-
# @private
|
24
|
+
# @api private
|
25
25
|
#
|
26
26
|
# @see Chrome.path=
|
27
27
|
#
|
@@ -58,8 +58,10 @@ module Selenium
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def launch_chrome(server_url)
|
61
|
+
path = self.class.binary_path
|
62
|
+
|
61
63
|
args = [
|
62
|
-
Platform.wrap_in_quotes_if_necessary(
|
64
|
+
Platform.wrap_in_quotes_if_necessary(path),
|
63
65
|
"--load-extension=#{Platform.wrap_in_quotes_if_necessary(tmp_extension_dir)}",
|
64
66
|
"--activate-on-launch",
|
65
67
|
"--disable-hang-monitor",
|
@@ -138,13 +140,17 @@ module Selenium
|
|
138
140
|
end
|
139
141
|
|
140
142
|
def windows_paths
|
141
|
-
[
|
143
|
+
paths = [
|
142
144
|
windows_registry_path,
|
143
145
|
"#{ENV['USERPROFILE']}\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe",
|
144
146
|
"#{ENV['USERPROFILE']}\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
|
145
147
|
"#{Platform.home}\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe",
|
146
148
|
"#{Platform.home}\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
|
147
149
|
].compact
|
150
|
+
|
151
|
+
paths.map! { |path| Platform.cygwin_path(path) } if Platform.cygwin?
|
152
|
+
|
153
|
+
paths
|
148
154
|
end
|
149
155
|
|
150
156
|
def windows_registry_path
|
@@ -7,6 +7,7 @@ require "selenium/webdriver/common/file_reaper"
|
|
7
7
|
require "selenium/webdriver/common/socket_poller"
|
8
8
|
require "selenium/webdriver/common/zipper"
|
9
9
|
require "selenium/webdriver/common/wait"
|
10
|
+
require "selenium/webdriver/common/alert"
|
10
11
|
require "selenium/webdriver/common/target_locator"
|
11
12
|
require "selenium/webdriver/common/navigation"
|
12
13
|
require "selenium/webdriver/common/timeouts"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Selenium
|
2
|
+
module WebDriver
|
3
|
+
class Alert
|
4
|
+
|
5
|
+
def initialize(bridge)
|
6
|
+
@bridge = bridge
|
7
|
+
end
|
8
|
+
|
9
|
+
def accept
|
10
|
+
@bridge.acceptAlert
|
11
|
+
end
|
12
|
+
|
13
|
+
def dismiss
|
14
|
+
@bridge.dismissAlert
|
15
|
+
end
|
16
|
+
|
17
|
+
def send_keys(keys)
|
18
|
+
@bridge.setAlertValue keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def text
|
22
|
+
@bridge.getAlertText
|
23
|
+
end
|
24
|
+
|
25
|
+
end # Alert
|
26
|
+
end # WebDriver
|
27
|
+
end # Selenium
|
@@ -4,20 +4,23 @@ module Selenium
|
|
4
4
|
#
|
5
5
|
# Shared across bridges
|
6
6
|
#
|
7
|
-
# @private
|
7
|
+
# @api private
|
8
8
|
#
|
9
9
|
|
10
10
|
module BridgeHelper
|
11
11
|
|
12
12
|
def unwrap_script_result(arg)
|
13
|
-
|
13
|
+
case arg
|
14
|
+
when Array
|
14
15
|
arg.map { |e| unwrap_script_result(e) }
|
15
|
-
|
16
|
-
if
|
17
|
-
Element.new self,
|
16
|
+
when Hash
|
17
|
+
if id = element_id_from(arg)
|
18
|
+
Element.new self, id
|
18
19
|
else
|
19
|
-
arg
|
20
|
+
arg.each { |k, v| arg[k] = unwrap_script_result(v) }
|
20
21
|
end
|
22
|
+
else
|
23
|
+
arg
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
@@ -61,4 +64,4 @@ module Selenium
|
|
61
64
|
|
62
65
|
end # BridgeHelper
|
63
66
|
end # WebDriver
|
64
|
-
end # Selenium
|
67
|
+
end # Selenium
|
@@ -16,20 +16,9 @@ module Selenium
|
|
16
16
|
class << self
|
17
17
|
|
18
18
|
#
|
19
|
-
#
|
19
|
+
# @api private
|
20
20
|
#
|
21
|
-
# @
|
22
|
-
# the driver type to use
|
23
|
-
# @param *rest
|
24
|
-
# arguments passed to Bridge.new
|
25
|
-
#
|
26
|
-
# @return [Driver]
|
27
|
-
#
|
28
|
-
# @example
|
29
|
-
#
|
30
|
-
# Driver.for :firefox, :profile => "some-profile"
|
31
|
-
# Driver.for :firefox, :profile => Profile.new
|
32
|
-
# Driver.for :remote, :url => "http://localhost:4444/wd/hub", :desired_capabilities => caps
|
21
|
+
# @see Selenium::WebDriver.for
|
33
22
|
#
|
34
23
|
|
35
24
|
def for(browser, *args)
|
@@ -55,7 +44,8 @@ module Selenium
|
|
55
44
|
end
|
56
45
|
|
57
46
|
#
|
58
|
-
# A new Driver instance with the given bridge
|
47
|
+
# A new Driver instance with the given bridge.
|
48
|
+
# End users should use Selenium::WebDriver.for instead of using this directly.
|
59
49
|
#
|
60
50
|
# @api private
|
61
51
|
#
|
@@ -201,7 +191,7 @@ module Selenium
|
|
201
191
|
# @param [String] script
|
202
192
|
# JavaScript source to execute
|
203
193
|
# @param [WebDriver::Element,Integer, Float, Boolean, NilClass, String, Array] *args
|
204
|
-
# Arguments will be available in the given script
|
194
|
+
# Arguments will be available in the given script in the 'arguments' pseudo-array.
|
205
195
|
#
|
206
196
|
# @return [WebDriver::Element,Integer,Float,Boolean,NilClass,String,Array]
|
207
197
|
# The value returned from the script.
|
@@ -237,6 +227,8 @@ module Selenium
|
|
237
227
|
# @param [String,Hash] id or selector
|
238
228
|
# @return [WebDriver::Element]
|
239
229
|
#
|
230
|
+
# Examples:
|
231
|
+
#
|
240
232
|
# driver['someElementId'] #=> #<WebDriver::Element:0x1011c3b88>
|
241
233
|
# driver[:tag_name => 'div'] #=> #<WebDriver::Element:0x1011c3b88>
|
242
234
|
#
|
@@ -253,7 +245,7 @@ module Selenium
|
|
253
245
|
#
|
254
246
|
# for Find
|
255
247
|
#
|
256
|
-
# @private
|
248
|
+
# @api private
|
257
249
|
#
|
258
250
|
|
259
251
|
def ref
|
@@ -8,7 +8,7 @@ module Selenium
|
|
8
8
|
#
|
9
9
|
# Creates a new Element
|
10
10
|
#
|
11
|
-
# @private
|
11
|
+
# @api private
|
12
12
|
#
|
13
13
|
|
14
14
|
def initialize(bridge, id)
|
@@ -274,7 +274,7 @@ module Selenium
|
|
274
274
|
#
|
275
275
|
# for Find and execute_script
|
276
276
|
#
|
277
|
-
# @private
|
277
|
+
# @api private
|
278
278
|
#
|
279
279
|
|
280
280
|
def ref
|
@@ -285,7 +285,7 @@ module Selenium
|
|
285
285
|
# Convert to a WebElement JSON Object for transmission over the wire.
|
286
286
|
# @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Basic_Concepts_And_Terms
|
287
287
|
#
|
288
|
-
# @private
|
288
|
+
# @api private
|
289
289
|
#
|
290
290
|
|
291
291
|
def to_json(*args)
|
@@ -295,7 +295,7 @@ module Selenium
|
|
295
295
|
#
|
296
296
|
# For Rails 3 - http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/
|
297
297
|
#
|
298
|
-
# @private
|
298
|
+
# @api private
|
299
299
|
#
|
300
300
|
|
301
301
|
def as_json(opts = nil)
|
@@ -3,7 +3,7 @@ module Selenium
|
|
3
3
|
class Options
|
4
4
|
|
5
5
|
#
|
6
|
-
# @private
|
6
|
+
# @api private
|
7
7
|
#
|
8
8
|
|
9
9
|
def initialize(bridge)
|
@@ -79,7 +79,7 @@ module Selenium
|
|
79
79
|
:name => cookie["name"],
|
80
80
|
:value => cookie["value"],
|
81
81
|
:path => cookie["path"],
|
82
|
-
:domain => strip_port(cookie["domain"]),
|
82
|
+
:domain => cookie["domain"] && strip_port(cookie["domain"]),
|
83
83
|
:expires => cookie["expiry"] && datetime_at(cookie['expiry']),
|
84
84
|
:secure => cookie["secure"]
|
85
85
|
}
|
@@ -3,7 +3,7 @@ require "rbconfig"
|
|
3
3
|
module Selenium
|
4
4
|
module WebDriver
|
5
5
|
|
6
|
-
# @private
|
6
|
+
# @api private
|
7
7
|
module Platform
|
8
8
|
|
9
9
|
module_function
|
@@ -27,7 +27,7 @@ module Selenium
|
|
27
27
|
@os ||= (
|
28
28
|
host_os = RbConfig::CONFIG['host_os']
|
29
29
|
case host_os
|
30
|
-
when /mswin|msys|
|
30
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
31
31
|
:windows
|
32
32
|
when /darwin|mac os/
|
33
33
|
:macosx
|
@@ -83,8 +83,16 @@ module Selenium
|
|
83
83
|
os == :linux
|
84
84
|
end
|
85
85
|
|
86
|
+
def cygwin?
|
87
|
+
RUBY_PLATFORM =~ /cygwin/
|
88
|
+
end
|
89
|
+
|
86
90
|
def wrap_in_quotes_if_necessary(str)
|
87
|
-
win? ? %{"#{str}"} : str
|
91
|
+
win? && !cygwin? ? %{"#{str}"} : str
|
92
|
+
end
|
93
|
+
|
94
|
+
def cygwin_path(path)
|
95
|
+
`cygpath "#{path}"`.strip
|
88
96
|
end
|
89
97
|
|
90
98
|
def make_writable(file)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "selenium/webdriver/common/platform"
|
1
2
|
require "socket"
|
2
3
|
|
3
4
|
module Selenium
|
@@ -35,12 +36,15 @@ module Selenium
|
|
35
36
|
|
36
37
|
private
|
37
38
|
|
39
|
+
SOCKET_ERRORS = [Errno::ECONNREFUSED, Errno::ENOTCONN, SocketError]
|
40
|
+
SOCKET_ERRORS << Errno::EPERM if Platform.cygwin?
|
41
|
+
|
38
42
|
def listening?
|
39
43
|
# There's a bug in 1.9.1 on Windows where this will succeed even if no
|
40
44
|
# one is listening. Users who hit that should upgrade their Ruby.
|
41
45
|
TCPSocket.new(@host, @port).close
|
42
46
|
true
|
43
|
-
rescue
|
47
|
+
rescue *SOCKET_ERRORS => e
|
44
48
|
$stderr.puts [@host, @port].inspect if $DEBUG
|
45
49
|
false
|
46
50
|
end
|
@@ -19,13 +19,13 @@ module Selenium
|
|
19
19
|
end
|
20
20
|
|
21
21
|
#
|
22
|
-
# switch to the
|
22
|
+
# switch to the given window handle
|
23
23
|
#
|
24
|
-
# If given a block, this method will
|
24
|
+
# If given a block, this method will switch back to the original window after
|
25
25
|
# block execution.
|
26
26
|
#
|
27
27
|
# @param id
|
28
|
-
# A window handle
|
28
|
+
# A window handle, obtained through Driver#window_handles
|
29
29
|
#
|
30
30
|
|
31
31
|
def window(id)
|
@@ -68,6 +68,14 @@ module Selenium
|
|
68
68
|
@bridge.switchToDefaultContent
|
69
69
|
end
|
70
70
|
|
71
|
+
#
|
72
|
+
# switches to the currently active modal dialog for this particular driver instance
|
73
|
+
#
|
74
|
+
|
75
|
+
def alert
|
76
|
+
Alert.new(@bridge)
|
77
|
+
end
|
78
|
+
|
71
79
|
end # TargetLocator
|
72
80
|
end # WebDriver
|
73
81
|
end # Selenium
|
@@ -14,6 +14,16 @@ module Selenium
|
|
14
14
|
@bridge.setImplicitWaitTimeout seconds * 1000
|
15
15
|
end
|
16
16
|
|
17
|
+
#
|
18
|
+
# Sets the amount of time to wait for an asynchronous script to finish
|
19
|
+
# execution before throwing an error. If the timeout is negative, then the
|
20
|
+
# script will be allowed to run indefinitely.
|
21
|
+
#
|
22
|
+
|
23
|
+
def script_timeout=(seconds)
|
24
|
+
@bridge.setScriptTimeout seconds * 1000
|
25
|
+
end
|
26
|
+
|
17
27
|
end # Timeouts
|
18
28
|
end # WebDriver
|
19
29
|
end # Selenium
|