selenium-webdriver 4.0.0.alpha1 → 4.0.0.alpha6
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 +139 -1
- data/LICENSE +1 -1
- data/lib/selenium/server.rb +3 -3
- data/lib/selenium/webdriver.rb +11 -7
- data/lib/selenium/webdriver/atoms/findElements.js +122 -0
- data/lib/selenium/webdriver/atoms/getAttribute.js +84 -7
- data/lib/selenium/webdriver/atoms/isDisplayed.js +75 -77
- data/lib/selenium/webdriver/chrome.rb +10 -9
- data/lib/selenium/webdriver/chrome/bridge.rb +20 -4
- data/lib/selenium/webdriver/chrome/driver.rb +3 -52
- data/lib/selenium/webdriver/chrome/options.rb +97 -57
- data/lib/selenium/webdriver/chrome/profile.rb +2 -2
- data/lib/selenium/webdriver/chrome/service.rb +0 -4
- data/lib/selenium/webdriver/common.rb +3 -0
- data/lib/selenium/webdriver/common/driver.rb +76 -17
- data/lib/selenium/webdriver/common/driver_extensions/{has_touch_screen.rb → has_devtools.rb} +10 -8
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +2 -1
- data/lib/selenium/webdriver/common/logger.rb +48 -16
- data/lib/selenium/webdriver/common/manager.rb +5 -0
- data/lib/selenium/webdriver/common/options.rb +60 -121
- data/lib/selenium/webdriver/common/platform.rb +3 -0
- data/lib/selenium/webdriver/common/port_prober.rb +4 -6
- data/lib/selenium/webdriver/common/profile_helper.rb +10 -2
- 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 +30 -113
- 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/wait.rb +1 -1
- data/lib/selenium/webdriver/devtools.rb +118 -0
- data/lib/selenium/webdriver/devtools/accessibility.rb +62 -0
- data/lib/selenium/webdriver/devtools/animation.rb +98 -0
- data/lib/selenium/webdriver/devtools/application_cache.rb +64 -0
- data/lib/selenium/webdriver/devtools/audits.rb +61 -0
- data/lib/selenium/webdriver/devtools/background_service.rb +67 -0
- data/lib/selenium/webdriver/devtools/browser.rb +123 -0
- data/lib/selenium/webdriver/devtools/cache_storage.rb +73 -0
- data/lib/selenium/webdriver/devtools/cast.rb +70 -0
- data/lib/selenium/webdriver/devtools/console.rb +57 -0
- data/lib/selenium/webdriver/devtools/css.rb +165 -0
- data/lib/selenium/webdriver/devtools/database.rb +64 -0
- data/lib/selenium/webdriver/devtools/debugger.rb +229 -0
- data/lib/selenium/webdriver/devtools/device_orientation.rb +53 -0
- data/lib/selenium/webdriver/devtools/dom.rb +320 -0
- data/lib/selenium/webdriver/devtools/domdebugger.rb +93 -0
- data/lib/selenium/webdriver/devtools/domsnapshot.rb +65 -0
- data/lib/selenium/webdriver/devtools/domstorage.rb +79 -0
- data/lib/selenium/webdriver/devtools/emulation.rb +180 -0
- data/lib/selenium/webdriver/devtools/fetch.rb +97 -0
- data/lib/selenium/webdriver/devtools/headless_experimental.rb +61 -0
- data/lib/selenium/webdriver/devtools/heap_profiler.rb +107 -0
- data/lib/selenium/webdriver/devtools/indexed_db.rb +100 -0
- data/lib/selenium/webdriver/devtools/input.rb +140 -0
- data/lib/selenium/webdriver/devtools/inspector.rb +55 -0
- data/lib/selenium/webdriver/devtools/io.rb +59 -0
- data/lib/selenium/webdriver/devtools/layer_tree.rb +95 -0
- data/lib/selenium/webdriver/devtools/log.rb +66 -0
- data/lib/selenium/webdriver/devtools/media.rb +57 -0
- data/lib/selenium/webdriver/devtools/memory.rb +86 -0
- data/lib/selenium/webdriver/devtools/network.rb +228 -0
- data/lib/selenium/webdriver/devtools/overlay.rb +157 -0
- data/lib/selenium/webdriver/devtools/page.rb +374 -0
- data/lib/selenium/webdriver/devtools/performance.rb +63 -0
- data/lib/selenium/webdriver/devtools/profiler.rb +111 -0
- data/lib/selenium/webdriver/devtools/runtime.rb +193 -0
- data/lib/selenium/webdriver/devtools/schema.rb +46 -0
- data/lib/selenium/webdriver/devtools/security.rb +71 -0
- data/lib/selenium/webdriver/devtools/service_worker.rb +116 -0
- data/lib/selenium/webdriver/devtools/storage.rb +95 -0
- data/lib/selenium/webdriver/devtools/system_info.rb +50 -0
- data/lib/selenium/webdriver/devtools/target.rb +141 -0
- data/lib/selenium/webdriver/devtools/tethering.rb +55 -0
- data/lib/selenium/webdriver/devtools/tracing.rb +76 -0
- data/lib/selenium/webdriver/devtools/web_audio.rb +70 -0
- data/lib/selenium/webdriver/devtools/web_authn.rb +94 -0
- data/lib/selenium/webdriver/edge.rb +29 -9
- data/lib/selenium/webdriver/{firefox/util.rb → edge_chrome/bridge.rb} +11 -20
- data/lib/selenium/webdriver/{common/w3c_options.rb → edge_chrome/driver.rb} +14 -17
- data/lib/selenium/webdriver/edge_chrome/options.rb +36 -0
- data/lib/selenium/webdriver/edge_chrome/profile.rb +33 -0
- data/lib/selenium/webdriver/edge_chrome/service.rb +36 -0
- data/lib/selenium/webdriver/{common/w3c_manager.rb → edge_html/driver.rb} +11 -17
- data/lib/selenium/webdriver/{edge → edge_html}/options.rb +26 -22
- data/lib/selenium/webdriver/{edge → edge_html}/service.rb +2 -6
- data/lib/selenium/webdriver/firefox.rb +18 -15
- data/lib/selenium/webdriver/firefox/bridge.rb +1 -1
- data/lib/selenium/webdriver/firefox/driver.rb +2 -30
- data/lib/selenium/webdriver/firefox/extension.rb +8 -0
- data/lib/selenium/webdriver/firefox/options.rb +47 -52
- data/lib/selenium/webdriver/firefox/profile.rb +7 -78
- data/lib/selenium/webdriver/firefox/service.rb +0 -4
- data/lib/selenium/webdriver/ie.rb +8 -7
- data/lib/selenium/webdriver/ie/driver.rb +0 -32
- data/lib/selenium/webdriver/ie/options.rb +10 -33
- data/lib/selenium/webdriver/ie/service.rb +5 -9
- data/lib/selenium/webdriver/remote.rb +16 -10
- data/lib/selenium/webdriver/remote/bridge.rb +34 -42
- data/lib/selenium/webdriver/remote/capabilities.rb +22 -6
- data/lib/selenium/webdriver/remote/driver.rb +6 -12
- data/lib/selenium/webdriver/remote/http/default.rb +9 -4
- data/lib/selenium/webdriver/remote/http/persistent.rb +5 -6
- data/lib/selenium/webdriver/safari.rb +9 -8
- data/lib/selenium/webdriver/safari/bridge.rb +4 -4
- data/lib/selenium/webdriver/safari/driver.rb +3 -29
- data/lib/selenium/webdriver/safari/options.rb +18 -19
- data/lib/selenium/webdriver/safari/service.rb +0 -4
- data/lib/selenium/webdriver/support.rb +1 -0
- data/lib/selenium/webdriver/support/cdp_client_generator.rb +77 -0
- data/lib/selenium/webdriver/support/color.rb +2 -2
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +1 -1
- data/lib/selenium/webdriver/support/relative_locator.rb +51 -0
- data/lib/selenium/webdriver/version.rb +1 -1
- data/selenium-webdriver.gemspec +5 -4
- metadata +81 -42
- data/lib/selenium/webdriver/common/bridge_helper.rb +0 -82
- data/lib/selenium/webdriver/common/keyboard.rb +0 -70
- 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/edge/driver.rb +0 -70
- data/lib/selenium/webdriver/firefox/binary.rb +0 -110
- 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/bridge.rb +0 -49
- 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/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
|
@@ -19,23 +19,26 @@
|
|
|
19
19
|
|
|
20
20
|
require 'net/http'
|
|
21
21
|
|
|
22
|
-
require 'selenium/webdriver/chrome/bridge'
|
|
23
|
-
require 'selenium/webdriver/chrome/driver'
|
|
24
|
-
require 'selenium/webdriver/chrome/profile'
|
|
25
|
-
require 'selenium/webdriver/chrome/options'
|
|
26
|
-
|
|
27
22
|
module Selenium
|
|
28
23
|
module WebDriver
|
|
29
24
|
module Chrome
|
|
25
|
+
autoload :Bridge, 'selenium/webdriver/chrome/bridge'
|
|
26
|
+
autoload :Driver, 'selenium/webdriver/chrome/driver'
|
|
27
|
+
autoload :Profile, 'selenium/webdriver/chrome/profile'
|
|
28
|
+
autoload :Options, 'selenium/webdriver/chrome/options'
|
|
29
|
+
autoload :Service, 'selenium/webdriver/chrome/service'
|
|
30
|
+
|
|
30
31
|
def self.driver_path=(path)
|
|
31
32
|
WebDriver.logger.deprecate 'Selenium::WebDriver::Chrome#driver_path=',
|
|
32
|
-
'Selenium::WebDriver::Chrome::Service#driver_path='
|
|
33
|
+
'Selenium::WebDriver::Chrome::Service#driver_path=',
|
|
34
|
+
id: :driver_path
|
|
33
35
|
Selenium::WebDriver::Chrome::Service.driver_path = path
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
def self.driver_path
|
|
37
39
|
WebDriver.logger.deprecate 'Selenium::WebDriver::Chrome#driver_path',
|
|
38
|
-
'Selenium::WebDriver::Chrome::Service#driver_path'
|
|
40
|
+
'Selenium::WebDriver::Chrome::Service#driver_path',
|
|
41
|
+
id: :driver_path
|
|
39
42
|
Selenium::WebDriver::Chrome::Service.driver_path
|
|
40
43
|
end
|
|
41
44
|
|
|
@@ -50,5 +53,3 @@ module Selenium
|
|
|
50
53
|
end # Chrome
|
|
51
54
|
end # WebDriver
|
|
52
55
|
end # Selenium
|
|
53
|
-
|
|
54
|
-
require 'selenium/webdriver/chrome/service'
|
|
@@ -20,12 +20,14 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Chrome
|
|
23
|
-
|
|
23
|
+
class Bridge < WebDriver::Remote::Bridge
|
|
24
24
|
|
|
25
25
|
COMMANDS = {
|
|
26
|
-
get_network_conditions: [:get, '
|
|
27
|
-
set_network_conditions: [:post, '
|
|
28
|
-
send_command: [:post, '
|
|
26
|
+
get_network_conditions: [:get, 'session/:session_id/chromium/network_conditions'],
|
|
27
|
+
set_network_conditions: [:post, 'session/:session_id/chromium/network_conditions'],
|
|
28
|
+
send_command: [:post, 'session/:session_id/goog/cdp/execute'],
|
|
29
|
+
get_available_log_types: [:get, 'session/:session_id/se/log/types'],
|
|
30
|
+
get_log: [:post, 'session/:session_id/se/log']
|
|
29
31
|
}.freeze
|
|
30
32
|
|
|
31
33
|
def commands(command)
|
|
@@ -44,6 +46,20 @@ module Selenium
|
|
|
44
46
|
execute :set_network_conditions, {}, {network_conditions: conditions}
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
def available_log_types
|
|
50
|
+
types = execute :get_available_log_types
|
|
51
|
+
Array(types).map(&:to_sym)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def log(type)
|
|
55
|
+
data = execute :get_log, {}, {type: type.to_s}
|
|
56
|
+
|
|
57
|
+
Array(data).map do |l|
|
|
58
|
+
LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
|
|
59
|
+
rescue KeyError
|
|
60
|
+
next
|
|
61
|
+
end
|
|
62
|
+
end
|
|
47
63
|
end # Bridge
|
|
48
64
|
end # Chrome
|
|
49
65
|
end # WebDriver
|
|
@@ -32,68 +32,19 @@ module Selenium
|
|
|
32
32
|
include DriverExtensions::HasLocation
|
|
33
33
|
include DriverExtensions::TakesScreenshot
|
|
34
34
|
include DriverExtensions::DownloadsFiles
|
|
35
|
-
|
|
36
|
-
def initialize(opts = {})
|
|
37
|
-
opts[:desired_capabilities] = create_capabilities(opts)
|
|
38
|
-
|
|
39
|
-
opts[:url] ||= service_url(opts)
|
|
40
|
-
|
|
41
|
-
listener = opts.delete(:listener)
|
|
42
|
-
desired_capabilities = opts.delete(:desired_capabilities)
|
|
43
|
-
|
|
44
|
-
@bridge = Remote::Bridge.new(opts)
|
|
45
|
-
@bridge.extend Bridge
|
|
46
|
-
@bridge.create_session(desired_capabilities)
|
|
47
|
-
|
|
48
|
-
super(@bridge, listener: listener)
|
|
49
|
-
end
|
|
35
|
+
include DriverExtensions::HasDevTools
|
|
50
36
|
|
|
51
37
|
def browser
|
|
52
38
|
:chrome
|
|
53
39
|
end
|
|
54
40
|
|
|
55
|
-
def
|
|
56
|
-
|
|
57
|
-
ensure
|
|
58
|
-
@service&.stop
|
|
41
|
+
def bridge_class
|
|
42
|
+
Bridge
|
|
59
43
|
end
|
|
60
44
|
|
|
61
45
|
def execute_cdp(cmd, **params)
|
|
62
46
|
@bridge.send_command(cmd: cmd, params: params)
|
|
63
47
|
end
|
|
64
|
-
|
|
65
|
-
private
|
|
66
|
-
|
|
67
|
-
def create_capabilities(opts)
|
|
68
|
-
caps = opts.delete(:desired_capabilities) { Remote::Capabilities.chrome }
|
|
69
|
-
options = opts.delete(:options) { Options.new }
|
|
70
|
-
|
|
71
|
-
profile = opts.delete(:profile)
|
|
72
|
-
if profile
|
|
73
|
-
profile = profile.as_json
|
|
74
|
-
|
|
75
|
-
options.add_argument("--user-data-dir=#{profile[:directory]}") if options.args.none?(&/user-data-dir/.method(:match?))
|
|
76
|
-
|
|
77
|
-
if profile[:extensions]
|
|
78
|
-
WebDriver.logger.deprecate 'Using Selenium::WebDriver::Chrome::Profile#extensions',
|
|
79
|
-
'Selenium::WebDriver::Chrome::Options#add_extension'
|
|
80
|
-
profile[:extensions].each do |extension|
|
|
81
|
-
options.add_encoded_extension(extension)
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
detach = opts.delete(:detach)
|
|
87
|
-
options.add_option(:detach, true) if detach
|
|
88
|
-
|
|
89
|
-
options = options.as_json
|
|
90
|
-
caps.merge!(options) unless options[Options::KEY].empty?
|
|
91
|
-
|
|
92
|
-
caps[:proxy] = opts.delete(:proxy) if opts.key?(:proxy)
|
|
93
|
-
caps[:proxy] ||= opts.delete('proxy') if opts.key?('proxy')
|
|
94
|
-
|
|
95
|
-
caps
|
|
96
|
-
end
|
|
97
48
|
end # Driver
|
|
98
49
|
end # Chrome
|
|
99
50
|
end # WebDriver
|
|
@@ -20,19 +20,44 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Chrome
|
|
23
|
-
class Options
|
|
24
|
-
|
|
25
|
-
attr_accessor :binary
|
|
23
|
+
class Options < WebDriver::Options
|
|
24
|
+
attr_accessor :profile
|
|
26
25
|
|
|
27
26
|
KEY = 'goog:chromeOptions'
|
|
27
|
+
BROWSER = 'chrome'
|
|
28
|
+
|
|
29
|
+
# see: http://chromedriver.chromium.org/capabilities
|
|
30
|
+
CAPABILITIES = {args: 'args',
|
|
31
|
+
binary: 'binary',
|
|
32
|
+
extensions: 'extensions',
|
|
33
|
+
local_state: 'localState',
|
|
34
|
+
prefs: 'prefs',
|
|
35
|
+
detach: 'detach',
|
|
36
|
+
debugger_address: 'debuggerAddress',
|
|
37
|
+
exclude_switches: 'excludeSwitches',
|
|
38
|
+
minidump_path: 'minidumpPath',
|
|
39
|
+
emulation: 'mobileEmulation',
|
|
40
|
+
perf_logging_prefs: 'perfLoggingPrefs',
|
|
41
|
+
window_types: 'windowTypes'}.freeze
|
|
42
|
+
|
|
43
|
+
CAPABILITIES.each_key do |key|
|
|
44
|
+
define_method key do
|
|
45
|
+
@options[key]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
define_method "#{key}=" do |value|
|
|
49
|
+
@options[key] = value
|
|
50
|
+
end
|
|
51
|
+
end
|
|
28
52
|
|
|
29
|
-
#
|
|
30
53
|
# Create a new Options instance.
|
|
31
54
|
#
|
|
32
55
|
# @example
|
|
33
56
|
# options = Selenium::WebDriver::Chrome::Options.new(args: ['start-maximized', 'user-data-dir=/tmp/temp_profile'])
|
|
34
57
|
# driver = Selenium::WebDriver.for(:chrome, options: options)
|
|
35
58
|
#
|
|
59
|
+
# @param [Profile] :profile An instance of a Chrome::Profile Class
|
|
60
|
+
# @param [Array] :encoded_extensions List of extensions that do not need to be Base64 encoded
|
|
36
61
|
# @param [Hash] opts the pre-defined options to create the Chrome::Options with
|
|
37
62
|
# @option opts [Array<String>] :args List of command-line arguments to use when starting Chrome
|
|
38
63
|
# @option opts [String] :binary Path to the Chrome executable to use
|
|
@@ -40,16 +65,21 @@ module Selenium
|
|
|
40
65
|
# @option opts [Array<String>] :extensions A list of paths to (.crx) Chrome extensions to install on startup
|
|
41
66
|
# @option opts [Hash] :options A hash for raw options
|
|
42
67
|
# @option opts [Hash] :emulation A hash for raw emulation options
|
|
68
|
+
# @option opts [Hash] :local_state A hash for the Local State file in the user data folder
|
|
69
|
+
# @option opts [Boolean] :detach whether browser is closed when the driver is sent the quit command
|
|
70
|
+
# @option opts [String] :debugger_address address of a Chrome debugger server to connect to
|
|
71
|
+
# @option opts [Array<String>] :exclude_switches command line switches to exclude
|
|
72
|
+
# @option opts [String] :minidump_path Directory to store Chrome minidumps (linux only)
|
|
73
|
+
# @option opts [Hash] :perf_logging_prefs A hash for performance logging preferences
|
|
74
|
+
# @option opts [Array<String>] :window_types A list of window types to appear in the list of window handles
|
|
43
75
|
#
|
|
44
76
|
|
|
45
|
-
def initialize(**opts)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@
|
|
49
|
-
@
|
|
50
|
-
@options
|
|
51
|
-
@emulation = opts.delete(:emulation) || {}
|
|
52
|
-
@encoded_extensions = []
|
|
77
|
+
def initialize(profile: nil, encoded_extensions: nil, **opts)
|
|
78
|
+
super(**opts)
|
|
79
|
+
|
|
80
|
+
@profile = profile
|
|
81
|
+
@options[:encoded_extensions] = encoded_extensions if encoded_extensions
|
|
82
|
+
@options[:extensions]&.each(&method(:validate_extension))
|
|
53
83
|
end
|
|
54
84
|
|
|
55
85
|
#
|
|
@@ -63,10 +93,9 @@ module Selenium
|
|
|
63
93
|
#
|
|
64
94
|
|
|
65
95
|
def add_extension(path)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
@extensions << path
|
|
96
|
+
validate_extension(path)
|
|
97
|
+
@options[:extensions] ||= []
|
|
98
|
+
@options[:extensions] << path
|
|
70
99
|
end
|
|
71
100
|
|
|
72
101
|
#
|
|
@@ -80,8 +109,10 @@ module Selenium
|
|
|
80
109
|
#
|
|
81
110
|
|
|
82
111
|
def add_encoded_extension(encoded)
|
|
83
|
-
@encoded_extensions
|
|
112
|
+
@options[:encoded_extensions] ||= []
|
|
113
|
+
@options[:encoded_extensions] << encoded
|
|
84
114
|
end
|
|
115
|
+
alias_method :encoded_extension=, :add_encoded_extension
|
|
85
116
|
|
|
86
117
|
#
|
|
87
118
|
# Add a command-line argument to use when starting Chrome.
|
|
@@ -94,22 +125,8 @@ module Selenium
|
|
|
94
125
|
#
|
|
95
126
|
|
|
96
127
|
def add_argument(arg)
|
|
97
|
-
@args
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
#
|
|
101
|
-
# Add a new option not yet handled by bindings.
|
|
102
|
-
#
|
|
103
|
-
# @example Leave Chrome open when chromedriver is killed
|
|
104
|
-
# options = Selenium::WebDriver::Chrome::Options.new
|
|
105
|
-
# options.add_option(:detach, true)
|
|
106
|
-
#
|
|
107
|
-
# @param [String, Symbol] name Name of the option
|
|
108
|
-
# @param [Boolean, String, Integer] value Value of the option
|
|
109
|
-
#
|
|
110
|
-
|
|
111
|
-
def add_option(name, value)
|
|
112
|
-
@options[name] = value
|
|
128
|
+
@options[:args] ||= []
|
|
129
|
+
@options[:args] << arg
|
|
113
130
|
end
|
|
114
131
|
|
|
115
132
|
#
|
|
@@ -124,7 +141,8 @@ module Selenium
|
|
|
124
141
|
#
|
|
125
142
|
|
|
126
143
|
def add_preference(name, value)
|
|
127
|
-
prefs
|
|
144
|
+
@options[:prefs] ||= {}
|
|
145
|
+
@options[:prefs][name] = value
|
|
128
146
|
end
|
|
129
147
|
|
|
130
148
|
#
|
|
@@ -140,7 +158,9 @@ module Selenium
|
|
|
140
158
|
end
|
|
141
159
|
|
|
142
160
|
#
|
|
143
|
-
# Add
|
|
161
|
+
# Add emulation device information
|
|
162
|
+
#
|
|
163
|
+
# see: http://chromedriver.chromium.org/mobile-emulation
|
|
144
164
|
#
|
|
145
165
|
# @example Start Chrome in mobile emulation mode by device name
|
|
146
166
|
# options = Selenium::WebDriver::Chrome::Options.new
|
|
@@ -150,35 +170,55 @@ module Selenium
|
|
|
150
170
|
# options = Selenium::WebDriver::Chrome::Options.new
|
|
151
171
|
# options.add_emulation(device_metrics: {width: 400, height: 800, pixelRatio: 1, touch: true})
|
|
152
172
|
#
|
|
153
|
-
# @param [
|
|
154
|
-
# @
|
|
155
|
-
# @
|
|
173
|
+
# @param [Hash] opts the pre-defined options for adding mobile emulation values
|
|
174
|
+
# @option opts [String] :device_name A valid device name from the Chrome DevTools Emulation panel
|
|
175
|
+
# @option opts [Hash] :device_metrics Hash containing width, height, pixelRatio, touch
|
|
176
|
+
# @option opts [String] :user_agent Full user agent
|
|
156
177
|
#
|
|
157
178
|
|
|
158
|
-
def add_emulation(
|
|
159
|
-
@
|
|
160
|
-
@emulation[:deviceMetrics] = device_metrics if device_metrics
|
|
161
|
-
@emulation[:userAgent] = user_agent if user_agent
|
|
179
|
+
def add_emulation(**opts)
|
|
180
|
+
@options[:emulation] = opts
|
|
162
181
|
end
|
|
163
182
|
|
|
164
|
-
|
|
165
|
-
# @api private
|
|
166
|
-
#
|
|
183
|
+
private
|
|
167
184
|
|
|
168
|
-
def
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
185
|
+
def process_browser_options(browser_options)
|
|
186
|
+
options = browser_options[KEY]
|
|
187
|
+
options['binary'] ||= binary_path if binary_path
|
|
188
|
+
(options['args'] || []) << "--user-data-dir=#{@profile[:directory]}" if @profile
|
|
189
|
+
merge_extensions(options)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def merge_extensions(browser_options)
|
|
193
|
+
extensions = browser_options['extensions'] || []
|
|
194
|
+
encoded_extensions = browser_options.delete(:encoded_extensions) || []
|
|
195
|
+
|
|
196
|
+
browser_options['extensions'] = extensions.map(&method(:encode_extension)) + encoded_extensions
|
|
197
|
+
browser_options.delete('extensions') if browser_options['extensions'].empty?
|
|
198
|
+
end
|
|
173
199
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
200
|
+
def binary_path
|
|
201
|
+
Chrome.path
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def encode_extension(path)
|
|
205
|
+
File.open(path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read }
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def validate_extension(path)
|
|
209
|
+
raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.file?(path)
|
|
210
|
+
raise Error::WebDriverError, "file was not an extension #{path.inspect}" unless File.extname(path) == '.crx'
|
|
211
|
+
end
|
|
180
212
|
|
|
181
|
-
|
|
213
|
+
def generate_as_json(value, camelize_keys: true)
|
|
214
|
+
if value.is_a?(Hash)
|
|
215
|
+
value.each_with_object({}) do |(key, val), hash|
|
|
216
|
+
key = convert_json_key(key, camelize: camelize_keys)
|
|
217
|
+
hash[key] = generate_as_json(val, camelize_keys: key != 'prefs')
|
|
218
|
+
end
|
|
219
|
+
else
|
|
220
|
+
super
|
|
221
|
+
end
|
|
182
222
|
end
|
|
183
223
|
end # Options
|
|
184
224
|
end # Chrome
|
|
@@ -77,8 +77,8 @@ module Selenium
|
|
|
77
77
|
|
|
78
78
|
extensions.concat(@encoded_extensions)
|
|
79
79
|
|
|
80
|
-
opts = {directory
|
|
81
|
-
opts[
|
|
80
|
+
opts = {'directory' => directory || layout_on_disk}
|
|
81
|
+
opts['extensions'] = extensions if extensions.any?
|
|
82
82
|
opts
|
|
83
83
|
end
|
|
84
84
|
|
|
@@ -23,6 +23,7 @@ require 'selenium/webdriver/common/proxy'
|
|
|
23
23
|
require 'selenium/webdriver/common/log_entry'
|
|
24
24
|
require 'selenium/webdriver/common/file_reaper'
|
|
25
25
|
require 'selenium/webdriver/common/service'
|
|
26
|
+
require 'selenium/webdriver/common/service_manager'
|
|
26
27
|
require 'selenium/webdriver/common/socket_lock'
|
|
27
28
|
require 'selenium/webdriver/common/socket_poller'
|
|
28
29
|
require 'selenium/webdriver/common/port_prober'
|
|
@@ -62,7 +63,9 @@ require 'selenium/webdriver/common/driver_extensions/has_permissions'
|
|
|
62
63
|
require 'selenium/webdriver/common/driver_extensions/has_debugger'
|
|
63
64
|
require 'selenium/webdriver/common/driver_extensions/uploads_files'
|
|
64
65
|
require 'selenium/webdriver/common/driver_extensions/has_addons'
|
|
66
|
+
require 'selenium/webdriver/common/driver_extensions/has_devtools'
|
|
65
67
|
require 'selenium/webdriver/common/keys'
|
|
66
68
|
require 'selenium/webdriver/common/profile_helper'
|
|
69
|
+
require 'selenium/webdriver/common/options'
|
|
67
70
|
require 'selenium/webdriver/common/driver'
|
|
68
71
|
require 'selenium/webdriver/common/element'
|
|
@@ -43,17 +43,21 @@ module Selenium
|
|
|
43
43
|
def for(browser, opts = {})
|
|
44
44
|
case browser
|
|
45
45
|
when :chrome
|
|
46
|
-
Chrome::Driver.new(opts)
|
|
46
|
+
Chrome::Driver.new(**opts)
|
|
47
47
|
when :internet_explorer, :ie
|
|
48
|
-
IE::Driver.new(opts)
|
|
48
|
+
IE::Driver.new(**opts)
|
|
49
49
|
when :safari
|
|
50
|
-
Safari::Driver.new(opts)
|
|
50
|
+
Safari::Driver.new(**opts)
|
|
51
51
|
when :firefox, :ff
|
|
52
|
-
Firefox::Driver.new(opts)
|
|
52
|
+
Firefox::Driver.new(**opts)
|
|
53
53
|
when :edge
|
|
54
|
-
Edge::Driver.new(opts)
|
|
54
|
+
Edge::Driver.new(**opts)
|
|
55
|
+
when :edge_chrome
|
|
56
|
+
EdgeChrome::Driver.new(**opts)
|
|
57
|
+
when :edge_html
|
|
58
|
+
EdgeHtml::Driver.new(**opts)
|
|
55
59
|
when :remote
|
|
56
|
-
Remote::Driver.new(opts)
|
|
60
|
+
Remote::Driver.new(**opts)
|
|
57
61
|
else
|
|
58
62
|
raise ArgumentError, "unknown driver: #{browser.inspect}"
|
|
59
63
|
end
|
|
@@ -67,9 +71,10 @@ module Selenium
|
|
|
67
71
|
# @api private
|
|
68
72
|
#
|
|
69
73
|
|
|
70
|
-
def initialize(bridge, listener: nil)
|
|
71
|
-
@
|
|
72
|
-
|
|
74
|
+
def initialize(bridge: nil, listener: nil, **opts)
|
|
75
|
+
@service = nil
|
|
76
|
+
bridge ||= create_bridge(**opts)
|
|
77
|
+
@bridge = listener ? Support::EventFiringBridge.new(bridge, listener) : bridge
|
|
73
78
|
end
|
|
74
79
|
|
|
75
80
|
def inspect
|
|
@@ -164,6 +169,8 @@ module Selenium
|
|
|
164
169
|
|
|
165
170
|
def quit
|
|
166
171
|
bridge.quit
|
|
172
|
+
ensure
|
|
173
|
+
@service&.stop
|
|
167
174
|
end
|
|
168
175
|
|
|
169
176
|
#
|
|
@@ -269,7 +276,7 @@ module Selenium
|
|
|
269
276
|
end
|
|
270
277
|
|
|
271
278
|
def browser
|
|
272
|
-
bridge
|
|
279
|
+
bridge&.browser
|
|
273
280
|
end
|
|
274
281
|
|
|
275
282
|
def capabilities
|
|
@@ -287,18 +294,70 @@ module Selenium
|
|
|
287
294
|
|
|
288
295
|
attr_reader :bridge
|
|
289
296
|
|
|
297
|
+
def create_bridge(**opts)
|
|
298
|
+
opts[:url] ||= service_url(opts)
|
|
299
|
+
caps = opts.delete(:capabilities)
|
|
300
|
+
# Note: This is deprecated
|
|
301
|
+
cap_array = caps.is_a?(Hash) ? [caps] : Array(caps)
|
|
302
|
+
|
|
303
|
+
desired_capabilities = opts.delete(:desired_capabilities)
|
|
304
|
+
if desired_capabilities
|
|
305
|
+
WebDriver.logger.deprecate(':desired_capabilities as a parameter for driver initialization',
|
|
306
|
+
':capabilities with an Array value of capabilities/options if necessary',
|
|
307
|
+
id: :desired_capabilities)
|
|
308
|
+
desired_capabilities = Remote::Capabilities.new(desired_capabilities) if desired_capabilities.is_a?(Hash)
|
|
309
|
+
cap_array << desired_capabilities
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
options = opts.delete(:options)
|
|
313
|
+
if options
|
|
314
|
+
WebDriver.logger.deprecate(':options as a parameter for driver initialization',
|
|
315
|
+
':capabilities with an Array of value capabilities/options if necessary',
|
|
316
|
+
id: :browser_options)
|
|
317
|
+
cap_array << options
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
capabilities = generate_capabilities(cap_array)
|
|
321
|
+
|
|
322
|
+
bridge_opts = {http_client: opts.delete(:http_client), url: opts.delete(:url)}
|
|
323
|
+
raise ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
|
|
324
|
+
|
|
325
|
+
bridge = (respond_to?(:bridge_class) ? bridge_class : Remote::Bridge).new(**bridge_opts)
|
|
326
|
+
|
|
327
|
+
bridge.create_session(capabilities)
|
|
328
|
+
bridge
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def generate_capabilities(cap_array)
|
|
332
|
+
cap_array.map { |cap|
|
|
333
|
+
if cap.is_a? Symbol
|
|
334
|
+
cap = Remote::Capabilities.send(cap)
|
|
335
|
+
elsif cap.is_a? Hash
|
|
336
|
+
WebDriver.logger.deprecate("passing a Hash value to :capabilities",
|
|
337
|
+
'Capabilities instance initialized with the Hash, or build values with Options class',
|
|
338
|
+
id: :capabilities_hash)
|
|
339
|
+
cap = Remote::Capabilities.new(cap)
|
|
340
|
+
elsif !cap.respond_to? :as_json
|
|
341
|
+
msg = ":capabilities parameter only accepts objects responding to #as_json which #{cap.class} does not"
|
|
342
|
+
raise ArgumentError, msg
|
|
343
|
+
end
|
|
344
|
+
cap&.as_json
|
|
345
|
+
}.inject(:merge) || Remote::Capabilities.send(browser || :new)
|
|
346
|
+
end
|
|
347
|
+
|
|
290
348
|
def service_url(opts)
|
|
291
|
-
|
|
349
|
+
service_config = opts.delete(:service)
|
|
292
350
|
%i[driver_opts driver_path port].each do |key|
|
|
293
351
|
next unless opts.key? key
|
|
294
352
|
|
|
295
|
-
WebDriver.logger.deprecate(":#{key}", ':service with an instance of Selenium::WebDriver::Service'
|
|
353
|
+
WebDriver.logger.deprecate(":#{key}", ':service with an instance of Selenium::WebDriver::Service',
|
|
354
|
+
id: "service_#{key}".to_sym)
|
|
296
355
|
end
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
@service.
|
|
356
|
+
service_config ||= Service.send(browser,
|
|
357
|
+
args: opts.delete(:driver_opts),
|
|
358
|
+
path: opts.delete(:driver_path),
|
|
359
|
+
port: opts.delete(:port))
|
|
360
|
+
@service = service_config.launch
|
|
302
361
|
@service.uri
|
|
303
362
|
end
|
|
304
363
|
end # Driver
|