selenium-webdriver 3.142.7 → 4.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +611 -5
  3. data/Gemfile +5 -1
  4. data/LICENSE +1 -1
  5. data/NOTICE +2 -0
  6. data/README.md +4 -5
  7. data/bin/linux/selenium-manager +0 -0
  8. data/bin/macos/selenium-manager +0 -0
  9. data/bin/windows/selenium-manager.exe +0 -0
  10. data/lib/selenium/server.rb +94 -79
  11. data/lib/selenium/webdriver/atoms/findElements.js +121 -0
  12. data/lib/selenium/webdriver/atoms/getAttribute.js +100 -7
  13. data/lib/selenium/webdriver/atoms/isDisplayed.js +76 -78
  14. data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
  15. data/lib/selenium/webdriver/atoms.rb +2 -3
  16. data/lib/selenium/webdriver/bidi/browsing_context.rb +88 -0
  17. data/lib/selenium/webdriver/bidi/browsing_context_info.rb +35 -0
  18. data/lib/selenium/webdriver/bidi/log/base_log_entry.rb +35 -0
  19. data/lib/selenium/webdriver/bidi/log/console_log_entry.rb +35 -0
  20. data/lib/selenium/webdriver/bidi/log/filter_by.rb +40 -0
  21. data/lib/selenium/webdriver/bidi/log/generic_log_entry.rb +33 -0
  22. data/lib/selenium/webdriver/bidi/log/javascript_log_entry.rb +33 -0
  23. data/lib/selenium/webdriver/bidi/log_inspector.rb +143 -0
  24. data/lib/selenium/webdriver/bidi/navigate_result.rb +33 -0
  25. data/lib/selenium/webdriver/bidi/session.rb +51 -0
  26. data/lib/selenium/webdriver/{common/keyboard.rb → bidi.rb} +21 -35
  27. data/lib/selenium/webdriver/chrome/driver.rb +9 -86
  28. data/lib/selenium/webdriver/chrome/features.rb +44 -0
  29. data/lib/selenium/webdriver/chrome/options.rb +9 -158
  30. data/lib/selenium/webdriver/chrome/profile.rb +3 -80
  31. data/lib/selenium/webdriver/chrome/service.rb +6 -33
  32. data/lib/selenium/webdriver/chrome.rb +5 -18
  33. data/lib/selenium/webdriver/chromium/driver.rb +61 -0
  34. data/lib/selenium/webdriver/{chrome/bridge.rb → chromium/features.rb} +51 -16
  35. data/lib/selenium/webdriver/chromium/options.rb +261 -0
  36. data/lib/selenium/webdriver/chromium/profile.rb +113 -0
  37. data/lib/selenium/webdriver/chromium/service.rb +42 -0
  38. data/lib/selenium/webdriver/chromium.rb +32 -0
  39. data/lib/selenium/webdriver/common/action_builder.rb +128 -238
  40. data/lib/selenium/webdriver/common/child_process.rb +124 -0
  41. data/lib/selenium/webdriver/common/driver.rb +94 -43
  42. data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -2
  43. data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +42 -0
  44. data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +0 -2
  45. data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +49 -0
  46. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +87 -0
  47. data/lib/selenium/webdriver/common/driver_extensions/{has_touch_screen.rb → has_bidi.rb} +9 -9
  48. data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +86 -0
  49. data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +36 -0
  50. data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +42 -0
  51. data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -2
  52. data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +41 -0
  53. data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +36 -0
  54. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -9
  55. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +143 -0
  56. data/lib/selenium/webdriver/common/driver_extensions/{has_remote_status.rb → has_logs.rb} +4 -4
  57. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +16 -1
  58. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +6 -27
  59. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +69 -0
  60. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +11 -13
  61. data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +75 -0
  62. data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
  63. data/lib/selenium/webdriver/common/driver_finder.rb +47 -0
  64. data/lib/selenium/webdriver/common/element.rb +89 -29
  65. data/lib/selenium/webdriver/common/error.rb +53 -194
  66. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
  67. data/lib/selenium/webdriver/common/interactions/input_device.rb +10 -4
  68. data/lib/selenium/webdriver/common/interactions/interaction.rb +12 -22
  69. data/lib/selenium/webdriver/common/interactions/interactions.rb +24 -4
  70. data/lib/selenium/webdriver/common/interactions/key_actions.rb +10 -6
  71. data/lib/selenium/webdriver/common/interactions/key_input.rb +11 -27
  72. data/lib/selenium/webdriver/common/interactions/none_input.rb +10 -8
  73. data/lib/selenium/webdriver/common/interactions/pause.rb +49 -0
  74. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +71 -82
  75. data/lib/selenium/webdriver/common/interactions/pointer_cancel.rb +45 -0
  76. data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +63 -0
  77. data/lib/selenium/webdriver/common/interactions/pointer_input.rb +15 -84
  78. data/lib/selenium/webdriver/common/interactions/pointer_move.rb +60 -0
  79. data/lib/selenium/webdriver/common/interactions/pointer_press.rb +85 -0
  80. data/lib/selenium/webdriver/common/interactions/scroll.rb +59 -0
  81. data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +48 -0
  82. data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +54 -0
  83. data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +113 -0
  84. data/lib/selenium/webdriver/common/{w3c_manager.rb → interactions/wheel_input.rb} +14 -17
  85. data/lib/selenium/webdriver/common/keys.rb +1 -0
  86. data/lib/selenium/webdriver/common/local_driver.rb +55 -0
  87. data/lib/selenium/webdriver/common/log_entry.rb +2 -2
  88. data/lib/selenium/webdriver/common/logger.rb +119 -19
  89. data/lib/selenium/webdriver/common/manager.rb +11 -38
  90. data/lib/selenium/webdriver/common/options.rb +169 -23
  91. data/lib/selenium/webdriver/common/platform.rb +14 -6
  92. data/lib/selenium/webdriver/common/port_prober.rb +4 -6
  93. data/lib/selenium/webdriver/common/profile_helper.rb +11 -9
  94. data/lib/selenium/webdriver/common/proxy.rb +8 -5
  95. data/lib/selenium/webdriver/common/search_context.rb +7 -9
  96. data/lib/selenium/webdriver/common/selenium_manager.rb +125 -0
  97. data/lib/selenium/webdriver/common/service.rb +26 -137
  98. data/lib/selenium/webdriver/common/service_manager.rb +144 -0
  99. data/lib/selenium/webdriver/common/shadow_root.rb +86 -0
  100. data/lib/selenium/webdriver/common/socket_lock.rb +4 -4
  101. data/lib/selenium/webdriver/common/socket_poller.rb +4 -4
  102. data/lib/selenium/webdriver/common/takes_screenshot.rb +65 -0
  103. data/lib/selenium/webdriver/common/target_locator.rb +31 -4
  104. data/lib/selenium/webdriver/common/timeouts.rb +31 -4
  105. data/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +85 -0
  106. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +72 -0
  107. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +62 -0
  108. data/lib/selenium/webdriver/common/wait.rb +1 -1
  109. data/lib/selenium/webdriver/common/websocket_connection.rb +164 -0
  110. data/lib/selenium/webdriver/common/window.rb +6 -10
  111. data/lib/selenium/webdriver/common/zipper.rb +4 -10
  112. data/lib/selenium/webdriver/common.rb +42 -18
  113. data/lib/selenium/webdriver/devtools/console_event.rb +36 -0
  114. data/lib/selenium/webdriver/devtools/exception_event.rb +34 -0
  115. data/lib/selenium/webdriver/devtools/mutation_event.rb +35 -0
  116. data/lib/selenium/webdriver/devtools/network_interceptor.rb +173 -0
  117. data/lib/selenium/webdriver/devtools/pinned_script.rb +57 -0
  118. data/lib/selenium/webdriver/devtools/request.rb +65 -0
  119. data/lib/selenium/webdriver/devtools/response.rb +64 -0
  120. data/lib/selenium/webdriver/devtools.rb +96 -0
  121. data/lib/selenium/webdriver/edge/driver.rb +11 -27
  122. data/lib/selenium/webdriver/edge/features.rb +44 -0
  123. data/lib/selenium/webdriver/edge/options.rb +18 -43
  124. data/lib/selenium/webdriver/edge/profile.rb +33 -0
  125. data/lib/selenium/webdriver/edge/service.rb +7 -27
  126. data/lib/selenium/webdriver/edge.rb +11 -14
  127. data/lib/selenium/webdriver/firefox/driver.rb +38 -19
  128. data/lib/selenium/webdriver/firefox/extension.rb +8 -0
  129. data/lib/selenium/webdriver/firefox/features.rb +66 -0
  130. data/lib/selenium/webdriver/firefox/options.rb +77 -50
  131. data/lib/selenium/webdriver/firefox/profile.rb +17 -71
  132. data/lib/selenium/webdriver/firefox/service.rb +3 -13
  133. data/lib/selenium/webdriver/firefox/util.rb +1 -1
  134. data/lib/selenium/webdriver/firefox.rb +17 -28
  135. data/lib/selenium/webdriver/ie/driver.rb +5 -45
  136. data/lib/selenium/webdriver/ie/options.rb +15 -46
  137. data/lib/selenium/webdriver/ie/service.rb +11 -19
  138. data/lib/selenium/webdriver/ie.rb +3 -16
  139. data/lib/selenium/webdriver/remote/bridge/commands.rb +170 -0
  140. data/lib/selenium/webdriver/remote/bridge.rb +592 -87
  141. data/lib/selenium/webdriver/remote/capabilities.rb +182 -124
  142. data/lib/selenium/webdriver/remote/driver.rb +30 -15
  143. data/lib/selenium/webdriver/remote/http/common.rb +3 -8
  144. data/lib/selenium/webdriver/remote/http/curb.rb +1 -3
  145. data/lib/selenium/webdriver/remote/http/default.rb +23 -31
  146. data/lib/selenium/webdriver/remote/response.rb +17 -49
  147. data/lib/selenium/webdriver/remote.rb +14 -12
  148. data/lib/selenium/webdriver/safari/driver.rb +7 -29
  149. data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +3 -5
  150. data/lib/selenium/webdriver/safari/options.rb +12 -27
  151. data/lib/selenium/webdriver/safari/service.rb +13 -11
  152. data/lib/selenium/webdriver/safari.rb +14 -20
  153. data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
  154. data/lib/selenium/webdriver/support/color.rb +24 -24
  155. data/lib/selenium/webdriver/support/event_firing_bridge.rb +4 -4
  156. data/lib/selenium/webdriver/support/guards/guard.rb +87 -0
  157. data/lib/selenium/webdriver/{firefox/marionette/bridge.rb → support/guards/guard_condition.rb} +21 -20
  158. data/lib/selenium/webdriver/support/guards.rb +95 -0
  159. data/lib/selenium/webdriver/support/relative_locator.rb +50 -0
  160. data/lib/selenium/webdriver/support/select.rb +6 -4
  161. data/lib/selenium/webdriver/support.rb +1 -0
  162. data/lib/selenium/webdriver/version.rb +1 -1
  163. data/lib/selenium/webdriver.rb +18 -17
  164. data/selenium-webdriver.gemspec +36 -18
  165. metadata +159 -89
  166. data/lib/selenium/webdriver/common/bridge_helper.rb +0 -82
  167. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -64
  168. data/lib/selenium/webdriver/common/mouse.rb +0 -89
  169. data/lib/selenium/webdriver/common/touch_action_builder.rb +0 -78
  170. data/lib/selenium/webdriver/common/touch_screen.rb +0 -123
  171. data/lib/selenium/webdriver/common/w3c_action_builder.rb +0 -212
  172. data/lib/selenium/webdriver/edge/bridge.rb +0 -76
  173. data/lib/selenium/webdriver/firefox/binary.rb +0 -187
  174. data/lib/selenium/webdriver/firefox/extension/prefs.json +0 -69
  175. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  176. data/lib/selenium/webdriver/firefox/launcher.rb +0 -111
  177. data/lib/selenium/webdriver/firefox/legacy/driver.rb +0 -83
  178. data/lib/selenium/webdriver/firefox/marionette/driver.rb +0 -90
  179. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  180. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  181. data/lib/selenium/webdriver/remote/http/persistent.rb +0 -60
  182. data/lib/selenium/webdriver/remote/oss/bridge.rb +0 -594
  183. data/lib/selenium/webdriver/remote/oss/commands.rb +0 -223
  184. data/lib/selenium/webdriver/remote/w3c/bridge.rb +0 -605
  185. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +0 -310
  186. data/lib/selenium/webdriver/remote/w3c/commands.rb +0 -157
@@ -17,62 +17,37 @@
17
17
  # specific language governing permissions and limitations
18
18
  # under the License.
19
19
 
20
+ require 'selenium/webdriver/chromium/options'
21
+
20
22
  module Selenium
21
23
  module WebDriver
22
24
  module Edge
23
- class Options
24
- attr_accessor :in_private, :start_page
25
- attr_reader :extension_paths
25
+ class Options < Chromium::Options
26
+ KEY = 'ms:edgeOptions'
27
+ BROWSER = 'MicrosoftEdge'
26
28
 
27
29
  #
28
- # Create a new Options instance for Edge.
29
- #
30
- # @example
31
- # options = Selenium::WebDriver::Edge::Options.new(in_private: true)
32
- # driver = Selenium::WebDriver.for :edge, options: options
33
- #
34
- # @param [Hash] opts the pre-defined options to create the Edge::Options with
35
- # @option opts [Boolean] :in_private Start in private mode. Default is false
36
- # @option opts [Array<String>] :extension_paths A list of full paths to extensions to install on startup
37
- # @option opts [String] :start_page Default page to start with
38
- #
39
- # @see https://docs.microsoft.com/en-us/microsoft-edge/webdriver
40
- #
41
-
42
- def initialize(**opts)
43
- @in_private = opts.delete(:in_private) || false
44
- @extension_paths = opts.delete(:extension_paths) || []
45
- @start_page = opts.delete(:start_page)
46
- end
47
-
30
+ # Changes the browser name enable webview2
31
+ # see: https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/webdriver
32
+ # Automation of WebView2 apps with Microsoft Edge WebDriver
48
33
  #
49
- # Add an extension by local path.
50
- #
51
- # @example
34
+ # @example Enable webview2
52
35
  # options = Selenium::WebDriver::Edge::Options.new
53
- # options.add_extension_path('C:\path\to\extension')
54
- #
55
- # @param [String] path The local path to the extension folder
36
+ # options.webview2!
56
37
  #
57
38
 
58
- def add_extension_path(path)
59
- raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.directory?(path)
60
-
61
- @extension_paths << path
39
+ def webview2!
40
+ @options[:browser_name] = 'webview2'
62
41
  end
63
42
 
64
- #
65
- # @api private
66
- #
67
-
68
- def as_json(*)
69
- opts = {}
43
+ private
70
44
 
71
- opts['ms:inPrivate'] = true if @in_private
72
- opts['ms:extensionPaths'] = @extension_paths if @extension_paths.any?
73
- opts['ms:startPage'] = @start_page if @start_page
45
+ def enable_logging(browser_options)
46
+ browser_options['ms:loggingPrefs'] = @logging_prefs
47
+ end
74
48
 
75
- opts
49
+ def binary_path
50
+ Edge.path
76
51
  end
77
52
  end # Options
78
53
  end # Edge
@@ -0,0 +1,33 @@
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
+ require 'selenium/webdriver/chromium/profile'
21
+
22
+ module Selenium
23
+ module WebDriver
24
+ module Edge
25
+ #
26
+ # @private
27
+ #
28
+
29
+ class Profile < Chromium::Profile
30
+ end # Profile
31
+ end # Edge
32
+ end # WebDriver
33
+ end # Selenium
@@ -17,36 +17,16 @@
17
17
  # specific language governing permissions and limitations
18
18
  # under the License.
19
19
 
20
+ require 'selenium/webdriver/chromium/service'
21
+
20
22
  module Selenium
21
23
  module WebDriver
22
24
  module Edge
23
- #
24
- # @api private
25
- #
26
-
27
- class Service < WebDriver::Service
28
- @default_port = 17556
29
- @executable = 'MicrosoftWebDriver'
30
- @missing_text = <<~ERROR
31
- Unable to find MicrosoftWebDriver. Please download the server from
32
- https://www.microsoft.com/en-us/download/details.aspx?id=48212 and place it somewhere on your PATH.
33
- More info at https://github.com/SeleniumHQ/selenium/wiki/MicrosoftWebDriver.
34
- ERROR
35
- @shutdown_supported = true
36
-
37
- private
38
-
39
- # Note: This processing is deprecated
40
- def extract_service_args(driver_opts)
41
- driver_args = super
42
- driver_opts = driver_opts.dup
43
- driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key? :host
44
- driver_args << "--package=#{driver_opts[:package]}" if driver_opts.key? :package
45
- driver_args << "--silent" if driver_opts[:silent] == true
46
- driver_args << "--verbose" if driver_opts[:verbose] == true
47
- driver_args
48
- end
25
+ class Service < Chromium::Service
26
+ DEFAULT_PORT = 9515
27
+ EXECUTABLE = 'msedgedriver'
28
+ SHUTDOWN_SUPPORTED = true
49
29
  end # Service
50
30
  end # Edge
51
31
  end # WebDriver
52
- end # Service
32
+ end # Selenium
@@ -19,26 +19,23 @@
19
19
 
20
20
  require 'net/http'
21
21
 
22
- require 'selenium/webdriver/edge/bridge'
23
- require 'selenium/webdriver/edge/driver'
24
- require 'selenium/webdriver/edge/options'
25
-
26
22
  module Selenium
27
23
  module WebDriver
28
24
  module Edge
29
- def self.driver_path=(path)
30
- WebDriver.logger.deprecate 'Selenium::WebDriver::Edge#driver_path=',
31
- 'Selenium::WebDriver::Edge::Service#driver_path='
32
- Selenium::WebDriver::Edge::Service.driver_path = path
25
+ autoload :Features, 'selenium/webdriver/edge/features'
26
+ autoload :Driver, 'selenium/webdriver/edge/driver'
27
+ autoload :Profile, 'selenium/webdriver/edge/profile'
28
+ autoload :Options, 'selenium/webdriver/edge/options'
29
+ autoload :Service, 'selenium/webdriver/edge/service'
30
+
31
+ def self.path=(path)
32
+ Platform.assert_executable path
33
+ @path = path
33
34
  end
34
35
 
35
- def self.driver_path
36
- WebDriver.logger.deprecate 'Selenium::WebDriver::Edge#driver_path',
37
- 'Selenium::WebDriver::Edge::Service#driver_path'
38
- Selenium::WebDriver::Edge::Service.driver_path
36
+ def self.path
37
+ @path ||= nil
39
38
  end
40
39
  end # Edge
41
40
  end # WebDriver
42
41
  end # Selenium
43
-
44
- require 'selenium/webdriver/edge/service'
@@ -20,30 +20,49 @@
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
23
+ #
24
+ # Driver implementation for Firefox using GeckoDriver.
25
+ # @api private
26
+ #
27
+
28
+ class Driver < WebDriver::Driver
29
+ EXTENSIONS = [DriverExtensions::HasAddons,
30
+ DriverExtensions::FullPageScreenshot,
31
+ DriverExtensions::HasContext,
32
+ DriverExtensions::HasBiDi,
33
+ DriverExtensions::HasDevTools,
34
+ DriverExtensions::HasLogEvents,
35
+ DriverExtensions::HasNetworkInterception,
36
+ DriverExtensions::HasWebStorage,
37
+ DriverExtensions::PrintsPage].freeze
38
+
39
+ include LocalDriver
40
+
41
+ def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
42
+ caps, url = initialize_local_driver(capabilities, options, service, url)
43
+ super(caps: caps, url: url, **opts)
44
+ end
38
45
 
39
- private
46
+ def browser
47
+ :firefox
48
+ end
49
+
50
+ private
40
51
 
41
- def marionette?(opts)
42
- opts.delete(:marionette) != false &&
43
- (!opts[:desired_capabilities] || opts[:desired_capabilities][:marionette] != false)
52
+ def devtools_url
53
+ if capabilities['moz:debuggerAddress'].nil?
54
+ raise(Error::WebDriverError, 'DevTools is not supported by this version of Firefox; use v85 or higher')
44
55
  end
56
+
57
+ uri = URI("http://#{capabilities['moz:debuggerAddress']}")
58
+ response = Net::HTTP.get(uri.hostname, '/json/version', uri.port)
59
+
60
+ JSON.parse(response)['webSocketDebuggerUrl']
45
61
  end
46
62
 
63
+ def devtools_version
64
+ Firefox::DEVTOOLS_VERSION
65
+ end
47
66
  end # Driver
48
67
  end # Firefox
49
68
  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
+ FIREFOX_COMMANDS = {
25
+ get_context: [:get, 'session/:session_id/moz/context'],
26
+ set_context: [:post, 'session/:session_id/moz/context'],
27
+ install_addon: [:post, 'session/:session_id/moz/addon/install'],
28
+ uninstall_addon: [:post, 'session/:session_id/moz/addon/uninstall'],
29
+ full_page_screenshot: [:get, 'session/:session_id/moz/screenshot/full']
30
+ }.freeze
31
+
32
+ def commands(command)
33
+ FIREFOX_COMMANDS[command] || self.class::COMMANDS[command]
34
+ end
35
+
36
+ def install_addon(path, temporary)
37
+ addon = if File.directory?(path)
38
+ Zipper.zip(path)
39
+ else
40
+ File.open(path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read }
41
+ end
42
+
43
+ payload = {addon: addon}
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,18 +20,32 @@
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://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions
29
+ CAPABILITIES = {binary: 'binary',
30
+ args: 'args',
31
+ log: 'log',
32
+ prefs: 'prefs',
33
+ env: 'env',
34
+ android_package: 'androidPackage',
35
+ android_activity: 'androidActivity',
36
+ android_device_serial: 'androidDeviceSerial',
37
+ android_intent_arguments: 'androidIntentArguments'}.freeze
38
+ BROWSER = 'firefox'
39
+
40
+ # NOTE: special handling of 'profile' to validate when set instead of when used
41
+ attr_reader :profile
42
+
29
43
  #
30
44
  # Create a new Options instance, only for W3C-capable versions of Firefox.
31
45
  #
32
46
  # @example
33
47
  # options = Selenium::WebDriver::Firefox::Options.new(args: ['--host=127.0.0.1'])
34
- # driver = Selenium::WebDriver.for :firefox, options: options
48
+ # driver = Selenium::WebDriver.for :firefox, capabilities: options
35
49
  #
36
50
  # @param [Hash] opts the pre-defined options to create the Firefox::Options with
37
51
  # @option opts [String] :binary Path to the Firefox executable to use
@@ -42,13 +56,18 @@ module Selenium
42
56
  # @option opts [Hash] :options A hash for raw options
43
57
  #
44
58
 
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) || {}
59
+ def initialize(log_level: nil, **opts)
60
+ @debugger_address = opts.delete(:debugger_address) { true }
61
+ opts[:accept_insecure_certs] = true unless opts.key?(:accept_insecure_certs)
62
+
63
+ super(**opts)
64
+
65
+ @options[:args] ||= []
66
+ @options[:prefs] ||= {}
67
+ @options[:env] ||= {}
68
+ @options[:log] ||= {level: log_level} if log_level
69
+
70
+ process_profile(@options.delete(:profile))
52
71
  end
53
72
 
54
73
  #
@@ -62,22 +81,7 @@ module Selenium
62
81
  #
63
82
 
64
83
  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
84
+ @options[:args] << arg
81
85
  end
82
86
 
83
87
  #
@@ -92,7 +96,7 @@ module Selenium
92
96
  #
93
97
 
94
98
  def add_preference(name, value)
95
- prefs[name] = value
99
+ @options[:prefs][name] = value
96
100
  end
97
101
 
98
102
  #
@@ -104,6 +108,9 @@ module Selenium
104
108
  #
105
109
 
106
110
  def headless!
111
+ WebDriver.logger.deprecate('`Options#headless!`',
112
+ "`Options#add_argument('-headless')`",
113
+ id: :headless)
107
114
  add_argument '-headless'
108
115
  end
109
116
 
@@ -123,38 +130,58 @@ module Selenium
123
130
  #
124
131
 
125
132
  def profile=(profile)
126
- @profile = process_profile(profile)
133
+ process_profile(profile)
127
134
  end
128
135
 
129
- #
130
- # @api private
131
- #
136
+ def log_level
137
+ @options.dig(:log, :level)
138
+ end
132
139
 
133
- def as_json(*)
134
- opts = @options
140
+ def log_level=(level)
141
+ @options[:log] = {level: level}
142
+ end
135
143
 
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
144
+ #
145
+ # Enables mobile browser use on Android.
146
+ #
147
+ # @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions#android
148
+ #
149
+ # @param [String] package The package name of the Chrome or WebView app.
150
+ # @param [String] serial_number The serial number of the device on which to launch the application.
151
+ # If not specified and multiple devices are attached, an error will be returned.
152
+ # @param [String] activity The fully qualified class name of the activity to be launched.
153
+ # @param [Array] intent_arguments Arguments to launch the intent with.
154
+ #
141
155
 
142
- {KEY => generate_as_json(opts)}
156
+ def enable_android(package: 'org.mozilla.firefox', serial_number: nil, activity: nil, intent_arguments: nil)
157
+ @options[:android_package] = package
158
+ @options[:android_activity] = activity unless activity.nil?
159
+ @options[:android_device_serial] = serial_number unless serial_number.nil?
160
+ @options[:android_intent_arguments] = intent_arguments unless intent_arguments.nil?
143
161
  end
144
162
 
145
163
  private
146
164
 
165
+ def process_browser_options(browser_options)
166
+ browser_options['moz:debuggerAddress'] = true if @debugger_address
167
+ options = browser_options[KEY]
168
+ options['binary'] ||= Firefox.path if Firefox.path
169
+ options['profile'] = @profile if @profile
170
+ end
171
+
147
172
  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
173
+ @profile = case profile
174
+ when nil
175
+ nil
176
+ when Profile
177
+ profile
178
+ else
179
+ Profile.from_name(profile)
180
+ end
181
+ end
182
+
183
+ def camelize?(key)
184
+ key != 'prefs'
158
185
  end
159
186
  end # Options
160
187
  end # Firefox