selenium-webdriver 4.0.0.alpha3 → 4.0.0.beta1
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 +160 -5
- data/LICENSE +1 -1
- data/README.md +4 -5
- data/lib/selenium/server.rb +19 -27
- data/lib/selenium/webdriver.rb +3 -3
- data/lib/selenium/webdriver/atoms/findElements.js +123 -0
- data/lib/selenium/webdriver/atoms/getAttribute.js +104 -7
- data/lib/selenium/webdriver/atoms/isDisplayed.js +76 -78
- data/lib/selenium/webdriver/atoms/mutationListener.js +38 -0
- data/lib/selenium/webdriver/chrome.rb +4 -2
- data/lib/selenium/webdriver/chrome/bridge.rb +4 -6
- data/lib/selenium/webdriver/chrome/driver.rb +19 -17
- data/lib/selenium/webdriver/chrome/features.rb +66 -0
- data/lib/selenium/webdriver/chrome/options.rb +55 -38
- data/lib/selenium/webdriver/chrome/profile.rb +1 -1
- data/lib/selenium/webdriver/chrome/service.rb +1 -5
- data/lib/selenium/webdriver/common.rb +7 -2
- data/lib/selenium/webdriver/common/driver.rb +84 -21
- data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +89 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +38 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -8
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +149 -0
- data/lib/selenium/webdriver/{edge_chrome/bridge.rb → common/driver_extensions/has_logs.rb} +7 -7
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +4 -27
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +1 -0
- data/lib/selenium/webdriver/common/driver_extensions/prints_page.rb +32 -0
- data/lib/selenium/webdriver/common/element.rb +5 -0
- data/lib/selenium/webdriver/common/logger.rb +48 -16
- data/lib/selenium/webdriver/common/manager.rb +11 -1
- data/lib/selenium/webdriver/common/options.rb +53 -12
- data/lib/selenium/webdriver/common/platform.rb +6 -1
- data/lib/selenium/webdriver/common/port_prober.rb +4 -6
- data/lib/selenium/webdriver/common/proxy.rb +0 -0
- data/lib/selenium/webdriver/common/search_context.rb +3 -2
- data/lib/selenium/webdriver/common/service.rb +12 -127
- data/lib/selenium/webdriver/common/service_manager.rb +151 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +2 -2
- data/lib/selenium/webdriver/common/takes_screenshot.rb +63 -0
- data/lib/selenium/webdriver/common/target_locator.rb +4 -4
- data/lib/selenium/webdriver/common/wait.rb +1 -1
- data/lib/selenium/webdriver/devtools.rb +135 -0
- data/lib/selenium/webdriver/devtools/console_event.rb +38 -0
- data/lib/selenium/webdriver/devtools/exception_event.rb +36 -0
- data/lib/selenium/webdriver/devtools/mutation_event.rb +37 -0
- data/lib/selenium/webdriver/devtools/v85/accessibility.rb +64 -0
- data/lib/selenium/webdriver/devtools/v85/animation.rb +100 -0
- data/lib/selenium/webdriver/devtools/v85/application_cache.rb +66 -0
- data/lib/selenium/webdriver/devtools/v85/audits.rb +63 -0
- data/lib/selenium/webdriver/devtools/v85/background_service.rb +69 -0
- data/lib/selenium/webdriver/devtools/v85/browser.rb +125 -0
- data/lib/selenium/webdriver/devtools/v85/cache_storage.rb +75 -0
- data/lib/selenium/webdriver/devtools/v85/cast.rb +72 -0
- data/lib/selenium/webdriver/devtools/v85/console.rb +59 -0
- data/lib/selenium/webdriver/devtools/v85/css.rb +167 -0
- data/lib/selenium/webdriver/devtools/v85/database.rb +66 -0
- data/lib/selenium/webdriver/devtools/v85/debugger.rb +231 -0
- data/lib/selenium/webdriver/devtools/v85/device_orientation.rb +55 -0
- data/lib/selenium/webdriver/devtools/v85/dom.rb +322 -0
- data/lib/selenium/webdriver/devtools/v85/dom_debugger.rb +95 -0
- data/lib/selenium/webdriver/devtools/v85/dom_snapshot.rb +67 -0
- data/lib/selenium/webdriver/devtools/v85/dom_storage.rb +81 -0
- data/lib/selenium/webdriver/devtools/v85/emulation.rb +182 -0
- data/lib/selenium/webdriver/devtools/v85/fetch.rb +99 -0
- data/lib/selenium/webdriver/devtools/v85/headless_experimental.rb +63 -0
- data/lib/selenium/webdriver/devtools/v85/heap_profiler.rb +109 -0
- data/lib/selenium/webdriver/devtools/v85/indexed_db.rb +102 -0
- data/lib/selenium/webdriver/devtools/v85/input.rb +143 -0
- data/lib/selenium/webdriver/devtools/v85/inspector.rb +57 -0
- data/lib/selenium/webdriver/devtools/v85/io.rb +61 -0
- data/lib/selenium/webdriver/devtools/v85/layer_tree.rb +97 -0
- data/lib/selenium/webdriver/devtools/v85/log.rb +68 -0
- data/lib/selenium/webdriver/devtools/v85/media.rb +59 -0
- data/lib/selenium/webdriver/devtools/v85/memory.rb +88 -0
- data/lib/selenium/webdriver/devtools/v85/network.rb +230 -0
- data/lib/selenium/webdriver/devtools/v85/overlay.rb +160 -0
- data/lib/selenium/webdriver/devtools/v85/page.rb +376 -0
- data/lib/selenium/webdriver/devtools/v85/performance.rb +65 -0
- data/lib/selenium/webdriver/devtools/v85/profiler.rb +113 -0
- data/lib/selenium/webdriver/devtools/v85/runtime.rb +196 -0
- data/lib/selenium/webdriver/devtools/v85/schema.rb +48 -0
- data/lib/selenium/webdriver/devtools/v85/security.rb +73 -0
- data/lib/selenium/webdriver/devtools/v85/service_worker.rb +118 -0
- data/lib/selenium/webdriver/devtools/v85/storage.rb +97 -0
- data/lib/selenium/webdriver/devtools/v85/system_info.rb +52 -0
- data/lib/selenium/webdriver/devtools/v85/target.rb +145 -0
- data/lib/selenium/webdriver/devtools/v85/tethering.rb +57 -0
- data/lib/selenium/webdriver/devtools/v85/tracing.rb +78 -0
- data/lib/selenium/webdriver/devtools/v85/web_audio.rb +72 -0
- data/lib/selenium/webdriver/devtools/v85/web_authn.rb +96 -0
- data/lib/selenium/webdriver/devtools/v86/accessibility.rb +64 -0
- data/lib/selenium/webdriver/devtools/v86/animation.rb +100 -0
- data/lib/selenium/webdriver/devtools/v86/application_cache.rb +66 -0
- data/lib/selenium/webdriver/devtools/v86/audits.rb +63 -0
- data/lib/selenium/webdriver/devtools/v86/background_service.rb +69 -0
- data/lib/selenium/webdriver/devtools/v86/browser.rb +125 -0
- data/lib/selenium/webdriver/devtools/v86/cache_storage.rb +75 -0
- data/lib/selenium/webdriver/devtools/v86/cast.rb +72 -0
- data/lib/selenium/webdriver/devtools/v86/console.rb +59 -0
- data/lib/selenium/webdriver/devtools/v86/css.rb +181 -0
- data/lib/selenium/webdriver/devtools/v86/database.rb +66 -0
- data/lib/selenium/webdriver/devtools/v86/debugger.rb +233 -0
- data/lib/selenium/webdriver/devtools/v86/device_orientation.rb +55 -0
- data/lib/selenium/webdriver/devtools/v86/dom.rb +329 -0
- data/lib/selenium/webdriver/devtools/v86/dom_debugger.rb +95 -0
- data/lib/selenium/webdriver/devtools/v86/dom_snapshot.rb +67 -0
- data/lib/selenium/webdriver/devtools/v86/dom_storage.rb +81 -0
- data/lib/selenium/webdriver/devtools/v86/emulation.rb +193 -0
- data/lib/selenium/webdriver/devtools/v86/fetch.rb +99 -0
- data/lib/selenium/webdriver/devtools/v86/headless_experimental.rb +63 -0
- data/lib/selenium/webdriver/devtools/v86/heap_profiler.rb +109 -0
- data/lib/selenium/webdriver/devtools/v86/indexed_db.rb +102 -0
- data/lib/selenium/webdriver/devtools/v86/input.rb +143 -0
- data/lib/selenium/webdriver/devtools/v86/inspector.rb +57 -0
- data/lib/selenium/webdriver/devtools/v86/io.rb +61 -0
- data/lib/selenium/webdriver/devtools/v86/layer_tree.rb +97 -0
- data/lib/selenium/webdriver/devtools/v86/log.rb +68 -0
- data/lib/selenium/webdriver/devtools/v86/media.rb +59 -0
- data/lib/selenium/webdriver/devtools/v86/memory.rb +88 -0
- data/lib/selenium/webdriver/devtools/v86/network.rb +235 -0
- data/lib/selenium/webdriver/devtools/v86/overlay.rb +183 -0
- data/lib/selenium/webdriver/devtools/v86/page.rb +376 -0
- data/lib/selenium/webdriver/devtools/v86/performance.rb +65 -0
- data/lib/selenium/webdriver/devtools/v86/profiler.rb +113 -0
- data/lib/selenium/webdriver/devtools/v86/runtime.rb +196 -0
- data/lib/selenium/webdriver/devtools/v86/schema.rb +48 -0
- data/lib/selenium/webdriver/devtools/v86/security.rb +73 -0
- data/lib/selenium/webdriver/devtools/v86/service_worker.rb +118 -0
- data/lib/selenium/webdriver/devtools/v86/storage.rb +97 -0
- data/lib/selenium/webdriver/devtools/v86/system_info.rb +52 -0
- data/lib/selenium/webdriver/devtools/v86/target.rb +145 -0
- data/lib/selenium/webdriver/devtools/v86/tethering.rb +57 -0
- data/lib/selenium/webdriver/devtools/v86/tracing.rb +78 -0
- data/lib/selenium/webdriver/devtools/v86/web_audio.rb +72 -0
- data/lib/selenium/webdriver/devtools/v86/web_authn.rb +102 -0
- data/lib/selenium/webdriver/devtools/v87/accessibility.rb +73 -0
- data/lib/selenium/webdriver/devtools/v87/animation.rb +100 -0
- data/lib/selenium/webdriver/devtools/v87/application_cache.rb +66 -0
- data/lib/selenium/webdriver/devtools/v87/audits.rb +63 -0
- data/lib/selenium/webdriver/devtools/v87/background_service.rb +69 -0
- data/lib/selenium/webdriver/devtools/v87/browser.rb +125 -0
- data/lib/selenium/webdriver/devtools/v87/cache_storage.rb +75 -0
- data/lib/selenium/webdriver/devtools/v87/cast.rb +72 -0
- data/lib/selenium/webdriver/{edge_html/driver.rb → devtools/v87/console.rb} +36 -30
- data/lib/selenium/webdriver/devtools/v87/css.rb +181 -0
- data/lib/selenium/webdriver/devtools/v87/database.rb +66 -0
- data/lib/selenium/webdriver/devtools/v87/debugger.rb +233 -0
- data/lib/selenium/webdriver/devtools/v87/device_orientation.rb +55 -0
- data/lib/selenium/webdriver/devtools/v87/dom.rb +329 -0
- data/lib/selenium/webdriver/devtools/v87/dom_debugger.rb +95 -0
- data/lib/selenium/webdriver/devtools/v87/dom_snapshot.rb +67 -0
- data/lib/selenium/webdriver/devtools/v87/dom_storage.rb +81 -0
- data/lib/selenium/webdriver/devtools/v87/emulation.rb +193 -0
- data/lib/selenium/webdriver/devtools/v87/fetch.rb +99 -0
- data/lib/selenium/webdriver/devtools/v87/headless_experimental.rb +63 -0
- data/lib/selenium/webdriver/devtools/v87/heap_profiler.rb +109 -0
- data/lib/selenium/webdriver/devtools/v87/indexed_db.rb +102 -0
- data/lib/selenium/webdriver/devtools/v87/input.rb +143 -0
- data/lib/selenium/webdriver/devtools/v87/inspector.rb +57 -0
- data/lib/selenium/webdriver/devtools/v87/io.rb +61 -0
- data/lib/selenium/webdriver/devtools/v87/layer_tree.rb +97 -0
- data/lib/selenium/webdriver/devtools/v87/log.rb +68 -0
- data/lib/selenium/webdriver/devtools/v87/media.rb +59 -0
- data/lib/selenium/webdriver/devtools/v87/memory.rb +88 -0
- data/lib/selenium/webdriver/devtools/v87/network.rb +247 -0
- data/lib/selenium/webdriver/devtools/v87/overlay.rb +183 -0
- data/lib/selenium/webdriver/devtools/v87/page.rb +376 -0
- data/lib/selenium/webdriver/devtools/v87/performance.rb +65 -0
- data/lib/selenium/webdriver/devtools/v87/profiler.rb +125 -0
- data/lib/selenium/webdriver/devtools/v87/runtime.rb +196 -0
- data/lib/selenium/webdriver/devtools/v87/schema.rb +48 -0
- data/lib/selenium/webdriver/devtools/v87/security.rb +73 -0
- data/lib/selenium/webdriver/devtools/v87/service_worker.rb +118 -0
- data/lib/selenium/webdriver/devtools/v87/storage.rb +97 -0
- data/lib/selenium/webdriver/devtools/v87/system_info.rb +52 -0
- data/lib/selenium/webdriver/devtools/v87/target.rb +145 -0
- data/lib/selenium/webdriver/devtools/v87/tethering.rb +57 -0
- data/lib/selenium/webdriver/devtools/v87/tracing.rb +78 -0
- data/lib/selenium/webdriver/devtools/v87/web_audio.rb +72 -0
- data/lib/selenium/webdriver/devtools/v87/web_authn.rb +102 -0
- data/lib/selenium/webdriver/devtools/v88/accessibility.rb +73 -0
- data/lib/selenium/webdriver/devtools/v88/animation.rb +100 -0
- data/lib/selenium/webdriver/devtools/v88/application_cache.rb +66 -0
- data/lib/selenium/webdriver/devtools/v88/audits.rb +63 -0
- data/lib/selenium/webdriver/devtools/v88/background_service.rb +69 -0
- data/lib/selenium/webdriver/devtools/v88/browser.rb +130 -0
- data/lib/selenium/webdriver/devtools/v88/cache_storage.rb +75 -0
- data/lib/selenium/webdriver/devtools/v88/cast.rb +72 -0
- data/lib/selenium/webdriver/devtools/v88/console.rb +59 -0
- data/lib/selenium/webdriver/devtools/v88/css.rb +181 -0
- data/lib/selenium/webdriver/devtools/v88/database.rb +66 -0
- data/lib/selenium/webdriver/devtools/v88/debugger.rb +233 -0
- data/lib/selenium/webdriver/devtools/v88/device_orientation.rb +55 -0
- data/lib/selenium/webdriver/devtools/v88/dom.rb +329 -0
- data/lib/selenium/webdriver/devtools/v88/dom_debugger.rb +95 -0
- data/lib/selenium/webdriver/devtools/v88/dom_snapshot.rb +67 -0
- data/lib/selenium/webdriver/devtools/v88/dom_storage.rb +81 -0
- data/lib/selenium/webdriver/devtools/v88/emulation.rb +198 -0
- data/lib/selenium/webdriver/devtools/v88/fetch.rb +99 -0
- data/lib/selenium/webdriver/devtools/v88/headless_experimental.rb +63 -0
- data/lib/selenium/webdriver/devtools/v88/heap_profiler.rb +109 -0
- data/lib/selenium/webdriver/devtools/v88/indexed_db.rb +102 -0
- data/lib/selenium/webdriver/devtools/v88/input.rb +148 -0
- data/lib/selenium/webdriver/devtools/v88/inspector.rb +57 -0
- data/lib/selenium/webdriver/devtools/v88/io.rb +61 -0
- data/lib/selenium/webdriver/devtools/v88/layer_tree.rb +97 -0
- data/lib/selenium/webdriver/devtools/v88/log.rb +68 -0
- data/lib/selenium/webdriver/devtools/v88/media.rb +59 -0
- data/lib/selenium/webdriver/devtools/v88/memory.rb +88 -0
- data/lib/selenium/webdriver/devtools/v88/network.rb +247 -0
- data/lib/selenium/webdriver/devtools/v88/overlay.rb +183 -0
- data/lib/selenium/webdriver/devtools/v88/page.rb +376 -0
- data/lib/selenium/webdriver/devtools/v88/performance.rb +65 -0
- data/lib/selenium/webdriver/devtools/v88/profiler.rb +125 -0
- data/lib/selenium/webdriver/devtools/v88/runtime.rb +197 -0
- data/lib/selenium/webdriver/devtools/v88/schema.rb +48 -0
- data/lib/selenium/webdriver/devtools/v88/security.rb +73 -0
- data/lib/selenium/webdriver/devtools/v88/service_worker.rb +118 -0
- data/lib/selenium/webdriver/devtools/v88/storage.rb +103 -0
- data/lib/selenium/webdriver/devtools/v88/system_info.rb +52 -0
- data/lib/selenium/webdriver/devtools/v88/target.rb +145 -0
- data/lib/selenium/webdriver/devtools/v88/tethering.rb +57 -0
- data/lib/selenium/webdriver/devtools/v88/tracing.rb +79 -0
- data/lib/selenium/webdriver/devtools/v88/web_audio.rb +72 -0
- data/lib/selenium/webdriver/devtools/v88/web_authn.rb +102 -0
- data/lib/selenium/webdriver/edge.rb +7 -27
- data/lib/selenium/webdriver/edge/bridge.rb +37 -0
- data/lib/selenium/webdriver/{edge_chrome → edge}/driver.rb +14 -4
- data/lib/selenium/webdriver/edge/features.rb +39 -0
- data/lib/selenium/webdriver/{edge_chrome → edge}/options.rb +12 -3
- data/lib/selenium/webdriver/{edge_chrome → edge}/profile.rb +2 -2
- data/lib/selenium/webdriver/{edge_chrome → edge}/service.rb +2 -6
- data/lib/selenium/webdriver/firefox.rb +10 -4
- data/lib/selenium/webdriver/firefox/bridge.rb +1 -1
- data/lib/selenium/webdriver/firefox/driver.rb +14 -14
- data/lib/selenium/webdriver/firefox/features.rb +47 -0
- data/lib/selenium/webdriver/firefox/options.rb +26 -29
- data/lib/selenium/webdriver/firefox/profile.rb +13 -76
- data/lib/selenium/webdriver/firefox/service.rb +1 -5
- data/lib/selenium/webdriver/ie.rb +4 -2
- data/lib/selenium/webdriver/ie/driver.rb +0 -16
- data/lib/selenium/webdriver/ie/options.rb +7 -20
- data/lib/selenium/webdriver/ie/service.rb +6 -10
- data/lib/selenium/webdriver/remote/bridge.rb +43 -67
- data/lib/selenium/webdriver/remote/capabilities.rb +13 -19
- data/lib/selenium/webdriver/remote/commands.rb +1 -0
- data/lib/selenium/webdriver/remote/driver.rb +10 -12
- data/lib/selenium/webdriver/remote/http/default.rb +6 -7
- data/lib/selenium/webdriver/remote/http/persistent.rb +6 -0
- data/lib/selenium/webdriver/safari.rb +11 -2
- data/lib/selenium/webdriver/safari/bridge.rb +1 -1
- data/lib/selenium/webdriver/safari/driver.rb +4 -17
- data/lib/selenium/webdriver/{common/driver_extensions/rotatable.rb → safari/features.rb} +26 -36
- data/lib/selenium/webdriver/safari/options.rb +1 -33
- data/lib/selenium/webdriver/safari/service.rb +0 -4
- data/lib/selenium/webdriver/support.rb +1 -0
- data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
- data/lib/selenium/webdriver/support/color.rb +2 -2
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +2 -2
- data/lib/selenium/webdriver/support/relative_locator.rb +51 -0
- data/lib/selenium/webdriver/version.rb +1 -1
- data/selenium-webdriver.gemspec +10 -7
- data/selenium_server_deploy.jar +0 -0
- metadata +254 -26
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -64
- data/lib/selenium/webdriver/edge_html/options.rb +0 -91
- data/lib/selenium/webdriver/edge_html/service.rb +0 -51
- data/lib/selenium/webdriver/firefox/binary.rb +0 -110
- data/lib/selenium/webdriver/firefox/extension/prefs.json +0 -69
|
@@ -36,6 +36,7 @@ module Selenium
|
|
|
36
36
|
# @option opts [String] :value A value
|
|
37
37
|
# @option opts [String] :path ('/') A path
|
|
38
38
|
# @option opts [String] :secure (false) A boolean
|
|
39
|
+
# @option opts [String] :same_site (Strict or Lax) currently supported only in chrome 80+ versions
|
|
39
40
|
# @option opts [Time,DateTime,Numeric,nil] :expires (nil) Expiry date, either as a Time, DateTime, or seconds since epoch.
|
|
40
41
|
#
|
|
41
42
|
# @raise [ArgumentError] if :name or :value is not specified
|
|
@@ -45,9 +46,15 @@ module Selenium
|
|
|
45
46
|
raise ArgumentError, 'name is required' unless opts[:name]
|
|
46
47
|
raise ArgumentError, 'value is required' unless opts[:value]
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
# NOTE: This is required because of https://bugs.chromium.org/p/chromedriver/issues/detail?id=3732
|
|
49
50
|
opts[:secure] ||= false
|
|
50
51
|
|
|
52
|
+
same_site = opts.delete(:same_site)
|
|
53
|
+
opts[:sameSite] = same_site if same_site
|
|
54
|
+
|
|
55
|
+
http_only = opts.delete(:http_only)
|
|
56
|
+
opts[:httpOnly] = http_only if http_only
|
|
57
|
+
|
|
51
58
|
obj = opts.delete(:expires)
|
|
52
59
|
opts[:expiry] = seconds_from(obj).to_i if obj
|
|
53
60
|
|
|
@@ -102,6 +109,7 @@ module Selenium
|
|
|
102
109
|
#
|
|
103
110
|
|
|
104
111
|
def logs
|
|
112
|
+
WebDriver.logger.deprecate('Manager#logs', 'Chrome::Driver#logs')
|
|
105
113
|
@logs ||= Logs.new(@bridge)
|
|
106
114
|
end
|
|
107
115
|
|
|
@@ -169,6 +177,8 @@ module Selenium
|
|
|
169
177
|
path: cookie['path'],
|
|
170
178
|
domain: cookie['domain'] && strip_port(cookie['domain']),
|
|
171
179
|
expires: cookie['expiry'] && datetime_at(cookie['expiry']),
|
|
180
|
+
same_site: cookie['sameSite'],
|
|
181
|
+
http_only: cookie['httpOnly'],
|
|
172
182
|
secure: cookie['secure']
|
|
173
183
|
}
|
|
174
184
|
end
|
|
@@ -20,16 +20,37 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
class Options
|
|
23
|
+
W3C_OPTIONS = %i[browser_name browser_version platform_name accept_insecure_certs page_load_strategy proxy
|
|
24
|
+
set_window_rect timeouts unhandled_prompt_behavior strict_file_interactability].freeze
|
|
25
|
+
|
|
26
|
+
def self.set_capabilities
|
|
27
|
+
(W3C_OPTIONS + self::CAPABILITIES.keys).each do |key|
|
|
28
|
+
next if method_defined? key
|
|
29
|
+
|
|
30
|
+
define_method key do
|
|
31
|
+
@options[key]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
define_method "#{key}=" do |value|
|
|
35
|
+
@options[key] = value
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
23
40
|
attr_accessor :options
|
|
24
41
|
|
|
25
42
|
def initialize(options: nil, **opts)
|
|
43
|
+
self.class.set_capabilities
|
|
44
|
+
|
|
26
45
|
@options = if options
|
|
27
46
|
WebDriver.logger.deprecate(":options as keyword for initializing #{self.class}",
|
|
28
|
-
"custom values directly in #new constructor"
|
|
47
|
+
"custom values directly in #new constructor",
|
|
48
|
+
id: :options_options)
|
|
29
49
|
opts.merge(options)
|
|
30
50
|
else
|
|
31
51
|
opts
|
|
32
52
|
end
|
|
53
|
+
@options[:browser_name] = self.class::BROWSER
|
|
33
54
|
end
|
|
34
55
|
|
|
35
56
|
#
|
|
@@ -54,22 +75,41 @@ module Selenium
|
|
|
54
75
|
def as_json(*)
|
|
55
76
|
options = @options.dup
|
|
56
77
|
|
|
57
|
-
|
|
78
|
+
w3c_options = options.select { |key, _val| W3C_OPTIONS.include?(key) }
|
|
79
|
+
options.delete_if { |key, _val| W3C_OPTIONS.include?(key) }
|
|
80
|
+
|
|
81
|
+
self.class::CAPABILITIES.each do |capability_alias, capability_name|
|
|
58
82
|
capability_value = options.delete(capability_alias)
|
|
59
|
-
|
|
83
|
+
options[capability_name] = capability_value unless capability_value.nil?
|
|
60
84
|
end
|
|
61
|
-
|
|
85
|
+
browser_options = defined?(self.class::KEY) ? {self.class::KEY => options} : options
|
|
86
|
+
|
|
87
|
+
process_browser_options(browser_options)
|
|
88
|
+
generate_as_json(w3c_options.merge(browser_options))
|
|
62
89
|
end
|
|
63
90
|
|
|
64
91
|
private
|
|
65
92
|
|
|
66
|
-
def
|
|
67
|
-
|
|
93
|
+
def process_browser_options(_browser_options)
|
|
94
|
+
nil
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def camelize?(_key)
|
|
98
|
+
true
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def generate_as_json(value, camelize_keys: true)
|
|
102
|
+
if value.is_a?(Hash)
|
|
103
|
+
value.each_with_object({}) do |(key, val), hash|
|
|
104
|
+
next if val.respond_to?(:empty?) && val.empty?
|
|
105
|
+
|
|
106
|
+
key = convert_json_key(key, camelize: camelize_keys)
|
|
107
|
+
hash[key] = generate_as_json(val, camelize_keys: camelize?(key))
|
|
108
|
+
end
|
|
109
|
+
elsif value.respond_to?(:as_json)
|
|
68
110
|
value.as_json
|
|
69
|
-
elsif value.is_a?(Hash)
|
|
70
|
-
value.each_with_object({}) { |(key, val), hash| hash[convert_json_key(key)] = generate_as_json(val) }
|
|
71
111
|
elsif value.is_a?(Array)
|
|
72
|
-
value.map(
|
|
112
|
+
value.map { |val| generate_as_json(val, camelize_keys: camelize_keys) }
|
|
73
113
|
elsif value.is_a?(Symbol)
|
|
74
114
|
value.to_s
|
|
75
115
|
else
|
|
@@ -77,15 +117,16 @@ module Selenium
|
|
|
77
117
|
end
|
|
78
118
|
end
|
|
79
119
|
|
|
80
|
-
def convert_json_key(key)
|
|
81
|
-
key =
|
|
120
|
+
def convert_json_key(key, camelize: true)
|
|
121
|
+
key = key.to_s if key.is_a?(Symbol)
|
|
122
|
+
key = camel_case(key) if camelize
|
|
82
123
|
return key if key.is_a?(String)
|
|
83
124
|
|
|
84
125
|
raise TypeError, "expected String or Symbol, got #{key.inspect}:#{key.class}"
|
|
85
126
|
end
|
|
86
127
|
|
|
87
128
|
def camel_case(str)
|
|
88
|
-
str.
|
|
129
|
+
str.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
|
|
89
130
|
end
|
|
90
131
|
end # Options
|
|
91
132
|
end # WebDriver
|
|
@@ -57,6 +57,8 @@ module Selenium
|
|
|
57
57
|
:jenkins
|
|
58
58
|
elsif ENV['APPVEYOR']
|
|
59
59
|
:appveyor
|
|
60
|
+
elsif ENV['GITHUB_ACTIONS']
|
|
61
|
+
:github
|
|
60
62
|
end
|
|
61
63
|
end
|
|
62
64
|
|
|
@@ -95,7 +97,10 @@ module Selenium
|
|
|
95
97
|
def wsl?
|
|
96
98
|
return false unless linux?
|
|
97
99
|
|
|
98
|
-
File.read('/proc/version').include?('
|
|
100
|
+
File.read('/proc/version').downcase.include?('microsoft')
|
|
101
|
+
rescue Errno::EACCES
|
|
102
|
+
# the file cannot be accessed on Linux on DeX
|
|
103
|
+
false
|
|
99
104
|
end
|
|
100
105
|
|
|
101
106
|
def cygwin?
|
|
@@ -32,12 +32,10 @@ module Selenium
|
|
|
32
32
|
|
|
33
33
|
def self.free?(port)
|
|
34
34
|
Platform.interfaces.each do |host|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
# ignored - some machines appear unable to bind to some of their interfaces
|
|
40
|
-
end
|
|
35
|
+
TCPServer.new(host, port).close
|
|
36
|
+
rescue *IGNORED_ERRORS => e
|
|
37
|
+
WebDriver.logger.debug("port prober could not bind to #{host}:#{port} (#{e.message})")
|
|
38
|
+
# ignored - some machines appear unable to bind to some of their interfaces
|
|
41
39
|
end
|
|
42
40
|
|
|
43
41
|
true
|
|
File without changes
|
|
@@ -30,6 +30,7 @@ module Selenium
|
|
|
30
30
|
link_text: 'link text',
|
|
31
31
|
name: 'name',
|
|
32
32
|
partial_link_text: 'partial link text',
|
|
33
|
+
relative: 'relative',
|
|
33
34
|
tag_name: 'tag name',
|
|
34
35
|
xpath: 'xpath'
|
|
35
36
|
}.freeze
|
|
@@ -59,7 +60,7 @@ module Selenium
|
|
|
59
60
|
by = FINDERS[how.to_sym]
|
|
60
61
|
raise ArgumentError, "cannot find element by #{how.inspect}" unless by
|
|
61
62
|
|
|
62
|
-
bridge.find_element_by by, what
|
|
63
|
+
bridge.find_element_by by, what, ref
|
|
63
64
|
rescue Selenium::WebDriver::Error::TimeoutError
|
|
64
65
|
# Implicit Wait times out in Edge
|
|
65
66
|
raise Selenium::WebDriver::Error::NoSuchElementError
|
|
@@ -77,7 +78,7 @@ module Selenium
|
|
|
77
78
|
by = FINDERS[how.to_sym]
|
|
78
79
|
raise ArgumentError, "cannot find elements by #{how.inspect}" unless by
|
|
79
80
|
|
|
80
|
-
bridge.find_elements_by by, what
|
|
81
|
+
bridge.find_elements_by by, what, ref
|
|
81
82
|
rescue Selenium::WebDriver::Error::TimeoutError
|
|
82
83
|
# Implicit Wait times out in Edge
|
|
83
84
|
[]
|
|
@@ -21,14 +21,10 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
#
|
|
23
23
|
# Base class implementing default behavior of service object,
|
|
24
|
-
# responsible for
|
|
24
|
+
# responsible for storing a service manager configuration.
|
|
25
25
|
#
|
|
26
26
|
|
|
27
27
|
class Service
|
|
28
|
-
START_TIMEOUT = 20
|
|
29
|
-
SOCKET_LOCK_TIMEOUT = 45
|
|
30
|
-
STOP_TIMEOUT = 20
|
|
31
|
-
|
|
32
28
|
class << self
|
|
33
29
|
attr_reader :driver_path
|
|
34
30
|
|
|
@@ -37,19 +33,6 @@ module Selenium
|
|
|
37
33
|
end
|
|
38
34
|
|
|
39
35
|
def firefox(**opts)
|
|
40
|
-
binary_path = Firefox::Binary.path
|
|
41
|
-
args = opts.delete(:args)
|
|
42
|
-
case args
|
|
43
|
-
when Hash
|
|
44
|
-
args[:binary] ||= binary_path
|
|
45
|
-
opts[:args] = args
|
|
46
|
-
when Array
|
|
47
|
-
opts[:args] = ["--binary=#{binary_path}"]
|
|
48
|
-
opts[:args] += args
|
|
49
|
-
else
|
|
50
|
-
opts[:args] = ["--binary=#{binary_path}"]
|
|
51
|
-
end
|
|
52
|
-
|
|
53
36
|
Firefox::Service.new(**opts)
|
|
54
37
|
end
|
|
55
38
|
|
|
@@ -62,14 +45,6 @@ module Selenium
|
|
|
62
45
|
Edge::Service.new(**opts)
|
|
63
46
|
end
|
|
64
47
|
|
|
65
|
-
def edge_chrome(**opts)
|
|
66
|
-
EdgeChrome::Service.new(**opts)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def edge_html(**opts)
|
|
70
|
-
EdgeHtml::Service.new(**opts)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
48
|
def safari(**opts)
|
|
74
49
|
Safari::Service.new(**opts)
|
|
75
50
|
end
|
|
@@ -81,7 +56,7 @@ module Selenium
|
|
|
81
56
|
end
|
|
82
57
|
|
|
83
58
|
attr_accessor :host
|
|
84
|
-
attr_reader :executable_path
|
|
59
|
+
attr_reader :executable_path, :port, :extra_args
|
|
85
60
|
|
|
86
61
|
#
|
|
87
62
|
# End users should use a class method for the desired driver, rather than using this directly.
|
|
@@ -103,31 +78,20 @@ module Selenium
|
|
|
103
78
|
raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1
|
|
104
79
|
end
|
|
105
80
|
|
|
106
|
-
def
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
socket_lock.locked do
|
|
112
|
-
find_free_port
|
|
113
|
-
start_process
|
|
114
|
-
connect_until_stable
|
|
115
|
-
end
|
|
81
|
+
def launch
|
|
82
|
+
sm = ServiceManager.new(self)
|
|
83
|
+
sm.start
|
|
84
|
+
sm
|
|
116
85
|
end
|
|
117
86
|
|
|
118
|
-
def
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
stop_server
|
|
122
|
-
@process.poll_for_exit STOP_TIMEOUT
|
|
123
|
-
rescue ChildProcess::TimeoutError
|
|
124
|
-
nil # noop
|
|
125
|
-
ensure
|
|
126
|
-
stop_process
|
|
87
|
+
def shutdown_supported
|
|
88
|
+
self.class::SHUTDOWN_SUPPORTED
|
|
127
89
|
end
|
|
128
90
|
|
|
129
|
-
|
|
130
|
-
|
|
91
|
+
protected
|
|
92
|
+
|
|
93
|
+
def extract_service_args(driver_opts)
|
|
94
|
+
driver_opts.key?(:args) ? driver_opts.delete(:args) : []
|
|
131
95
|
end
|
|
132
96
|
|
|
133
97
|
private
|
|
@@ -141,85 +105,6 @@ module Selenium
|
|
|
141
105
|
Platform.assert_executable path
|
|
142
106
|
path
|
|
143
107
|
end
|
|
144
|
-
|
|
145
|
-
def build_process(*command)
|
|
146
|
-
WebDriver.logger.debug("Executing Process #{command}")
|
|
147
|
-
@process = ChildProcess.build(*command)
|
|
148
|
-
if WebDriver.logger.debug?
|
|
149
|
-
@process.io.stdout = @process.io.stderr = WebDriver.logger.io
|
|
150
|
-
elsif Platform.jruby?
|
|
151
|
-
# Apparently we need to read the output of drivers on JRuby.
|
|
152
|
-
@process.io.stdout = @process.io.stderr = File.new(Platform.null_device, 'w')
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
@process
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def connect_to_server
|
|
159
|
-
Net::HTTP.start(@host, @port) do |http|
|
|
160
|
-
http.open_timeout = STOP_TIMEOUT / 2
|
|
161
|
-
http.read_timeout = STOP_TIMEOUT / 2
|
|
162
|
-
|
|
163
|
-
yield http
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def find_free_port
|
|
168
|
-
@port = PortProber.above(@port)
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def start_process
|
|
172
|
-
@process = build_process(@executable_path, "--port=#{@port}", *@extra_args)
|
|
173
|
-
# Note: this is a bug only in Windows 7
|
|
174
|
-
@process.leader = true unless Platform.windows?
|
|
175
|
-
@process.start
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def stop_process
|
|
179
|
-
return if process_exited?
|
|
180
|
-
|
|
181
|
-
@process.stop STOP_TIMEOUT
|
|
182
|
-
@process.io.stdout.close if Platform.jruby? && !WebDriver.logger.debug?
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
def stop_server
|
|
186
|
-
return if process_exited?
|
|
187
|
-
|
|
188
|
-
connect_to_server do |http|
|
|
189
|
-
headers = WebDriver::Remote::Http::Common::DEFAULT_HEADERS.dup
|
|
190
|
-
http.get('/shutdown', headers)
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
def process_running?
|
|
195
|
-
defined?(@process) && @process&.alive?
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
def process_exited?
|
|
199
|
-
@process.nil? || @process.exited?
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
def connect_until_stable
|
|
203
|
-
socket_poller = SocketPoller.new @host, @port, START_TIMEOUT
|
|
204
|
-
return if socket_poller.connected?
|
|
205
|
-
|
|
206
|
-
raise Error::WebDriverError, cannot_connect_error_text
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def cannot_connect_error_text
|
|
210
|
-
"unable to connect to #{self.class::EXECUTABLE} #{@host}:#{@port}"
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def socket_lock
|
|
214
|
-
@socket_lock ||= SocketLock.new(@port - 1, SOCKET_LOCK_TIMEOUT)
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
protected
|
|
218
|
-
|
|
219
|
-
def extract_service_args(driver_opts)
|
|
220
|
-
driver_opts.key?(:args) ? driver_opts.delete(:args) : []
|
|
221
|
-
end
|
|
222
|
-
|
|
223
108
|
end # Service
|
|
224
109
|
end # WebDriver
|
|
225
110
|
end # Selenium
|
|
@@ -0,0 +1,151 @@
|
|
|
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
|
+
#
|
|
23
|
+
# Base class implementing default behavior of service_manager object,
|
|
24
|
+
# responsible for starting and stopping driver implementations.
|
|
25
|
+
#
|
|
26
|
+
# @api private
|
|
27
|
+
#
|
|
28
|
+
class ServiceManager
|
|
29
|
+
START_TIMEOUT = 20
|
|
30
|
+
SOCKET_LOCK_TIMEOUT = 45
|
|
31
|
+
STOP_TIMEOUT = 20
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# End users should use a class method for the desired driver, rather than using this directly.
|
|
35
|
+
#
|
|
36
|
+
# @api private
|
|
37
|
+
#
|
|
38
|
+
|
|
39
|
+
def initialize(config)
|
|
40
|
+
@executable_path = config.executable_path
|
|
41
|
+
@host = Platform.localhost
|
|
42
|
+
@port = config.port
|
|
43
|
+
@extra_args = config.extra_args
|
|
44
|
+
@shutdown_supported = config.shutdown_supported
|
|
45
|
+
|
|
46
|
+
raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def start
|
|
50
|
+
raise "already started: #{uri.inspect} #{@executable_path.inspect}" if process_running?
|
|
51
|
+
|
|
52
|
+
Platform.exit_hook(&method(:stop)) # make sure we don't leave the server running
|
|
53
|
+
|
|
54
|
+
socket_lock.locked do
|
|
55
|
+
find_free_port
|
|
56
|
+
start_process
|
|
57
|
+
connect_until_stable
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def stop
|
|
62
|
+
return unless @shutdown_supported
|
|
63
|
+
|
|
64
|
+
stop_server
|
|
65
|
+
@process.poll_for_exit STOP_TIMEOUT
|
|
66
|
+
rescue ChildProcess::TimeoutError
|
|
67
|
+
nil # noop
|
|
68
|
+
ensure
|
|
69
|
+
stop_process
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def uri
|
|
73
|
+
@uri ||= URI.parse("http://#{@host}:#{@port}")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def build_process(*command)
|
|
79
|
+
WebDriver.logger.debug("Executing Process #{command}")
|
|
80
|
+
@process = ChildProcess.build(*command)
|
|
81
|
+
if WebDriver.logger.debug?
|
|
82
|
+
@process.io.stdout = @process.io.stderr = WebDriver.logger.io
|
|
83
|
+
elsif Platform.jruby?
|
|
84
|
+
# Apparently we need to read the output of drivers on JRuby.
|
|
85
|
+
@process.io.stdout = @process.io.stderr = File.new(Platform.null_device, 'w')
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
@process
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def connect_to_server
|
|
92
|
+
Net::HTTP.start(@host, @port) do |http|
|
|
93
|
+
http.open_timeout = STOP_TIMEOUT / 2
|
|
94
|
+
http.read_timeout = STOP_TIMEOUT / 2
|
|
95
|
+
|
|
96
|
+
yield http
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def find_free_port
|
|
101
|
+
@port = PortProber.above(@port)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def start_process
|
|
105
|
+
@process = build_process(@executable_path, "--port=#{@port}", *@extra_args)
|
|
106
|
+
# NOTE: this is a bug only in Windows 7
|
|
107
|
+
@process.leader = true unless Platform.windows?
|
|
108
|
+
@process.start
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def stop_process
|
|
112
|
+
return if process_exited?
|
|
113
|
+
|
|
114
|
+
@process.stop STOP_TIMEOUT
|
|
115
|
+
@process.io.stdout.close if Platform.jruby? && !WebDriver.logger.debug?
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def stop_server
|
|
119
|
+
return if process_exited?
|
|
120
|
+
|
|
121
|
+
connect_to_server do |http|
|
|
122
|
+
headers = WebDriver::Remote::Http::Common::DEFAULT_HEADERS.dup
|
|
123
|
+
http.get('/shutdown', headers)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def process_running?
|
|
128
|
+
defined?(@process) && @process&.alive?
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def process_exited?
|
|
132
|
+
@process.nil? || @process.exited?
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def connect_until_stable
|
|
136
|
+
socket_poller = SocketPoller.new @host, @port, START_TIMEOUT
|
|
137
|
+
return if socket_poller.connected?
|
|
138
|
+
|
|
139
|
+
raise Error::WebDriverError, cannot_connect_error_text
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def cannot_connect_error_text
|
|
143
|
+
"unable to connect to #{@executable_path} #{@host}:#{@port}"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def socket_lock
|
|
147
|
+
@socket_lock ||= SocketLock.new(@port - 1, SOCKET_LOCK_TIMEOUT)
|
|
148
|
+
end
|
|
149
|
+
end # Service
|
|
150
|
+
end # WebDriver
|
|
151
|
+
end # Selenium
|