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.
- data/CHANGES +18 -1
- data/lib/selenium/client/legacy_driver.rb +9 -0
- data/lib/selenium/webdriver/android/bridge.rb +1 -1
- data/lib/selenium/webdriver/chrome/bridge.rb +0 -4
- data/lib/selenium/webdriver/chrome/command_executor.rb +2 -2
- data/lib/selenium/webdriver/chrome/extension.zip +0 -0
- data/lib/selenium/webdriver/common.rb +3 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +22 -0
- data/lib/selenium/webdriver/common/element.rb +10 -0
- data/lib/selenium/webdriver/common/keyboard.rb +48 -0
- data/lib/selenium/webdriver/common/mouse.rb +63 -0
- data/lib/selenium/webdriver/common/platform.rb +26 -11
- data/lib/selenium/webdriver/common/proxy.rb +1 -1
- data/lib/selenium/webdriver/common/zipper.rb +0 -1
- data/lib/selenium/webdriver/firefox/bridge.rb +8 -8
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +1 -1
- data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/firefox/profile.rb +9 -5
- data/lib/selenium/webdriver/firefox/socket_lock.rb +1 -11
- data/lib/selenium/webdriver/ie.rb +3 -1
- data/lib/selenium/webdriver/ie/bridge.rb +23 -12
- 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/ie/server.rb +64 -0
- data/lib/selenium/webdriver/iphone/bridge.rb +1 -1
- data/lib/selenium/webdriver/remote/bridge.rb +62 -8
- data/lib/selenium/webdriver/remote/capabilities.rb +10 -3
- data/lib/selenium/webdriver/remote/commands.rb +67 -59
- data/lib/selenium/webdriver/remote/http/common.rb +4 -0
- data/lib/selenium/webdriver/remote/http/default.rb +10 -4
- data/lib/selenium/webdriver/remote/http/persistent.rb +34 -0
- metadata +169 -196
- data/lib/selenium/webdriver/ie/lib.rb +0 -26
data/CHANGES
CHANGED
@@ -1,4 +1,21 @@
|
|
1
|
-
0.1.
|
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.
|
@@ -46,13 +46,13 @@ module Selenium
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def uri
|
49
|
-
"http
|
49
|
+
"http://#{Platform.localhost}:#{port}/chromeCommandExecutor"
|
50
50
|
end
|
51
51
|
|
52
52
|
private
|
53
53
|
|
54
54
|
def localhost
|
55
|
-
Platform.ironruby? ?
|
55
|
+
Platform.ironruby? ? Platform.localhost : "0.0.0.0" # yeah, weird..
|
56
56
|
end
|
57
57
|
|
58
58
|
def start_run_loop
|
Binary file
|
@@ -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
|
-
|
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
|
132
|
-
:os
|
133
|
-
:ruby187?
|
134
|
-
:ruby19?
|
135
|
-
:jruby?
|
136
|
-
:win?
|
137
|
-
:home
|
138
|
-
: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
|
|
@@ -6,14 +6,12 @@ module Selenium
|
|
6
6
|
class Bridge < Remote::Bridge
|
7
7
|
|
8
8
|
def initialize(opts = {})
|
9
|
-
|
10
|
-
|
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
|
-
|
49
|
-
|
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
|
Binary file
|
@@ -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
|
|
Binary file
|
Binary file
|
@@ -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
|
-
|
54
|
-
@
|
55
|
-
@
|
56
|
-
@
|
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(
|
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/
|
18
|
+
require "selenium/webdriver/ie/server"
|
17
19
|
require "selenium/webdriver/ie/bridge"
|