selenium-webdriver 3.142.7 → 4.16.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 (188) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +685 -5
  3. data/Gemfile +6 -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 +93 -90
  11. data/lib/selenium/webdriver/atoms/findElements.js +122 -0
  12. data/lib/selenium/webdriver/atoms/getAttribute.js +100 -7
  13. data/lib/selenium/webdriver/atoms/isDisplayed.js +77 -78
  14. data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
  15. data/lib/selenium/webdriver/atoms.rb +5 -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 +48 -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 +7 -29
  32. data/lib/selenium/webdriver/chrome.rb +5 -20
  33. data/lib/selenium/webdriver/chromium/driver.rb +60 -0
  34. data/lib/selenium/webdriver/{chrome/bridge.rb → chromium/features.rb} +48 -17
  35. data/lib/selenium/webdriver/chromium/options.rb +243 -0
  36. data/lib/selenium/webdriver/chromium/profile.rb +113 -0
  37. data/lib/selenium/webdriver/chromium.rb +29 -0
  38. data/lib/selenium/webdriver/common/action_builder.rb +126 -238
  39. data/lib/selenium/webdriver/common/child_process.rb +124 -0
  40. data/lib/selenium/webdriver/common/driver.rb +82 -43
  41. data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -2
  42. data/lib/selenium/webdriver/common/driver_extensions/{has_location.rb → full_page_screenshot.rb} +13 -11
  43. data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +0 -2
  44. data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +49 -0
  45. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +87 -0
  46. data/lib/selenium/webdriver/common/driver_extensions/{has_touch_screen.rb → has_bidi.rb} +9 -9
  47. data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +86 -0
  48. data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +36 -0
  49. data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +42 -0
  50. data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -2
  51. data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +41 -0
  52. data/lib/selenium/webdriver/common/driver_extensions/has_file_downloads.rb +65 -0
  53. data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +36 -0
  54. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +143 -0
  55. data/lib/selenium/webdriver/common/driver_extensions/{has_remote_status.rb → has_logs.rb} +4 -4
  56. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +16 -1
  57. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +69 -0
  58. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +11 -13
  59. data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +75 -0
  60. data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
  61. data/lib/selenium/webdriver/common/driver_finder.rb +45 -0
  62. data/lib/selenium/webdriver/common/element.rb +89 -29
  63. data/lib/selenium/webdriver/common/error.rb +53 -194
  64. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
  65. data/lib/selenium/webdriver/common/interactions/input_device.rb +10 -4
  66. data/lib/selenium/webdriver/common/interactions/interaction.rb +12 -22
  67. data/lib/selenium/webdriver/common/interactions/interactions.rb +24 -4
  68. data/lib/selenium/webdriver/common/interactions/key_actions.rb +10 -6
  69. data/lib/selenium/webdriver/common/interactions/key_input.rb +11 -27
  70. data/lib/selenium/webdriver/common/interactions/none_input.rb +10 -8
  71. data/lib/selenium/webdriver/common/interactions/pause.rb +49 -0
  72. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +71 -82
  73. data/lib/selenium/webdriver/common/interactions/pointer_cancel.rb +45 -0
  74. data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +63 -0
  75. data/lib/selenium/webdriver/common/interactions/pointer_input.rb +15 -84
  76. data/lib/selenium/webdriver/common/interactions/pointer_move.rb +60 -0
  77. data/lib/selenium/webdriver/common/interactions/pointer_press.rb +85 -0
  78. data/lib/selenium/webdriver/common/interactions/scroll.rb +59 -0
  79. data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +48 -0
  80. data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +54 -0
  81. data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +113 -0
  82. data/lib/selenium/webdriver/common/{w3c_manager.rb → interactions/wheel_input.rb} +14 -17
  83. data/lib/selenium/webdriver/common/keys.rb +1 -0
  84. data/lib/selenium/webdriver/common/local_driver.rb +46 -0
  85. data/lib/selenium/webdriver/common/log_entry.rb +2 -2
  86. data/lib/selenium/webdriver/common/logger.rb +119 -19
  87. data/lib/selenium/webdriver/common/manager.rb +11 -38
  88. data/lib/selenium/webdriver/common/options.rb +154 -23
  89. data/lib/selenium/webdriver/common/platform.rb +15 -52
  90. data/lib/selenium/webdriver/common/port_prober.rb +4 -6
  91. data/lib/selenium/webdriver/common/profile_helper.rb +11 -9
  92. data/lib/selenium/webdriver/common/proxy.rb +8 -5
  93. data/lib/selenium/webdriver/common/search_context.rb +7 -9
  94. data/lib/selenium/webdriver/common/selenium_manager.rb +140 -0
  95. data/lib/selenium/webdriver/common/service.rb +26 -143
  96. data/lib/selenium/webdriver/common/service_manager.rb +144 -0
  97. data/lib/selenium/webdriver/common/shadow_root.rb +86 -0
  98. data/lib/selenium/webdriver/common/socket_lock.rb +4 -4
  99. data/lib/selenium/webdriver/common/socket_poller.rb +4 -4
  100. data/lib/selenium/webdriver/common/takes_screenshot.rb +65 -0
  101. data/lib/selenium/webdriver/common/target_locator.rb +31 -4
  102. data/lib/selenium/webdriver/common/timeouts.rb +31 -4
  103. data/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +85 -0
  104. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +72 -0
  105. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +62 -0
  106. data/lib/selenium/webdriver/common/wait.rb +1 -1
  107. data/lib/selenium/webdriver/common/websocket_connection.rb +164 -0
  108. data/lib/selenium/webdriver/common/window.rb +6 -10
  109. data/lib/selenium/webdriver/common/zipper.rb +4 -10
  110. data/lib/selenium/webdriver/common.rb +43 -20
  111. data/lib/selenium/webdriver/devtools/console_event.rb +36 -0
  112. data/lib/selenium/webdriver/devtools/exception_event.rb +34 -0
  113. data/lib/selenium/webdriver/devtools/mutation_event.rb +35 -0
  114. data/lib/selenium/webdriver/devtools/network_interceptor.rb +173 -0
  115. data/lib/selenium/webdriver/devtools/pinned_script.rb +57 -0
  116. data/lib/selenium/webdriver/devtools/request.rb +65 -0
  117. data/lib/selenium/webdriver/devtools/response.rb +64 -0
  118. data/lib/selenium/webdriver/devtools.rb +96 -0
  119. data/lib/selenium/webdriver/edge/driver.rb +11 -27
  120. data/lib/selenium/webdriver/edge/features.rb +48 -0
  121. data/lib/selenium/webdriver/edge/options.rb +18 -43
  122. data/lib/selenium/webdriver/edge/profile.rb +33 -0
  123. data/lib/selenium/webdriver/edge/service.rb +8 -23
  124. data/lib/selenium/webdriver/edge.rb +11 -16
  125. data/lib/selenium/webdriver/firefox/driver.rb +38 -19
  126. data/lib/selenium/webdriver/firefox/extension.rb +8 -0
  127. data/lib/selenium/webdriver/firefox/features.rb +70 -0
  128. data/lib/selenium/webdriver/firefox/options.rb +73 -61
  129. data/lib/selenium/webdriver/firefox/profile.rb +20 -72
  130. data/lib/selenium/webdriver/firefox/service.rb +3 -25
  131. data/lib/selenium/webdriver/firefox/util.rb +1 -1
  132. data/lib/selenium/webdriver/firefox.rb +17 -28
  133. data/lib/selenium/webdriver/ie/driver.rb +5 -45
  134. data/lib/selenium/webdriver/ie/features.rb +34 -0
  135. data/lib/selenium/webdriver/ie/options.rb +14 -44
  136. data/lib/selenium/webdriver/ie/service.rb +3 -27
  137. data/lib/selenium/webdriver/ie.rb +4 -16
  138. data/lib/selenium/webdriver/remote/bridge/commands.rb +164 -0
  139. data/lib/selenium/webdriver/remote/bridge.rb +574 -88
  140. data/lib/selenium/webdriver/remote/capabilities.rb +144 -158
  141. data/lib/selenium/webdriver/remote/driver.rb +45 -14
  142. data/lib/selenium/webdriver/remote/features.rb +75 -0
  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 +24 -33
  146. data/lib/selenium/webdriver/remote/response.rb +17 -49
  147. data/lib/selenium/webdriver/remote/server_error.rb +1 -1
  148. data/lib/selenium/webdriver/remote.rb +15 -12
  149. data/lib/selenium/webdriver/safari/driver.rb +7 -29
  150. data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +7 -5
  151. data/lib/selenium/webdriver/safari/options.rb +12 -27
  152. data/lib/selenium/webdriver/safari/service.rb +13 -11
  153. data/lib/selenium/webdriver/safari.rb +14 -20
  154. data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
  155. data/lib/selenium/webdriver/support/color.rb +24 -24
  156. data/lib/selenium/webdriver/support/event_firing_bridge.rb +5 -5
  157. data/lib/selenium/webdriver/support/guards/guard.rb +90 -0
  158. data/lib/selenium/webdriver/{firefox/marionette/bridge.rb → support/guards/guard_condition.rb} +21 -20
  159. data/lib/selenium/webdriver/support/guards.rb +95 -0
  160. data/lib/selenium/webdriver/support/relative_locator.rb +50 -0
  161. data/lib/selenium/webdriver/support/select.rb +6 -4
  162. data/lib/selenium/webdriver/support.rb +1 -0
  163. data/lib/selenium/webdriver/version.rb +1 -1
  164. data/lib/selenium/webdriver.rb +19 -17
  165. data/selenium-webdriver.gemspec +36 -18
  166. metadata +161 -91
  167. data/lib/selenium/webdriver/common/bridge_helper.rb +0 -82
  168. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +0 -58
  169. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -64
  170. data/lib/selenium/webdriver/common/mouse.rb +0 -89
  171. data/lib/selenium/webdriver/common/touch_action_builder.rb +0 -78
  172. data/lib/selenium/webdriver/common/touch_screen.rb +0 -123
  173. data/lib/selenium/webdriver/common/w3c_action_builder.rb +0 -212
  174. data/lib/selenium/webdriver/edge/bridge.rb +0 -76
  175. data/lib/selenium/webdriver/firefox/binary.rb +0 -187
  176. data/lib/selenium/webdriver/firefox/extension/prefs.json +0 -69
  177. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  178. data/lib/selenium/webdriver/firefox/launcher.rb +0 -111
  179. data/lib/selenium/webdriver/firefox/legacy/driver.rb +0 -83
  180. data/lib/selenium/webdriver/firefox/marionette/driver.rb +0 -90
  181. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  182. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  183. data/lib/selenium/webdriver/remote/http/persistent.rb +0 -60
  184. data/lib/selenium/webdriver/remote/oss/bridge.rb +0 -594
  185. data/lib/selenium/webdriver/remote/oss/commands.rb +0 -223
  186. data/lib/selenium/webdriver/remote/w3c/bridge.rb +0 -605
  187. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +0 -310
  188. 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(options: nil, service: nil, url: nil, **opts)
34
+ caps, url = initialize_local_driver(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,48 @@
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 command_list
39
+ CHROME_COMMANDS.merge(CHROMIUM_COMMANDS).merge(self.class::COMMANDS)
40
+ end
41
+
42
+ def commands(command)
43
+ command_list[command]
44
+ end
45
+ end # Bridge
46
+ end # Chrome
47
+ end # WebDriver
48
+ 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
@@ -20,38 +20,16 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Chrome
23
- #
24
- # @api private
25
- #
26
-
27
23
  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
24
+ DEFAULT_PORT = 9515
25
+ EXECUTABLE = 'chromedriver'
26
+ SHUTDOWN_SUPPORTED = true
41
27
 
42
- private
28
+ def log
29
+ return @log unless @log.is_a? String
43
30
 
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
31
+ @args << "--log-path=#{@log}"
32
+ @log = nil
55
33
  end
56
34
  end # Service
57
35
  end # Chrome
@@ -17,27 +17,14 @@
17
17
  # specific language governing permissions and limitations
18
18
  # under the License.
19
19
 
20
- require 'net/http'
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
20
  module Selenium
28
21
  module WebDriver
29
22
  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
23
+ autoload :Features, 'selenium/webdriver/chrome/features'
24
+ autoload :Driver, 'selenium/webdriver/chrome/driver'
25
+ autoload :Profile, 'selenium/webdriver/chrome/profile'
26
+ autoload :Options, 'selenium/webdriver/chrome/options'
27
+ autoload :Service, 'selenium/webdriver/chrome/service'
41
28
 
42
29
  def self.path=(path)
43
30
  Platform.assert_executable path
@@ -50,5 +37,3 @@ module Selenium
50
37
  end # Chrome
51
38
  end # WebDriver
52
39
  end # Selenium
53
-
54
- require 'selenium/webdriver/chrome/service'
@@ -0,0 +1,60 @@
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::HasPermissions,
37
+ DriverExtensions::DownloadsFiles,
38
+ DriverExtensions::HasDevTools,
39
+ DriverExtensions::HasAuthentication,
40
+ DriverExtensions::HasLogs,
41
+ DriverExtensions::HasLogEvents,
42
+ DriverExtensions::HasPinnedScripts,
43
+ DriverExtensions::PrintsPage].freeze
44
+
45
+ protected
46
+
47
+ def devtools_url
48
+ uri = URI(devtools_address)
49
+ response = Net::HTTP.get(uri.hostname, '/json/version', uri.port)
50
+
51
+ JSON.parse(response)['webSocketDebuggerUrl']
52
+ end
53
+
54
+ def devtools_version
55
+ Integer(capabilities.browser_version.split('.').first)
56
+ end
57
+ end # Driver
58
+ end # Chromium
59
+ end # WebDriver
60
+ end # Selenium
@@ -19,33 +19,66 @@
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
- def commands(command)
34
- COMMANDS[command] || super
34
+ def launch_app(id)
35
+ execute :launch_app, {}, {id: id}
35
36
  end
36
37
 
37
- def network_conditions
38
- execute :get_network_conditions
38
+ def cast_sinks
39
+ execute :get_cast_sinks
39
40
  end
40
41
 
41
- def send_command(command_params)
42
- execute :send_command, {}, command_params
42
+ def cast_sink_to_use=(name)
43
+ execute :set_cast_sink_to_use, {}, {sinkName: name}
44
+ end
45
+
46
+ def cast_issue_message
47
+ execute :cast_issue_message
48
+ end
49
+
50
+ def start_cast_tab_mirroring(name)
51
+ execute :start_cast_tab_mirroring, {}, {sinkName: name}
52
+ end
53
+
54
+ def start_cast_desktop_mirroring(name)
55
+ execute :start_cast_desktop_mirroring, {}, {sinkName: name}
56
+ end
57
+
58
+ def stop_casting(name)
59
+ execute :stop_casting, {}, {sinkName: name}
60
+ end
61
+
62
+ def set_permission(name, value)
63
+ execute :set_permission, {}, {descriptor: {name: name}, state: value}
64
+ end
65
+
66
+ def network_conditions
67
+ execute :get_network_conditions
43
68
  end
44
69
 
45
70
  def network_conditions=(conditions)
46
71
  execute :set_network_conditions, {}, {network_conditions: conditions}
47
72
  end
48
73
 
74
+ def delete_network_conditions
75
+ execute :delete_network_conditions
76
+ end
77
+
78
+ def send_command(command_params)
79
+ execute :send_command, {}, command_params
80
+ end
81
+
49
82
  def available_log_types
50
83
  types = execute :get_available_log_types
51
84
  Array(types).map(&:to_sym)
@@ -55,14 +88,12 @@ module Selenium
55
88
  data = execute :get_log, {}, {type: type.to_s}
56
89
 
57
90
  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
91
+ LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
92
+ rescue KeyError
93
+ next
63
94
  end
64
95
  end
65
96
  end # Bridge
66
- end # Chrome
97
+ end # Chromium
67
98
  end # WebDriver
68
99
  end # Selenium