selenium-webdriver 2.45.0 → 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 +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'
|