selenium-webdriver 2.45.0 → 3.142.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES +795 -3
- data/Gemfile +2 -0
- data/{COPYING → LICENSE} +1 -3
- data/README.md +13 -9
- data/lib/selenium/server.rb +93 -71
- data/lib/selenium/webdriver/atoms/getAttribute.js +7 -0
- data/lib/selenium/webdriver/atoms/isDisplayed.js +102 -0
- data/lib/selenium/webdriver/atoms.rb +37 -0
- data/lib/selenium/webdriver/chrome/bridge.rb +47 -99
- 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 +40 -20
- data/lib/selenium/webdriver/chrome/service.rb +46 -62
- data/lib/selenium/webdriver/chrome.rb +34 -6
- data/lib/selenium/webdriver/common/action_builder.rb +69 -56
- data/lib/selenium/webdriver/common/alert.rb +25 -8
- data/lib/selenium/webdriver/common/bridge_helper.rb +35 -20
- data/lib/selenium/webdriver/common/driver.rb +90 -63
- 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_debugger.rb +42 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +26 -11
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +51 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +58 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +51 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +23 -6
- data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +19 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +24 -7
- data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +19 -3
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +23 -7
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +26 -5
- data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +20 -6
- data/lib/selenium/webdriver/common/element.rb +79 -37
- data/lib/selenium/webdriver/common/error.rb +282 -106
- data/lib/selenium/webdriver/common/file_reaper.rb +23 -12
- data/lib/selenium/webdriver/common/html5/local_storage.rb +29 -12
- data/lib/selenium/webdriver/common/html5/session_storage.rb +29 -12
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +29 -18
- 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/common/interactions/interactions.rb +43 -0
- 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/common/interactions/none_input.rb +36 -0
- 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 +27 -12
- data/lib/selenium/webdriver/common/keys.rb +118 -81
- data/lib/selenium/webdriver/common/log_entry.rb +27 -8
- data/lib/selenium/webdriver/common/logger.rb +115 -0
- data/lib/selenium/webdriver/common/logs.rb +24 -7
- data/lib/selenium/webdriver/common/manager.rb +177 -0
- data/lib/selenium/webdriver/common/mouse.rb +29 -12
- data/lib/selenium/webdriver/common/navigation.rb +21 -4
- data/lib/selenium/webdriver/common/options.rb +43 -126
- data/lib/selenium/webdriver/common/platform.rb +101 -97
- data/lib/selenium/webdriver/common/port_prober.rb +24 -17
- data/lib/selenium/webdriver/common/profile_helper.rb +27 -11
- data/lib/selenium/webdriver/common/proxy.rb +86 -73
- data/lib/selenium/webdriver/common/search_context.rb +49 -33
- data/lib/selenium/webdriver/common/service.rb +219 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +82 -0
- data/lib/selenium/webdriver/common/socket_poller.rb +47 -26
- data/lib/selenium/webdriver/common/target_locator.rb +35 -14
- data/lib/selenium/webdriver/common/timeouts.rb +23 -6
- data/lib/selenium/webdriver/common/touch_action_builder.rb +25 -11
- data/lib/selenium/webdriver/common/touch_screen.rb +42 -24
- 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 +34 -14
- data/lib/selenium/webdriver/common/window.rb +75 -16
- data/lib/selenium/webdriver/common/zipper.rb +26 -11
- data/lib/selenium/webdriver/common.rb +40 -7
- data/lib/selenium/webdriver/edge/bridge.rb +76 -0
- 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 +52 -0
- data/lib/selenium/webdriver/edge.rb +44 -0
- data/lib/selenium/webdriver/firefox/binary.rb +70 -48
- data/lib/selenium/webdriver/firefox/driver.rb +50 -0
- data/lib/selenium/webdriver/firefox/extension/prefs.json +14 -13
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/extension.rb +50 -19
- data/lib/selenium/webdriver/firefox/launcher.rb +33 -28
- 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 +66 -48
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +28 -16
- data/lib/selenium/webdriver/firefox/service.rb +52 -0
- data/lib/selenium/webdriver/firefox/util.rb +19 -2
- data/lib/selenium/webdriver/firefox.rb +46 -10
- 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 +32 -10
- data/lib/selenium/webdriver/remote/bridge.rb +117 -572
- data/lib/selenium/webdriver/remote/capabilities.rb +116 -99
- data/lib/selenium/webdriver/remote/driver.rb +51 -0
- data/lib/selenium/webdriver/remote/http/common.rb +54 -23
- data/lib/selenium/webdriver/remote/http/curb.rb +30 -12
- data/lib/selenium/webdriver/remote/http/default.rb +85 -42
- data/lib/selenium/webdriver/remote/http/persistent.rb +29 -7
- 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 +68 -30
- data/lib/selenium/webdriver/remote/server_error.rb +22 -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 +27 -13
- data/lib/selenium/webdriver/safari/bridge.rb +38 -107
- data/lib/selenium/webdriver/safari/driver.rb +68 -0
- data/lib/selenium/webdriver/safari/options.rb +56 -75
- data/lib/selenium/webdriver/safari/service.rb +38 -0
- data/lib/selenium/webdriver/safari.rb +49 -31
- data/lib/selenium/webdriver/support/abstract_event_listener.rb +40 -6
- data/lib/selenium/webdriver/support/block_event_listener.rb +24 -7
- data/lib/selenium/webdriver/support/color.rb +82 -46
- data/lib/selenium/webdriver/support/escaper.rb +43 -0
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +56 -39
- data/lib/selenium/webdriver/support/select.rb +66 -89
- data/lib/selenium/webdriver/support.rb +20 -0
- data/lib/selenium/webdriver/version.rb +24 -0
- data/lib/selenium/webdriver.rb +55 -25
- data/lib/selenium-webdriver.rb +19 -0
- data/selenium-webdriver.gemspec +42 -29
- metadata +331 -260
- data/Gemfile.lock +0 -48
- data/lib/selenium/client/base.rb +0 -132
- data/lib/selenium/client/driver.rb +0 -10
- data/lib/selenium/client/errors.rb +0 -9
- data/lib/selenium/client/extensions.rb +0 -118
- data/lib/selenium/client/idiomatic.rb +0 -488
- data/lib/selenium/client/javascript_expression_builder.rb +0 -116
- data/lib/selenium/client/javascript_frameworks/jquery.rb +0 -13
- data/lib/selenium/client/javascript_frameworks/prototype.rb +0 -13
- data/lib/selenium/client/legacy_driver.rb +0 -1720
- data/lib/selenium/client/protocol.rb +0 -104
- data/lib/selenium/client/selenium_helper.rb +0 -34
- data/lib/selenium/client.rb +0 -38
- data/lib/selenium/rake/server_task.rb +0 -157
- data/lib/selenium/webdriver/android/bridge.rb +0 -49
- data/lib/selenium/webdriver/android.rb +0 -9
- data/lib/selenium/webdriver/common/core_ext/base64.rb +0 -9
- data/lib/selenium/webdriver/common/core_ext/dir.rb +0 -42
- data/lib/selenium/webdriver/common/core_ext/string.rb +0 -5
- data/lib/selenium/webdriver/common/driver_extensions/has_browser_connection.rb +0 -17
- data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +0 -39
- data/lib/selenium/webdriver/common/html5/location.rb +0 -0
- data/lib/selenium/webdriver/common/json_helper.rb +0 -34
- data/lib/selenium/webdriver/firefox/bridge.rb +0 -70
- data/lib/selenium/webdriver/firefox/socket_lock.rb +0 -61
- data/lib/selenium/webdriver/ie/bridge.rb +0 -69
- data/lib/selenium/webdriver/ie/server.rb +0 -90
- data/lib/selenium/webdriver/iphone/bridge.rb +0 -45
- data/lib/selenium/webdriver/iphone.rb +0 -9
- data/lib/selenium/webdriver/opera/bridge.rb +0 -112
- data/lib/selenium/webdriver/opera/service.rb +0 -49
- data/lib/selenium/webdriver/opera.rb +0 -24
- data/lib/selenium/webdriver/phantomjs/bridge.rb +0 -59
- data/lib/selenium/webdriver/phantomjs/service.rb +0 -90
- data/lib/selenium/webdriver/phantomjs.rb +0 -22
- data/lib/selenium/webdriver/remote/commands.rb +0 -192
- data/lib/selenium/webdriver/safari/browser.rb +0 -20
- data/lib/selenium/webdriver/safari/extensions.rb +0 -170
- data/lib/selenium/webdriver/safari/resources/SafariDriver.safariextz +0 -0
- data/lib/selenium/webdriver/safari/resources/client.js +0 -6903
- data/lib/selenium/webdriver/safari/server.rb +0 -145
- data/lib/selenium-client.rb +0 -2
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
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 Support
|
23
|
+
module Escaper
|
24
|
+
def self.escape(str)
|
25
|
+
if str.include?('"') && str.include?("'")
|
26
|
+
parts = str.split('"', -1).map { |part| %("#{part}") }
|
27
|
+
|
28
|
+
quoted = parts.join(%(, '"', ))
|
29
|
+
.gsub(/^"", |, ""$/, '')
|
30
|
+
|
31
|
+
"concat(#{quoted})"
|
32
|
+
elsif str.include?('"')
|
33
|
+
# escape string with just a quote into being single quoted: f"oo -> 'f"oo'
|
34
|
+
"'#{str}'"
|
35
|
+
else
|
36
|
+
# otherwise return the quoted string
|
37
|
+
%("#{str}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end # Escaper
|
41
|
+
end # Support
|
42
|
+
end # WebDriver
|
43
|
+
end # Selenium
|
@@ -1,7 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
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
|
+
|
1
20
|
module Selenium
|
2
21
|
module WebDriver
|
3
22
|
module Support
|
4
|
-
|
5
23
|
#
|
6
24
|
# @api private
|
7
25
|
#
|
@@ -10,69 +28,69 @@ module Selenium
|
|
10
28
|
def initialize(delegate, listener)
|
11
29
|
@delegate = delegate
|
12
30
|
|
13
|
-
if listener.respond_to? :call
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
31
|
+
@listener = if listener.respond_to? :call
|
32
|
+
BlockEventListener.new(listener)
|
33
|
+
else
|
34
|
+
listener
|
35
|
+
end
|
18
36
|
end
|
19
37
|
|
20
38
|
def get(url)
|
21
|
-
dispatch(:navigate_to, url, driver)
|
39
|
+
dispatch(:navigate_to, url, driver) do
|
22
40
|
@delegate.get(url)
|
23
|
-
|
41
|
+
end
|
24
42
|
end
|
25
43
|
|
26
|
-
def
|
27
|
-
dispatch(:navigate_forward, driver)
|
28
|
-
@delegate.
|
29
|
-
|
44
|
+
def go_forward
|
45
|
+
dispatch(:navigate_forward, driver) do
|
46
|
+
@delegate.go_forward
|
47
|
+
end
|
30
48
|
end
|
31
49
|
|
32
|
-
def
|
33
|
-
dispatch(:navigate_back, driver)
|
34
|
-
@delegate.
|
35
|
-
|
50
|
+
def go_back
|
51
|
+
dispatch(:navigate_back, driver) do
|
52
|
+
@delegate.go_back
|
53
|
+
end
|
36
54
|
end
|
37
55
|
|
38
|
-
def
|
39
|
-
dispatch(:click, create_element(ref), driver)
|
40
|
-
@delegate.
|
41
|
-
|
56
|
+
def click_element(ref)
|
57
|
+
dispatch(:click, create_element(ref), driver) do
|
58
|
+
@delegate.click_element(ref)
|
59
|
+
end
|
42
60
|
end
|
43
61
|
|
44
|
-
def
|
45
|
-
dispatch(:change_value_of, create_element(ref), driver)
|
46
|
-
@delegate.
|
47
|
-
|
62
|
+
def clear_element(ref)
|
63
|
+
dispatch(:change_value_of, create_element(ref), driver) do
|
64
|
+
@delegate.clear_element(ref)
|
65
|
+
end
|
48
66
|
end
|
49
67
|
|
50
|
-
def
|
51
|
-
dispatch(:change_value_of, create_element(ref), driver)
|
52
|
-
@delegate.
|
53
|
-
|
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
|
54
72
|
end
|
55
73
|
|
56
74
|
def find_element_by(how, what, parent = nil)
|
57
|
-
e = dispatch(:find, how, what, driver)
|
75
|
+
e = dispatch(:find, how, what, driver) do
|
58
76
|
@delegate.find_element_by how, what, parent
|
59
|
-
|
77
|
+
end
|
60
78
|
|
61
79
|
Element.new self, e.ref
|
62
80
|
end
|
63
81
|
|
64
82
|
def find_elements_by(how, what, parent = nil)
|
65
|
-
es = dispatch(:find, how, what, driver)
|
83
|
+
es = dispatch(:find, how, what, driver) do
|
66
84
|
@delegate.find_elements_by(how, what, parent)
|
67
|
-
|
85
|
+
end
|
68
86
|
|
69
87
|
es.map { |e| Element.new self, e.ref }
|
70
88
|
end
|
71
89
|
|
72
|
-
def
|
73
|
-
dispatch(:execute_script, script, driver)
|
74
|
-
@delegate.
|
75
|
-
|
90
|
+
def execute_script(script, *args)
|
91
|
+
dispatch(:execute_script, script, driver) do
|
92
|
+
@delegate.execute_script(script, *args)
|
93
|
+
end
|
76
94
|
end
|
77
95
|
|
78
96
|
def quit
|
@@ -94,7 +112,7 @@ module Selenium
|
|
94
112
|
@driver ||= Driver.new(self)
|
95
113
|
end
|
96
114
|
|
97
|
-
def dispatch(name, *args
|
115
|
+
def dispatch(name, *args)
|
98
116
|
@listener.__send__("before_#{name}", *args)
|
99
117
|
returned = yield
|
100
118
|
@listener.__send__("after_#{name}", *args)
|
@@ -102,11 +120,10 @@ module Selenium
|
|
102
120
|
returned
|
103
121
|
end
|
104
122
|
|
105
|
-
def method_missing(meth, *args, &blk)
|
123
|
+
def method_missing(meth, *args, &blk) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
|
106
124
|
@delegate.__send__(meth, *args, &blk)
|
107
125
|
end
|
108
126
|
end # EventFiringBridge
|
109
|
-
|
110
127
|
end # Support
|
111
128
|
end # WebDriver
|
112
129
|
end # Selenium
|
@@ -1,8 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
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
|
+
|
1
20
|
module Selenium
|
2
21
|
module WebDriver
|
3
22
|
module Support
|
4
23
|
class Select
|
5
|
-
|
6
24
|
#
|
7
25
|
# @param [Element] element The select element to use
|
8
26
|
#
|
@@ -10,12 +28,10 @@ module Selenium
|
|
10
28
|
def initialize(element)
|
11
29
|
tag_name = element.tag_name
|
12
30
|
|
13
|
-
|
14
|
-
raise ArgumentError, "unexpected tag name #{tag_name.inspect}"
|
15
|
-
end
|
31
|
+
raise ArgumentError, "unexpected tag name #{tag_name.inspect}" unless tag_name.casecmp('select').zero?
|
16
32
|
|
17
33
|
@element = element
|
18
|
-
@multi
|
34
|
+
@multi = ![nil, 'false'].include?(element.attribute(:multiple))
|
19
35
|
end
|
20
36
|
|
21
37
|
#
|
@@ -35,7 +51,7 @@ module Selenium
|
|
35
51
|
#
|
36
52
|
|
37
53
|
def options
|
38
|
-
@element.find_elements :
|
54
|
+
@element.find_elements tag_name: 'option'
|
39
55
|
end
|
40
56
|
|
41
57
|
#
|
@@ -45,7 +61,7 @@ module Selenium
|
|
45
61
|
#
|
46
62
|
|
47
63
|
def selected_options
|
48
|
-
options.select
|
64
|
+
options.select(&:selected?)
|
49
65
|
end
|
50
66
|
|
51
67
|
#
|
@@ -56,8 +72,10 @@ module Selenium
|
|
56
72
|
#
|
57
73
|
|
58
74
|
def first_selected_option
|
59
|
-
option = options.find
|
60
|
-
option
|
75
|
+
option = options.find(&:selected?)
|
76
|
+
return option if option
|
77
|
+
|
78
|
+
raise Error::NoSuchElementError, 'no options are selected'
|
61
79
|
end
|
62
80
|
|
63
81
|
#
|
@@ -98,6 +116,7 @@ module Selenium
|
|
98
116
|
#
|
99
117
|
# @param [:text, :index, :value] how How to find the option
|
100
118
|
# @param [String] what What value to find the option by.
|
119
|
+
# @raise [Error::UnsupportedOperationError] if the element does not support multiple selections.
|
101
120
|
#
|
102
121
|
# @see Select#select_by
|
103
122
|
#
|
@@ -122,9 +141,7 @@ module Selenium
|
|
122
141
|
#
|
123
142
|
|
124
143
|
def select_all
|
125
|
-
unless multiple?
|
126
|
-
raise Error::UnsupportedOperationError, 'you may only select all options of a multi-select'
|
127
|
-
end
|
144
|
+
raise Error::UnsupportedOperationError, 'you may only select all options of a multi-select' unless multiple?
|
128
145
|
|
129
146
|
options.each { |e| select_option e }
|
130
147
|
end
|
@@ -136,9 +153,7 @@ module Selenium
|
|
136
153
|
#
|
137
154
|
|
138
155
|
def deselect_all
|
139
|
-
unless multiple?
|
140
|
-
raise Error::UnsupportedOperationError, 'you may only deselect all options of a multi-select'
|
141
|
-
end
|
156
|
+
raise Error::UnsupportedOperationError, 'you may only deselect all options of a multi-select' unless multiple?
|
142
157
|
|
143
158
|
options.each { |e| deselect_option e }
|
144
159
|
end
|
@@ -148,65 +163,57 @@ module Selenium
|
|
148
163
|
def select_by_text(text)
|
149
164
|
opts = find_by_text text
|
150
165
|
|
151
|
-
|
152
|
-
raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
|
153
|
-
end
|
166
|
+
return select_options(opts) unless opts.empty?
|
154
167
|
|
155
|
-
|
168
|
+
raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
|
156
169
|
end
|
157
170
|
|
158
171
|
def select_by_index(index)
|
159
172
|
opts = find_by_index index
|
160
173
|
|
161
|
-
|
162
|
-
raise Error::NoSuchElementError, "cannot locate element with index: #{index.inspect}"
|
163
|
-
end
|
174
|
+
return select_option(opts.first) unless opts.empty?
|
164
175
|
|
165
|
-
|
176
|
+
raise Error::NoSuchElementError, "cannot locate element with index: #{index.inspect}"
|
166
177
|
end
|
167
178
|
|
168
179
|
def select_by_value(value)
|
169
180
|
opts = find_by_value value
|
170
181
|
|
171
|
-
|
172
|
-
raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
|
173
|
-
end
|
182
|
+
return select_options(opts) unless opts.empty?
|
174
183
|
|
175
|
-
|
184
|
+
raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
|
176
185
|
end
|
177
186
|
|
178
187
|
def deselect_by_text(text)
|
188
|
+
raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?
|
189
|
+
|
179
190
|
opts = find_by_text text
|
180
191
|
|
181
|
-
|
182
|
-
raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
|
183
|
-
end
|
192
|
+
return deselect_options(opts) unless opts.empty?
|
184
193
|
|
185
|
-
|
194
|
+
raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
|
186
195
|
end
|
187
196
|
|
188
197
|
def deselect_by_value(value)
|
198
|
+
raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?
|
199
|
+
|
189
200
|
opts = find_by_value value
|
190
201
|
|
191
|
-
|
192
|
-
raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
|
193
|
-
end
|
202
|
+
return deselect_options(opts) unless opts.empty?
|
194
203
|
|
195
|
-
|
204
|
+
raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
|
196
205
|
end
|
197
206
|
|
198
207
|
def deselect_by_index(index)
|
208
|
+
raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?
|
209
|
+
|
199
210
|
opts = find_by_index index
|
200
211
|
|
201
|
-
|
202
|
-
raise Error::NoSuchElementError, "cannot locate option with index: #{index}"
|
203
|
-
end
|
212
|
+
return deselect_option(opts.first) unless opts.empty?
|
204
213
|
|
205
|
-
|
214
|
+
raise Error::NoSuchElementError, "cannot locate option with index: #{index}"
|
206
215
|
end
|
207
216
|
|
208
|
-
private
|
209
|
-
|
210
217
|
def select_option(option)
|
211
218
|
option.click unless option.selected?
|
212
219
|
end
|
@@ -233,61 +240,31 @@ module Selenium
|
|
233
240
|
|
234
241
|
def find_by_text(text)
|
235
242
|
xpath = ".//option[normalize-space(.) = #{Escaper.escape text}]"
|
236
|
-
opts = @element.find_elements(:
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
else
|
244
|
-
xpath = ".//option[contains(., #{Escaper.escape longest_word})]"
|
245
|
-
candidates = @element.find_elements(:xpath, xpath)
|
246
|
-
end
|
247
|
-
|
248
|
-
if multiple?
|
249
|
-
candidates.select { |option| text == option.text }
|
250
|
-
else
|
251
|
-
Array(candidates.find { |option| text == option.text })
|
252
|
-
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
|
253
250
|
else
|
254
|
-
|
251
|
+
xpath = ".//option[contains(., #{Escaper.escape longest_word})]"
|
252
|
+
candidates = @element.find_elements(xpath: xpath)
|
255
253
|
end
|
254
|
+
|
255
|
+
return Array(candidates.find { |option| text == option.text }) unless multiple?
|
256
|
+
|
257
|
+
candidates.select { |option| text == option.text }
|
256
258
|
end
|
257
259
|
|
258
260
|
def find_by_index(index)
|
259
|
-
index
|
260
|
-
options.select { |option| option.attribute(:index) == index }
|
261
|
+
options.select { |option| option.attribute(:index) == index.to_s }
|
261
262
|
end
|
262
263
|
|
263
264
|
def find_by_value(value)
|
264
|
-
@element.find_elements(:
|
265
|
+
@element.find_elements(xpath: ".//option[@value = #{Escaper.escape value}]")
|
265
266
|
end
|
266
|
-
|
267
|
-
#
|
268
|
-
# @api private
|
269
|
-
#
|
270
|
-
|
271
|
-
module Escaper
|
272
|
-
def self.escape(str)
|
273
|
-
if str.include?('"') && str.include?("'")
|
274
|
-
parts = str.split('"', -1).map { |part| %{"#{part}"} }
|
275
|
-
|
276
|
-
quoted = parts.join(%{, '"', }).
|
277
|
-
gsub(/^"", |, ""$/, '')
|
278
|
-
|
279
|
-
"concat(#{quoted})"
|
280
|
-
elsif str.include?('"')
|
281
|
-
# escape string with just a quote into being single quoted: f"oo -> 'f"oo'
|
282
|
-
"'#{str}'"
|
283
|
-
else
|
284
|
-
# otherwise return the quoted string
|
285
|
-
%{"#{str}"}
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end # Escaper
|
289
|
-
|
290
267
|
end # Select
|
291
|
-
end
|
292
|
-
end
|
293
|
-
end
|
268
|
+
end # Support
|
269
|
+
end # WebDriver
|
270
|
+
end # Selenium
|
@@ -1,5 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
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
|
+
|
1
20
|
require 'selenium/webdriver/support/event_firing_bridge'
|
2
21
|
require 'selenium/webdriver/support/abstract_event_listener'
|
3
22
|
require 'selenium/webdriver/support/block_event_listener'
|
23
|
+
require 'selenium/webdriver/support/escaper'
|
4
24
|
require 'selenium/webdriver/support/select'
|
5
25
|
require 'selenium/webdriver/support/color'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
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
|
+
VERSION = '3.142.7'
|
23
|
+
end # WebDriver
|
24
|
+
end # Selenium
|
data/lib/selenium/webdriver.rb
CHANGED
@@ -1,25 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
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
|
+
|
1
20
|
require 'childprocess'
|
2
21
|
require 'tmpdir'
|
3
22
|
require 'fileutils'
|
4
23
|
require 'date'
|
24
|
+
require 'json'
|
25
|
+
require 'set'
|
5
26
|
|
6
|
-
require 'multi_json'
|
7
27
|
require 'selenium/webdriver/common'
|
28
|
+
require 'selenium/webdriver/atoms'
|
29
|
+
require 'selenium/webdriver/version'
|
8
30
|
|
9
31
|
module Selenium
|
10
32
|
module WebDriver
|
11
|
-
extend JsonHelper
|
12
|
-
|
13
33
|
Point = Struct.new(:x, :y)
|
14
34
|
Dimension = Struct.new(:width, :height)
|
35
|
+
Rectangle = Struct.new(:x, :y, :width, :height)
|
15
36
|
Location = Struct.new(:latitude, :longitude, :altitude)
|
16
37
|
|
17
|
-
autoload :Android, 'selenium/webdriver/android'
|
18
38
|
autoload :Chrome, 'selenium/webdriver/chrome'
|
39
|
+
autoload :Edge, 'selenium/webdriver/edge'
|
19
40
|
autoload :Firefox, 'selenium/webdriver/firefox'
|
20
41
|
autoload :IE, 'selenium/webdriver/ie'
|
21
|
-
autoload :IPhone, 'selenium/webdriver/iphone'
|
22
|
-
autoload :Opera, 'selenium/webdriver/opera'
|
23
42
|
autoload :PhantomJS, 'selenium/webdriver/phantomjs'
|
24
43
|
autoload :Remote, 'selenium/webdriver/remote'
|
25
44
|
autoload :Safari, 'selenium/webdriver/safari'
|
@@ -28,37 +47,39 @@ module Selenium
|
|
28
47
|
# @api private
|
29
48
|
|
30
49
|
def self.root
|
31
|
-
@root ||= File.expand_path(
|
50
|
+
@root ||= File.expand_path('..', __dir__)
|
32
51
|
end
|
33
52
|
|
34
53
|
#
|
35
54
|
# Create a new Driver instance with the correct bridge for the given browser
|
36
55
|
#
|
37
|
-
# @
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
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
|
41
63
|
#
|
42
64
|
# @return [Driver]
|
43
65
|
#
|
44
|
-
# @see Selenium::WebDriver::Remote::
|
45
|
-
# @see Selenium::WebDriver::Firefox::
|
46
|
-
# @see Selenium::WebDriver::IE::
|
47
|
-
# @see Selenium::WebDriver::
|
48
|
-
# @see Selenium::WebDriver::
|
49
|
-
# @see Selenium::WebDriver::
|
50
|
-
# @see Selenium::WebDriver::
|
51
|
-
# @see Selenium::WebDriver::PhantomJS::Bridge
|
52
|
-
# @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
|
53
73
|
#
|
54
74
|
# @example
|
55
75
|
#
|
56
|
-
# WebDriver.for :firefox, :
|
57
|
-
# WebDriver.for :firefox, :
|
58
|
-
# 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
|
59
79
|
#
|
60
|
-
# One special argument is not passed on to the bridges, :listener.
|
61
|
-
#
|
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.
|
62
83
|
#
|
63
84
|
# @see Selenium::WebDriver::Support::AbstractEventListener
|
64
85
|
#
|
@@ -67,5 +88,14 @@ module Selenium
|
|
67
88
|
WebDriver::Driver.for(*args)
|
68
89
|
end
|
69
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
|
70
100
|
end # WebDriver
|
71
101
|
end # Selenium
|
data/lib/selenium-webdriver.rb
CHANGED
@@ -1 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
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
|
+
|
1
20
|
require 'selenium/webdriver'
|