selenium-webdriver 0.1.2 → 0.1.3.dev
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|