selenium-webdriver 2.53.3 → 3.142.7
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.
- checksums.yaml +7 -0
- data/CHANGES +665 -8
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/README.md +2 -3
- data/lib/selenium/server.rb +76 -73
- data/lib/selenium/webdriver/atoms/getAttribute.js +7 -0
- data/lib/selenium/webdriver/atoms/isDisplayed.js +102 -0
- data/lib/selenium/webdriver/{phantomjs.rb → atoms.rb} +10 -14
- data/lib/selenium/webdriver/chrome/bridge.rb +30 -101
- data/lib/selenium/webdriver/chrome/driver.rb +127 -0
- data/lib/selenium/webdriver/chrome/options.rb +190 -0
- data/lib/selenium/webdriver/chrome/profile.rb +21 -20
- data/lib/selenium/webdriver/chrome/service.rb +26 -93
- data/lib/selenium/webdriver/chrome.rb +15 -6
- data/lib/selenium/webdriver/common/action_builder.rb +52 -58
- data/lib/selenium/webdriver/common/alert.rb +7 -15
- data/lib/selenium/webdriver/common/bridge_helper.rb +18 -22
- data/lib/selenium/webdriver/common/driver.rb +72 -72
- data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +45 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +50 -0
- data/lib/selenium/webdriver/common/driver_extensions/{has_input_devices.rb → has_debugger.rb} +11 -27
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +6 -10
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +51 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +7 -8
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +51 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +2 -4
- data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +2 -4
- data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +3 -5
- data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +2 -5
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +6 -9
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +9 -7
- data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +3 -8
- data/lib/selenium/webdriver/common/element.rb +59 -39
- data/lib/selenium/webdriver/common/error.rb +259 -104
- data/lib/selenium/webdriver/common/file_reaper.rb +6 -14
- data/lib/selenium/webdriver/common/html5/local_storage.rb +8 -10
- data/lib/selenium/webdriver/common/html5/session_storage.rb +8 -10
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +8 -16
- data/lib/selenium/webdriver/common/interactions/input_device.rb +54 -0
- data/lib/selenium/webdriver/common/interactions/interaction.rb +53 -0
- data/lib/selenium/webdriver/{safari/browser.rb → common/interactions/interactions.rb} +17 -14
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +145 -0
- data/lib/selenium/webdriver/common/interactions/key_input.rb +66 -0
- data/lib/selenium/webdriver/{android.rb → common/interactions/none_input.rb} +14 -6
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +363 -0
- data/lib/selenium/webdriver/common/interactions/pointer_input.rb +139 -0
- data/lib/selenium/webdriver/common/keyboard.rb +10 -14
- data/lib/selenium/webdriver/common/keys.rb +102 -82
- data/lib/selenium/webdriver/common/log_entry.rb +7 -8
- data/lib/selenium/webdriver/common/logger.rb +115 -0
- data/lib/selenium/webdriver/common/logs.rb +4 -6
- data/lib/selenium/webdriver/common/manager.rb +177 -0
- data/lib/selenium/webdriver/common/mouse.rb +12 -14
- data/lib/selenium/webdriver/common/navigation.rb +4 -6
- data/lib/selenium/webdriver/common/options.rb +26 -127
- data/lib/selenium/webdriver/common/platform.rb +75 -101
- data/lib/selenium/webdriver/common/port_prober.rb +7 -19
- data/lib/selenium/webdriver/common/profile_helper.rb +8 -11
- data/lib/selenium/webdriver/common/proxy.rb +68 -74
- data/lib/selenium/webdriver/common/search_context.rb +28 -37
- data/lib/selenium/webdriver/common/service.rb +219 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +15 -16
- data/lib/selenium/webdriver/common/socket_poller.rb +30 -28
- data/lib/selenium/webdriver/common/target_locator.rb +16 -18
- data/lib/selenium/webdriver/common/timeouts.rb +6 -8
- data/lib/selenium/webdriver/common/touch_action_builder.rb +5 -10
- data/lib/selenium/webdriver/common/touch_screen.rb +22 -23
- data/lib/selenium/webdriver/common/w3c_action_builder.rb +212 -0
- data/lib/selenium/webdriver/common/w3c_manager.rb +45 -0
- data/lib/selenium/webdriver/common/wait.rb +17 -16
- data/lib/selenium/webdriver/common/window.rb +50 -17
- data/lib/selenium/webdriver/common/zipper.rb +9 -13
- data/lib/selenium/webdriver/common.rb +21 -7
- data/lib/selenium/webdriver/edge/bridge.rb +34 -63
- data/lib/selenium/webdriver/edge/driver.rb +66 -0
- data/lib/selenium/webdriver/edge/options.rb +80 -0
- data/lib/selenium/webdriver/edge/service.rb +23 -95
- data/lib/selenium/webdriver/edge.rb +13 -13
- data/lib/selenium/webdriver/firefox/binary.rb +45 -60
- data/lib/selenium/webdriver/firefox/driver.rb +50 -0
- data/lib/selenium/webdriver/firefox/extension/prefs.json +3 -12
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/extension.rb +20 -10
- data/lib/selenium/webdriver/firefox/launcher.rb +16 -22
- data/lib/selenium/webdriver/firefox/legacy/driver.rb +83 -0
- data/lib/selenium/webdriver/firefox/marionette/bridge.rb +49 -0
- data/lib/selenium/webdriver/firefox/marionette/driver.rb +90 -0
- data/lib/selenium/webdriver/firefox/options.rb +162 -0
- data/lib/selenium/webdriver/firefox/profile.rb +47 -48
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +11 -18
- data/lib/selenium/webdriver/firefox/service.rb +24 -95
- data/lib/selenium/webdriver/firefox/util.rb +2 -4
- data/lib/selenium/webdriver/firefox.rb +27 -12
- data/lib/selenium/webdriver/ie/driver.rb +85 -0
- data/lib/selenium/webdriver/ie/options.rb +138 -0
- data/lib/selenium/webdriver/ie/service.rb +54 -0
- data/lib/selenium/webdriver/ie.rb +12 -10
- data/lib/selenium/webdriver/remote/bridge.rb +100 -564
- data/lib/selenium/webdriver/remote/capabilities.rb +98 -100
- data/lib/selenium/webdriver/remote/driver.rb +51 -0
- data/lib/selenium/webdriver/remote/http/common.rb +34 -22
- data/lib/selenium/webdriver/remote/http/curb.rb +13 -14
- data/lib/selenium/webdriver/remote/http/default.rb +62 -43
- data/lib/selenium/webdriver/remote/http/persistent.rb +12 -9
- data/lib/selenium/webdriver/remote/oss/bridge.rb +594 -0
- data/lib/selenium/webdriver/remote/oss/commands.rb +223 -0
- data/lib/selenium/webdriver/remote/response.rb +48 -28
- data/lib/selenium/webdriver/remote/server_error.rb +3 -5
- data/lib/selenium/webdriver/remote/w3c/bridge.rb +605 -0
- data/lib/selenium/webdriver/remote/w3c/capabilities.rb +310 -0
- data/lib/selenium/webdriver/remote/w3c/commands.rb +157 -0
- data/lib/selenium/webdriver/remote.rb +10 -16
- data/lib/selenium/webdriver/safari/bridge.rb +17 -101
- data/lib/selenium/webdriver/{firefox/w3c_bridge.rb → safari/driver.rb} +27 -25
- data/lib/selenium/webdriver/safari/options.rb +29 -31
- data/lib/selenium/webdriver/safari/service.rb +38 -0
- data/lib/selenium/webdriver/safari.rb +27 -27
- data/lib/selenium/webdriver/support/abstract_event_listener.rb +19 -4
- data/lib/selenium/webdriver/support/block_event_listener.rb +3 -5
- data/lib/selenium/webdriver/support/color.rb +60 -43
- data/lib/selenium/webdriver/support/escaper.rb +43 -0
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +39 -41
- data/lib/selenium/webdriver/support/select.rb +45 -97
- data/lib/selenium/webdriver/support.rb +3 -2
- data/lib/selenium/webdriver/{iphone.rb → version.rb} +3 -7
- data/lib/selenium/webdriver.rb +36 -23
- data/lib/selenium-webdriver.rb +2 -2
- data/selenium-webdriver.gemspec +42 -29
- metadata +331 -262
- 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/javascript_frameworks/jquery.rb +0 -32
- data/lib/selenium/client/javascript_frameworks/prototype.rb +0 -32
- 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/client.rb +0 -57
- 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/common/w3c_error.rb +0 -194
- data/lib/selenium/webdriver/edge/legacy_support.rb +0 -117
- data/lib/selenium/webdriver/firefox/bridge.rb +0 -89
- data/lib/selenium/webdriver/ie/bridge.rb +0 -88
- data/lib/selenium/webdriver/ie/server.rb +0 -133
- data/lib/selenium/webdriver/iphone/bridge.rb +0 -64
- data/lib/selenium/webdriver/phantomjs/bridge.rb +0 -78
- data/lib/selenium/webdriver/phantomjs/service.rb +0 -130
- data/lib/selenium/webdriver/remote/commands.rb +0 -211
- data/lib/selenium/webdriver/remote/w3c_bridge.rb +0 -668
- data/lib/selenium/webdriver/remote/w3c_capabilities.rb +0 -236
- data/lib/selenium/webdriver/remote/w3c_commands.rb +0 -132
- data/lib/selenium/webdriver/safari/resources/client.js +0 -7255
- data/lib/selenium/webdriver/safari/server.rb +0 -187
- data/lib/selenium-client.rb +0 -21
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
4
|
# or more contributor license agreements. See the NOTICE file
|
|
5
5
|
# distributed with this work for additional information
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Support
|
|
23
|
-
|
|
24
23
|
#
|
|
25
24
|
# @api private
|
|
26
25
|
#
|
|
@@ -29,69 +28,69 @@ module Selenium
|
|
|
29
28
|
def initialize(delegate, listener)
|
|
30
29
|
@delegate = delegate
|
|
31
30
|
|
|
32
|
-
if listener.respond_to? :call
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
@listener = if listener.respond_to? :call
|
|
32
|
+
BlockEventListener.new(listener)
|
|
33
|
+
else
|
|
34
|
+
listener
|
|
35
|
+
end
|
|
37
36
|
end
|
|
38
37
|
|
|
39
38
|
def get(url)
|
|
40
|
-
dispatch(:navigate_to, url, driver)
|
|
39
|
+
dispatch(:navigate_to, url, driver) do
|
|
41
40
|
@delegate.get(url)
|
|
42
|
-
|
|
41
|
+
end
|
|
43
42
|
end
|
|
44
43
|
|
|
45
|
-
def
|
|
46
|
-
dispatch(:navigate_forward, driver)
|
|
47
|
-
@delegate.
|
|
48
|
-
|
|
44
|
+
def go_forward
|
|
45
|
+
dispatch(:navigate_forward, driver) do
|
|
46
|
+
@delegate.go_forward
|
|
47
|
+
end
|
|
49
48
|
end
|
|
50
49
|
|
|
51
|
-
def
|
|
52
|
-
dispatch(:navigate_back, driver)
|
|
53
|
-
@delegate.
|
|
54
|
-
|
|
50
|
+
def go_back
|
|
51
|
+
dispatch(:navigate_back, driver) do
|
|
52
|
+
@delegate.go_back
|
|
53
|
+
end
|
|
55
54
|
end
|
|
56
55
|
|
|
57
|
-
def
|
|
58
|
-
dispatch(:click, create_element(ref), driver)
|
|
59
|
-
@delegate.
|
|
60
|
-
|
|
56
|
+
def click_element(ref)
|
|
57
|
+
dispatch(:click, create_element(ref), driver) do
|
|
58
|
+
@delegate.click_element(ref)
|
|
59
|
+
end
|
|
61
60
|
end
|
|
62
61
|
|
|
63
|
-
def
|
|
64
|
-
dispatch(:change_value_of, create_element(ref), driver)
|
|
65
|
-
@delegate.
|
|
66
|
-
|
|
62
|
+
def clear_element(ref)
|
|
63
|
+
dispatch(:change_value_of, create_element(ref), driver) do
|
|
64
|
+
@delegate.clear_element(ref)
|
|
65
|
+
end
|
|
67
66
|
end
|
|
68
67
|
|
|
69
|
-
def
|
|
70
|
-
dispatch(:change_value_of, create_element(ref), driver)
|
|
71
|
-
@delegate.
|
|
72
|
-
|
|
68
|
+
def send_keys_to_element(ref, keys)
|
|
69
|
+
dispatch(:change_value_of, create_element(ref), driver) do
|
|
70
|
+
@delegate.send_keys_to_element(ref, keys)
|
|
71
|
+
end
|
|
73
72
|
end
|
|
74
73
|
|
|
75
74
|
def find_element_by(how, what, parent = nil)
|
|
76
|
-
e = dispatch(:find, how, what, driver)
|
|
75
|
+
e = dispatch(:find, how, what, driver) do
|
|
77
76
|
@delegate.find_element_by how, what, parent
|
|
78
|
-
|
|
77
|
+
end
|
|
79
78
|
|
|
80
79
|
Element.new self, e.ref
|
|
81
80
|
end
|
|
82
81
|
|
|
83
82
|
def find_elements_by(how, what, parent = nil)
|
|
84
|
-
es = dispatch(:find, how, what, driver)
|
|
83
|
+
es = dispatch(:find, how, what, driver) do
|
|
85
84
|
@delegate.find_elements_by(how, what, parent)
|
|
86
|
-
|
|
85
|
+
end
|
|
87
86
|
|
|
88
87
|
es.map { |e| Element.new self, e.ref }
|
|
89
88
|
end
|
|
90
89
|
|
|
91
|
-
def
|
|
92
|
-
dispatch(:execute_script, script, driver)
|
|
93
|
-
@delegate.
|
|
94
|
-
|
|
90
|
+
def execute_script(script, *args)
|
|
91
|
+
dispatch(:execute_script, script, driver) do
|
|
92
|
+
@delegate.execute_script(script, *args)
|
|
93
|
+
end
|
|
95
94
|
end
|
|
96
95
|
|
|
97
96
|
def quit
|
|
@@ -113,7 +112,7 @@ module Selenium
|
|
|
113
112
|
@driver ||= Driver.new(self)
|
|
114
113
|
end
|
|
115
114
|
|
|
116
|
-
def dispatch(name, *args
|
|
115
|
+
def dispatch(name, *args)
|
|
117
116
|
@listener.__send__("before_#{name}", *args)
|
|
118
117
|
returned = yield
|
|
119
118
|
@listener.__send__("after_#{name}", *args)
|
|
@@ -121,11 +120,10 @@ module Selenium
|
|
|
121
120
|
returned
|
|
122
121
|
end
|
|
123
122
|
|
|
124
|
-
def method_missing(meth, *args, &blk)
|
|
123
|
+
def method_missing(meth, *args, &blk) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
|
|
125
124
|
@delegate.__send__(meth, *args, &blk)
|
|
126
125
|
end
|
|
127
126
|
end # EventFiringBridge
|
|
128
|
-
|
|
129
127
|
end # Support
|
|
130
128
|
end # WebDriver
|
|
131
129
|
end # Selenium
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
4
|
# or more contributor license agreements. See the NOTICE file
|
|
5
5
|
# distributed with this work for additional information
|
|
@@ -21,7 +21,6 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Support
|
|
23
23
|
class Select
|
|
24
|
-
|
|
25
24
|
#
|
|
26
25
|
# @param [Element] element The select element to use
|
|
27
26
|
#
|
|
@@ -29,12 +28,10 @@ module Selenium
|
|
|
29
28
|
def initialize(element)
|
|
30
29
|
tag_name = element.tag_name
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
raise ArgumentError, "unexpected tag name #{tag_name.inspect}"
|
|
34
|
-
end
|
|
31
|
+
raise ArgumentError, "unexpected tag name #{tag_name.inspect}" unless tag_name.casecmp('select').zero?
|
|
35
32
|
|
|
36
33
|
@element = element
|
|
37
|
-
@multi
|
|
34
|
+
@multi = ![nil, 'false'].include?(element.attribute(:multiple))
|
|
38
35
|
end
|
|
39
36
|
|
|
40
37
|
#
|
|
@@ -54,7 +51,7 @@ module Selenium
|
|
|
54
51
|
#
|
|
55
52
|
|
|
56
53
|
def options
|
|
57
|
-
@element.find_elements :
|
|
54
|
+
@element.find_elements tag_name: 'option'
|
|
58
55
|
end
|
|
59
56
|
|
|
60
57
|
#
|
|
@@ -64,7 +61,7 @@ module Selenium
|
|
|
64
61
|
#
|
|
65
62
|
|
|
66
63
|
def selected_options
|
|
67
|
-
options.select
|
|
64
|
+
options.select(&:selected?)
|
|
68
65
|
end
|
|
69
66
|
|
|
70
67
|
#
|
|
@@ -75,8 +72,10 @@ module Selenium
|
|
|
75
72
|
#
|
|
76
73
|
|
|
77
74
|
def first_selected_option
|
|
78
|
-
option = options.find
|
|
79
|
-
option
|
|
75
|
+
option = options.find(&:selected?)
|
|
76
|
+
return option if option
|
|
77
|
+
|
|
78
|
+
raise Error::NoSuchElementError, 'no options are selected'
|
|
80
79
|
end
|
|
81
80
|
|
|
82
81
|
#
|
|
@@ -142,9 +141,7 @@ module Selenium
|
|
|
142
141
|
#
|
|
143
142
|
|
|
144
143
|
def select_all
|
|
145
|
-
unless multiple?
|
|
146
|
-
raise Error::UnsupportedOperationError, 'you may only select all options of a multi-select'
|
|
147
|
-
end
|
|
144
|
+
raise Error::UnsupportedOperationError, 'you may only select all options of a multi-select' unless multiple?
|
|
148
145
|
|
|
149
146
|
options.each { |e| select_option e }
|
|
150
147
|
end
|
|
@@ -156,9 +153,7 @@ module Selenium
|
|
|
156
153
|
#
|
|
157
154
|
|
|
158
155
|
def deselect_all
|
|
159
|
-
unless multiple?
|
|
160
|
-
raise Error::UnsupportedOperationError, 'you may only deselect all options of a multi-select'
|
|
161
|
-
end
|
|
156
|
+
raise Error::UnsupportedOperationError, 'you may only deselect all options of a multi-select' unless multiple?
|
|
162
157
|
|
|
163
158
|
options.each { |e| deselect_option e }
|
|
164
159
|
end
|
|
@@ -168,74 +163,57 @@ module Selenium
|
|
|
168
163
|
def select_by_text(text)
|
|
169
164
|
opts = find_by_text text
|
|
170
165
|
|
|
171
|
-
|
|
172
|
-
raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
|
|
173
|
-
end
|
|
166
|
+
return select_options(opts) unless opts.empty?
|
|
174
167
|
|
|
175
|
-
|
|
168
|
+
raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
|
|
176
169
|
end
|
|
177
170
|
|
|
178
171
|
def select_by_index(index)
|
|
179
172
|
opts = find_by_index index
|
|
180
173
|
|
|
181
|
-
|
|
182
|
-
raise Error::NoSuchElementError, "cannot locate element with index: #{index.inspect}"
|
|
183
|
-
end
|
|
174
|
+
return select_option(opts.first) unless opts.empty?
|
|
184
175
|
|
|
185
|
-
|
|
176
|
+
raise Error::NoSuchElementError, "cannot locate element with index: #{index.inspect}"
|
|
186
177
|
end
|
|
187
178
|
|
|
188
179
|
def select_by_value(value)
|
|
189
180
|
opts = find_by_value value
|
|
190
181
|
|
|
191
|
-
|
|
192
|
-
raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
|
|
193
|
-
end
|
|
182
|
+
return select_options(opts) unless opts.empty?
|
|
194
183
|
|
|
195
|
-
|
|
184
|
+
raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
|
|
196
185
|
end
|
|
197
186
|
|
|
198
187
|
def deselect_by_text(text)
|
|
199
|
-
unless multiple?
|
|
200
|
-
|
|
201
|
-
end
|
|
188
|
+
raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?
|
|
189
|
+
|
|
202
190
|
opts = find_by_text text
|
|
203
191
|
|
|
204
|
-
|
|
205
|
-
raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
|
|
206
|
-
end
|
|
192
|
+
return deselect_options(opts) unless opts.empty?
|
|
207
193
|
|
|
208
|
-
|
|
194
|
+
raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
|
|
209
195
|
end
|
|
210
196
|
|
|
211
197
|
def deselect_by_value(value)
|
|
212
|
-
unless multiple?
|
|
213
|
-
|
|
214
|
-
end
|
|
198
|
+
raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?
|
|
199
|
+
|
|
215
200
|
opts = find_by_value value
|
|
216
201
|
|
|
217
|
-
|
|
218
|
-
raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
|
|
219
|
-
end
|
|
202
|
+
return deselect_options(opts) unless opts.empty?
|
|
220
203
|
|
|
221
|
-
|
|
204
|
+
raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
|
|
222
205
|
end
|
|
223
206
|
|
|
224
207
|
def deselect_by_index(index)
|
|
225
|
-
unless multiple?
|
|
226
|
-
|
|
227
|
-
end
|
|
208
|
+
raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?
|
|
209
|
+
|
|
228
210
|
opts = find_by_index index
|
|
229
211
|
|
|
230
|
-
|
|
231
|
-
raise Error::NoSuchElementError, "cannot locate option with index: #{index}"
|
|
232
|
-
end
|
|
212
|
+
return deselect_option(opts.first) unless opts.empty?
|
|
233
213
|
|
|
234
|
-
|
|
214
|
+
raise Error::NoSuchElementError, "cannot locate option with index: #{index}"
|
|
235
215
|
end
|
|
236
216
|
|
|
237
|
-
private
|
|
238
|
-
|
|
239
217
|
def select_option(option)
|
|
240
218
|
option.click unless option.selected?
|
|
241
219
|
end
|
|
@@ -262,60 +240,30 @@ module Selenium
|
|
|
262
240
|
|
|
263
241
|
def find_by_text(text)
|
|
264
242
|
xpath = ".//option[normalize-space(.) = #{Escaper.escape text}]"
|
|
265
|
-
opts = @element.find_elements(:
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
else
|
|
273
|
-
xpath = ".//option[contains(., #{Escaper.escape longest_word})]"
|
|
274
|
-
candidates = @element.find_elements(:xpath, xpath)
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
if multiple?
|
|
278
|
-
candidates.select { |option| text == option.text }
|
|
279
|
-
else
|
|
280
|
-
Array(candidates.find { |option| text == option.text })
|
|
281
|
-
end
|
|
243
|
+
opts = @element.find_elements(xpath: xpath)
|
|
244
|
+
|
|
245
|
+
return opts unless opts.empty? && text =~ /\s+/
|
|
246
|
+
|
|
247
|
+
longest_word = text.split(/\s+/).max_by(&:length)
|
|
248
|
+
if longest_word.empty?
|
|
249
|
+
candidates = options
|
|
282
250
|
else
|
|
283
|
-
|
|
251
|
+
xpath = ".//option[contains(., #{Escaper.escape longest_word})]"
|
|
252
|
+
candidates = @element.find_elements(xpath: xpath)
|
|
284
253
|
end
|
|
254
|
+
|
|
255
|
+
return Array(candidates.find { |option| text == option.text }) unless multiple?
|
|
256
|
+
|
|
257
|
+
candidates.select { |option| text == option.text }
|
|
285
258
|
end
|
|
286
259
|
|
|
287
260
|
def find_by_index(index)
|
|
288
|
-
index
|
|
289
|
-
options.select { |option| option.attribute(:index) == index }
|
|
261
|
+
options.select { |option| option.attribute(:index) == index.to_s }
|
|
290
262
|
end
|
|
291
263
|
|
|
292
264
|
def find_by_value(value)
|
|
293
|
-
@element.find_elements(:
|
|
265
|
+
@element.find_elements(xpath: ".//option[@value = #{Escaper.escape value}]")
|
|
294
266
|
end
|
|
295
|
-
|
|
296
|
-
#
|
|
297
|
-
# @api private
|
|
298
|
-
#
|
|
299
|
-
|
|
300
|
-
module Escaper
|
|
301
|
-
def self.escape(str)
|
|
302
|
-
if str.include?('"') && str.include?("'")
|
|
303
|
-
parts = str.split('"', -1).map { |part| %{"#{part}"} }
|
|
304
|
-
|
|
305
|
-
quoted = parts.join(%{, '"', }).
|
|
306
|
-
gsub(/^"", |, ""$/, '')
|
|
307
|
-
|
|
308
|
-
"concat(#{quoted})"
|
|
309
|
-
elsif str.include?('"')
|
|
310
|
-
# escape string with just a quote into being single quoted: f"oo -> 'f"oo'
|
|
311
|
-
"'#{str}'"
|
|
312
|
-
else
|
|
313
|
-
# otherwise return the quoted string
|
|
314
|
-
%{"#{str}"}
|
|
315
|
-
end
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
end # Escaper
|
|
319
267
|
end # Select
|
|
320
268
|
end # Support
|
|
321
269
|
end # WebDriver
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
4
|
# or more contributor license agreements. See the NOTICE file
|
|
5
5
|
# distributed with this work for additional information
|
|
@@ -20,5 +20,6 @@
|
|
|
20
20
|
require 'selenium/webdriver/support/event_firing_bridge'
|
|
21
21
|
require 'selenium/webdriver/support/abstract_event_listener'
|
|
22
22
|
require 'selenium/webdriver/support/block_event_listener'
|
|
23
|
+
require 'selenium/webdriver/support/escaper'
|
|
23
24
|
require 'selenium/webdriver/support/select'
|
|
24
25
|
require 'selenium/webdriver/support/color'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
4
|
# or more contributor license agreements. See the NOTICE file
|
|
5
5
|
# distributed with this work for additional information
|
|
@@ -19,10 +19,6 @@
|
|
|
19
19
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
end # IPhone
|
|
22
|
+
VERSION = '3.142.7'
|
|
25
23
|
end # WebDriver
|
|
26
24
|
end # Selenium
|
|
27
|
-
|
|
28
|
-
require 'selenium/webdriver/iphone/bridge'
|
data/lib/selenium/webdriver.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
4
|
# or more contributor license agreements. See the NOTICE file
|
|
5
5
|
# distributed with this work for additional information
|
|
@@ -22,21 +22,23 @@ require 'tmpdir'
|
|
|
22
22
|
require 'fileutils'
|
|
23
23
|
require 'date'
|
|
24
24
|
require 'json'
|
|
25
|
+
require 'set'
|
|
25
26
|
|
|
26
27
|
require 'selenium/webdriver/common'
|
|
28
|
+
require 'selenium/webdriver/atoms'
|
|
29
|
+
require 'selenium/webdriver/version'
|
|
27
30
|
|
|
28
31
|
module Selenium
|
|
29
32
|
module WebDriver
|
|
30
33
|
Point = Struct.new(:x, :y)
|
|
31
34
|
Dimension = Struct.new(:width, :height)
|
|
35
|
+
Rectangle = Struct.new(:x, :y, :width, :height)
|
|
32
36
|
Location = Struct.new(:latitude, :longitude, :altitude)
|
|
33
37
|
|
|
34
|
-
autoload :Android, 'selenium/webdriver/android'
|
|
35
38
|
autoload :Chrome, 'selenium/webdriver/chrome'
|
|
36
39
|
autoload :Edge, 'selenium/webdriver/edge'
|
|
37
40
|
autoload :Firefox, 'selenium/webdriver/firefox'
|
|
38
41
|
autoload :IE, 'selenium/webdriver/ie'
|
|
39
|
-
autoload :IPhone, 'selenium/webdriver/iphone'
|
|
40
42
|
autoload :PhantomJS, 'selenium/webdriver/phantomjs'
|
|
41
43
|
autoload :Remote, 'selenium/webdriver/remote'
|
|
42
44
|
autoload :Safari, 'selenium/webdriver/safari'
|
|
@@ -45,37 +47,39 @@ module Selenium
|
|
|
45
47
|
# @api private
|
|
46
48
|
|
|
47
49
|
def self.root
|
|
48
|
-
@root ||= File.expand_path(
|
|
50
|
+
@root ||= File.expand_path('..', __dir__)
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
#
|
|
52
54
|
# Create a new Driver instance with the correct bridge for the given browser
|
|
53
55
|
#
|
|
54
|
-
# @
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
56
|
+
# @overload for(browser)
|
|
57
|
+
# @param [:ie, :internet_explorer, :edge, :remote, :chrome, :firefox, :ff, :phantomjs, :safari] browser The browser to
|
|
58
|
+
# create the driver for
|
|
59
|
+
# @overload for(browser, opts)
|
|
60
|
+
# @param [:ie, :internet_explorer, :edge, :remote, :chrome, :firefox, :ff, :phantomjs, :safari] browser The browser to
|
|
61
|
+
# create the driver for
|
|
62
|
+
# @param [Hash] opts Options passed to Driver.new
|
|
58
63
|
#
|
|
59
64
|
# @return [Driver]
|
|
60
65
|
#
|
|
61
|
-
# @see Selenium::WebDriver::Remote::
|
|
62
|
-
# @see Selenium::WebDriver::Firefox::
|
|
63
|
-
# @see Selenium::WebDriver::IE::
|
|
64
|
-
# @see Selenium::WebDriver::Edge::
|
|
65
|
-
# @see Selenium::WebDriver::Chrome::
|
|
66
|
-
# @see Selenium::WebDriver::
|
|
67
|
-
# @see Selenium::WebDriver::
|
|
68
|
-
# @see Selenium::WebDriver::PhantomJS::Bridge
|
|
69
|
-
# @see Selenium::WebDriver::Safari::Bridge
|
|
66
|
+
# @see Selenium::WebDriver::Remote::Driver
|
|
67
|
+
# @see Selenium::WebDriver::Firefox::Driver
|
|
68
|
+
# @see Selenium::WebDriver::IE::Driver
|
|
69
|
+
# @see Selenium::WebDriver::Edge::Driver
|
|
70
|
+
# @see Selenium::WebDriver::Chrome::Driver
|
|
71
|
+
# @see Selenium::WebDriver::PhantomJS::Driver
|
|
72
|
+
# @see Selenium::WebDriver::Safari::Driver
|
|
70
73
|
#
|
|
71
74
|
# @example
|
|
72
75
|
#
|
|
73
|
-
# WebDriver.for :firefox, :
|
|
74
|
-
# WebDriver.for :firefox, :
|
|
75
|
-
# WebDriver.for :remote, :
|
|
76
|
+
# WebDriver.for :firefox, profile: 'some-profile'
|
|
77
|
+
# WebDriver.for :firefox, profile: Profile.new
|
|
78
|
+
# WebDriver.for :remote, url: "http://localhost:4444/wd/hub", desired_capabilities: caps
|
|
76
79
|
#
|
|
77
|
-
# One special argument is not passed on to the bridges, :listener.
|
|
78
|
-
#
|
|
80
|
+
# One special argument is not passed on to the bridges, :listener.
|
|
81
|
+
# You can pass a listener for this option to get notified of WebDriver events.
|
|
82
|
+
# The passed object must respond to #call or implement the methods from AbstractEventListener.
|
|
79
83
|
#
|
|
80
84
|
# @see Selenium::WebDriver::Support::AbstractEventListener
|
|
81
85
|
#
|
|
@@ -84,5 +88,14 @@ module Selenium
|
|
|
84
88
|
WebDriver::Driver.for(*args)
|
|
85
89
|
end
|
|
86
90
|
|
|
91
|
+
#
|
|
92
|
+
# Returns logger instance that can be used across the whole Selenium.
|
|
93
|
+
#
|
|
94
|
+
# @return [Logger]
|
|
95
|
+
#
|
|
96
|
+
|
|
97
|
+
def self.logger
|
|
98
|
+
@logger ||= WebDriver::Logger.new
|
|
99
|
+
end
|
|
87
100
|
end # WebDriver
|
|
88
101
|
end # Selenium
|
data/lib/selenium-webdriver.rb
CHANGED
data/selenium-webdriver.gemspec
CHANGED
|
@@ -1,34 +1,47 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
root = File.expand_path(File.dirname(__FILE__))
|
|
4
|
-
if root != Dir.pwd
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
raise "cwd must be #{root} when reading gemspec" if root != Dir.pwd
|
|
5
|
+
|
|
6
|
+
$LOAD_PATH.push(File.expand_path('lib', root))
|
|
7
|
+
require 'selenium/webdriver/version'
|
|
7
8
|
|
|
8
9
|
Gem::Specification.new do |s|
|
|
9
|
-
s.name
|
|
10
|
-
s.version =
|
|
11
|
-
|
|
12
|
-
s.authors
|
|
13
|
-
s.email
|
|
14
|
-
|
|
15
|
-
s.summary
|
|
16
|
-
s.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
s.
|
|
21
|
-
|
|
22
|
-
s.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
s.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
s.
|
|
31
|
-
s.
|
|
32
|
-
|
|
33
|
-
s.
|
|
10
|
+
s.name = 'selenium-webdriver'
|
|
11
|
+
s.version = Selenium::WebDriver::VERSION
|
|
12
|
+
|
|
13
|
+
s.authors = ['Alex Rodionov', 'Titus Fortner', 'Thomas Walpole']
|
|
14
|
+
s.email = ['p0deje@gmail.com', 'titusfortner@gmail.com', 'twalpole@gmail.com']
|
|
15
|
+
|
|
16
|
+
s.summary = 'The next generation developer focused tool for automated testing of webapps'
|
|
17
|
+
s.description = 'WebDriver is a tool for writing automated tests of websites. ' \
|
|
18
|
+
'It aims to mimic the behaviour of a real user, ' \
|
|
19
|
+
'and as such interacts with the HTML of the application.'
|
|
20
|
+
|
|
21
|
+
s.license = 'Apache-2.0'
|
|
22
|
+
s.homepage = 'https://github.com/SeleniumHQ/selenium'
|
|
23
|
+
s.metadata = {
|
|
24
|
+
'changelog_uri' => 'https://github.com/SeleniumHQ/selenium/blob/master/rb/CHANGES',
|
|
25
|
+
'source_code_uri' => 'https://github.com/SeleniumHQ/selenium/tree/master/rb'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
s.required_rubygems_version = Gem::Requirement.new('> 1.3.1') if s.respond_to? :required_rubygems_version=
|
|
29
|
+
s.required_ruby_version = Gem::Requirement.new('>= 2.3')
|
|
30
|
+
|
|
31
|
+
s.files = Dir[root + '/**/*'].reject { |e| e =~ /ruby\.iml|build\.desc/ }.map { |e| e.sub(root + '/', '') }
|
|
32
|
+
s.require_paths = ['lib']
|
|
33
|
+
|
|
34
|
+
s.add_runtime_dependency 'childprocess', ['>= 0.5', '< 4.0']
|
|
35
|
+
s.add_runtime_dependency 'rubyzip', ['>= 1.2.2']
|
|
36
|
+
|
|
37
|
+
# childprocess requires ffi on windows but doesn't declare it in its dependencies
|
|
38
|
+
s.add_development_dependency 'ffi'
|
|
39
|
+
s.add_development_dependency 'rack', ['~> 2.0']
|
|
40
|
+
s.add_development_dependency 'rake'
|
|
41
|
+
s.add_development_dependency 'rspec', ['~> 3.0']
|
|
42
|
+
s.add_development_dependency 'rubocop', ['~> 0.67.0']
|
|
43
|
+
s.add_development_dependency 'rubocop-performance'
|
|
44
|
+
s.add_development_dependency 'rubocop-rspec'
|
|
45
|
+
s.add_development_dependency 'webmock', ['~> 3.5']
|
|
46
|
+
s.add_development_dependency 'yard', ['~> 0.9.11']
|
|
34
47
|
end
|