selenium-webdriver 2.47.1 → 2.48.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +18 -0
- data/Gemfile.lock +1 -1
- data/lib/selenium/client/base.rb +3 -3
- data/lib/selenium/client/extensions.rb +15 -18
- data/lib/selenium/client/idiomatic.rb +26 -26
- data/lib/selenium/client/javascript_expression_builder.rb +8 -8
- data/lib/selenium/webdriver/common.rb +1 -1
- data/lib/selenium/webdriver/common/driver.rb +5 -1
- data/lib/selenium/webdriver/common/error.rb +5 -8
- data/lib/selenium/webdriver/common/search_context.rb +6 -0
- data/lib/selenium/webdriver/common/target_locator.rb +4 -0
- data/lib/selenium/webdriver/common/w3c_error.rb +194 -0
- data/lib/selenium/webdriver/firefox.rb +3 -0
- data/lib/selenium/webdriver/firefox/binary.rb +13 -0
- data/lib/selenium/webdriver/firefox/extension/prefs.json +2 -1
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/service.rb +120 -0
- data/lib/selenium/webdriver/firefox/w3c_bridge.rb +97 -0
- data/lib/selenium/webdriver/remote.rb +3 -0
- data/lib/selenium/webdriver/remote/bridge.rb +17 -10
- data/lib/selenium/webdriver/remote/capabilities.rb +1 -2
- data/lib/selenium/webdriver/remote/commands.rb +5 -0
- data/lib/selenium/webdriver/remote/response.rb +5 -6
- data/lib/selenium/webdriver/remote/w3c_bridge.rb +676 -0
- data/lib/selenium/webdriver/remote/w3c_capabilities.rb +208 -0
- data/lib/selenium/webdriver/remote/w3c_commands.rb +133 -0
- data/lib/selenium/webdriver/safari/resources/client.js +653 -629
- data/selenium-webdriver.gemspec +1 -1
- metadata +8 -4
- data/lib/selenium/webdriver/common/core_ext/string.rb +0 -24
- data/lib/selenium/webdriver/safari/resources/SafariDriver.safariextz +0 -0
data/CHANGES
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
2.48.0 (2015-10-07)
|
2
|
+
===================
|
3
|
+
|
4
|
+
Firefox:
|
5
|
+
* Initial implementation of Mozilla's Wires Driver for Marionette; Supported in version 43 and higher
|
6
|
+
|
7
|
+
Edge:
|
8
|
+
* Fix execution with Remote Server
|
9
|
+
* Fix Javascript Execution
|
10
|
+
* Implement Alert Handling
|
11
|
+
* Implement Window Switching
|
12
|
+
|
13
|
+
Ruby:
|
14
|
+
* Initial implementation of W3C WebDriver syntax to support Mozilla Wires
|
15
|
+
* Change to RSpec expect syntax
|
16
|
+
* Specs can be run from relative directories
|
17
|
+
|
18
|
+
|
1
19
|
2.47.1 (2015-07-31)
|
2
20
|
===================
|
3
21
|
|
data/Gemfile.lock
CHANGED
data/lib/selenium/client/base.rb
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
module Selenium
|
21
21
|
module Client
|
22
22
|
|
23
|
-
|
23
|
+
# Driver constructor and session management commands
|
24
24
|
module Base
|
25
25
|
include Selenium::Client::Protocol
|
26
26
|
include Selenium::Client::GeneratedDriver
|
@@ -133,7 +133,7 @@ module Selenium
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def stop
|
136
|
-
|
136
|
+
close_current_browser_session
|
137
137
|
end
|
138
138
|
|
139
139
|
def chrome_backend?
|
@@ -143,7 +143,7 @@ module Selenium
|
|
143
143
|
def javascript_extension=(new_javascript_extension)
|
144
144
|
@extension_js = new_javascript_extension
|
145
145
|
end
|
146
|
-
|
146
|
+
alias :set_extension_js :javascript_extension=
|
147
147
|
|
148
148
|
end
|
149
149
|
|
@@ -23,22 +23,19 @@ module Selenium
|
|
23
23
|
# Convenience methods not explicitly part of the protocol
|
24
24
|
module Extensions
|
25
25
|
|
26
|
-
|
27
|
-
#
|
26
|
+
# These for all Ajax request to finish (Only works if you are using prototype, the wait happens in the browser)
|
28
27
|
def wait_for_ajax(options={})
|
29
|
-
|
30
|
-
|
31
|
-
options[:timeout_in_seconds]
|
28
|
+
builder = JavascriptExpressionBuilder.new active_javascript_framework(options)
|
29
|
+
wait_for_condition builder.no_pending_ajax_requests.script, options[:timeout_in_seconds]
|
32
30
|
end
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
32
|
+
# Wait for all Prototype effects to be processed (the wait happens in the browser).
|
33
|
+
#
|
34
|
+
# Credits to http://github.com/brynary/webrat/tree/master
|
35
|
+
def wait_for_effects(options={})
|
36
|
+
builder = JavascriptExpressionBuilder.new active_javascript_framework(options)
|
37
|
+
wait_for_condition builder.no_pending_effects.script, options[:timeout_in_seconds]
|
38
|
+
end
|
42
39
|
|
43
40
|
# Wait for an element to be present (the wait happens in the browser).
|
44
41
|
def wait_for_element(locator, options={})
|
@@ -54,8 +51,8 @@ module Selenium
|
|
54
51
|
wait_for_condition builder.script, options[:timeout_in_seconds]
|
55
52
|
end
|
56
53
|
|
57
|
-
|
58
|
-
|
54
|
+
# Wait for some text to be present (the wait is happening browser side).
|
55
|
+
#
|
59
56
|
# wait_for_text will search for the given argument within the innerHTML
|
60
57
|
# of the current DOM. Note that this method treats a single string
|
61
58
|
# as a special case.
|
@@ -86,7 +83,7 @@ module Selenium
|
|
86
83
|
#
|
87
84
|
def wait_for_text(pattern, options={})
|
88
85
|
builder = JavascriptExpressionBuilder.new
|
89
|
-
|
86
|
+
builder.find_text(pattern, options).append("text_match == true;")
|
90
87
|
wait_for_condition builder.script, options[:timeout_in_seconds]
|
91
88
|
end
|
92
89
|
|
@@ -95,7 +92,7 @@ module Selenium
|
|
95
92
|
# See wait_for_text for usage details.
|
96
93
|
def wait_for_no_text(pattern, options={})
|
97
94
|
builder = JavascriptExpressionBuilder.new
|
98
|
-
|
95
|
+
builder.find_text(pattern, options).append("text_match == false;")
|
99
96
|
wait_for_condition builder.script, options[:timeout_in_seconds]
|
100
97
|
end
|
101
98
|
|
@@ -132,4 +129,4 @@ module Selenium
|
|
132
129
|
end
|
133
130
|
|
134
131
|
end
|
135
|
-
end
|
132
|
+
end
|
@@ -20,9 +20,9 @@
|
|
20
20
|
module Selenium
|
21
21
|
module Client
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
# Provide a more idiomatic API than the generated Ruby driver.
|
24
|
+
#
|
25
|
+
# Work in progress...
|
26
26
|
module Idiomatic
|
27
27
|
|
28
28
|
# Return the text content of an HTML element (rendered text shown to
|
@@ -102,31 +102,31 @@ module Selenium
|
|
102
102
|
def wait_for(options)
|
103
103
|
if options[:wait_for] == :page
|
104
104
|
wait_for_page options[:timeout_in_seconds]
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
105
|
+
elsif options[:wait_for] == :ajax
|
106
|
+
wait_for_ajax options
|
107
|
+
elsif options[:wait_for] == :element
|
108
|
+
wait_for_element options[:element], options
|
109
|
+
elsif options[:wait_for] == :no_element
|
110
|
+
wait_for_no_element options[:element], options
|
111
|
+
elsif options[:wait_for] == :text
|
112
|
+
wait_for_text options[:text], options
|
113
|
+
elsif options[:wait_for] == :no_text
|
114
114
|
wait_for_no_text options[:text], options
|
115
|
-
|
116
|
-
|
115
|
+
elsif options[:wait_for] == :effects
|
116
|
+
wait_for_effects options
|
117
117
|
elsif options[:wait_for] == :popup
|
118
|
-
|
119
|
-
|
118
|
+
wait_for_popup options[:window], options[:timeout_in_seconds]
|
119
|
+
select_window options[:window] if options[:select]
|
120
120
|
elsif options[:wait_for] == :value
|
121
|
-
|
121
|
+
wait_for_field_value options[:element], options[:value], options
|
122
122
|
elsif options[:wait_for] == :no_value
|
123
|
-
|
123
|
+
wait_for_no_field_value options[:element], options[:value], options
|
124
124
|
elsif options[:wait_for] == :visible
|
125
|
-
|
125
|
+
wait_for_visible options[:element], options
|
126
126
|
elsif options[:wait_for] == :not_visible
|
127
|
-
|
128
|
-
|
129
|
-
|
127
|
+
wait_for_not_visible options[:element], options
|
128
|
+
elsif options[:wait_for] == :condition
|
129
|
+
wait_for_condition options[:javascript], options[:timeout_in_seconds]
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -206,7 +206,7 @@ module Selenium
|
|
206
206
|
|
207
207
|
# Alias for +field+
|
208
208
|
def value(locator)
|
209
|
-
|
209
|
+
field locator
|
210
210
|
end
|
211
211
|
|
212
212
|
# Returns whether a toggle-button (checkbox/radio) is checked.
|
@@ -397,7 +397,7 @@ module Selenium
|
|
397
397
|
# the optionsString's format is "path=/path/, max_age=60, domain=.foo.com". The order of options are irrelevant, the unit of the value of 'max_age' is second. Note that specifying a domain that isn't a subset of the current domain will usually fail.
|
398
398
|
def create_cookie(name_value_pair, options="")
|
399
399
|
if options.kind_of? Hash
|
400
|
-
|
400
|
+
options = options.keys.collect {|key| "#{key}=#{options[key]}" }.sort.join(", ")
|
401
401
|
end
|
402
402
|
remote_control_command "createCookie", [name_value_pair,options,]
|
403
403
|
end
|
@@ -417,8 +417,8 @@ module Selenium
|
|
417
417
|
# 'optionsString' is options for the cookie. Currently supported options include 'path', 'domain' and 'recurse.' The optionsString's format is "path=/path/, domain=.foo.com, recurse=true". The order of options are irrelevant. Note that specifying a domain that isn't a subset of the current domain will usually fail.
|
418
418
|
def delete_cookie(name, options="")
|
419
419
|
if options.kind_of? Hash
|
420
|
-
|
421
|
-
|
420
|
+
ordered_keys = options.keys.sort {|a,b| a.to_s <=> b.to_s }
|
421
|
+
options = ordered_keys.collect {|key| "#{key}=#{options[key]}" }.join(", ")
|
422
422
|
end
|
423
423
|
remote_control_command "deleteCookie", [name,options,]
|
424
424
|
end
|
@@ -28,18 +28,18 @@ module Selenium
|
|
28
28
|
@script = ""
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
def append(text)
|
32
|
+
@script << text
|
33
|
+
self
|
34
|
+
end
|
35
35
|
|
36
36
|
def no_pending_ajax_requests
|
37
37
|
append window_script("#{@framework.ajax_request_tracker} == 0")
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
def no_pending_effects
|
41
|
+
append window_script("Effect.Queue.size() == 0")
|
42
|
+
end
|
43
43
|
|
44
44
|
def visible(locator)
|
45
45
|
append "selenium.isVisible('#{quote_escaped(locator)}')"
|
@@ -132,4 +132,4 @@ module Selenium
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
end
|
135
|
-
end
|
135
|
+
end
|
@@ -18,8 +18,8 @@
|
|
18
18
|
# under the License.
|
19
19
|
|
20
20
|
require 'selenium/webdriver/common/core_ext/dir'
|
21
|
-
require 'selenium/webdriver/common/core_ext/string'
|
22
21
|
require 'selenium/webdriver/common/core_ext/base64'
|
22
|
+
require 'selenium/webdriver/common/w3c_error'
|
23
23
|
require 'selenium/webdriver/common/error'
|
24
24
|
require 'selenium/webdriver/common/platform'
|
25
25
|
require 'selenium/webdriver/common/proxy'
|
@@ -47,7 +47,11 @@ module Selenium
|
|
47
47
|
|
48
48
|
bridge = case browser
|
49
49
|
when :firefox, :ff
|
50
|
-
|
50
|
+
if Remote::W3CCapabilities.w3c?(opts)
|
51
|
+
Firefox::W3CBridge.new(opts)
|
52
|
+
else
|
53
|
+
Firefox::Bridge.new(opts)
|
54
|
+
end
|
51
55
|
when :remote
|
52
56
|
Remote::Bridge.new(opts)
|
53
57
|
when :ie, :internet_explorer
|
@@ -206,18 +206,15 @@ module Selenium
|
|
206
206
|
MoveTargetOutOfBoundsError # 34
|
207
207
|
]
|
208
208
|
|
209
|
-
# aliased for backwards compatibility
|
210
|
-
ObsoleteElementError = StaleElementReferenceError
|
211
|
-
UnhandledError = UnknownError
|
212
|
-
UnexpectedJavascriptError = JavascriptError
|
213
|
-
NoAlertOpenError = NoAlertPresentError
|
214
|
-
ElementNotDisplayedError = ElementNotVisibleError
|
215
|
-
|
216
209
|
class << self
|
217
210
|
def for_code(code)
|
218
211
|
return if [nil, 0].include? code
|
212
|
+
return Errors[code - 1] if code.is_a? Fixnum
|
219
213
|
|
220
|
-
|
214
|
+
klass_name = code.split(' ').map(&:capitalize).join
|
215
|
+
Error.const_get("#{klass_name}Error")
|
216
|
+
rescue NameError
|
217
|
+
WebDriverError
|
221
218
|
end
|
222
219
|
end
|
223
220
|
|
@@ -59,6 +59,9 @@ module Selenium
|
|
59
59
|
end
|
60
60
|
|
61
61
|
bridge.find_element_by by, what.to_s, ref
|
62
|
+
rescue Selenium::WebDriver::Error::TimeOutError
|
63
|
+
# Implicit Wait times out in Edge
|
64
|
+
raise Selenium::WebDriver::Error::NoSuchElementError
|
62
65
|
end
|
63
66
|
|
64
67
|
#
|
@@ -79,6 +82,9 @@ module Selenium
|
|
79
82
|
end
|
80
83
|
|
81
84
|
bridge.find_elements_by by, what.to_s, ref
|
85
|
+
rescue Selenium::WebDriver::Error::TimeOutError
|
86
|
+
# Implicit Wait times out in Edge
|
87
|
+
[]
|
82
88
|
end
|
83
89
|
|
84
90
|
private
|
@@ -0,0 +1,194 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Licensed to the Software Freedom Conservancy (SFC) under one
|
4
|
+
# or more contributor license agreements. See the NOTICE file
|
5
|
+
# distributed with this work for additional information
|
6
|
+
# regarding copyright ownership. The SFC licenses this file
|
7
|
+
# to you under the Apache License, Version 2.0 (the
|
8
|
+
# "License"); you may not use this file except in compliance
|
9
|
+
# with the License. You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing,
|
14
|
+
# software distributed under the License is distributed on an
|
15
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
16
|
+
# KIND, either express or implied. See the License for the
|
17
|
+
# specific language governing permissions and limitations
|
18
|
+
# under the License.
|
19
|
+
|
20
|
+
module Selenium
|
21
|
+
module WebDriver
|
22
|
+
module Error
|
23
|
+
|
24
|
+
class WebDriverError < StandardError; end
|
25
|
+
|
26
|
+
#
|
27
|
+
# An attempt was made to select an element that cannot be selected.
|
28
|
+
#
|
29
|
+
|
30
|
+
class ElementNotSelectableError < WebDriverError; end
|
31
|
+
|
32
|
+
#
|
33
|
+
# An element command could not be completed because the element is
|
34
|
+
# not visible on the page.
|
35
|
+
#
|
36
|
+
|
37
|
+
class ElementNotVisibleError < WebDriverError; end
|
38
|
+
|
39
|
+
#
|
40
|
+
# The arguments passed to a command are either invalid or malformed.
|
41
|
+
#
|
42
|
+
|
43
|
+
class InvalidArgumentError < WebDriverError; end
|
44
|
+
|
45
|
+
#
|
46
|
+
# An illegal attempt was made to set a cookie under a different
|
47
|
+
# domain than the current page.
|
48
|
+
#
|
49
|
+
|
50
|
+
class InvalidCookieDomainError < WebDriverError; end
|
51
|
+
|
52
|
+
#
|
53
|
+
# The coordinates provided to an interactions operation are invalid.
|
54
|
+
#
|
55
|
+
|
56
|
+
class InvalidElementCoordinatesError < WebDriverError; end
|
57
|
+
|
58
|
+
#
|
59
|
+
# An element command could not be completed because the element is
|
60
|
+
# in an invalid state, e.g. attempting to click an element that is no
|
61
|
+
# longer attached to the document.
|
62
|
+
#
|
63
|
+
|
64
|
+
class InvalidElementStateError < WebDriverError; end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Argument was an invalid selector.
|
68
|
+
#
|
69
|
+
|
70
|
+
class InvalidSelectorError < WebDriverError; end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Occurs if the given session id is not in the list of active sessions,
|
74
|
+
# meaning the session either does not exist or that it’s not active.
|
75
|
+
#
|
76
|
+
|
77
|
+
class InvalidSessionIdError < WebDriverError; end
|
78
|
+
|
79
|
+
#
|
80
|
+
# An error occurred while executing JavaScript supplied by the user.
|
81
|
+
#
|
82
|
+
|
83
|
+
class JavascriptError < WebDriverError; end
|
84
|
+
|
85
|
+
#
|
86
|
+
# The target for mouse interaction is not in the browser’s viewport and
|
87
|
+
# cannot be brought into that viewport.
|
88
|
+
#
|
89
|
+
|
90
|
+
class MoveTargetOutOfBoundsError < WebDriverError; end
|
91
|
+
|
92
|
+
#
|
93
|
+
# An attempt was made to operate on a modal dialog when one was not open.
|
94
|
+
#
|
95
|
+
|
96
|
+
class NoSuchAlertError < WebDriverError; end
|
97
|
+
|
98
|
+
#
|
99
|
+
# An element could not be located on the page using the given
|
100
|
+
# search parameters.
|
101
|
+
#
|
102
|
+
|
103
|
+
class NoSuchElementError < WebDriverError; end
|
104
|
+
|
105
|
+
#
|
106
|
+
# A request to switch to a frame could not be satisfied because the
|
107
|
+
# frame could not be found.
|
108
|
+
#
|
109
|
+
|
110
|
+
class NoSuchFrameError < WebDriverError; end
|
111
|
+
|
112
|
+
#
|
113
|
+
# A request to switch to a window could not be satisfied because the
|
114
|
+
# window could not be found.
|
115
|
+
#
|
116
|
+
|
117
|
+
class NoSuchWindowError < WebDriverError; end
|
118
|
+
|
119
|
+
#
|
120
|
+
# A script did not complete before its timeout expired.
|
121
|
+
#
|
122
|
+
|
123
|
+
class ScriptTimeoutError < WebDriverError; end
|
124
|
+
|
125
|
+
#
|
126
|
+
# A new session could not be created.
|
127
|
+
#
|
128
|
+
|
129
|
+
class SessionNotCreatedError < WebDriverError; end
|
130
|
+
|
131
|
+
#
|
132
|
+
# An element command failed because the referenced element is no longer
|
133
|
+
# attached to the DOM.
|
134
|
+
#
|
135
|
+
|
136
|
+
class StaleElementReferenceError < WebDriverError; end
|
137
|
+
|
138
|
+
#
|
139
|
+
# An operation did not complete before its timeout expired.
|
140
|
+
#
|
141
|
+
|
142
|
+
class TimeoutError < WebDriverError; end
|
143
|
+
|
144
|
+
#
|
145
|
+
# A request to set a cookie’s value could not be satisfied.
|
146
|
+
#
|
147
|
+
|
148
|
+
class UnableToSetCookieError < WebDriverError; end
|
149
|
+
|
150
|
+
#
|
151
|
+
# A screen capture was made impossible.
|
152
|
+
#
|
153
|
+
|
154
|
+
class UnableToCaptureScreenError < WebDriverError; end
|
155
|
+
|
156
|
+
#
|
157
|
+
# A modal dialog was open, blocking this operation.
|
158
|
+
#
|
159
|
+
|
160
|
+
class UnexpectedAlertOpenError < WebDriverError; end
|
161
|
+
|
162
|
+
#
|
163
|
+
# An unknown error occurred in the remote end while processing
|
164
|
+
# the command.
|
165
|
+
#
|
166
|
+
|
167
|
+
class UnknownError < WebDriverError; end
|
168
|
+
|
169
|
+
#
|
170
|
+
# The requested command matched a known URL but did not match a
|
171
|
+
# method for that URL.
|
172
|
+
#
|
173
|
+
|
174
|
+
class UnknownMethodError < WebDriverError; end
|
175
|
+
|
176
|
+
#
|
177
|
+
# Indicates that a command that should have executed properly cannot be supported for some reason.
|
178
|
+
#
|
179
|
+
|
180
|
+
class UnsupportedOperationError < WebDriverError; end
|
181
|
+
|
182
|
+
# aliased for backwards compatibility
|
183
|
+
NoAlertPresentError = NoSuchAlertError
|
184
|
+
ScriptTimeOutError = ScriptTimeoutError
|
185
|
+
ObsoleteElementError = StaleElementReferenceError
|
186
|
+
UnhandledError = UnknownError
|
187
|
+
UnexpectedJavascriptError = JavascriptError
|
188
|
+
NoAlertOpenError = NoAlertPresentError
|
189
|
+
ElementNotDisplayedError = ElementNotVisibleError
|
190
|
+
|
191
|
+
|
192
|
+
end # Error
|
193
|
+
end # WebDriver
|
194
|
+
end # Selenium
|