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,109 +17,32 @@
17
17
  # specific language governing permissions and limitations
18
18
  # under the License.
19
19
 
20
+ require 'selenium/webdriver/chromium/driver'
21
+
20
22
  module Selenium
21
23
  module WebDriver
22
24
  module Chrome
23
-
24
25
  #
25
26
  # Driver implementation for Chrome.
26
27
  # @api private
27
28
  #
28
29
 
29
- class Driver < WebDriver::Driver
30
- include DriverExtensions::HasNetworkConditions
31
- include DriverExtensions::HasTouchScreen
32
- include DriverExtensions::HasWebStorage
33
- include DriverExtensions::HasLocation
34
- include DriverExtensions::TakesScreenshot
35
- include DriverExtensions::DownloadsFiles
36
-
37
- def initialize(opts = {})
38
- opts[:desired_capabilities] = create_capabilities(opts)
30
+ class Driver < Chromium::Driver
31
+ include LocalDriver
39
32
 
40
- opts[:url] ||= service_url(opts)
41
-
42
- listener = opts.delete(:listener)
43
- @bridge = Remote::Bridge.handshake(**opts)
44
- @bridge.extend Bridge
45
-
46
- super(@bridge, listener: listener)
33
+ def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
34
+ caps, url = initialize_local_driver(capabilities, options, service, url)
35
+ super(caps: caps, url: url, **opts)
47
36
  end
48
37
 
49
38
  def browser
50
39
  :chrome
51
40
  end
52
41
 
53
- def quit
54
- super
55
- ensure
56
- @service&.stop
57
- end
58
-
59
- def execute_cdp(cmd, **params)
60
- @bridge.send_command(cmd: cmd, params: params)
61
- end
62
-
63
42
  private
64
43
 
65
- def create_capabilities(opts)
66
- caps = opts.delete(:desired_capabilities) { Remote::Capabilities.chrome }
67
- options = opts.delete(:options) { Options.new }
68
-
69
- args = opts.delete(:args) || opts.delete(:switches)
70
- if args
71
- WebDriver.logger.deprecate ':args or :switches', 'Selenium::WebDriver::Chrome::Options#add_argument'
72
- raise ArgumentError, ':args must be an Array of Strings' unless args.is_a? Array
73
-
74
- args.each { |arg| options.add_argument(arg.to_s) }
75
- end
76
-
77
- profile = opts.delete(:profile)
78
- if profile
79
- WebDriver.logger.deprecate 'Selenium::WebDriver::Chrome::Driver#new with `:profile` parameter',
80
- 'Selenium::WebDriver::Chrome::Options#profile or Options#add_option'
81
-
82
- profile = profile.as_json
83
-
84
- if options.args.none?(&/user-data-dir/.method(:match?))
85
- options.add_argument("--user-data-dir=#{profile['directory']}")
86
- end
87
-
88
- if profile['extensions']
89
- WebDriver.logger.deprecate 'Selenium::WebDriver::Chrome::Profile#extensions',
90
- 'Selenium::WebDriver::Chrome::Options#add_extension'
91
- profile['extensions'].each do |extension|
92
- options.add_encoded_extension(extension)
93
- end
94
- end
95
- end
96
-
97
- if opts.key?(:detach)
98
- WebDriver.logger.deprecate 'Selenium::WebDriver::Chrome::Driver#new with `:detach` parameter',
99
- 'Selenium::WebDriver::Chrome::Options#new or Options#add_option'
100
- options.add_option(:detach, opts.delete(:detach))
101
- end
102
-
103
- prefs = opts.delete(:prefs)
104
- if prefs
105
- WebDriver.logger.deprecate ':prefs', 'Selenium::WebDriver::Chrome::Options#add_preference'
106
- prefs.each do |key, value|
107
- options.add_preference(key, value)
108
- end
109
- end
110
-
111
- options = options.as_json
112
- caps.merge!(options) unless options[Options::KEY].empty?
113
-
114
- if opts.key?(:proxy) || opts.key?('proxy')
115
- WebDriver.logger.deprecate 'Selenium::WebDriver::Chrome::Driver#new with `:proxy` parameter',
116
- 'Selenium::WebDriver::Chrome::Capabilities#proxy='
117
-
118
- caps[:proxy] = opts.delete(:proxy) if opts.key?(:proxy)
119
- caps[:proxy] ||= opts.delete('proxy') if opts.key?('proxy')
120
- end
121
-
122
- caps
44
+ def devtools_address
45
+ "http://#{capabilities['goog:chromeOptions']['debuggerAddress']}"
123
46
  end
124
47
  end # Driver
125
48
  end # Chrome
@@ -0,0 +1,44 @@
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/features'
21
+
22
+ module Selenium
23
+ module WebDriver
24
+ module Chrome
25
+ module Features
26
+ include WebDriver::Chromium::Features
27
+
28
+ CHROME_COMMANDS = {
29
+ get_cast_sinks: [:get, 'session/:session_id/goog/cast/get_sinks'],
30
+ set_cast_sink_to_use: [:post, 'session/:session_id/goog/cast/set_sink_to_use'],
31
+ start_cast_tab_mirroring: [:post, 'session/:session_id/goog/cast/start_tab_mirroring'],
32
+ start_cast_desktop_mirroring: [:post, 'session/:session_id/goog/cast/start_desktop_mirroring'],
33
+ get_cast_issue_message: [:get, 'session/:session_id/goog/cast/get_issue_message'],
34
+ stop_casting: [:post, 'session/:session_id/goog/cast/stop_casting'],
35
+ send_command: [:post, 'session/:session_id/goog/cdp/execute']
36
+ }.freeze
37
+
38
+ def commands(command)
39
+ CHROME_COMMANDS[command] || CHROMIUM_COMMANDS[command] || self.class::COMMANDS[command]
40
+ end
41
+ end # Bridge
42
+ end # Chrome
43
+ end # WebDriver
44
+ end # Selenium
@@ -17,172 +17,23 @@
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 Chrome
23
- class Options < WebDriver::Common::Options
24
- attr_reader :args, :prefs, :options, :emulation, :extensions, :encoded_extensions
25
- attr_accessor :binary, :profile, :detach
26
-
25
+ class Options < Chromium::Options
27
26
  KEY = 'goog:chromeOptions'
27
+ BROWSER = 'chrome'
28
28
 
29
- #
30
- # Create a new Options instance.
31
- #
32
- # @example
33
- # options = Selenium::WebDriver::Chrome::Options.new(args: ['start-maximized', 'user-data-dir=/tmp/temp_profile'])
34
- # driver = Selenium::WebDriver.for(:chrome, options: options)
35
- #
36
- # @param [Hash] opts the pre-defined options to create the Chrome::Options with
37
- # @option opts [Array<String>] :args List of command-line arguments to use when starting Chrome
38
- # @option opts [String] :binary Path to the Chrome executable to use
39
- # @option opts [Hash] :prefs A hash with each entry consisting of the name of the preference and its value
40
- # @option opts [Array<String>] :extensions A list of paths to (.crx) Chrome extensions to install on startup
41
- # @option opts [Hash] :options A hash for raw options
42
- # @option opts [Hash] :emulation A hash for raw emulation options
43
- #
44
-
45
- def initialize(**opts)
46
- @args = Set.new(opts.delete(:args) || [])
47
- @binary = opts.delete(:binary) || Chrome.path
48
- @prefs = opts.delete(:prefs) || {}
49
- @extensions = opts.delete(:extensions) || []
50
- @options = opts.delete(:options) || {}
51
- @emulation = opts.delete(:emulation) || {}
52
- @detach = opts.delete(:detach)
53
- @profile = opts.delete(:profile)
54
- @encoded_extensions = []
55
- end
56
-
57
- #
58
- # Add an extension by local path.
59
- #
60
- # @example
61
- # options = Selenium::WebDriver::Chrome::Options.new
62
- # options.add_extension('/path/to/extension.crx')
63
- #
64
- # @param [String] path The local path to the .crx file
65
- #
66
-
67
- def add_extension(path)
68
- raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.file?(path)
69
- raise Error::WebDriverError, "file was not an extension #{path.inspect}" unless File.extname(path) == '.crx'
70
-
71
- @extensions << path
72
- end
73
-
74
- #
75
- # Add an extension by Base64-encoded string.
76
- #
77
- # @example
78
- # options = Selenium::WebDriver::Chrome::Options.new
79
- # options.add_encoded_extension(encoded_string)
80
- #
81
- # @param [String] encoded The Base64-encoded string of the .crx file
82
- #
29
+ private
83
30
 
84
- def add_encoded_extension(encoded)
85
- @encoded_extensions << encoded
31
+ def enable_logging(browser_options)
32
+ browser_options['goog:loggingPrefs'] = @logging_prefs
86
33
  end
87
34
 
88
- #
89
- # Add a command-line argument to use when starting Chrome.
90
- #
91
- # @example Start Chrome maximized
92
- # options = Selenium::WebDriver::Chrome::Options.new
93
- # options.add_argument('start-maximized')
94
- #
95
- # @param [String] arg The command-line argument to add
96
- #
97
-
98
- def add_argument(arg)
99
- @args << arg
100
- end
101
-
102
- #
103
- # Add a new option not yet handled by bindings.
104
- #
105
- # @example Leave Chrome open when chromedriver is killed
106
- # options = Selenium::WebDriver::Chrome::Options.new
107
- # options.add_option(:detach, true)
108
- #
109
- # @param [String, Symbol] name Name of the option
110
- # @param [Boolean, String, Integer] value Value of the option
111
- #
112
-
113
- def add_option(name, value)
114
- @options[name] = value
115
- end
116
-
117
- #
118
- # Add a preference that is only applied to the user profile in use.
119
- #
120
- # @example Set the default homepage
121
- # options = Selenium::WebDriver::Chrome::Options.new
122
- # options.add_preference('homepage', 'http://www.seleniumhq.com/')
123
- #
124
- # @param [String] name Key of the preference
125
- # @param [Boolean, String, Integer] value Value of the preference
126
- #
127
-
128
- def add_preference(name, value)
129
- prefs[name] = value
130
- end
131
-
132
- #
133
- # Run Chrome in headless mode.
134
- #
135
- # @example Enable headless mode
136
- # options = Selenium::WebDriver::Chrome::Options.new
137
- # options.headless!
138
- #
139
-
140
- def headless!
141
- add_argument '--headless'
142
- end
143
-
144
- #
145
- # Add an emulation device name
146
- #
147
- # @example Start Chrome in mobile emulation mode by device name
148
- # options = Selenium::WebDriver::Chrome::Options.new
149
- # options.add_emulation(device_name: 'iPhone 6')
150
- #
151
- # @example Start Chrome in mobile emulation mode by device metrics
152
- # options = Selenium::WebDriver::Chrome::Options.new
153
- # options.add_emulation(device_metrics: {width: 400, height: 800, pixelRatio: 1, touch: true})
154
- #
155
- # @param [String] device_name Name of the device or a hash containing width, height, pixelRatio, touch
156
- # @param [Hash] device_metrics Hash containing width, height, pixelRatio, touch
157
- # @param [String] user_agent Full user agent
158
- #
159
-
160
- def add_emulation(device_name: nil, device_metrics: nil, user_agent: nil)
161
- @emulation[:deviceName] = device_name if device_name
162
- @emulation[:deviceMetrics] = device_metrics if device_metrics
163
- @emulation[:userAgent] = user_agent if user_agent
164
- end
165
-
166
- #
167
- # @api private
168
- #
169
-
170
- def as_json(*)
171
- extensions = @extensions.map do |crx_path|
172
- File.open(crx_path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read }
173
- end
174
- extensions.concat(@encoded_extensions)
175
- add_argument("--user-data-dir=#{@profile[:directory]}") if @profile
176
-
177
- opts = @options
178
- opts[:binary] = @binary if @binary
179
- opts[:args] = @args.to_a if @args.any?
180
- opts[:extensions] = extensions if extensions.any?
181
- opts[:mobileEmulation] = @emulation unless @emulation.empty?
182
- opts[:prefs] = @prefs unless @prefs.empty?
183
- opts[:detach] = @detach if !@detach.nil? && @detach != false
184
-
185
- {KEY => generate_as_json(opts)}
35
+ def binary_path
36
+ Chrome.path
186
37
  end
187
38
  end # Options
188
39
  end # Chrome
@@ -17,6 +17,8 @@
17
17
  # specific language governing permissions and limitations
18
18
  # under the License.
19
19
 
20
+ require 'selenium/webdriver/chromium/profile'
21
+
20
22
  module Selenium
21
23
  module WebDriver
22
24
  module Chrome
@@ -24,86 +26,7 @@ module Selenium
24
26
  # @private
25
27
  #
26
28
 
27
- class Profile
28
- include ProfileHelper
29
-
30
- attr_reader :directory
31
-
32
- def initialize(model = nil)
33
- @model = verify_model(model)
34
- @extensions = []
35
- @encoded_extensions = []
36
- end
37
-
38
- def add_extension(path)
39
- raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.file?(path)
40
-
41
- @extensions << path
42
- end
43
-
44
- def add_encoded_extension(encoded)
45
- @encoded_extensions << encoded
46
- end
47
-
48
- #
49
- # Set a preference in the profile.
50
- #
51
- # See https://src.chromium.org/svn/trunk/src/chrome/common/pref_names.cc
52
- #
53
-
54
- def []=(key, value)
55
- parts = key.split('.')
56
- parts[0..-2].inject(prefs) { |a, e| a[e] ||= {} }[parts.last] = value
57
- end
58
-
59
- def [](key)
60
- parts = key.split('.')
61
- parts.inject(prefs) { |a, e| a.fetch(e) }
62
- end
63
-
64
- def layout_on_disk
65
- @directory = @model ? create_tmp_copy(@model) : Dir.mktmpdir('webdriver-chrome-profile')
66
- FileReaper << @directory
67
-
68
- write_prefs_to @directory
69
-
70
- @directory
71
- end
72
-
73
- def as_json(*)
74
- extensions = @extensions.map do |crx_path|
75
- File.open(crx_path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read }
76
- end
77
-
78
- extensions.concat(@encoded_extensions)
79
-
80
- opts = {'directory' => directory || layout_on_disk}
81
- opts['extensions'] = extensions if extensions.any?
82
- opts
83
- end
84
-
85
- private
86
-
87
- def write_prefs_to(dir)
88
- prefs_file = prefs_file_for(dir)
89
-
90
- FileUtils.mkdir_p File.dirname(prefs_file)
91
- File.open(prefs_file, 'w') { |file| file << JSON.generate(prefs) }
92
- end
93
-
94
- def prefs
95
- @prefs ||= read_model_prefs
96
- end
97
-
98
- def read_model_prefs
99
- return {} unless @model
100
-
101
- JSON.parse File.read(prefs_file_for(@model))
102
- end
103
-
104
- def prefs_file_for(dir)
105
- File.join dir, 'Default', 'Preferences'
106
- end
29
+ class Profile < Chromium::Profile
107
30
  end # Profile
108
31
  end # Chrome
109
32
  end # WebDriver
@@ -17,42 +17,15 @@
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 Chrome
23
- #
24
- # @api private
25
- #
26
-
27
- class Service < WebDriver::Service
28
- @default_port = 9515
29
- @executable = 'chromedriver'
30
- @missing_text = <<~ERROR
31
- Unable to find chromedriver. Please download the server from
32
- https://chromedriver.storage.googleapis.com/index.html and place it somewhere on your PATH.
33
- More info at https://github.com/SeleniumHQ/selenium/wiki/ChromeDriver.
34
- ERROR
35
- @shutdown_supported = true
36
-
37
- def self.driver_path=(path)
38
- Platform.assert_executable path if path.is_a?(String)
39
- @driver_path = path
40
- end
41
-
42
- private
43
-
44
- # Note: This processing is deprecated
45
- def extract_service_args(driver_opts)
46
- driver_args = super
47
- driver_opts = driver_opts.dup
48
- driver_args << "--log-path=#{driver_opts.delete(:log_path)}" if driver_opts.key?(:log_path)
49
- driver_args << "--url-base=#{driver_opts.delete(:url_base)}" if driver_opts.key?(:url_base)
50
- driver_args << "--port-server=#{driver_opts.delete(:port_server)}" if driver_opts.key?(:port_server)
51
- driver_args << "--whitelisted-ips=#{driver_opts.delete(:whitelisted_ips)}" if driver_opts.key?(:whitelisted_ips)
52
- driver_args << "--verbose" if driver_opts.key?(:verbose)
53
- driver_args << "--silent" if driver_opts.key?(:silent)
54
- driver_args
55
- end
25
+ class Service < Chromium::Service
26
+ DEFAULT_PORT = 9515
27
+ EXECUTABLE = 'chromedriver'
28
+ SHUTDOWN_SUPPORTED = true
56
29
  end # Service
57
30
  end # Chrome
58
31
  end # WebDriver
@@ -19,25 +19,14 @@
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
30
- def self.driver_path=(path)
31
- WebDriver.logger.deprecate 'Selenium::WebDriver::Chrome#driver_path=',
32
- 'Selenium::WebDriver::Chrome::Service#driver_path='
33
- Selenium::WebDriver::Chrome::Service.driver_path = path
34
- end
35
-
36
- def self.driver_path
37
- WebDriver.logger.deprecate 'Selenium::WebDriver::Chrome#driver_path',
38
- 'Selenium::WebDriver::Chrome::Service#driver_path'
39
- Selenium::WebDriver::Chrome::Service.driver_path
40
- end
25
+ autoload :Features, 'selenium/webdriver/chrome/features'
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'
41
30
 
42
31
  def self.path=(path)
43
32
  Platform.assert_executable path
@@ -50,5 +39,3 @@ module Selenium
50
39
  end # Chrome
51
40
  end # WebDriver
52
41
  end # Selenium
53
-
54
- require 'selenium/webdriver/chrome/service'
@@ -0,0 +1,61 @@
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 Chromium
23
+ #
24
+ # Driver implementation for Chrome.
25
+ # @api private
26
+ #
27
+
28
+ class Driver < WebDriver::Driver
29
+ EXTENSIONS = [DriverExtensions::HasCDP,
30
+ DriverExtensions::HasBiDi,
31
+ DriverExtensions::HasCasting,
32
+ DriverExtensions::HasNetworkConditions,
33
+ DriverExtensions::HasNetworkInterception,
34
+ DriverExtensions::HasWebStorage,
35
+ DriverExtensions::HasLaunching,
36
+ DriverExtensions::HasLocation,
37
+ DriverExtensions::HasPermissions,
38
+ DriverExtensions::DownloadsFiles,
39
+ DriverExtensions::HasDevTools,
40
+ DriverExtensions::HasAuthentication,
41
+ DriverExtensions::HasLogs,
42
+ DriverExtensions::HasLogEvents,
43
+ DriverExtensions::HasPinnedScripts,
44
+ DriverExtensions::PrintsPage].freeze
45
+
46
+ protected
47
+
48
+ def devtools_url
49
+ uri = URI(devtools_address)
50
+ response = Net::HTTP.get(uri.hostname, '/json/version', uri.port)
51
+
52
+ JSON.parse(response)['webSocketDebuggerUrl']
53
+ end
54
+
55
+ def devtools_version
56
+ Integer(capabilities.browser_version.split('.').first)
57
+ end
58
+ end # Driver
59
+ end # Chromium
60
+ end # WebDriver
61
+ end # Selenium
@@ -19,33 +19,70 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- module Chrome
23
- module Bridge
24
-
25
- COMMANDS = {
22
+ module Chromium
23
+ module Features
24
+ CHROMIUM_COMMANDS = {
25
+ launch_app: [:post, 'session/:session_id/chromium/launch_app'],
26
26
  get_network_conditions: [:get, 'session/:session_id/chromium/network_conditions'],
27
27
  set_network_conditions: [:post, 'session/:session_id/chromium/network_conditions'],
28
- send_command: [:post, 'session/:session_id/goog/cdp/execute'],
28
+ delete_network_conditions: [:delete, 'session/:session_id/chromium/network_conditions'],
29
+ set_permission: [:post, 'session/:session_id/permissions'],
29
30
  get_available_log_types: [:get, 'session/:session_id/se/log/types'],
30
31
  get_log: [:post, 'session/:session_id/se/log']
31
32
  }.freeze
32
33
 
33
34
  def commands(command)
34
- COMMANDS[command] || super
35
+ CHROME_COMMANDS[command] || self.class::COMMANDS[command]
35
36
  end
36
37
 
37
- def network_conditions
38
- execute :get_network_conditions
38
+ def launch_app(id)
39
+ execute :launch_app, {}, {id: id}
39
40
  end
40
41
 
41
- def send_command(command_params)
42
- execute :send_command, {}, command_params
42
+ def cast_sinks
43
+ execute :get_cast_sinks
44
+ end
45
+
46
+ def cast_sink_to_use=(name)
47
+ execute :set_cast_sink_to_use, {}, {sinkName: name}
48
+ end
49
+
50
+ def cast_issue_message
51
+ execute :cast_issue_message
52
+ end
53
+
54
+ def start_cast_tab_mirroring(name)
55
+ execute :start_cast_tab_mirroring, {}, {sinkName: name}
56
+ end
57
+
58
+ def start_cast_desktop_mirroring(name)
59
+ execute :start_cast_desktop_mirroring, {}, {sinkName: name}
60
+ end
61
+
62
+ def stop_casting(name)
63
+ execute :stop_casting, {}, {sinkName: name}
64
+ end
65
+
66
+ def set_permission(name, value)
67
+ execute :set_permission, {}, {descriptor: {name: name}, state: value}
68
+ end
69
+
70
+ def network_conditions
71
+ execute :get_network_conditions
43
72
  end
44
73
 
45
74
  def network_conditions=(conditions)
46
75
  execute :set_network_conditions, {}, {network_conditions: conditions}
47
76
  end
48
77
 
78
+ def delete_network_conditions
79
+ execute :delete_network_conditions
80
+ end
81
+
82
+ def send_command(command_params)
83
+ execute :send_command, {}, command_params
84
+ end
85
+
49
86
  def available_log_types
50
87
  types = execute :get_available_log_types
51
88
  Array(types).map(&:to_sym)
@@ -55,14 +92,12 @@ module Selenium
55
92
  data = execute :get_log, {}, {type: type.to_s}
56
93
 
57
94
  Array(data).map do |l|
58
- begin
59
- LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
60
- rescue KeyError
61
- next
62
- end
95
+ LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
96
+ rescue KeyError
97
+ next
63
98
  end
64
99
  end
65
100
  end # Bridge
66
- end # Chrome
101
+ end # Chromium
67
102
  end # WebDriver
68
103
  end # Selenium