selenium-webdriver 3.142.7 → 4.0.3

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.
Files changed (137) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +350 -5
  3. data/Gemfile +3 -1
  4. data/LICENSE +1 -1
  5. data/NOTICE +2 -0
  6. data/README.md +4 -5
  7. data/lib/selenium/server.rb +69 -63
  8. data/lib/selenium/webdriver/atoms/findElements.js +122 -0
  9. data/lib/selenium/webdriver/atoms/getAttribute.js +100 -7
  10. data/lib/selenium/webdriver/atoms/isDisplayed.js +76 -78
  11. data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
  12. data/lib/selenium/webdriver/chrome/driver.rb +26 -83
  13. data/lib/selenium/webdriver/chrome/{bridge.rb → features.rb} +50 -12
  14. data/lib/selenium/webdriver/chrome/options.rb +129 -58
  15. data/lib/selenium/webdriver/chrome/profile.rb +6 -3
  16. data/lib/selenium/webdriver/chrome/service.rb +8 -15
  17. data/lib/selenium/webdriver/chrome.rb +10 -9
  18. data/lib/selenium/webdriver/common/action_builder.rb +97 -249
  19. data/lib/selenium/webdriver/common/driver.rb +112 -23
  20. data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +43 -0
  21. data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +51 -0
  22. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +89 -0
  23. data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +77 -0
  24. data/lib/selenium/webdriver/common/driver_extensions/{has_touch_screen.rb → has_cdp.rb} +10 -8
  25. data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +45 -0
  26. data/lib/selenium/webdriver/{firefox/util.rb → common/driver_extensions/has_devtools.rb} +16 -19
  27. data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +38 -0
  28. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -8
  29. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +144 -0
  30. data/lib/selenium/webdriver/common/driver_extensions/has_logs.rb +30 -0
  31. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +17 -0
  32. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +6 -27
  33. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +136 -0
  34. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +11 -11
  35. data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +77 -0
  36. data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +1 -0
  37. data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
  38. data/lib/selenium/webdriver/common/element.rb +82 -22
  39. data/lib/selenium/webdriver/common/error.rb +32 -196
  40. data/lib/selenium/webdriver/common/interactions/interaction.rb +4 -1
  41. data/lib/selenium/webdriver/common/interactions/key_actions.rb +5 -5
  42. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +13 -13
  43. data/lib/selenium/webdriver/common/log_entry.rb +2 -2
  44. data/lib/selenium/webdriver/common/logger.rb +50 -15
  45. data/lib/selenium/webdriver/common/manager.rb +15 -15
  46. data/lib/selenium/webdriver/common/options.rb +154 -23
  47. data/lib/selenium/webdriver/common/platform.rb +6 -1
  48. data/lib/selenium/webdriver/common/port_prober.rb +4 -6
  49. data/lib/selenium/webdriver/common/profile_helper.rb +11 -9
  50. data/lib/selenium/webdriver/common/proxy.rb +6 -3
  51. data/lib/selenium/webdriver/common/search_context.rb +7 -3
  52. data/lib/selenium/webdriver/common/service.rb +17 -125
  53. data/lib/selenium/webdriver/common/service_manager.rb +151 -0
  54. data/lib/selenium/webdriver/common/shadow_root.rb +87 -0
  55. data/lib/selenium/webdriver/common/socket_lock.rb +2 -2
  56. data/lib/selenium/webdriver/common/socket_poller.rb +2 -2
  57. data/lib/selenium/webdriver/common/takes_screenshot.rb +66 -0
  58. data/lib/selenium/webdriver/common/target_locator.rb +32 -4
  59. data/lib/selenium/webdriver/common/timeouts.rb +31 -4
  60. data/lib/selenium/webdriver/common/wait.rb +1 -1
  61. data/lib/selenium/webdriver/common/window.rb +0 -4
  62. data/lib/selenium/webdriver/common/zipper.rb +1 -9
  63. data/lib/selenium/webdriver/common.rb +23 -17
  64. data/lib/selenium/webdriver/devtools/console_event.rb +38 -0
  65. data/lib/selenium/webdriver/devtools/exception_event.rb +36 -0
  66. data/lib/selenium/webdriver/devtools/mutation_event.rb +37 -0
  67. data/lib/selenium/webdriver/devtools/pinned_script.rb +59 -0
  68. data/lib/selenium/webdriver/devtools/request.rb +67 -0
  69. data/lib/selenium/webdriver/devtools/response.rb +66 -0
  70. data/lib/selenium/webdriver/devtools.rb +182 -0
  71. data/lib/selenium/webdriver/edge/driver.rb +7 -29
  72. data/lib/selenium/webdriver/edge/features.rb +44 -0
  73. data/lib/selenium/webdriver/edge/options.rb +11 -48
  74. data/lib/selenium/webdriver/{common/w3c_manager.rb → edge/profile.rb} +7 -19
  75. data/lib/selenium/webdriver/edge/service.rb +10 -26
  76. data/lib/selenium/webdriver/edge.rb +11 -14
  77. data/lib/selenium/webdriver/firefox/driver.rb +31 -19
  78. data/lib/selenium/webdriver/firefox/extension.rb +8 -0
  79. data/lib/selenium/webdriver/firefox/features.rb +66 -0
  80. data/lib/selenium/webdriver/firefox/options.rb +70 -49
  81. data/lib/selenium/webdriver/firefox/profile.rb +21 -71
  82. data/lib/selenium/webdriver/firefox/service.rb +5 -9
  83. data/lib/selenium/webdriver/firefox.rb +22 -20
  84. data/lib/selenium/webdriver/ie/driver.rb +1 -47
  85. data/lib/selenium/webdriver/ie/options.rb +13 -44
  86. data/lib/selenium/webdriver/ie/service.rb +13 -15
  87. data/lib/selenium/webdriver/ie.rb +8 -7
  88. data/lib/selenium/webdriver/remote/bridge.rb +558 -86
  89. data/lib/selenium/webdriver/remote/capabilities.rb +159 -123
  90. data/lib/selenium/webdriver/remote/commands.rb +163 -0
  91. data/lib/selenium/webdriver/remote/driver.rb +22 -12
  92. data/lib/selenium/webdriver/remote/http/common.rb +0 -5
  93. data/lib/selenium/webdriver/remote/http/default.rb +17 -20
  94. data/lib/selenium/webdriver/remote/http/persistent.rb +11 -6
  95. data/lib/selenium/webdriver/remote/response.rb +16 -47
  96. data/lib/selenium/webdriver/remote.rb +15 -13
  97. data/lib/selenium/webdriver/safari/driver.rb +3 -31
  98. data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +3 -3
  99. data/lib/selenium/webdriver/safari/options.rb +10 -29
  100. data/lib/selenium/webdriver/safari/service.rb +4 -8
  101. data/lib/selenium/webdriver/safari.rb +17 -9
  102. data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
  103. data/lib/selenium/webdriver/support/cdp/domain.rb.erb +63 -0
  104. data/lib/selenium/webdriver/support/cdp_client_generator.rb +108 -0
  105. data/lib/selenium/webdriver/support/color.rb +2 -2
  106. data/lib/selenium/webdriver/support/event_firing_bridge.rb +4 -4
  107. data/lib/selenium/webdriver/support/guards/guard.rb +89 -0
  108. data/lib/selenium/webdriver/{firefox/marionette/bridge.rb → support/guards/guard_condition.rb} +22 -19
  109. data/lib/selenium/webdriver/support/guards.rb +95 -0
  110. data/lib/selenium/webdriver/support/relative_locator.rb +51 -0
  111. data/lib/selenium/webdriver/support/select.rb +3 -3
  112. data/lib/selenium/webdriver/support.rb +1 -0
  113. data/lib/selenium/webdriver/version.rb +1 -1
  114. data/lib/selenium/webdriver.rb +12 -12
  115. data/selenium-webdriver.gemspec +28 -12
  116. metadata +128 -69
  117. data/lib/selenium/webdriver/common/bridge_helper.rb +0 -82
  118. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -64
  119. data/lib/selenium/webdriver/common/keyboard.rb +0 -70
  120. data/lib/selenium/webdriver/common/mouse.rb +0 -89
  121. data/lib/selenium/webdriver/common/touch_action_builder.rb +0 -78
  122. data/lib/selenium/webdriver/common/touch_screen.rb +0 -123
  123. data/lib/selenium/webdriver/common/w3c_action_builder.rb +0 -212
  124. data/lib/selenium/webdriver/edge/bridge.rb +0 -76
  125. data/lib/selenium/webdriver/firefox/binary.rb +0 -187
  126. data/lib/selenium/webdriver/firefox/extension/prefs.json +0 -69
  127. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  128. data/lib/selenium/webdriver/firefox/launcher.rb +0 -111
  129. data/lib/selenium/webdriver/firefox/legacy/driver.rb +0 -83
  130. data/lib/selenium/webdriver/firefox/marionette/driver.rb +0 -90
  131. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  132. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  133. data/lib/selenium/webdriver/remote/oss/bridge.rb +0 -594
  134. data/lib/selenium/webdriver/remote/oss/commands.rb +0 -223
  135. data/lib/selenium/webdriver/remote/w3c/bridge.rb +0 -605
  136. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +0 -310
  137. data/lib/selenium/webdriver/remote/w3c/commands.rb +0 -157
@@ -20,30 +20,42 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Firefox
23
- module Driver
24
- class << self
25
-
26
- #
27
- # Instantiates correct Firefox driver implementation
28
- # @return [Marionette::Driver, Legacy::Driver]
29
- #
30
-
31
- def new(**opts)
32
- if marionette?(opts)
33
- Firefox::Marionette::Driver.new(opts)
34
- else
35
- Firefox::Legacy::Driver.new(opts)
36
- end
37
- end
38
23
 
39
- private
24
+ #
25
+ # Driver implementation for Firefox using GeckoDriver.
26
+ # @api private
27
+ #
28
+
29
+ class Driver < WebDriver::Driver
30
+ EXTENSIONS = [DriverExtensions::HasAddons,
31
+ DriverExtensions::FullPageScreenshot,
32
+ DriverExtensions::HasContext,
33
+ DriverExtensions::HasDevTools,
34
+ DriverExtensions::HasLogEvents,
35
+ DriverExtensions::HasNetworkInterception,
36
+ DriverExtensions::HasWebStorage,
37
+ DriverExtensions::PrintsPage].freeze
38
+
39
+ def browser
40
+ :firefox
41
+ end
42
+
43
+ private
40
44
 
41
- def marionette?(opts)
42
- opts.delete(:marionette) != false &&
43
- (!opts[:desired_capabilities] || opts[:desired_capabilities][:marionette] != false)
45
+ def devtools_url
46
+ if capabilities['moz:debuggerAddress'].nil?
47
+ raise(Error::WebDriverError, "DevTools is not supported by this version of Firefox; use v85 or higher")
44
48
  end
49
+
50
+ uri = URI("http://#{capabilities['moz:debuggerAddress']}")
51
+ response = Net::HTTP.get(uri.hostname, '/json/version', uri.port)
52
+
53
+ JSON.parse(response)['webSocketDebuggerUrl']
45
54
  end
46
55
 
56
+ def devtools_version
57
+ Firefox::DEVTOOLS_VERSION
58
+ end
47
59
  end # Driver
48
60
  end # Firefox
49
61
  end # WebDriver
@@ -87,6 +87,14 @@ module Selenium
87
87
  return unless File.exist?(manifest_path)
88
88
 
89
89
  manifest = JSON.parse(File.read(manifest_path))
90
+ applications_gecko_id(manifest) || name_and_version(manifest)
91
+ end
92
+
93
+ def applications_gecko_id(manifest)
94
+ manifest.dig('applications', 'gecko', 'id')&.strip
95
+ end
96
+
97
+ def name_and_version(manifest)
90
98
  [manifest['name'].delete(' '), manifest['version']].join('@')
91
99
  end
92
100
  end # Extension
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module Firefox
23
+ module Features
24
+
25
+ FIREFOX_COMMANDS = {
26
+ get_context: [:get, 'session/:session_id/moz/context'],
27
+ set_context: [:post, 'session/:session_id/moz/context'],
28
+ install_addon: [:post, 'session/:session_id/moz/addon/install'],
29
+ uninstall_addon: [:post, 'session/:session_id/moz/addon/uninstall'],
30
+ full_page_screenshot: [:get, 'session/:session_id/moz/screenshot/full']
31
+ }.freeze
32
+
33
+ def commands(command)
34
+ FIREFOX_COMMANDS[command] || self.class::COMMANDS[command]
35
+ end
36
+
37
+ def install_addon(path, temporary)
38
+ if @file_detector
39
+ local_file = @file_detector.call(path)
40
+ path = upload(local_file) if local_file
41
+ end
42
+
43
+ payload = {path: path}
44
+ payload[:temporary] = temporary unless temporary.nil?
45
+ execute :install_addon, {}, payload
46
+ end
47
+
48
+ def uninstall_addon(id)
49
+ execute :uninstall_addon, {}, {id: id}
50
+ end
51
+
52
+ def full_screenshot
53
+ execute :full_page_screenshot
54
+ end
55
+
56
+ def context=(context)
57
+ execute :set_context, {}, {context: context}
58
+ end
59
+
60
+ def context
61
+ execute :get_context
62
+ end
63
+ end # Bridge
64
+ end # Firefox
65
+ end # WebDriver
66
+ end # Selenium
@@ -20,12 +20,25 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Firefox
23
- class Options < WebDriver::Common::Options
24
- attr_reader :args, :prefs, :options, :profile
25
- attr_accessor :binary, :log_level
23
+ class Options < WebDriver::Options
24
+ attr_accessor :debugger_address
26
25
 
27
26
  KEY = 'moz:firefoxOptions'
28
27
 
28
+ # see: https://firefox-source-docs.mozilla.org/testing/geckodriver/Capabilities.html
29
+ CAPABILITIES = {binary: 'binary',
30
+ args: 'args',
31
+ log: 'log',
32
+ prefs: 'prefs',
33
+ android_package: 'androidPackage',
34
+ android_activity: 'androidActivity',
35
+ android_device_serial: 'androidDeviceSerial',
36
+ android_intent_arguments: 'androidIntentArguments'}.freeze
37
+ BROWSER = 'firefox'
38
+
39
+ # NOTE: special handling of 'profile' to validate when set instead of when used
40
+ attr_reader :profile
41
+
29
42
  #
30
43
  # Create a new Options instance, only for W3C-capable versions of Firefox.
31
44
  #
@@ -42,13 +55,16 @@ module Selenium
42
55
  # @option opts [Hash] :options A hash for raw options
43
56
  #
44
57
 
45
- def initialize(**opts)
46
- @args = Set.new(opts.delete(:args) || [])
47
- @binary = opts.delete(:binary)
48
- @profile = process_profile(opts.delete(:profile))
49
- @log_level = opts.delete(:log_level)
50
- @prefs = opts.delete(:prefs) || {}
51
- @options = opts.delete(:options) || {}
58
+ def initialize(log_level: nil, **opts)
59
+ @debugger_address = opts.delete(:debugger_address)
60
+
61
+ super(**opts)
62
+
63
+ @options[:args] ||= []
64
+ @options[:prefs] ||= {}
65
+ @options[:log] ||= {level: log_level} if log_level
66
+
67
+ process_profile(@options.delete(:profile))
52
68
  end
53
69
 
54
70
  #
@@ -62,22 +78,7 @@ module Selenium
62
78
  #
63
79
 
64
80
  def add_argument(arg)
65
- @args << arg
66
- end
67
-
68
- #
69
- # Add a new option not yet handled by these bindings.
70
- #
71
- # @example
72
- # options = Selenium::WebDriver::Firefox::Options.new
73
- # options.add_option(:foo, 'bar')
74
- #
75
- # @param [String, Symbol] name Name of the option
76
- # @param [Boolean, String, Integer] value Value of the option
77
- #
78
-
79
- def add_option(name, value)
80
- @options[name] = value
81
+ @options[:args] << arg
81
82
  end
82
83
 
83
84
  #
@@ -92,7 +93,7 @@ module Selenium
92
93
  #
93
94
 
94
95
  def add_preference(name, value)
95
- prefs[name] = value
96
+ @options[:prefs][name] = value
96
97
  end
97
98
 
98
99
  #
@@ -123,38 +124,58 @@ module Selenium
123
124
  #
124
125
 
125
126
  def profile=(profile)
126
- @profile = process_profile(profile)
127
+ process_profile(profile)
127
128
  end
128
129
 
129
- #
130
- # @api private
131
- #
130
+ def log_level
131
+ @options.dig(:log, :level)
132
+ end
132
133
 
133
- def as_json(*)
134
- opts = @options
134
+ def log_level=(level)
135
+ @options[:log] = {level: level}
136
+ end
135
137
 
136
- opts[:profile] = @profile.encoded if @profile
137
- opts[:args] = @args.to_a if @args.any?
138
- opts[:binary] = @binary if @binary
139
- opts[:prefs] = @prefs unless @prefs.empty?
140
- opts[:log] = {level: @log_level} if @log_level
138
+ #
139
+ # Enables mobile browser use on Android.
140
+ #
141
+ # @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions#android
142
+ #
143
+ # @param [String] package The package name of the Chrome or WebView app.
144
+ # @param [String] serial_number The serial number of the device on which to launch the application.
145
+ # If not specified and multiple devices are attached, an error will be returned.
146
+ # @param [String] activity The fully qualified class name of the activity to be launched.
147
+ # @param [Array] intent_arguments Arguments to launch the intent with.
148
+ #
141
149
 
142
- {KEY => generate_as_json(opts)}
150
+ def enable_android(package: 'org.mozilla.firefox', serial_number: nil, activity: nil, intent_arguments: nil)
151
+ @options[:android_package] = package
152
+ @options[:android_activity] = activity unless activity.nil?
153
+ @options[:android_device_serial] = serial_number unless serial_number.nil?
154
+ @options[:android_intent_arguments] = intent_arguments unless intent_arguments.nil?
143
155
  end
144
156
 
145
157
  private
146
158
 
159
+ def process_browser_options(browser_options)
160
+ browser_options['moz:debuggerAddress'] = true if @debugger_address
161
+ options = browser_options[KEY]
162
+ options['binary'] ||= Firefox.path if Firefox.path
163
+ options['profile'] = @profile if @profile
164
+ end
165
+
147
166
  def process_profile(profile)
148
- return unless profile
149
-
150
- case profile
151
- when Profile
152
- profile
153
- when String
154
- Profile.from_name(profile)
155
- else
156
- raise Error::WebDriverError, "don't know how to handle profile: #{profile.inspect}"
157
- end
167
+ @profile = case profile
168
+ when nil
169
+ nil
170
+ when Profile
171
+ profile
172
+ else
173
+ Profile.from_name(profile)
174
+ end
175
+ end
176
+
177
+ def camelize?(key)
178
+ key != "prefs"
158
179
  end
159
180
  end # Options
160
181
  end # Firefox
@@ -23,18 +23,18 @@ module Selenium
23
23
  class Profile
24
24
  include ProfileHelper
25
25
 
26
- VALID_PREFERENCE_TYPES = [TrueClass, FalseClass, Integer, Float, String].freeze
27
- WEBDRIVER_EXTENSION_PATH = File.expand_path("#{WebDriver.root}/selenium/webdriver/firefox/extension/webdriver.xpi")
28
- WEBDRIVER_PREFS = {
29
- native_events: 'webdriver_enable_native_events',
30
- untrusted_certs: 'webdriver_accept_untrusted_certs',
31
- untrusted_issuer: 'webdriver_assume_untrusted_issuer',
32
- port: 'webdriver_firefox_port',
33
- log_file: 'webdriver.log.file'
26
+ VALID_PREFERENCE_TYPES = [TrueClass, FalseClass, Integer, Float, String].freeze
27
+
28
+ DEFAULT_PREFERENCES = {
29
+ "browser.newtabpage.enabled" => false,
30
+ "browser.startup.homepage" => "about:blank",
31
+ "browser.usedOnWindows10.introURL" => "about:blank",
32
+ "network.captive-portal-service.enabled" => false,
33
+ "security.csp.enable" => false
34
34
  }.freeze
35
35
 
36
36
  attr_reader :name, :log_file
37
- attr_writer :secure_ssl, :native_events, :load_no_focus_lib
37
+ attr_writer :secure_ssl, :load_no_focus_lib
38
38
 
39
39
  class << self
40
40
  def ini
@@ -48,10 +48,8 @@ module Selenium
48
48
  raise Error::WebDriverError, "unable to find profile named: #{name.inspect}"
49
49
  end
50
50
 
51
- def default_preferences
52
- @default_preferences ||= JSON.parse(
53
- File.read(File.expand_path("#{WebDriver.root}/selenium/webdriver/firefox/extension/prefs.json"))
54
- ).freeze
51
+ def decoded(json)
52
+ JSON.parse(json)
55
53
  end
56
54
  end
57
55
 
@@ -70,25 +68,7 @@ module Selenium
70
68
  def initialize(model = nil)
71
69
  @model = verify_model(model)
72
70
 
73
- model_prefs = read_model_prefs
74
-
75
- if model_prefs.empty?
76
- @native_events = DEFAULT_ENABLE_NATIVE_EVENTS
77
- @secure_ssl = DEFAULT_SECURE_SSL
78
- @untrusted_issuer = DEFAULT_ASSUME_UNTRUSTED_ISSUER
79
- @load_no_focus_lib = DEFAULT_LOAD_NO_FOCUS_LIB
80
-
81
- @additional_prefs = {}
82
- else
83
- # TODO: clean this up
84
- @native_events = model_prefs.delete(WEBDRIVER_PREFS[:native_events]) == 'true'
85
- @secure_ssl = model_prefs.delete(WEBDRIVER_PREFS[:untrusted_certs]) != 'true'
86
- @untrusted_issuer = model_prefs.delete(WEBDRIVER_PREFS[:untrusted_issuer]) == 'true'
87
- # not stored in profile atm, so will always be false.
88
- @load_no_focus_lib = model_prefs.delete(WEBDRIVER_PREFS[:load_no_focus_lib]) == 'true'
89
- @additional_prefs = model_prefs
90
- end
91
-
71
+ @additional_prefs = read_model_prefs
92
72
  @extensions = {}
93
73
  end
94
74
 
@@ -116,7 +96,7 @@ module Selenium
116
96
  raise TypeError, "expected one of #{VALID_PREFERENCE_TYPES.inspect}, got #{value.inspect}:#{value.class}"
117
97
  end
118
98
 
119
- if value.is_a?(String) && Util.stringified?(value)
99
+ if value.is_a?(String) && stringified?(value)
120
100
  raise ArgumentError, "preference values must be plain strings: #{key.inspect} => #{value.inspect}"
121
101
  end
122
102
 
@@ -132,12 +112,6 @@ module Selenium
132
112
  self[WEBDRIVER_PREFS[:log_file]] = file
133
113
  end
134
114
 
135
- def add_webdriver_extension
136
- return if @extensions.key?(:webdriver)
137
-
138
- add_extension(WEBDRIVER_EXTENSION_PATH, :webdriver)
139
- end
140
-
141
115
  #
142
116
  # Add the extension (directory, .zip or .xpi) at the given path to the profile.
143
117
  #
@@ -146,26 +120,6 @@ module Selenium
146
120
  @extensions[name] = Extension.new(path)
147
121
  end
148
122
 
149
- def native_events?
150
- @native_events == true
151
- end
152
-
153
- def load_no_focus_lib?
154
- @load_no_focus_lib == true
155
- end
156
-
157
- def secure_ssl?
158
- @secure_ssl == true
159
- end
160
-
161
- def assume_untrusted_certificate_issuer?
162
- @untrusted_issuer == true
163
- end
164
-
165
- def assume_untrusted_certificate_issuer=(bool)
166
- @untrusted_issuer = bool
167
- end
168
-
169
123
  def proxy=(proxy)
170
124
  raise TypeError, "expected #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}" unless proxy.is_a? Proxy
171
125
 
@@ -189,9 +143,7 @@ module Selenium
189
143
  end
190
144
  end
191
145
 
192
- def encoded
193
- Zipper.zip(layout_on_disk)
194
- end
146
+ alias_method :as_json, :encoded
195
147
 
196
148
  private
197
149
 
@@ -236,17 +188,11 @@ module Selenium
236
188
  def update_user_prefs_in(directory)
237
189
  path = File.join(directory, 'user.js')
238
190
  prefs = read_user_prefs(path)
239
-
240
- prefs.merge! self.class.default_preferences.fetch 'mutable'
241
- prefs.merge! @additional_prefs
242
- prefs.merge! self.class.default_preferences.fetch 'frozen'
243
-
244
- prefs[WEBDRIVER_PREFS[:untrusted_certs]] = !secure_ssl?
245
- prefs[WEBDRIVER_PREFS[:native_events]] = native_events?
246
- prefs[WEBDRIVER_PREFS[:untrusted_issuer]] = assume_untrusted_certificate_issuer?
191
+ prefs.merge! self.class::DEFAULT_PREFERENCES
192
+ prefs.merge!(@additional_prefs)
247
193
 
248
194
  # If the user sets the home page, we should also start up there
249
- prefs['startup.homepage_welcome_url'] = prefs['browser.startup.homepage']
195
+ prefs['startup.homepage_welcome_url'] ||= prefs['browser.startup.homepage']
250
196
 
251
197
  write_prefs prefs, path
252
198
  end
@@ -275,6 +221,10 @@ module Selenium
275
221
  end
276
222
  end
277
223
  end
224
+
225
+ def stringified?(str)
226
+ /^".*"$/.match?(str)
227
+ end
278
228
  end # Profile
279
229
  end # Firefox
280
230
  end # WebDriver
@@ -20,23 +20,19 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Firefox
23
- #
24
- # @api private
25
- #
26
-
27
23
  class Service < WebDriver::Service
28
- @default_port = 4444
29
- @executable = 'geckodriver'
30
- @missing_text = <<~ERROR
24
+ DEFAULT_PORT = 4444
25
+ EXECUTABLE = 'geckodriver'
26
+ MISSING_TEXT = <<~ERROR
31
27
  Unable to find Mozilla geckodriver. Please download the server from
32
28
  https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH.
33
29
  More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver.
34
30
  ERROR
35
- @shutdown_supported = false
31
+ SHUTDOWN_SUPPORTED = false
36
32
 
37
33
  private
38
34
 
39
- # Note: This processing is deprecated
35
+ # NOTE: This processing is deprecated
40
36
  def extract_service_args(driver_opts)
41
37
  driver_args = super
42
38
  driver_opts = driver_opts.dup
@@ -21,46 +21,48 @@ require 'timeout'
21
21
  require 'socket'
22
22
  require 'rexml/document'
23
23
 
24
- require 'selenium/webdriver/firefox/driver'
25
-
26
- require 'selenium/webdriver/firefox/util'
27
- require 'selenium/webdriver/firefox/extension'
28
- require 'selenium/webdriver/firefox/binary'
29
- require 'selenium/webdriver/firefox/profiles_ini'
30
- require 'selenium/webdriver/firefox/profile'
31
- require 'selenium/webdriver/firefox/launcher'
32
- require 'selenium/webdriver/firefox/legacy/driver'
33
-
34
- require 'selenium/webdriver/firefox/marionette/bridge'
35
- require 'selenium/webdriver/firefox/marionette/driver'
36
- require 'selenium/webdriver/firefox/options'
37
-
38
24
  module Selenium
39
25
  module WebDriver
40
26
  module Firefox
27
+ autoload :Extension, 'selenium/webdriver/firefox/extension'
28
+ autoload :ProfilesIni, 'selenium/webdriver/firefox/profiles_ini'
29
+ autoload :Profile, 'selenium/webdriver/firefox/profile'
30
+ autoload :Features, 'selenium/webdriver/firefox/features'
31
+ autoload :Driver, 'selenium/webdriver/firefox/driver'
32
+ autoload :Options, 'selenium/webdriver/firefox/options'
33
+ autoload :Service, 'selenium/webdriver/firefox/service'
34
+
41
35
  DEFAULT_PORT = 7055
42
- DEFAULT_ENABLE_NATIVE_EVENTS = Platform.os == :windows
43
36
  DEFAULT_SECURE_SSL = false
44
37
  DEFAULT_ASSUME_UNTRUSTED_ISSUER = true
45
38
  DEFAULT_LOAD_NO_FOCUS_LIB = false
46
39
 
40
+ # Mozilla Automation Team asked to only support 85
41
+ # until WebDriver Bidi is available.
42
+ DEVTOOLS_VERSION = 85
43
+
47
44
  def self.driver_path=(path)
48
45
  WebDriver.logger.deprecate 'Selenium::WebDriver::Firefox#driver_path=',
49
- 'Selenium::WebDriver::Firefox::Service#driver_path='
46
+ 'Selenium::WebDriver::Firefox::Service#driver_path=',
47
+ id: :driver_path
50
48
  Selenium::WebDriver::Firefox::Service.driver_path = path
51
49
  end
52
50
 
53
51
  def self.driver_path
54
52
  WebDriver.logger.deprecate 'Selenium::WebDriver::Firefox#driver_path',
55
- 'Selenium::WebDriver::Firefox::Service#driver_path'
53
+ 'Selenium::WebDriver::Firefox::Service#driver_path',
54
+ id: :driver_path
56
55
  Selenium::WebDriver::Firefox::Service.driver_path
57
56
  end
58
57
 
59
58
  def self.path=(path)
60
- Binary.path = path
59
+ Platform.assert_executable path
60
+ @path = path
61
+ end
62
+
63
+ def self.path
64
+ @path ||= nil
61
65
  end
62
66
  end # Firefox
63
67
  end # WebDriver
64
68
  end # Selenium
65
-
66
- require 'selenium/webdriver/firefox/service'
@@ -28,57 +28,11 @@ module Selenium
28
28
  #
29
29
 
30
30
  class Driver < WebDriver::Driver
31
- include DriverExtensions::HasWebStorage
32
- include DriverExtensions::TakesScreenshot
33
-
34
- def initialize(opts = {})
35
- opts[:desired_capabilities] = create_capabilities(opts)
36
-
37
- opts[:url] ||= service_url(opts)
38
-
39
- listener = opts.delete(:listener)
40
- @bridge = Remote::Bridge.handshake(**opts)
41
- super(@bridge, listener: listener)
42
- end
31
+ EXTENSIONS = [DriverExtensions::HasWebStorage].freeze
43
32
 
44
33
  def browser
45
34
  :internet_explorer
46
35
  end
47
-
48
- def quit
49
- super
50
- ensure
51
- @service&.stop
52
- end
53
-
54
- private
55
-
56
- def create_capabilities(opts)
57
- caps = opts.delete(:desired_capabilities) { Remote::Capabilities.internet_explorer }
58
- options = opts.delete(:options) { Options.new }
59
-
60
- if opts.delete(:introduce_flakiness_by_ignoring_security_domains)
61
- WebDriver.logger.deprecate ':introduce_flakiness_by_ignoring_security_domains',
62
- 'Selenium::WebDriver::IE::Options#ignore_protected_mode_settings='
63
- options.ignore_protected_mode_settings = true
64
- end
65
-
66
- native_events = opts.delete(:native_events)
67
- unless native_events.nil?
68
- WebDriver.logger.deprecate ':native_events', 'Selenium::WebDriver::IE::Options#native_events='
69
- options.native_events = native_events
70
- end
71
-
72
- # Backward compatibility with older IEDriverServer versions
73
- caps[:ignore_protected_mode_settings] = options.ignore_protected_mode_settings
74
- caps[:native_events] = options.native_events
75
-
76
- options = options.as_json
77
- caps.merge!(options) unless options.empty?
78
-
79
- caps
80
- end
81
-
82
36
  end # Driver
83
37
  end # IE
84
38
  end # WebDriver