selenium-webdriver 3.142.7 → 4.10.0
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 +5 -5
- data/CHANGES +611 -5
- data/Gemfile +5 -1
- data/LICENSE +1 -1
- data/NOTICE +2 -0
- data/README.md +4 -5
- data/bin/linux/selenium-manager +0 -0
- data/bin/macos/selenium-manager +0 -0
- data/bin/windows/selenium-manager.exe +0 -0
- data/lib/selenium/server.rb +94 -79
- data/lib/selenium/webdriver/atoms/findElements.js +121 -0
- data/lib/selenium/webdriver/atoms/getAttribute.js +100 -7
- data/lib/selenium/webdriver/atoms/isDisplayed.js +76 -78
- data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
- data/lib/selenium/webdriver/atoms.rb +2 -3
- data/lib/selenium/webdriver/bidi/browsing_context.rb +88 -0
- data/lib/selenium/webdriver/bidi/browsing_context_info.rb +35 -0
- data/lib/selenium/webdriver/bidi/log/base_log_entry.rb +35 -0
- data/lib/selenium/webdriver/bidi/log/console_log_entry.rb +35 -0
- data/lib/selenium/webdriver/bidi/log/filter_by.rb +40 -0
- data/lib/selenium/webdriver/bidi/log/generic_log_entry.rb +33 -0
- data/lib/selenium/webdriver/bidi/log/javascript_log_entry.rb +33 -0
- data/lib/selenium/webdriver/bidi/log_inspector.rb +143 -0
- data/lib/selenium/webdriver/bidi/navigate_result.rb +33 -0
- data/lib/selenium/webdriver/bidi/session.rb +51 -0
- data/lib/selenium/webdriver/{common/keyboard.rb → bidi.rb} +21 -35
- data/lib/selenium/webdriver/chrome/driver.rb +9 -86
- data/lib/selenium/webdriver/chrome/features.rb +44 -0
- data/lib/selenium/webdriver/chrome/options.rb +9 -158
- data/lib/selenium/webdriver/chrome/profile.rb +3 -80
- data/lib/selenium/webdriver/chrome/service.rb +6 -33
- data/lib/selenium/webdriver/chrome.rb +5 -18
- data/lib/selenium/webdriver/chromium/driver.rb +61 -0
- data/lib/selenium/webdriver/{chrome/bridge.rb → chromium/features.rb} +51 -16
- data/lib/selenium/webdriver/chromium/options.rb +261 -0
- data/lib/selenium/webdriver/chromium/profile.rb +113 -0
- data/lib/selenium/webdriver/chromium/service.rb +42 -0
- data/lib/selenium/webdriver/chromium.rb +32 -0
- data/lib/selenium/webdriver/common/action_builder.rb +128 -238
- data/lib/selenium/webdriver/common/child_process.rb +124 -0
- data/lib/selenium/webdriver/common/driver.rb +94 -43
- data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +42 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +49 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +87 -0
- data/lib/selenium/webdriver/common/driver_extensions/{has_touch_screen.rb → has_bidi.rb} +9 -9
- data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +86 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +36 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +42 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +41 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +36 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -9
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +143 -0
- data/lib/selenium/webdriver/common/driver_extensions/{has_remote_status.rb → has_logs.rb} +4 -4
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +16 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +6 -27
- data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +69 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +11 -13
- data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +75 -0
- data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
- data/lib/selenium/webdriver/common/driver_finder.rb +47 -0
- data/lib/selenium/webdriver/common/element.rb +89 -29
- data/lib/selenium/webdriver/common/error.rb +53 -194
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
- data/lib/selenium/webdriver/common/interactions/input_device.rb +10 -4
- data/lib/selenium/webdriver/common/interactions/interaction.rb +12 -22
- data/lib/selenium/webdriver/common/interactions/interactions.rb +24 -4
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +10 -6
- data/lib/selenium/webdriver/common/interactions/key_input.rb +11 -27
- data/lib/selenium/webdriver/common/interactions/none_input.rb +10 -8
- data/lib/selenium/webdriver/common/interactions/pause.rb +49 -0
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +71 -82
- data/lib/selenium/webdriver/common/interactions/pointer_cancel.rb +45 -0
- data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +63 -0
- data/lib/selenium/webdriver/common/interactions/pointer_input.rb +15 -84
- data/lib/selenium/webdriver/common/interactions/pointer_move.rb +60 -0
- data/lib/selenium/webdriver/common/interactions/pointer_press.rb +85 -0
- data/lib/selenium/webdriver/common/interactions/scroll.rb +59 -0
- data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +48 -0
- data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +54 -0
- data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +113 -0
- data/lib/selenium/webdriver/common/{w3c_manager.rb → interactions/wheel_input.rb} +14 -17
- data/lib/selenium/webdriver/common/keys.rb +1 -0
- data/lib/selenium/webdriver/common/local_driver.rb +55 -0
- data/lib/selenium/webdriver/common/log_entry.rb +2 -2
- data/lib/selenium/webdriver/common/logger.rb +119 -19
- data/lib/selenium/webdriver/common/manager.rb +11 -38
- data/lib/selenium/webdriver/common/options.rb +169 -23
- data/lib/selenium/webdriver/common/platform.rb +14 -6
- data/lib/selenium/webdriver/common/port_prober.rb +4 -6
- data/lib/selenium/webdriver/common/profile_helper.rb +11 -9
- data/lib/selenium/webdriver/common/proxy.rb +8 -5
- data/lib/selenium/webdriver/common/search_context.rb +7 -9
- data/lib/selenium/webdriver/common/selenium_manager.rb +125 -0
- data/lib/selenium/webdriver/common/service.rb +26 -137
- data/lib/selenium/webdriver/common/service_manager.rb +144 -0
- data/lib/selenium/webdriver/common/shadow_root.rb +86 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +4 -4
- data/lib/selenium/webdriver/common/socket_poller.rb +4 -4
- data/lib/selenium/webdriver/common/takes_screenshot.rb +65 -0
- data/lib/selenium/webdriver/common/target_locator.rb +31 -4
- data/lib/selenium/webdriver/common/timeouts.rb +31 -4
- data/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +85 -0
- data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +72 -0
- data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +62 -0
- data/lib/selenium/webdriver/common/wait.rb +1 -1
- data/lib/selenium/webdriver/common/websocket_connection.rb +164 -0
- data/lib/selenium/webdriver/common/window.rb +6 -10
- data/lib/selenium/webdriver/common/zipper.rb +4 -10
- data/lib/selenium/webdriver/common.rb +42 -18
- data/lib/selenium/webdriver/devtools/console_event.rb +36 -0
- data/lib/selenium/webdriver/devtools/exception_event.rb +34 -0
- data/lib/selenium/webdriver/devtools/mutation_event.rb +35 -0
- data/lib/selenium/webdriver/devtools/network_interceptor.rb +173 -0
- data/lib/selenium/webdriver/devtools/pinned_script.rb +57 -0
- data/lib/selenium/webdriver/devtools/request.rb +65 -0
- data/lib/selenium/webdriver/devtools/response.rb +64 -0
- data/lib/selenium/webdriver/devtools.rb +96 -0
- data/lib/selenium/webdriver/edge/driver.rb +11 -27
- data/lib/selenium/webdriver/edge/features.rb +44 -0
- data/lib/selenium/webdriver/edge/options.rb +18 -43
- data/lib/selenium/webdriver/edge/profile.rb +33 -0
- data/lib/selenium/webdriver/edge/service.rb +7 -27
- data/lib/selenium/webdriver/edge.rb +11 -14
- data/lib/selenium/webdriver/firefox/driver.rb +38 -19
- data/lib/selenium/webdriver/firefox/extension.rb +8 -0
- data/lib/selenium/webdriver/firefox/features.rb +66 -0
- data/lib/selenium/webdriver/firefox/options.rb +77 -50
- data/lib/selenium/webdriver/firefox/profile.rb +17 -71
- data/lib/selenium/webdriver/firefox/service.rb +3 -13
- data/lib/selenium/webdriver/firefox/util.rb +1 -1
- data/lib/selenium/webdriver/firefox.rb +17 -28
- data/lib/selenium/webdriver/ie/driver.rb +5 -45
- data/lib/selenium/webdriver/ie/options.rb +15 -46
- data/lib/selenium/webdriver/ie/service.rb +11 -19
- data/lib/selenium/webdriver/ie.rb +3 -16
- data/lib/selenium/webdriver/remote/bridge/commands.rb +170 -0
- data/lib/selenium/webdriver/remote/bridge.rb +592 -87
- data/lib/selenium/webdriver/remote/capabilities.rb +182 -124
- data/lib/selenium/webdriver/remote/driver.rb +30 -15
- data/lib/selenium/webdriver/remote/http/common.rb +3 -8
- data/lib/selenium/webdriver/remote/http/curb.rb +1 -3
- data/lib/selenium/webdriver/remote/http/default.rb +23 -31
- data/lib/selenium/webdriver/remote/response.rb +17 -49
- data/lib/selenium/webdriver/remote.rb +14 -12
- data/lib/selenium/webdriver/safari/driver.rb +7 -29
- data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +3 -5
- data/lib/selenium/webdriver/safari/options.rb +12 -27
- data/lib/selenium/webdriver/safari/service.rb +13 -11
- data/lib/selenium/webdriver/safari.rb +14 -20
- data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
- data/lib/selenium/webdriver/support/color.rb +24 -24
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +4 -4
- data/lib/selenium/webdriver/support/guards/guard.rb +87 -0
- data/lib/selenium/webdriver/{firefox/marionette/bridge.rb → support/guards/guard_condition.rb} +21 -20
- data/lib/selenium/webdriver/support/guards.rb +95 -0
- data/lib/selenium/webdriver/support/relative_locator.rb +50 -0
- data/lib/selenium/webdriver/support/select.rb +6 -4
- data/lib/selenium/webdriver/support.rb +1 -0
- data/lib/selenium/webdriver/version.rb +1 -1
- data/lib/selenium/webdriver.rb +18 -17
- data/selenium-webdriver.gemspec +36 -18
- metadata +159 -89
- data/lib/selenium/webdriver/common/bridge_helper.rb +0 -82
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -64
- data/lib/selenium/webdriver/common/mouse.rb +0 -89
- data/lib/selenium/webdriver/common/touch_action_builder.rb +0 -78
- data/lib/selenium/webdriver/common/touch_screen.rb +0 -123
- data/lib/selenium/webdriver/common/w3c_action_builder.rb +0 -212
- data/lib/selenium/webdriver/edge/bridge.rb +0 -76
- data/lib/selenium/webdriver/firefox/binary.rb +0 -187
- data/lib/selenium/webdriver/firefox/extension/prefs.json +0 -69
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +0 -111
- data/lib/selenium/webdriver/firefox/legacy/driver.rb +0 -83
- data/lib/selenium/webdriver/firefox/marionette/driver.rb +0 -90
- data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/remote/http/persistent.rb +0 -60
- data/lib/selenium/webdriver/remote/oss/bridge.rb +0 -594
- data/lib/selenium/webdriver/remote/oss/commands.rb +0 -223
- data/lib/selenium/webdriver/remote/w3c/bridge.rb +0 -605
- data/lib/selenium/webdriver/remote/w3c/capabilities.rb +0 -310
- data/lib/selenium/webdriver/remote/w3c/commands.rb +0 -157
@@ -24,48 +24,58 @@ module Selenium
|
|
24
24
|
# Specification of the desired and/or actual capabilities of the browser that the
|
25
25
|
# server is being asked to create.
|
26
26
|
#
|
27
|
+
|
27
28
|
class Capabilities
|
28
|
-
|
29
|
-
browser_name
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
29
|
+
KNOWN = [
|
30
|
+
:browser_name,
|
31
|
+
:browser_version,
|
32
|
+
:platform_name,
|
33
|
+
:accept_insecure_certs,
|
34
|
+
:page_load_strategy,
|
35
|
+
:proxy,
|
36
|
+
:set_window_rect,
|
37
|
+
:timeouts,
|
38
|
+
:unhandled_prompt_behavior,
|
39
|
+
:strict_file_interactability,
|
40
|
+
:web_socket_url,
|
41
|
+
|
42
|
+
# remote-specific (webdriver.remote.sessionid)
|
43
|
+
:remote_session_id
|
44
|
+
].freeze
|
45
|
+
|
46
|
+
(KNOWN - %i[proxy timeouts]).each do |key|
|
47
|
+
define_method key do
|
48
|
+
@capabilities[key]
|
46
49
|
end
|
47
50
|
|
48
|
-
next if key == :proxy
|
49
|
-
|
50
51
|
define_method "#{key}=" do |value|
|
51
52
|
@capabilities[key] = value
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
55
56
|
#
|
56
|
-
#
|
57
|
-
# It is true if not set explicitly.
|
57
|
+
# Backward compatibility
|
58
58
|
#
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
|
60
|
+
def version
|
61
|
+
WebDriver.logger.deprecate('`Capabilities#version`', '`Capabilities#browser_version`', id: :jwp_caps)
|
62
|
+
browser_version
|
62
63
|
end
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
def version=(value)
|
66
|
+
WebDriver.logger.deprecate('`Capabilities#version=`', '`Capabilities#browser_version=`', id: :jwp_caps)
|
67
|
+
self.browser_version = value
|
68
|
+
end
|
69
|
+
|
70
|
+
def platform
|
71
|
+
WebDriver.logger.deprecate('`Capabilities#platform`', '`Capabilities#platform_name`', id: :jwp_caps)
|
72
|
+
platform_name
|
73
|
+
end
|
74
|
+
|
75
|
+
def platform=(value)
|
76
|
+
WebDriver.logger.deprecate('`Capabilities#platform=`', '`Capabilities#platform_name=`', id: :jwp_caps)
|
77
|
+
self.platform_name = value
|
78
|
+
end
|
69
79
|
|
70
80
|
#
|
71
81
|
# Convenience methods for the common choices.
|
@@ -73,81 +83,59 @@ module Selenium
|
|
73
83
|
|
74
84
|
class << self
|
75
85
|
def chrome(opts = {})
|
86
|
+
WebDriver.logger.deprecate('Remote::Capabilities.chrome', 'Options.chrome', id: :caps_browsers)
|
76
87
|
new({
|
77
|
-
browser_name: 'chrome'
|
78
|
-
javascript_enabled: true,
|
79
|
-
css_selectors_enabled: true
|
88
|
+
browser_name: 'chrome'
|
80
89
|
}.merge(opts))
|
81
90
|
end
|
82
91
|
|
83
92
|
def edge(opts = {})
|
93
|
+
WebDriver.logger.deprecate('Remote::Capabilities.edge', 'Options.edge', id: :caps_browsers)
|
84
94
|
new({
|
85
|
-
browser_name: 'MicrosoftEdge'
|
86
|
-
platform: :windows
|
95
|
+
browser_name: 'MicrosoftEdge'
|
87
96
|
}.merge(opts))
|
88
97
|
end
|
98
|
+
alias microsoftedge edge
|
89
99
|
|
90
100
|
def firefox(opts = {})
|
91
|
-
|
92
|
-
opts[:platform_name] = opts.delete(:platform) if opts.key?(:platform)
|
93
|
-
opts[:timeouts] = {}
|
94
|
-
opts[:timeouts]['implicit'] = opts.delete(:implicit_timeout) if opts.key?(:implicit_timeout)
|
95
|
-
opts[:timeouts]['pageLoad'] = opts.delete(:page_load_timeout) if opts.key?(:page_load_timeout)
|
96
|
-
opts[:timeouts]['script'] = opts.delete(:script_timeout) if opts.key?(:script_timeout)
|
97
|
-
new({browser_name: 'firefox', marionette: true}.merge(opts))
|
98
|
-
end
|
99
|
-
|
100
|
-
def firefox_legacy(opts = {})
|
101
|
+
WebDriver.logger.deprecate('Remote::Capabilities.firefox', 'Options.firefox', id: :caps_browsers)
|
101
102
|
new({
|
102
|
-
browser_name: 'firefox'
|
103
|
-
javascript_enabled: true,
|
104
|
-
takes_screenshot: true,
|
105
|
-
css_selectors_enabled: true
|
103
|
+
browser_name: 'firefox'
|
106
104
|
}.merge(opts))
|
107
105
|
end
|
106
|
+
alias ff firefox
|
108
107
|
|
109
|
-
def
|
108
|
+
def safari(opts = {})
|
109
|
+
WebDriver.logger.deprecate('Remote::Capabilities.safari', 'Options.safari', id: :caps_browsers)
|
110
110
|
new({
|
111
|
-
browser_name: '
|
111
|
+
browser_name: Selenium::WebDriver::Safari.technology_preview? ? 'Safari Technology Preview' : 'safari'
|
112
112
|
}.merge(opts))
|
113
113
|
end
|
114
114
|
|
115
|
-
def
|
115
|
+
def htmlunit(opts = {})
|
116
|
+
WebDriver.logger.deprecate('Remote::Capabilities.htmlunit',
|
117
|
+
'as argument in constructor',
|
118
|
+
id: :caps_browsers)
|
116
119
|
new({
|
117
|
-
browser_name: 'htmlunit'
|
118
|
-
javascript_enabled: true
|
120
|
+
browser_name: 'htmlunit'
|
119
121
|
}.merge(opts))
|
120
122
|
end
|
121
123
|
|
122
124
|
def internet_explorer(opts = {})
|
125
|
+
WebDriver.logger.deprecate('Remote::Capabilities.ie', 'Options.ie', id: :caps_browsers)
|
123
126
|
new({
|
124
127
|
browser_name: 'internet explorer',
|
125
|
-
|
126
|
-
takes_screenshot: true,
|
127
|
-
css_selectors_enabled: true,
|
128
|
-
native_events: true
|
128
|
+
platform_name: :windows
|
129
129
|
}.merge(opts))
|
130
130
|
end
|
131
|
-
|
131
|
+
alias ie internet_explorer
|
132
132
|
|
133
|
-
def
|
134
|
-
|
135
|
-
new({
|
136
|
-
browser_name: 'phantomjs',
|
137
|
-
javascript_enabled: true,
|
138
|
-
takes_screenshot: true,
|
139
|
-
css_selectors_enabled: true
|
140
|
-
}.merge(opts))
|
133
|
+
def always_match(capabilities)
|
134
|
+
new(always_match: capabilities)
|
141
135
|
end
|
142
136
|
|
143
|
-
def
|
144
|
-
new(
|
145
|
-
browser_name: 'safari',
|
146
|
-
platform: :mac,
|
147
|
-
javascript_enabled: true,
|
148
|
-
takes_screenshot: true,
|
149
|
-
css_selectors_enabled: true
|
150
|
-
}.merge(opts))
|
137
|
+
def first_match(*capabilities)
|
138
|
+
new(first_match: capabilities)
|
151
139
|
end
|
152
140
|
|
153
141
|
#
|
@@ -156,41 +144,62 @@ module Selenium
|
|
156
144
|
|
157
145
|
def json_create(data)
|
158
146
|
data = data.dup
|
159
|
-
|
160
147
|
caps = new
|
161
|
-
|
162
|
-
caps
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
148
|
+
|
149
|
+
process_timeouts(caps, data.delete('timeouts'))
|
150
|
+
|
151
|
+
if data.key?('proxy')
|
152
|
+
proxy = data.delete('proxy')
|
153
|
+
caps.proxy = Proxy.json_create(proxy) unless proxy.nil? || proxy.empty?
|
154
|
+
end
|
155
|
+
|
156
|
+
# Remote Server Specific
|
157
|
+
if data.key?('webdriver.remote.sessionid')
|
158
|
+
caps[:remote_session_id] =
|
159
|
+
data.delete('webdriver.remote.sessionid')
|
160
|
+
end
|
161
|
+
|
162
|
+
KNOWN.each do |cap|
|
163
|
+
data_value = camel_case(cap)
|
164
|
+
caps[cap] = data.delete(data_value) if data.key?(data_value)
|
165
|
+
end
|
170
166
|
|
171
167
|
# any remaining pairs will be added as is, with no conversion
|
172
168
|
caps.merge!(data)
|
173
169
|
|
174
170
|
caps
|
175
171
|
end
|
172
|
+
|
173
|
+
def camel_case(str_or_sym)
|
174
|
+
str_or_sym.to_s.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
|
175
|
+
end
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
def process_timeouts(caps, timeouts)
|
180
|
+
return if timeouts.nil?
|
181
|
+
|
182
|
+
caps.implicit_timeout = timeouts['implicit']
|
183
|
+
caps.page_load_timeout = timeouts['pageLoad']
|
184
|
+
caps.script_timeout = timeouts['script']
|
185
|
+
end
|
176
186
|
end
|
177
187
|
|
178
188
|
#
|
179
|
-
# @
|
180
|
-
# @option :
|
181
|
-
# @option :
|
182
|
-
# @option :
|
183
|
-
# @option :
|
184
|
-
# @option :
|
185
|
-
# @option :native_events [Boolean] does this driver use native events?
|
186
|
-
# @option :proxy [Selenium::WebDriver::Proxy, Hash] proxy configuration
|
189
|
+
# @param [Hash] opts
|
190
|
+
# @option :browser_name [String] required browser name
|
191
|
+
# @option :browser_version [String] required browser version number
|
192
|
+
# @option :platform_name [Symbol] one of :any, :win, :mac, or :x
|
193
|
+
# @option :accept_insecure_certs [Boolean] does the driver accept insecure SSL certifications?
|
194
|
+
# @option :proxy [Selenium::WebDriver::Proxy, Hash] proxy configuration
|
187
195
|
#
|
188
196
|
# @api public
|
189
197
|
#
|
190
198
|
|
191
199
|
def initialize(opts = {})
|
192
|
-
@capabilities =
|
193
|
-
self.proxy
|
200
|
+
@capabilities = {}
|
201
|
+
self.proxy = opts.delete(:proxy) if opts[:proxy]
|
202
|
+
@capabilities.merge!(opts)
|
194
203
|
end
|
195
204
|
|
196
205
|
#
|
@@ -215,6 +224,10 @@ module Selenium
|
|
215
224
|
end
|
216
225
|
end
|
217
226
|
|
227
|
+
def proxy
|
228
|
+
@capabilities[:proxy]
|
229
|
+
end
|
230
|
+
|
218
231
|
def proxy=(proxy)
|
219
232
|
case proxy
|
220
233
|
when Hash
|
@@ -226,37 +239,46 @@ module Selenium
|
|
226
239
|
end
|
227
240
|
end
|
228
241
|
|
242
|
+
def timeouts
|
243
|
+
@capabilities[:timeouts] ||= {}
|
244
|
+
end
|
245
|
+
|
246
|
+
def timeouts=(timeouts)
|
247
|
+
@capabilities[:timeouts] = timeouts
|
248
|
+
end
|
249
|
+
|
250
|
+
def implicit_timeout
|
251
|
+
timeouts[:implicit]
|
252
|
+
end
|
253
|
+
|
254
|
+
def implicit_timeout=(timeout)
|
255
|
+
timeouts[:implicit] = timeout
|
256
|
+
end
|
257
|
+
|
258
|
+
def page_load_timeout
|
259
|
+
timeouts[:page_load] || timeouts[:pageLoad]
|
260
|
+
end
|
261
|
+
|
262
|
+
def page_load_timeout=(timeout)
|
263
|
+
timeouts[:page_load] = timeout
|
264
|
+
end
|
265
|
+
|
266
|
+
def script_timeout
|
267
|
+
timeouts[:script]
|
268
|
+
end
|
269
|
+
|
270
|
+
def script_timeout=(timeout)
|
271
|
+
timeouts[:script] = timeout
|
272
|
+
end
|
273
|
+
|
229
274
|
#
|
230
275
|
# @api private
|
231
276
|
#
|
232
277
|
|
233
|
-
def as_json(*)
|
234
|
-
|
235
|
-
|
236
|
-
@capabilities.each do |key, value|
|
237
|
-
case key
|
238
|
-
when :platform
|
239
|
-
hash['platform'] = value.to_s.upcase
|
240
|
-
when :firefox_profile
|
241
|
-
if value
|
242
|
-
WebDriver.logger.deprecate(':firefox_profile capabilitiy', 'Selenium::WebDriver::Firefox::Options#profile')
|
243
|
-
hash['firefox_profile'] = value.as_json['zip']
|
244
|
-
end
|
245
|
-
when :proxy
|
246
|
-
hash['proxy'] = value.as_json if value
|
247
|
-
when String, :firefox_binary
|
248
|
-
if key == :firefox_binary && value
|
249
|
-
WebDriver.logger.deprecate(':firefox_binary capabilitiy', 'Selenium::WebDriver::Firefox::Options#binary')
|
250
|
-
end
|
251
|
-
hash[key.to_s] = value
|
252
|
-
when Symbol
|
253
|
-
hash[camel_case(key.to_s)] = value
|
254
|
-
else
|
255
|
-
raise TypeError, "expected String or Symbol, got #{key.inspect}:#{key.class} / #{value.inspect}"
|
256
|
-
end
|
278
|
+
def as_json(*)
|
279
|
+
@capabilities.each_with_object({}) do |(key, value), hash|
|
280
|
+
hash[convert_key(key)] = process_capabilities(key, value, hash)
|
257
281
|
end
|
258
|
-
|
259
|
-
hash
|
260
282
|
end
|
261
283
|
|
262
284
|
def to_json(*)
|
@@ -268,7 +290,8 @@ module Selenium
|
|
268
290
|
|
269
291
|
as_json == other.as_json
|
270
292
|
end
|
271
|
-
|
293
|
+
|
294
|
+
alias eql? ==
|
272
295
|
|
273
296
|
protected
|
274
297
|
|
@@ -276,8 +299,43 @@ module Selenium
|
|
276
299
|
|
277
300
|
private
|
278
301
|
|
279
|
-
def
|
280
|
-
|
302
|
+
def process_capabilities(key, value, hash)
|
303
|
+
case value
|
304
|
+
when Array
|
305
|
+
value.map { |v| process_capabilities(key, v, hash) }
|
306
|
+
when Hash
|
307
|
+
value.each_with_object({}) do |(k, v), h|
|
308
|
+
h[convert_key(k)] = process_capabilities(k, v, h)
|
309
|
+
end
|
310
|
+
when Capabilities, Options
|
311
|
+
value.as_json
|
312
|
+
else
|
313
|
+
convert_value(key, value)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def convert_key(key)
|
318
|
+
case key
|
319
|
+
when String
|
320
|
+
key.to_s
|
321
|
+
when Symbol
|
322
|
+
self.class.camel_case(key)
|
323
|
+
else
|
324
|
+
raise TypeError, "expected String or Symbol, got #{key.inspect}:#{key.class}"
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def convert_value(key, value)
|
329
|
+
case key
|
330
|
+
when :platform
|
331
|
+
value.to_s.upcase
|
332
|
+
when :proxy
|
333
|
+
value&.as_json
|
334
|
+
when :unhandled_prompt_behavior
|
335
|
+
value.is_a?(Symbol) ? value.to_s.tr('_', ' ') : value
|
336
|
+
else
|
337
|
+
value
|
338
|
+
end
|
281
339
|
end
|
282
340
|
end # Capabilities
|
283
341
|
end # Remote
|
@@ -20,7 +20,6 @@
|
|
20
20
|
module Selenium
|
21
21
|
module WebDriver
|
22
22
|
module Remote
|
23
|
-
|
24
23
|
#
|
25
24
|
# Driver implementation for remote server.
|
26
25
|
# @api private
|
@@ -28,23 +27,39 @@ module Selenium
|
|
28
27
|
|
29
28
|
class Driver < WebDriver::Driver
|
30
29
|
include DriverExtensions::UploadsFiles
|
31
|
-
include DriverExtensions::TakesScreenshot
|
32
30
|
include DriverExtensions::HasSessionId
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
31
|
+
|
32
|
+
def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
|
33
|
+
raise ArgumentError, "Can not set :service object on #{self.class}" if service
|
34
|
+
|
35
|
+
url ||= "http://#{Platform.localhost}:4444/wd/hub"
|
36
|
+
caps = process_options(options, capabilities)
|
37
|
+
super(caps: caps, url: url, **opts)
|
38
|
+
@bridge.file_detector = ->((filename, *)) { File.exist?(filename) && filename.to_s }
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def devtools_url
|
44
|
+
capabilities['se:cdp']
|
45
|
+
end
|
46
|
+
|
47
|
+
def devtools_version
|
48
|
+
cdp_version = capabilities['se:cdpVersion']&.split('.')&.first
|
49
|
+
raise Error::WebDriverError, 'DevTools is not supported by the Remote Server' unless cdp_version
|
50
|
+
|
51
|
+
Integer(cdp_version)
|
46
52
|
end
|
47
53
|
|
54
|
+
def process_options(options, capabilities)
|
55
|
+
if options && capabilities
|
56
|
+
msg = "Don't use both :options and :capabilities when initializing #{self.class}, prefer :options"
|
57
|
+
raise ArgumentError, msg
|
58
|
+
elsif options.nil? && capabilities.nil?
|
59
|
+
raise ArgumentError, "#{self.class} needs :options to be set"
|
60
|
+
end
|
61
|
+
options ? options.as_json : generate_capabilities(capabilities)
|
62
|
+
end
|
48
63
|
end # Driver
|
49
64
|
end # Remote
|
50
65
|
end # WebDriver
|
@@ -30,13 +30,8 @@ module Selenium
|
|
30
30
|
'User-Agent' => "selenium/#{WebDriver::VERSION} (ruby #{Platform.os})"
|
31
31
|
}.freeze
|
32
32
|
|
33
|
-
attr_accessor :timeout
|
34
33
|
attr_writer :server_url
|
35
34
|
|
36
|
-
def initialize
|
37
|
-
@timeout = nil
|
38
|
-
end
|
39
|
-
|
40
35
|
def quit_errors
|
41
36
|
[IOError]
|
42
37
|
end
|
@@ -54,8 +49,8 @@ module Selenium
|
|
54
49
|
payload = JSON.generate(command_hash)
|
55
50
|
headers['Content-Length'] = payload.bytesize.to_s if %i[post put].include?(verb)
|
56
51
|
|
57
|
-
WebDriver.logger.
|
58
|
-
WebDriver.logger.debug(" > #{headers.inspect}")
|
52
|
+
WebDriver.logger.debug(" >>> #{url} | #{payload}", id: :command)
|
53
|
+
WebDriver.logger.debug(" > #{headers.inspect}", id: :header)
|
59
54
|
elsif verb == :post
|
60
55
|
payload = '{}'
|
61
56
|
headers['Content-Length'] = '2'
|
@@ -80,7 +75,7 @@ module Selenium
|
|
80
75
|
code = code.to_i
|
81
76
|
body = body.to_s.strip
|
82
77
|
content_type = content_type.to_s
|
83
|
-
WebDriver.logger.
|
78
|
+
WebDriver.logger.debug("<- #{body}", id: :command)
|
84
79
|
|
85
80
|
if content_type.include? CONTENT_TYPE
|
86
81
|
raise Error::WebDriverError, "empty body: #{content_type.inspect} (#{code})\n#{body}" if body.empty?
|
@@ -22,7 +22,6 @@ require 'curb'
|
|
22
22
|
module Selenium
|
23
23
|
module WebDriver
|
24
24
|
module Remote
|
25
|
-
|
26
25
|
module Http
|
27
26
|
#
|
28
27
|
# An alternative to the default Net::HTTP client.
|
@@ -38,7 +37,6 @@ module Selenium
|
|
38
37
|
#
|
39
38
|
|
40
39
|
class Curb < Common
|
41
|
-
|
42
40
|
def quit_errors
|
43
41
|
[Curl::Err::RecvError] + super
|
44
42
|
end
|
@@ -85,7 +83,7 @@ module Selenium
|
|
85
83
|
c.max_redirects = MAX_REDIRECTS
|
86
84
|
c.follow_location = true
|
87
85
|
c.timeout = @timeout if @timeout
|
88
|
-
c.verbose = WebDriver.logger.
|
86
|
+
c.verbose = WebDriver.logger.debug?
|
89
87
|
|
90
88
|
c
|
91
89
|
end
|
@@ -28,8 +28,7 @@ module Selenium
|
|
28
28
|
class Default < Common
|
29
29
|
attr_writer :proxy
|
30
30
|
|
31
|
-
attr_accessor :open_timeout
|
32
|
-
attr_accessor :read_timeout
|
31
|
+
attr_accessor :open_timeout, :read_timeout
|
33
32
|
|
34
33
|
# Initializes object.
|
35
34
|
# Warning: Setting {#open_timeout} to non-nil values will cause a separate thread to spawn.
|
@@ -39,15 +38,7 @@ module Selenium
|
|
39
38
|
def initialize(open_timeout: nil, read_timeout: nil)
|
40
39
|
@open_timeout = open_timeout
|
41
40
|
@read_timeout = read_timeout
|
42
|
-
|
43
|
-
|
44
|
-
# Maintaining backward compatibility.
|
45
|
-
# @param [Numeric] value - Timeout in seconds to apply to both open timeout and read timeouts.
|
46
|
-
# @deprecated Please set the specific desired timeout {#read_timeout} or {#open_timeout} directly.
|
47
|
-
def timeout=(value)
|
48
|
-
WebDriver.logger.deprecate ':timeout=', '#read_timeout= and #open_timeout='
|
49
|
-
self.open_timeout = value
|
50
|
-
self.read_timeout = value
|
41
|
+
super()
|
51
42
|
end
|
52
43
|
|
53
44
|
def close
|
@@ -64,14 +55,18 @@ module Selenium
|
|
64
55
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
65
56
|
end
|
66
57
|
|
67
|
-
|
68
|
-
http.open_timeout = open_timeout
|
58
|
+
http.open_timeout = open_timeout if open_timeout
|
69
59
|
http.read_timeout = read_timeout if read_timeout
|
70
60
|
|
71
|
-
http
|
61
|
+
start(http)
|
62
|
+
http
|
72
63
|
end
|
73
64
|
end
|
74
65
|
|
66
|
+
def start(http)
|
67
|
+
http.start
|
68
|
+
end
|
69
|
+
|
75
70
|
MAX_RETRIES = 3
|
76
71
|
|
77
72
|
def request(verb, url, headers, payload, redirects = 0)
|
@@ -80,9 +75,10 @@ module Selenium
|
|
80
75
|
begin
|
81
76
|
request = new_request_for(verb, url, headers, payload)
|
82
77
|
response = response_for(request)
|
83
|
-
rescue Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EADDRINUSE
|
84
|
-
# a retry is sometimes needed
|
85
|
-
# run out of ephemeral ports
|
78
|
+
rescue Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EADDRINUSE, Errno::EADDRNOTAVAIL
|
79
|
+
# a retry is sometimes needed:
|
80
|
+
# on Windows XP where we may quickly run out of ephemeral ports
|
81
|
+
# when the port becomes temporarily unavailable
|
86
82
|
#
|
87
83
|
# A more robust solution is bumping the MaxUserPort setting
|
88
84
|
# as described here:
|
@@ -93,15 +89,8 @@ module Selenium
|
|
93
89
|
retries += 1
|
94
90
|
sleep 2
|
95
91
|
retry
|
96
|
-
rescue Errno::
|
97
|
-
|
98
|
-
raise if retries >= MAX_RETRIES
|
99
|
-
|
100
|
-
retries += 1
|
101
|
-
sleep 2
|
102
|
-
retry
|
103
|
-
rescue Errno::ECONNREFUSED => ex
|
104
|
-
raise ex.class, "using proxy: #{proxy.http}" if use_proxy?
|
92
|
+
rescue Errno::ECONNREFUSED => e
|
93
|
+
raise e.class, "using proxy: #{proxy.http}" if use_proxy?
|
105
94
|
|
106
95
|
raise
|
107
96
|
end
|
@@ -111,6 +100,7 @@ module Selenium
|
|
111
100
|
|
112
101
|
request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil, redirects + 1)
|
113
102
|
else
|
103
|
+
WebDriver.logger.debug(" <<< #{response.instance_variable_get(:@header).inspect}", id: :header)
|
114
104
|
create_response response.code, response.body, response.content_type
|
115
105
|
end
|
116
106
|
end
|
@@ -132,12 +122,14 @@ module Selenium
|
|
132
122
|
def new_http_client
|
133
123
|
if use_proxy?
|
134
124
|
url = @proxy.http
|
135
|
-
|
125
|
+
unless proxy.respond_to?(:http) && url
|
126
|
+
raise Error::WebDriverError,
|
127
|
+
"expected HTTP proxy, got #{@proxy.inspect}"
|
128
|
+
end
|
136
129
|
|
137
130
|
proxy = URI.parse(url)
|
138
131
|
|
139
|
-
|
140
|
-
clazz.new(server_url.host, server_url.port)
|
132
|
+
Net::HTTP.new(server_url.host, server_url.port, proxy.host, proxy.port, proxy.user, proxy.password)
|
141
133
|
else
|
142
134
|
Net::HTTP.new server_url.host, server_url.port
|
143
135
|
end
|
@@ -145,8 +137,8 @@ module Selenium
|
|
145
137
|
|
146
138
|
def proxy
|
147
139
|
@proxy ||= begin
|
148
|
-
proxy = ENV
|
149
|
-
no_proxy = ENV
|
140
|
+
proxy = ENV.fetch('http_proxy', nil) || ENV.fetch('HTTP_PROXY', nil)
|
141
|
+
no_proxy = ENV.fetch('no_proxy', nil) || ENV.fetch('NO_PROXY', nil)
|
150
142
|
|
151
143
|
if proxy
|
152
144
|
proxy = "http://#{proxy}" unless proxy.start_with?('http://')
|