selenium-webdriver 2.53.4 → 3.0.0.beta1
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 +24 -18
- data/README.md +2 -3
- data/lib/selenium/server.rb +64 -68
- data/lib/selenium/webdriver.rb +5 -9
- data/lib/selenium/webdriver/chrome.rb +18 -3
- data/lib/selenium/webdriver/chrome/bridge.rb +13 -16
- data/lib/selenium/webdriver/chrome/profile.rb +7 -9
- data/lib/selenium/webdriver/chrome/service.rb +8 -84
- data/lib/selenium/webdriver/common.rb +1 -2
- data/lib/selenium/webdriver/common/action_builder.rb +28 -38
- data/lib/selenium/webdriver/common/alert.rb +7 -10
- data/lib/selenium/webdriver/common/bridge_helper.rb +10 -15
- data/lib/selenium/webdriver/common/driver.rb +19 -28
- data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +0 -3
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +4 -6
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +4 -5
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +0 -3
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +3 -6
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +2 -5
- data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +2 -5
- data/lib/selenium/webdriver/common/element.rb +27 -29
- data/lib/selenium/webdriver/common/error.rb +17 -20
- data/lib/selenium/webdriver/common/file_reaper.rb +3 -9
- data/lib/selenium/webdriver/common/html5/local_storage.rb +6 -8
- data/lib/selenium/webdriver/common/html5/session_storage.rb +6 -8
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +6 -15
- data/lib/selenium/webdriver/common/keyboard.rb +7 -12
- data/lib/selenium/webdriver/common/keys.rb +67 -69
- data/lib/selenium/webdriver/common/log_entry.rb +3 -4
- data/lib/selenium/webdriver/common/logs.rb +2 -4
- data/lib/selenium/webdriver/common/mouse.rb +9 -12
- data/lib/selenium/webdriver/common/navigation.rb +2 -4
- data/lib/selenium/webdriver/common/options.rb +16 -19
- data/lib/selenium/webdriver/common/platform.rb +61 -90
- data/lib/selenium/webdriver/common/port_prober.rb +1 -2
- data/lib/selenium/webdriver/common/profile_helper.rb +5 -8
- data/lib/selenium/webdriver/common/proxy.rb +58 -70
- data/lib/selenium/webdriver/common/search_context.rb +15 -19
- data/lib/selenium/webdriver/common/service.rb +127 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +5 -11
- data/lib/selenium/webdriver/common/socket_poller.rb +4 -9
- data/lib/selenium/webdriver/common/target_locator.rb +11 -13
- data/lib/selenium/webdriver/common/timeouts.rb +4 -6
- data/lib/selenium/webdriver/common/touch_action_builder.rb +2 -4
- data/lib/selenium/webdriver/common/touch_screen.rb +15 -18
- data/lib/selenium/webdriver/common/w3c_error.rb +3 -6
- data/lib/selenium/webdriver/common/wait.rb +6 -11
- data/lib/selenium/webdriver/common/window.rb +12 -15
- data/lib/selenium/webdriver/common/zipper.rb +6 -8
- data/lib/selenium/webdriver/edge.rb +18 -3
- data/lib/selenium/webdriver/edge/bridge.rb +11 -16
- data/lib/selenium/webdriver/edge/legacy_support.rb +38 -39
- data/lib/selenium/webdriver/edge/service.rb +8 -82
- data/lib/selenium/webdriver/firefox.rb +25 -6
- data/lib/selenium/webdriver/firefox/binary.rb +37 -53
- data/lib/selenium/webdriver/firefox/bridge.rb +3 -6
- data/lib/selenium/webdriver/firefox/extension.rb +4 -6
- data/lib/selenium/webdriver/firefox/extension/prefs.json +1 -10
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +8 -11
- data/lib/selenium/webdriver/firefox/profile.rb +40 -42
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +8 -15
- data/lib/selenium/webdriver/firefox/service.rb +23 -79
- data/lib/selenium/webdriver/firefox/util.rb +0 -2
- data/lib/selenium/webdriver/firefox/w3c_bridge.rb +2 -4
- data/lib/selenium/webdriver/ie.rb +16 -7
- data/lib/selenium/webdriver/ie/bridge.rb +16 -23
- data/lib/selenium/webdriver/{iphone.rb → ie/service.rb} +26 -4
- data/lib/selenium/webdriver/phantomjs.rb +8 -3
- data/lib/selenium/webdriver/phantomjs/bridge.rb +9 -11
- data/lib/selenium/webdriver/phantomjs/service.rb +17 -81
- data/lib/selenium/webdriver/remote.rb +0 -2
- data/lib/selenium/webdriver/remote/bridge.rb +193 -191
- data/lib/selenium/webdriver/remote/capabilities.rb +60 -90
- data/lib/selenium/webdriver/remote/commands.rb +197 -192
- data/lib/selenium/webdriver/remote/http/common.rb +15 -13
- data/lib/selenium/webdriver/remote/http/curb.rb +5 -9
- data/lib/selenium/webdriver/remote/http/default.rb +32 -37
- data/lib/selenium/webdriver/remote/http/persistent.rb +4 -6
- data/lib/selenium/webdriver/remote/response.rb +13 -21
- data/lib/selenium/webdriver/remote/server_error.rb +1 -3
- data/lib/selenium/webdriver/remote/w3c_bridge.rb +200 -195
- data/lib/selenium/webdriver/remote/w3c_capabilities.rb +38 -46
- data/lib/selenium/webdriver/remote/w3c_commands.rb +116 -113
- data/lib/selenium/webdriver/safari.rb +23 -7
- data/lib/selenium/{client/javascript_frameworks/jquery.rb → webdriver/safari/apple_bridge.rb} +28 -9
- data/lib/selenium/webdriver/safari/browser.rb +0 -2
- data/lib/selenium/webdriver/safari/{bridge.rb → legacy_bridge.rb} +12 -9
- data/lib/selenium/webdriver/safari/options.rb +3 -4
- data/lib/selenium/webdriver/safari/resources/client.js +56 -7255
- data/lib/selenium/webdriver/safari/server.rb +18 -24
- data/lib/selenium/{client/javascript_frameworks/prototype.rb → webdriver/safari/service.rb} +27 -9
- data/lib/selenium/webdriver/support.rb +1 -0
- data/lib/selenium/webdriver/support/abstract_event_listener.rb +17 -2
- data/lib/selenium/webdriver/support/block_event_listener.rb +1 -3
- data/lib/selenium/webdriver/support/color.rb +55 -38
- data/lib/selenium/webdriver/{android.rb → support/escaper.rb} +19 -4
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +36 -38
- data/lib/selenium/webdriver/support/select.rb +33 -84
- data/selenium-webdriver.gemspec +23 -23
- metadata +19 -30
- data/lib/selenium-client.rb +0 -21
- data/lib/selenium/client.rb +0 -57
- data/lib/selenium/client/base.rb +0 -151
- data/lib/selenium/client/driver.rb +0 -29
- data/lib/selenium/client/errors.rb +0 -28
- data/lib/selenium/client/extensions.rb +0 -132
- data/lib/selenium/client/idiomatic.rb +0 -507
- data/lib/selenium/client/javascript_expression_builder.rb +0 -135
- data/lib/selenium/client/legacy_driver.rb +0 -1722
- data/lib/selenium/client/protocol.rb +0 -123
- data/lib/selenium/client/selenium_helper.rb +0 -49
- data/lib/selenium/rake/server_task.rb +0 -176
- data/lib/selenium/webdriver/android/bridge.rb +0 -68
- data/lib/selenium/webdriver/common/core_ext/base64.rb +0 -28
- data/lib/selenium/webdriver/common/core_ext/dir.rb +0 -61
- data/lib/selenium/webdriver/common/html5/location.rb +0 -19
- data/lib/selenium/webdriver/ie/server.rb +0 -133
- data/lib/selenium/webdriver/iphone/bridge.rb +0 -64
|
@@ -23,8 +23,8 @@ module Selenium
|
|
|
23
23
|
module Http
|
|
24
24
|
class Common
|
|
25
25
|
MAX_REDIRECTS = 20 # same as chromium/gecko
|
|
26
|
-
CONTENT_TYPE =
|
|
27
|
-
DEFAULT_HEADERS = {
|
|
26
|
+
CONTENT_TYPE = 'application/json'.freeze
|
|
27
|
+
DEFAULT_HEADERS = {'Accept' => CONTENT_TYPE}.freeze
|
|
28
28
|
|
|
29
29
|
attr_accessor :timeout
|
|
30
30
|
attr_writer :server_url
|
|
@@ -38,22 +38,22 @@ module Selenium
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def call(verb, url, command_hash)
|
|
41
|
-
url = server_url.merge(url) unless url.
|
|
41
|
+
url = server_url.merge(url) unless url.is_a?(URI)
|
|
42
42
|
headers = DEFAULT_HEADERS.dup
|
|
43
|
-
headers['Cache-Control'] =
|
|
43
|
+
headers['Cache-Control'] = 'no-cache' if verb == :get
|
|
44
44
|
|
|
45
45
|
if command_hash
|
|
46
46
|
payload = JSON.generate(command_hash)
|
|
47
|
-
headers[
|
|
48
|
-
headers[
|
|
47
|
+
headers['Content-Type'] = "#{CONTENT_TYPE}; charset=utf-8"
|
|
48
|
+
headers['Content-Length'] = payload.bytesize.to_s if [:post, :put].include?(verb)
|
|
49
49
|
|
|
50
50
|
if $DEBUG
|
|
51
51
|
puts " >>> #{url} | #{payload}"
|
|
52
52
|
puts " > #{headers.inspect}"
|
|
53
53
|
end
|
|
54
54
|
elsif verb == :post
|
|
55
|
-
payload =
|
|
56
|
-
headers[
|
|
55
|
+
payload = '{}'
|
|
56
|
+
headers['Content-Length'] = '2'
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
request verb, url, headers, payload
|
|
@@ -62,15 +62,18 @@ module Selenium
|
|
|
62
62
|
private
|
|
63
63
|
|
|
64
64
|
def server_url
|
|
65
|
-
@server_url
|
|
65
|
+
return @server_url if @server_url
|
|
66
|
+
raise Error::WebDriverError, 'server_url not set'
|
|
66
67
|
end
|
|
67
68
|
|
|
68
|
-
def request(
|
|
69
|
-
raise NotImplementedError,
|
|
69
|
+
def request(*)
|
|
70
|
+
raise NotImplementedError, 'subclass responsibility'
|
|
70
71
|
end
|
|
71
72
|
|
|
72
73
|
def create_response(code, body, content_type)
|
|
73
|
-
code
|
|
74
|
+
code = code.to_i
|
|
75
|
+
body = body.to_s.strip
|
|
76
|
+
content_type = content_type.to_s
|
|
74
77
|
puts "<- #{body}\n" if $DEBUG
|
|
75
78
|
|
|
76
79
|
if content_type.include? CONTENT_TYPE
|
|
@@ -85,7 +88,6 @@ module Selenium
|
|
|
85
88
|
raise Error::WebDriverError, msg
|
|
86
89
|
end
|
|
87
90
|
end
|
|
88
|
-
|
|
89
91
|
end # Common
|
|
90
92
|
end # Http
|
|
91
93
|
end # Remote
|
|
@@ -22,12 +22,10 @@ require 'curb'
|
|
|
22
22
|
module Selenium
|
|
23
23
|
module WebDriver
|
|
24
24
|
module Remote
|
|
25
|
-
|
|
26
25
|
# added for rescue
|
|
27
26
|
Bridge::QUIT_ERRORS << Curl::Err::RecvError
|
|
28
27
|
|
|
29
28
|
module Http
|
|
30
|
-
|
|
31
29
|
#
|
|
32
30
|
# An alternative to the default Net::HTTP client.
|
|
33
31
|
#
|
|
@@ -42,15 +40,14 @@ module Selenium
|
|
|
42
40
|
#
|
|
43
41
|
|
|
44
42
|
class Curb < Common
|
|
45
|
-
|
|
46
43
|
private
|
|
47
44
|
|
|
48
45
|
def request(verb, url, headers, payload)
|
|
49
|
-
client.url
|
|
46
|
+
client.url = url.to_s
|
|
50
47
|
|
|
51
48
|
# workaround for http://github.com/taf2/curb/issues/issue/40
|
|
52
49
|
# curb will handle this for us anyway
|
|
53
|
-
headers.delete
|
|
50
|
+
headers.delete 'Content-Length'
|
|
54
51
|
|
|
55
52
|
client.headers = headers
|
|
56
53
|
|
|
@@ -62,10 +59,10 @@ module Selenium
|
|
|
62
59
|
when :get
|
|
63
60
|
client.http_get
|
|
64
61
|
when :post
|
|
65
|
-
client.post_body = payload ||
|
|
62
|
+
client.post_body = payload || ''
|
|
66
63
|
client.http_post
|
|
67
64
|
when :put
|
|
68
|
-
client.put_data = payload ||
|
|
65
|
+
client.put_data = payload || ''
|
|
69
66
|
client.http_put
|
|
70
67
|
when :delete
|
|
71
68
|
client.http_delete
|
|
@@ -85,12 +82,11 @@ module Selenium
|
|
|
85
82
|
c.max_redirects = MAX_REDIRECTS
|
|
86
83
|
c.follow_location = true
|
|
87
84
|
c.timeout = @timeout if @timeout
|
|
88
|
-
c.verbose =
|
|
85
|
+
c.verbose = $DEBUG
|
|
89
86
|
|
|
90
87
|
c
|
|
91
88
|
)
|
|
92
89
|
end
|
|
93
|
-
|
|
94
90
|
end # Curb
|
|
95
91
|
end # Http
|
|
96
92
|
end # Remote
|
|
@@ -24,7 +24,6 @@ module Selenium
|
|
|
24
24
|
module WebDriver
|
|
25
25
|
module Remote
|
|
26
26
|
module Http
|
|
27
|
-
|
|
28
27
|
# @api private
|
|
29
28
|
class Default < Common
|
|
30
29
|
attr_accessor :proxy
|
|
@@ -33,18 +32,18 @@ module Selenium
|
|
|
33
32
|
|
|
34
33
|
def http
|
|
35
34
|
@http ||= (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
http = new_http_client
|
|
36
|
+
if server_url.scheme == 'https'
|
|
37
|
+
http.use_ssl = true
|
|
38
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
39
|
+
end
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
if @timeout
|
|
42
|
+
http.open_timeout = @timeout
|
|
43
|
+
http.read_timeout = @timeout
|
|
44
|
+
end
|
|
46
45
|
|
|
47
|
-
|
|
46
|
+
http
|
|
48
47
|
)
|
|
49
48
|
end
|
|
50
49
|
|
|
@@ -76,15 +75,12 @@ module Selenium
|
|
|
76
75
|
retry
|
|
77
76
|
|
|
78
77
|
rescue Errno::ECONNREFUSED => ex
|
|
79
|
-
if use_proxy?
|
|
80
|
-
|
|
81
|
-
else
|
|
82
|
-
raise
|
|
83
|
-
end
|
|
78
|
+
raise ex.class, "using proxy: #{proxy.http}" if use_proxy?
|
|
79
|
+
raise
|
|
84
80
|
end
|
|
85
81
|
|
|
86
|
-
if response.
|
|
87
|
-
raise Error::WebDriverError,
|
|
82
|
+
if response.is_a? Net::HTTPRedirection
|
|
83
|
+
raise Error::WebDriverError, 'too many redirects' if redirects >= MAX_REDIRECTS
|
|
88
84
|
request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil, redirects + 1)
|
|
89
85
|
else
|
|
90
86
|
create_response response.code, response.body, response.content_type
|
|
@@ -109,7 +105,8 @@ module Selenium
|
|
|
109
105
|
|
|
110
106
|
def new_http_client
|
|
111
107
|
if use_proxy?
|
|
112
|
-
|
|
108
|
+
url = @proxy.http
|
|
109
|
+
unless proxy.respond_to?(:http) && url
|
|
113
110
|
raise Error::WebDriverError, "expected HTTP proxy, got #{@proxy.inspect}"
|
|
114
111
|
end
|
|
115
112
|
|
|
@@ -124,13 +121,13 @@ module Selenium
|
|
|
124
121
|
|
|
125
122
|
def proxy
|
|
126
123
|
@proxy ||= (
|
|
127
|
-
|
|
128
|
-
|
|
124
|
+
proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
|
|
125
|
+
no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
|
|
129
126
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
127
|
+
if proxy
|
|
128
|
+
proxy = "http://#{proxy}" unless proxy.start_with?('http://')
|
|
129
|
+
Proxy.new(http: proxy, no_proxy: no_proxy)
|
|
130
|
+
end
|
|
134
131
|
)
|
|
135
132
|
end
|
|
136
133
|
|
|
@@ -138,24 +135,22 @@ module Selenium
|
|
|
138
135
|
return false if proxy.nil?
|
|
139
136
|
|
|
140
137
|
if proxy.no_proxy
|
|
141
|
-
ignored = proxy.no_proxy.split(
|
|
142
|
-
host ==
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
138
|
+
ignored = proxy.no_proxy.split(',').any? do |host|
|
|
139
|
+
host == '*' ||
|
|
140
|
+
host == server_url.host || (
|
|
141
|
+
begin
|
|
142
|
+
IPAddr.new(host).include?(server_url.host)
|
|
143
|
+
rescue ArgumentError
|
|
144
|
+
false
|
|
145
|
+
end
|
|
146
|
+
)
|
|
151
147
|
end
|
|
152
148
|
|
|
153
|
-
|
|
149
|
+
!ignored
|
|
154
150
|
else
|
|
155
151
|
true
|
|
156
152
|
end
|
|
157
153
|
end
|
|
158
|
-
|
|
159
154
|
end # Default
|
|
160
155
|
end # Http
|
|
161
156
|
end # Remote
|
|
@@ -23,10 +23,8 @@ module Selenium
|
|
|
23
23
|
module WebDriver
|
|
24
24
|
module Remote
|
|
25
25
|
module Http
|
|
26
|
-
|
|
27
26
|
# @api private
|
|
28
27
|
class Persistent < Default
|
|
29
|
-
|
|
30
28
|
def close
|
|
31
29
|
@http.shutdown if @http
|
|
32
30
|
end
|
|
@@ -37,19 +35,19 @@ module Selenium
|
|
|
37
35
|
proxy = nil
|
|
38
36
|
|
|
39
37
|
if @proxy
|
|
40
|
-
unless @proxy.respond_to?(:http)
|
|
41
|
-
|
|
38
|
+
unless @proxy.respond_to?(:http)
|
|
39
|
+
url = @proxy.http
|
|
40
|
+
raise Error::WebDriverError, "expected HTTP proxy, got #{@proxy.inspect}" unless url
|
|
42
41
|
end
|
|
43
42
|
proxy = URI.parse(url)
|
|
44
43
|
end
|
|
45
44
|
|
|
46
|
-
Net::HTTP::Persistent.new
|
|
45
|
+
Net::HTTP::Persistent.new 'webdriver', proxy
|
|
47
46
|
end
|
|
48
47
|
|
|
49
48
|
def response_for(request)
|
|
50
49
|
http.request server_url, request
|
|
51
50
|
end
|
|
52
|
-
|
|
53
51
|
end # Persistent
|
|
54
52
|
end # Http
|
|
55
53
|
end # Remote
|
|
@@ -20,10 +20,8 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Remote
|
|
23
|
-
|
|
24
23
|
# @api private
|
|
25
24
|
class Response
|
|
26
|
-
|
|
27
25
|
attr_reader :code, :payload
|
|
28
26
|
attr_writer :payload
|
|
29
27
|
|
|
@@ -49,9 +47,10 @@ module Selenium
|
|
|
49
47
|
|
|
50
48
|
case val
|
|
51
49
|
when Hash
|
|
52
|
-
msg = val['message']
|
|
53
|
-
|
|
54
|
-
msg << "
|
|
50
|
+
msg = val['message']
|
|
51
|
+
return 'unknown error' unless msg
|
|
52
|
+
msg << ": #{val['alert']['text'].inspect}" if val['alert'].is_a?(Hash) && val['alert']['text']
|
|
53
|
+
msg << " (#{val['class']})" if val['class']
|
|
55
54
|
msg
|
|
56
55
|
when String
|
|
57
56
|
val
|
|
@@ -67,34 +66,28 @@ module Selenium
|
|
|
67
66
|
private
|
|
68
67
|
|
|
69
68
|
def assert_ok
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
end
|
|
69
|
+
e = error
|
|
70
|
+
raise e if e
|
|
71
|
+
return unless @code.nil? || @code >= 400
|
|
72
|
+
raise Error::ServerError, self
|
|
75
73
|
end
|
|
76
74
|
|
|
77
75
|
def add_backtrace(ex)
|
|
78
|
-
unless value.
|
|
79
|
-
return
|
|
80
|
-
end
|
|
76
|
+
return unless value.is_a?(Hash) && value['stackTrace']
|
|
81
77
|
|
|
82
78
|
server_trace = value['stackTrace']
|
|
83
79
|
|
|
84
80
|
backtrace = server_trace.map do |frame|
|
|
85
|
-
next unless frame.
|
|
81
|
+
next unless frame.is_a?(Hash)
|
|
86
82
|
|
|
87
83
|
file = frame['fileName']
|
|
88
84
|
line = frame['lineNumber']
|
|
89
85
|
meth = frame['methodName']
|
|
90
86
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
end
|
|
87
|
+
class_name = frame['className']
|
|
88
|
+
file = "#{class_name}(#{file})" if class_name
|
|
94
89
|
|
|
95
|
-
if meth.nil? || meth.empty?
|
|
96
|
-
meth = 'unknown'
|
|
97
|
-
end
|
|
90
|
+
meth = 'unknown' if meth.nil? || meth.empty?
|
|
98
91
|
|
|
99
92
|
"[remote server] #{file}:#{line}:in `#{meth}'"
|
|
100
93
|
end.compact
|
|
@@ -109,7 +102,6 @@ module Selenium
|
|
|
109
102
|
def value
|
|
110
103
|
@payload['value'] || @payload['message']
|
|
111
104
|
end
|
|
112
|
-
|
|
113
105
|
end # Response
|
|
114
106
|
end # Remote
|
|
115
107
|
end # WebDriver
|
|
@@ -21,15 +21,13 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Error
|
|
23
23
|
class ServerError < StandardError
|
|
24
|
-
|
|
25
24
|
def initialize(response)
|
|
26
|
-
if response.
|
|
25
|
+
if response.is_a? String
|
|
27
26
|
super(response)
|
|
28
27
|
else
|
|
29
28
|
super("status code #{response.code}")
|
|
30
29
|
end
|
|
31
30
|
end
|
|
32
|
-
|
|
33
31
|
end # ServerError
|
|
34
32
|
end # Error
|
|
35
33
|
end # WebDriver
|
|
@@ -22,7 +22,6 @@ require 'json'
|
|
|
22
22
|
module Selenium
|
|
23
23
|
module WebDriver
|
|
24
24
|
module Remote
|
|
25
|
-
|
|
26
25
|
#
|
|
27
26
|
# Low level bridge to the remote server, through which the rest of the API works.
|
|
28
27
|
#
|
|
@@ -32,6 +31,7 @@ module Selenium
|
|
|
32
31
|
class W3CBridge
|
|
33
32
|
include BridgeHelper
|
|
34
33
|
|
|
34
|
+
# TODO: constant shouldn't be modified in class
|
|
35
35
|
COMMANDS = {}
|
|
36
36
|
|
|
37
37
|
#
|
|
@@ -62,16 +62,13 @@ module Selenium
|
|
|
62
62
|
#
|
|
63
63
|
|
|
64
64
|
def initialize(opts = {})
|
|
65
|
-
|
|
66
|
-
require_relative '../edge/legacy_support'
|
|
67
|
-
extend Edge::LegacySupport
|
|
68
|
-
end
|
|
65
|
+
edge_check(opts)
|
|
69
66
|
|
|
70
67
|
opts = opts.dup
|
|
71
68
|
|
|
72
|
-
http_client
|
|
69
|
+
http_client = opts.delete(:http_client) { Http::Default.new }
|
|
73
70
|
desired_capabilities = opts.delete(:desired_capabilities) { W3CCapabilities.firefox }
|
|
74
|
-
url
|
|
71
|
+
url = opts.delete(:url) { "http://#{Platform.localhost}:4444/wd/hub" }
|
|
75
72
|
|
|
76
73
|
desired_capabilities = W3CCapabilities.send(desired_capabilities) if desired_capabilities.is_a? Symbol
|
|
77
74
|
|
|
@@ -81,23 +78,30 @@ module Selenium
|
|
|
81
78
|
raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
|
|
82
79
|
end
|
|
83
80
|
|
|
84
|
-
uri = url.
|
|
85
|
-
uri.path +=
|
|
81
|
+
uri = url.is_a?(URI) ? url : URI.parse(url)
|
|
82
|
+
uri.path += '/' unless uri.path =~ %r{\/$}
|
|
86
83
|
|
|
87
84
|
http_client.server_url = uri
|
|
88
85
|
|
|
89
|
-
@http
|
|
90
|
-
@capabilities
|
|
86
|
+
@http = http_client
|
|
87
|
+
@capabilities = create_session(desired_capabilities)
|
|
91
88
|
@file_detector = nil
|
|
92
89
|
end
|
|
93
90
|
|
|
94
91
|
def browser
|
|
95
92
|
@browser ||= (
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
name = @capabilities.browser_name
|
|
94
|
+
name ? name.tr(' ', '_').to_sym : 'unknown'
|
|
98
95
|
)
|
|
99
96
|
end
|
|
100
97
|
|
|
98
|
+
def edge_check(opts)
|
|
99
|
+
caps = opts[:desired_capabilities]
|
|
100
|
+
return unless caps && caps[:browser_name] && caps[:browser_name] == 'MicrosoftEdge'
|
|
101
|
+
require_relative '../edge/legacy_support'
|
|
102
|
+
extend Edge::LegacySupport
|
|
103
|
+
end
|
|
104
|
+
|
|
101
105
|
def driver_extensions
|
|
102
106
|
[
|
|
103
107
|
DriverExtensions::HasInputDevices,
|
|
@@ -116,14 +120,15 @@ module Selenium
|
|
|
116
120
|
#
|
|
117
121
|
|
|
118
122
|
def session_id
|
|
119
|
-
@session_id || raise(Error::WebDriverError,
|
|
123
|
+
@session_id || raise(Error::WebDriverError, 'no current session exists')
|
|
120
124
|
end
|
|
121
125
|
|
|
122
126
|
def create_session(desired_capabilities)
|
|
123
|
-
resp = raw_execute :newSession, {}, :
|
|
124
|
-
@session_id = resp['sessionId']
|
|
127
|
+
resp = raw_execute :newSession, {}, {desiredCapabilities: desired_capabilities}
|
|
128
|
+
@session_id = resp['sessionId']
|
|
129
|
+
return W3CCapabilities.json_create resp['value'] if @session_id
|
|
125
130
|
|
|
126
|
-
|
|
131
|
+
raise Error::WebDriverError, 'no sessionId in returned payload'
|
|
127
132
|
end
|
|
128
133
|
|
|
129
134
|
def status
|
|
@@ -133,38 +138,38 @@ module Selenium
|
|
|
133
138
|
end
|
|
134
139
|
|
|
135
140
|
def get(url)
|
|
136
|
-
execute :get, {}, :
|
|
141
|
+
execute :get, {}, {url: url}
|
|
137
142
|
end
|
|
138
143
|
|
|
139
|
-
def
|
|
140
|
-
|
|
144
|
+
def implicit_wait_timeout=(milliseconds)
|
|
145
|
+
timeout('implicit', milliseconds)
|
|
141
146
|
end
|
|
142
147
|
|
|
143
|
-
def
|
|
144
|
-
|
|
148
|
+
def script_timeout=(milliseconds)
|
|
149
|
+
timeout('script', milliseconds)
|
|
145
150
|
end
|
|
146
151
|
|
|
147
|
-
def
|
|
148
|
-
execute :setTimeout, {}, :
|
|
152
|
+
def timeout(type, milliseconds)
|
|
153
|
+
execute :setTimeout, {}, {type: type, ms: milliseconds}
|
|
149
154
|
end
|
|
150
155
|
|
|
151
156
|
#
|
|
152
157
|
# alerts
|
|
153
158
|
#
|
|
154
159
|
|
|
155
|
-
def
|
|
160
|
+
def accept_alert
|
|
156
161
|
execute :acceptAlert
|
|
157
162
|
end
|
|
158
163
|
|
|
159
|
-
def
|
|
164
|
+
def dismiss_alert
|
|
160
165
|
execute :dismissAlert
|
|
161
166
|
end
|
|
162
167
|
|
|
163
|
-
def
|
|
164
|
-
execute :sendAlertText, {}, {:
|
|
168
|
+
def alert=(keys)
|
|
169
|
+
execute :sendAlertText, {}, {handler: 'prompt', text: keys}
|
|
165
170
|
end
|
|
166
171
|
|
|
167
|
-
def
|
|
172
|
+
def alert_text
|
|
168
173
|
execute :getAlertText
|
|
169
174
|
end
|
|
170
175
|
|
|
@@ -172,46 +177,46 @@ module Selenium
|
|
|
172
177
|
# navigation
|
|
173
178
|
#
|
|
174
179
|
|
|
175
|
-
def
|
|
180
|
+
def go_back
|
|
176
181
|
execute :back
|
|
177
182
|
end
|
|
178
183
|
|
|
179
|
-
def
|
|
184
|
+
def go_forward
|
|
180
185
|
execute :forward
|
|
181
186
|
end
|
|
182
187
|
|
|
183
|
-
def
|
|
188
|
+
def url
|
|
184
189
|
execute :getCurrentUrl
|
|
185
190
|
end
|
|
186
191
|
|
|
187
|
-
def
|
|
192
|
+
def title
|
|
188
193
|
execute :getTitle
|
|
189
194
|
end
|
|
190
195
|
|
|
191
|
-
def
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
196
|
+
def page_source
|
|
197
|
+
execute_script('var source = document.documentElement.outerHTML;' \
|
|
198
|
+
'if (!source) { source = new XMLSerializer().serializeToString(document); }' \
|
|
199
|
+
'return source;')
|
|
195
200
|
end
|
|
196
201
|
|
|
197
|
-
def
|
|
198
|
-
execute :switchToWindow, {}, :
|
|
202
|
+
def switch_to_window(name)
|
|
203
|
+
execute :switchToWindow, {}, {handle: name}
|
|
199
204
|
end
|
|
200
205
|
|
|
201
|
-
def
|
|
206
|
+
def switch_to_frame(id)
|
|
202
207
|
id = find_element_by('id', id) if id.is_a? String
|
|
203
|
-
execute :switchToFrame, {}, :
|
|
208
|
+
execute :switchToFrame, {}, {id: id}
|
|
204
209
|
end
|
|
205
210
|
|
|
206
|
-
def
|
|
211
|
+
def switch_to_parent_frame
|
|
207
212
|
execute :switchToParentFrame
|
|
208
213
|
end
|
|
209
214
|
|
|
210
|
-
def
|
|
211
|
-
|
|
215
|
+
def switch_to_default_content
|
|
216
|
+
switch_to_frame nil
|
|
212
217
|
end
|
|
213
218
|
|
|
214
|
-
QUIT_ERRORS = [IOError]
|
|
219
|
+
QUIT_ERRORS = [IOError].freeze
|
|
215
220
|
|
|
216
221
|
def quit
|
|
217
222
|
execute :deleteSession
|
|
@@ -231,34 +236,34 @@ module Selenium
|
|
|
231
236
|
# window handling
|
|
232
237
|
#
|
|
233
238
|
|
|
234
|
-
def
|
|
239
|
+
def window_handles
|
|
235
240
|
execute :getWindowHandles
|
|
236
241
|
end
|
|
237
242
|
|
|
238
|
-
def
|
|
243
|
+
def window_handle
|
|
239
244
|
execute :getWindowHandle
|
|
240
245
|
end
|
|
241
246
|
|
|
242
|
-
def
|
|
247
|
+
def resize_window(width, height, handle = :current)
|
|
243
248
|
unless handle == :current
|
|
244
249
|
raise Error::WebDriverError, 'Switch to desired window before changing its size'
|
|
245
250
|
end
|
|
246
|
-
execute :setWindowSize, {}, {:
|
|
247
|
-
|
|
251
|
+
execute :setWindowSize, {}, {width: width,
|
|
252
|
+
height: height}
|
|
248
253
|
end
|
|
249
254
|
|
|
250
|
-
def
|
|
255
|
+
def maximize_window(handle = :current)
|
|
251
256
|
unless handle == :current
|
|
252
257
|
raise Error::UnsupportedOperationError, 'Switch to desired window before changing its size'
|
|
253
258
|
end
|
|
254
259
|
execute :maximizeWindow
|
|
255
260
|
end
|
|
256
261
|
|
|
257
|
-
def
|
|
262
|
+
def full_screen_window
|
|
258
263
|
execute :fullscreenWindow
|
|
259
264
|
end
|
|
260
265
|
|
|
261
|
-
def
|
|
266
|
+
def window_size(handle = :current)
|
|
262
267
|
unless handle == :current
|
|
263
268
|
raise Error::UnsupportedOperationError, 'Switch to desired window before getting its size'
|
|
264
269
|
end
|
|
@@ -267,15 +272,15 @@ module Selenium
|
|
|
267
272
|
Dimension.new data['width'], data['height']
|
|
268
273
|
end
|
|
269
274
|
|
|
270
|
-
def
|
|
275
|
+
def reposition_window(_x, _y, _handle = nil)
|
|
271
276
|
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting the Window Position'
|
|
272
277
|
end
|
|
273
278
|
|
|
274
|
-
def
|
|
279
|
+
def window_position(_handle = nil)
|
|
275
280
|
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting the Window Position'
|
|
276
281
|
end
|
|
277
282
|
|
|
278
|
-
def
|
|
283
|
+
def screenshot
|
|
279
284
|
execute :takeScreenshot
|
|
280
285
|
end
|
|
281
286
|
|
|
@@ -283,67 +288,67 @@ module Selenium
|
|
|
283
288
|
# HTML 5
|
|
284
289
|
#
|
|
285
290
|
|
|
286
|
-
def
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
def getLocalStorageKeys
|
|
295
|
-
executeScript("return Object.keys(localStorage)")
|
|
291
|
+
def local_storage_item(key, value = nil)
|
|
292
|
+
if value
|
|
293
|
+
execute_script("localStorage.setItem('#{key}', '#{value}')")
|
|
294
|
+
else
|
|
295
|
+
execute_script("return localStorage.getItem('#{key}')")
|
|
296
|
+
end
|
|
296
297
|
end
|
|
297
298
|
|
|
298
|
-
def
|
|
299
|
-
|
|
299
|
+
def remove_local_storage_item(key)
|
|
300
|
+
execute_script("localStorage.removeItem('#{key}')")
|
|
300
301
|
end
|
|
301
302
|
|
|
302
|
-
def
|
|
303
|
-
|
|
303
|
+
def local_storage_keys
|
|
304
|
+
execute_script('return Object.keys(localStorage)')
|
|
304
305
|
end
|
|
305
306
|
|
|
306
|
-
def
|
|
307
|
-
|
|
307
|
+
def clear_local_storage
|
|
308
|
+
execute_script('localStorage.clear()')
|
|
308
309
|
end
|
|
309
310
|
|
|
310
|
-
def
|
|
311
|
-
|
|
311
|
+
def local_storage_size
|
|
312
|
+
execute_script('return localStorage.length')
|
|
312
313
|
end
|
|
313
314
|
|
|
314
|
-
def
|
|
315
|
-
|
|
315
|
+
def session_storage_item(key, value = nil)
|
|
316
|
+
if value
|
|
317
|
+
execute_script("sessionStorage.setItem('#{key}', '#{value}')")
|
|
318
|
+
else
|
|
319
|
+
execute_script("return sessionStorage.getItem('#{key}')")
|
|
320
|
+
end
|
|
316
321
|
end
|
|
317
322
|
|
|
318
|
-
def
|
|
319
|
-
|
|
323
|
+
def remove_session_storage_item(key)
|
|
324
|
+
execute_script("sessionStorage.removeItem('#{key}')")
|
|
320
325
|
end
|
|
321
326
|
|
|
322
|
-
def
|
|
323
|
-
|
|
327
|
+
def session_storage_keys
|
|
328
|
+
execute_script('return Object.keys(sessionStorage)')
|
|
324
329
|
end
|
|
325
330
|
|
|
326
|
-
def
|
|
327
|
-
|
|
331
|
+
def clear_session_storage
|
|
332
|
+
execute_script('sessionStorage.clear()')
|
|
328
333
|
end
|
|
329
334
|
|
|
330
|
-
def
|
|
331
|
-
|
|
335
|
+
def session_storage_size
|
|
336
|
+
execute_script('return sessionStorage.length')
|
|
332
337
|
end
|
|
333
338
|
|
|
334
|
-
def
|
|
339
|
+
def location
|
|
335
340
|
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting location'
|
|
336
341
|
end
|
|
337
342
|
|
|
338
|
-
def
|
|
343
|
+
def set_location(_lat, _lon, _alt)
|
|
339
344
|
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting location'
|
|
340
345
|
end
|
|
341
346
|
|
|
342
|
-
def
|
|
347
|
+
def network_connection
|
|
343
348
|
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting network connection'
|
|
344
349
|
end
|
|
345
350
|
|
|
346
|
-
def
|
|
351
|
+
def network_connection=(_type)
|
|
347
352
|
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting network connection'
|
|
348
353
|
end
|
|
349
354
|
|
|
@@ -351,13 +356,13 @@ module Selenium
|
|
|
351
356
|
# javascript execution
|
|
352
357
|
#
|
|
353
358
|
|
|
354
|
-
def
|
|
355
|
-
result = execute :executeScript, {}, :
|
|
359
|
+
def execute_script(script, *args)
|
|
360
|
+
result = execute :executeScript, {}, {script: script, args: args}
|
|
356
361
|
unwrap_script_result result
|
|
357
362
|
end
|
|
358
363
|
|
|
359
|
-
def
|
|
360
|
-
result = execute :executeAsyncScript, {}, :
|
|
364
|
+
def execute_async_script(script, *args)
|
|
365
|
+
result = execute :executeAsyncScript, {}, {script: script, args: args}
|
|
361
366
|
unwrap_script_result result
|
|
362
367
|
end
|
|
363
368
|
|
|
@@ -365,139 +370,139 @@ module Selenium
|
|
|
365
370
|
# cookies
|
|
366
371
|
#
|
|
367
372
|
|
|
368
|
-
def
|
|
369
|
-
execute :addCookie, {}, :
|
|
373
|
+
def add_cookie(cookie)
|
|
374
|
+
execute :addCookie, {}, {cookie: cookie}
|
|
370
375
|
end
|
|
371
376
|
|
|
372
|
-
def
|
|
373
|
-
execute :deleteCookie, :
|
|
377
|
+
def delete_cookie(name)
|
|
378
|
+
execute :deleteCookie, name: name
|
|
374
379
|
end
|
|
375
380
|
|
|
376
|
-
# TODO - write specs
|
|
377
|
-
def
|
|
378
|
-
execute :getCookie, :
|
|
381
|
+
# TODO: - write specs
|
|
382
|
+
def cookie(name)
|
|
383
|
+
execute :getCookie, name: name
|
|
379
384
|
end
|
|
380
385
|
|
|
381
|
-
def
|
|
386
|
+
def cookies
|
|
382
387
|
execute :getAllCookies
|
|
383
388
|
end
|
|
384
389
|
|
|
385
|
-
def
|
|
386
|
-
|
|
390
|
+
def delete_all_cookies
|
|
391
|
+
cookies.each { |cookie| delete_cookie(cookie['name']) }
|
|
387
392
|
end
|
|
388
393
|
|
|
389
394
|
#
|
|
390
395
|
# actions
|
|
391
396
|
#
|
|
392
397
|
|
|
393
|
-
def
|
|
394
|
-
execute :elementClick, :
|
|
398
|
+
def click_element(element)
|
|
399
|
+
execute :elementClick, id: element
|
|
395
400
|
end
|
|
396
401
|
|
|
397
402
|
def click
|
|
398
|
-
execute :click, {}, :
|
|
403
|
+
execute :click, {}, {button: 0}
|
|
399
404
|
end
|
|
400
405
|
|
|
401
|
-
def
|
|
406
|
+
def double_click
|
|
402
407
|
execute :doubleClick
|
|
403
408
|
end
|
|
404
409
|
|
|
405
|
-
def
|
|
406
|
-
execute :click, {}, :
|
|
410
|
+
def context_click
|
|
411
|
+
execute :click, {}, {button: 2}
|
|
407
412
|
end
|
|
408
413
|
|
|
409
|
-
def
|
|
414
|
+
def mouse_down
|
|
410
415
|
execute :mouseDown
|
|
411
416
|
end
|
|
412
417
|
|
|
413
|
-
def
|
|
418
|
+
def mouse_up
|
|
414
419
|
execute :mouseUp
|
|
415
420
|
end
|
|
416
421
|
|
|
417
|
-
def
|
|
418
|
-
params = {
|
|
422
|
+
def mouse_move_to(element, x = nil, y = nil)
|
|
423
|
+
params = {element: element}
|
|
419
424
|
|
|
420
425
|
if x && y
|
|
421
|
-
params
|
|
426
|
+
params[:xoffset] = x
|
|
427
|
+
params[:yoffset] = y
|
|
422
428
|
end
|
|
423
429
|
|
|
424
430
|
execute :mouseMoveTo, {}, params
|
|
425
431
|
end
|
|
426
432
|
|
|
427
|
-
def
|
|
428
|
-
|
|
433
|
+
def send_keys_to_active_element(keys)
|
|
434
|
+
send_keys_to_element(active_element, keys)
|
|
429
435
|
end
|
|
430
436
|
|
|
431
|
-
# TODO - Implement file verification
|
|
432
|
-
def
|
|
433
|
-
execute :elementSendKeys, {:
|
|
437
|
+
# TODO: - Implement file verification
|
|
438
|
+
def send_keys_to_element(element, keys)
|
|
439
|
+
execute :elementSendKeys, {id: element}, {value: keys.join('').split(//)}
|
|
434
440
|
end
|
|
435
441
|
|
|
436
|
-
def
|
|
437
|
-
execute :elementClear, :
|
|
442
|
+
def clear_element(element)
|
|
443
|
+
execute :elementClear, id: element
|
|
438
444
|
end
|
|
439
445
|
|
|
440
|
-
def
|
|
441
|
-
|
|
442
|
-
"e.initEvent('submit', true, true);"
|
|
443
|
-
|
|
446
|
+
def submit_element(element)
|
|
447
|
+
execute_script("var e = arguments[0].ownerDocument.createEvent('Event');" \
|
|
448
|
+
"e.initEvent('submit', true, true);" \
|
|
449
|
+
'if (arguments[0].dispatchEvent(e)) { arguments[0].submit() }', element)
|
|
444
450
|
end
|
|
445
451
|
|
|
446
|
-
def
|
|
447
|
-
execute :dragElement, {:
|
|
452
|
+
def drag_element(element, right_by, down_by)
|
|
453
|
+
execute :dragElement, {id: element}, {x: right_by, y: down_by}
|
|
448
454
|
end
|
|
449
455
|
|
|
450
|
-
def
|
|
451
|
-
execute :touchSingleTap, {}, :
|
|
456
|
+
def touch_single_tap(element)
|
|
457
|
+
execute :touchSingleTap, {}, {element: element}
|
|
452
458
|
end
|
|
453
459
|
|
|
454
|
-
def
|
|
455
|
-
execute :touchDoubleTap, {}, :
|
|
460
|
+
def touch_double_tap(element)
|
|
461
|
+
execute :touchDoubleTap, {}, {element: element}
|
|
456
462
|
end
|
|
457
463
|
|
|
458
|
-
def
|
|
459
|
-
execute :touchLongPress, {}, :
|
|
464
|
+
def touch_long_press(element)
|
|
465
|
+
execute :touchLongPress, {}, {element: element}
|
|
460
466
|
end
|
|
461
467
|
|
|
462
|
-
def
|
|
463
|
-
execute :touchDown, {}, :
|
|
468
|
+
def touch_down(x, y)
|
|
469
|
+
execute :touchDown, {}, {x: x, y: y}
|
|
464
470
|
end
|
|
465
471
|
|
|
466
|
-
def
|
|
467
|
-
execute :touchUp, {}, :
|
|
472
|
+
def touch_up(x, y)
|
|
473
|
+
execute :touchUp, {}, {x: x, y: y}
|
|
468
474
|
end
|
|
469
475
|
|
|
470
|
-
def
|
|
471
|
-
execute :touchMove, {}, :
|
|
476
|
+
def touch_move(x, y)
|
|
477
|
+
execute :touchMove, {}, {x: x, y: y}
|
|
472
478
|
end
|
|
473
479
|
|
|
474
|
-
def
|
|
480
|
+
def touch_scroll(element, x, y)
|
|
475
481
|
if element
|
|
476
|
-
execute :touchScroll, {}, :
|
|
477
|
-
|
|
478
|
-
|
|
482
|
+
execute :touchScroll, {}, {element: element,
|
|
483
|
+
xoffset: x,
|
|
484
|
+
yoffset: y}
|
|
479
485
|
else
|
|
480
|
-
execute :touchScroll, {}, :
|
|
486
|
+
execute :touchScroll, {}, {xoffset: x, yoffset: y}
|
|
481
487
|
end
|
|
482
488
|
end
|
|
483
489
|
|
|
484
|
-
def
|
|
485
|
-
execute :touchFlick, {}, :
|
|
490
|
+
def touch_flick(xspeed, yspeed)
|
|
491
|
+
execute :touchFlick, {}, {xspeed: xspeed, yspeed: yspeed}
|
|
486
492
|
end
|
|
487
493
|
|
|
488
|
-
def
|
|
489
|
-
execute :touchFlick, {}, :
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
+
def touch_element_flick(element, right_by, down_by, speed)
|
|
495
|
+
execute :touchFlick, {}, {element: element,
|
|
496
|
+
xoffset: right_by,
|
|
497
|
+
yoffset: down_by,
|
|
498
|
+
speed: speed}
|
|
494
499
|
end
|
|
495
500
|
|
|
496
|
-
def
|
|
497
|
-
execute :setScreenOrientation, {}, :
|
|
501
|
+
def screen_orientation=(orientation)
|
|
502
|
+
execute :setScreenOrientation, {}, {orientation: orientation}
|
|
498
503
|
end
|
|
499
504
|
|
|
500
|
-
def
|
|
505
|
+
def screen_orientation
|
|
501
506
|
execute :getScreenOrientation
|
|
502
507
|
end
|
|
503
508
|
|
|
@@ -505,74 +510,75 @@ module Selenium
|
|
|
505
510
|
# element properties
|
|
506
511
|
#
|
|
507
512
|
|
|
508
|
-
def
|
|
509
|
-
execute :getElementTagName, :
|
|
513
|
+
def element_tag_name(element)
|
|
514
|
+
execute :getElementTagName, id: element
|
|
510
515
|
end
|
|
511
516
|
|
|
512
|
-
def
|
|
513
|
-
execute :getElementAttribute, :
|
|
517
|
+
def element_attribute(element, name)
|
|
518
|
+
execute :getElementAttribute, id: element, name: name
|
|
514
519
|
end
|
|
515
520
|
|
|
516
|
-
def
|
|
517
|
-
execute :getElementProperty, :
|
|
521
|
+
def element_value(element)
|
|
522
|
+
execute :getElementProperty, id: element, name: 'value'
|
|
518
523
|
end
|
|
519
524
|
|
|
520
|
-
def
|
|
521
|
-
execute :getElementText, :
|
|
525
|
+
def element_text(element)
|
|
526
|
+
execute :getElementText, id: element
|
|
522
527
|
end
|
|
523
528
|
|
|
524
|
-
def
|
|
525
|
-
data = execute :getElementRect, :
|
|
529
|
+
def element_location(element)
|
|
530
|
+
data = execute :getElementRect, id: element
|
|
526
531
|
|
|
527
532
|
Point.new data['x'], data['y']
|
|
528
533
|
end
|
|
529
534
|
|
|
530
|
-
def
|
|
531
|
-
|
|
532
|
-
|
|
535
|
+
def element_location_once_scrolled_into_view(element)
|
|
536
|
+
send_keys_to_element(element, [''])
|
|
537
|
+
element_location(element)
|
|
533
538
|
end
|
|
534
539
|
|
|
535
|
-
def
|
|
536
|
-
data = execute :getElementRect, :
|
|
540
|
+
def element_size(element)
|
|
541
|
+
data = execute :getElementRect, id: element
|
|
537
542
|
|
|
538
543
|
Dimension.new data['width'], data['height']
|
|
539
544
|
end
|
|
540
545
|
|
|
541
|
-
def
|
|
542
|
-
execute :isElementEnabled, :
|
|
546
|
+
def element_enabled?(element)
|
|
547
|
+
execute :isElementEnabled, id: element
|
|
543
548
|
end
|
|
544
549
|
|
|
545
|
-
def
|
|
546
|
-
execute :isElementSelected, :
|
|
550
|
+
def element_selected?(element)
|
|
551
|
+
execute :isElementSelected, id: element
|
|
547
552
|
end
|
|
548
553
|
|
|
549
|
-
def
|
|
554
|
+
def element_displayed?(element)
|
|
550
555
|
jwp = Selenium::WebDriver::Remote::Bridge::COMMANDS[:isElementDisplayed]
|
|
551
556
|
self.class.command(:isElementDisplayed, jwp.first, jwp.last)
|
|
552
|
-
execute :isElementDisplayed, :
|
|
557
|
+
execute :isElementDisplayed, id: element
|
|
553
558
|
end
|
|
554
559
|
|
|
555
|
-
def
|
|
556
|
-
execute :getElementCssValue, :
|
|
560
|
+
def element_value_of_css_property(element, prop)
|
|
561
|
+
execute :getElementCssValue, id: element, property_name: prop
|
|
557
562
|
end
|
|
558
563
|
|
|
559
564
|
#
|
|
560
565
|
# finding elements
|
|
561
566
|
#
|
|
562
567
|
|
|
563
|
-
def
|
|
568
|
+
def active_element
|
|
564
569
|
Element.new self, element_id_from(execute(:getActiveElement))
|
|
565
570
|
end
|
|
566
|
-
|
|
571
|
+
|
|
572
|
+
alias_method :switch_to_active_element, :active_element
|
|
567
573
|
|
|
568
574
|
def find_element_by(how, what, parent = nil)
|
|
569
575
|
how, what = convert_locators(how, what)
|
|
570
576
|
|
|
571
|
-
if parent
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
577
|
+
id = if parent
|
|
578
|
+
execute :findChildElement, {id: parent}, {using: how, value: what}
|
|
579
|
+
else
|
|
580
|
+
execute :findElement, {}, {using: how, value: what}
|
|
581
|
+
end
|
|
576
582
|
|
|
577
583
|
Element.new self, element_id_from(id)
|
|
578
584
|
end
|
|
@@ -580,11 +586,11 @@ module Selenium
|
|
|
580
586
|
def find_elements_by(how, what, parent = nil)
|
|
581
587
|
how, what = convert_locators(how, what)
|
|
582
588
|
|
|
583
|
-
if parent
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
589
|
+
ids = if parent
|
|
590
|
+
execute :findChildElements, {id: parent}, {using: how, value: what}
|
|
591
|
+
else
|
|
592
|
+
execute :findElements, {}, {using: how, value: what}
|
|
593
|
+
end
|
|
588
594
|
|
|
589
595
|
ids.map { |id| Element.new self, element_id_from(id) }
|
|
590
596
|
end
|
|
@@ -605,7 +611,7 @@ module Selenium
|
|
|
605
611
|
when 'tag name'
|
|
606
612
|
how = 'css selector'
|
|
607
613
|
end
|
|
608
|
-
|
|
614
|
+
[how, what]
|
|
609
615
|
end
|
|
610
616
|
|
|
611
617
|
#
|
|
@@ -628,14 +634,14 @@ module Selenium
|
|
|
628
634
|
|
|
629
635
|
def raw_execute(command, opts = {}, command_hash = nil)
|
|
630
636
|
verb, path = COMMANDS[command] || raise(ArgumentError, "unknown command: #{command.inspect}")
|
|
631
|
-
path
|
|
637
|
+
path = path.dup
|
|
632
638
|
|
|
633
|
-
path[':session_id'] = @session_id if path.include?(
|
|
639
|
+
path[':session_id'] = @session_id if path.include?(':session_id')
|
|
634
640
|
|
|
635
641
|
begin
|
|
636
|
-
opts.each
|
|
642
|
+
opts.each do |key, value|
|
|
637
643
|
path[key.inspect] = escaper.escape(value.to_s)
|
|
638
|
-
|
|
644
|
+
end
|
|
639
645
|
rescue IndexError
|
|
640
646
|
raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
|
|
641
647
|
end
|
|
@@ -661,7 +667,6 @@ module Selenium
|
|
|
661
667
|
|
|
662
668
|
string
|
|
663
669
|
end
|
|
664
|
-
|
|
665
670
|
end # W3CBridge
|
|
666
671
|
end # Remote
|
|
667
672
|
end # WebDriver
|