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
@@ -20,12 +20,12 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Remote
23
+ #
23
24
  # @api private
24
- class Response
25
- STACKTRACE_KEY = 'stackTrace'
25
+ #
26
26
 
27
+ class Response
27
28
  attr_reader :code, :payload
28
- attr_writer :payload
29
29
 
30
30
  def initialize(code, payload = nil)
31
31
  @code = code
@@ -35,33 +35,16 @@ module Selenium
35
35
  end
36
36
 
37
37
  def error
38
- klass = Error.for_code(status) || return
38
+ error, message, backtrace = process_error
39
+ klass = Error.for_error(error) || return
39
40
 
40
- ex = klass.new(error_message)
41
+ ex = klass.new(message)
41
42
  ex.set_backtrace(caller)
42
- add_backtrace ex
43
+ add_backtrace ex, backtrace
43
44
 
44
45
  ex
45
46
  end
46
47
 
47
- def error_message
48
- val = value
49
-
50
- case val
51
- when Hash
52
- msg = val['message']
53
- return 'unknown error' unless msg
54
-
55
- msg << ": #{val['alert']['text'].inspect}" if val['alert'].is_a?(Hash) && val['alert']['text']
56
- msg << " (#{val['class']})" if val['class']
57
- msg
58
- when String
59
- val
60
- else
61
- "unknown error, status=#{status}: #{val.inspect}"
62
- end
63
- end
64
-
65
48
  def [](key)
66
49
  @payload[key]
67
50
  end
@@ -76,14 +59,7 @@ module Selenium
76
59
  raise Error::ServerError, self
77
60
  end
78
61
 
79
- def add_backtrace(ex)
80
- return unless error_payload.is_a?(Hash)
81
-
82
- # Legacy Firefox returns String in ['value'], while we expect Hash.
83
- # Use #dig when Firefox legacy is removed (4.0).
84
- server_trace = error_payload[STACKTRACE_KEY] ||
85
- error_payload[STACKTRACE_KEY.downcase] ||
86
- (error_payload['value'] && error_payload['value'][STACKTRACE_KEY])
62
+ def add_backtrace(ex, server_trace)
87
63
  return unless server_trace
88
64
 
89
65
  backtrace = case server_trace
@@ -97,7 +73,7 @@ module Selenium
97
73
  end
98
74
 
99
75
  def backtrace_from_remote(server_trace)
100
- server_trace.map { |frame|
76
+ server_trace.filter_map do |frame|
101
77
  next unless frame.is_a?(Hash)
102
78
 
103
79
  file = frame['fileName']
@@ -110,25 +86,17 @@ module Selenium
110
86
  meth = 'unknown' if meth.nil? || meth.empty?
111
87
 
112
88
  "[remote server] #{file}:#{line}:in `#{meth}'"
113
- }.compact
114
- end
115
-
116
- def error_payload
117
- # Even errors are wrapped in 'value' for w3c
118
- # Grab 'value' key for error, leave original payload alone and let the bridge process
119
- @error_payload ||= !@payload.key?('sessionId') ? @payload['value'] : @payload
120
- end
121
-
122
- def status
123
- return unless error_payload.is_a? Hash
124
-
125
- @status ||= error_payload['status'] || error_payload['error']
89
+ end
126
90
  end
127
91
 
128
- def value
129
- return unless error_payload.is_a? Hash
92
+ def process_error
93
+ return unless self['value'].is_a?(Hash)
130
94
 
131
- @value ||= error_payload['value'] || error_payload['message']
95
+ [
96
+ self['value']['error'],
97
+ self['value']['message'],
98
+ self['value']['stacktrace']
99
+ ]
132
100
  end
133
101
  end # Response
134
102
  end # Remote
@@ -18,18 +18,20 @@
18
18
  # under the License.
19
19
 
20
20
  require 'uri'
21
-
22
- require 'selenium/webdriver/remote/bridge'
23
- require 'selenium/webdriver/remote/driver'
24
- require 'selenium/webdriver/remote/response'
25
21
  require 'selenium/webdriver/remote/server_error'
26
- require 'selenium/webdriver/remote/http/common'
27
- require 'selenium/webdriver/remote/http/default'
28
22
 
29
- require 'selenium/webdriver/remote/capabilities'
30
- require 'selenium/webdriver/remote/oss/bridge'
31
- require 'selenium/webdriver/remote/oss/commands'
23
+ module Selenium
24
+ module WebDriver
25
+ module Remote
26
+ autoload :Bridge, 'selenium/webdriver/remote/bridge'
27
+ autoload :Driver, 'selenium/webdriver/remote/driver'
28
+ autoload :Response, 'selenium/webdriver/remote/response'
29
+ autoload :Capabilities, 'selenium/webdriver/remote/capabilities'
32
30
 
33
- require 'selenium/webdriver/remote/w3c/bridge'
34
- require 'selenium/webdriver/remote/w3c/capabilities'
35
- require 'selenium/webdriver/remote/w3c/commands'
31
+ module Http
32
+ autoload :Common, 'selenium/webdriver/remote/http/common'
33
+ autoload :Default, 'selenium/webdriver/remote/http/default'
34
+ end
35
+ end
36
+ end
37
+ end
@@ -20,48 +20,26 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Safari
23
-
24
23
  #
25
24
  # Driver implementation for Safari.
26
25
  # @api private
27
26
  #
28
27
 
29
28
  class Driver < WebDriver::Driver
30
- include DriverExtensions::HasDebugger
31
- include DriverExtensions::HasPermissions
32
- include DriverExtensions::TakesScreenshot
33
-
34
- def initialize(opts = {})
35
- opts[:desired_capabilities] = create_capabilities(opts)
36
-
37
- opts[:url] ||= service_url(opts)
29
+ EXTENSIONS = [DriverExtensions::HasDebugger,
30
+ DriverExtensions::HasApplePermissions,
31
+ DriverExtensions::HasWebStorage].freeze
38
32
 
39
- listener = opts.delete(:listener)
40
- @bridge = Remote::Bridge.handshake(**opts)
41
- @bridge.extend Bridge
33
+ include LocalDriver
42
34
 
43
- super(@bridge, listener: listener)
35
+ def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
36
+ caps, url = initialize_local_driver(capabilities, options, service, url)
37
+ super(caps: caps, url: url, **opts)
44
38
  end
45
39
 
46
40
  def browser
47
41
  :safari
48
42
  end
49
-
50
- def quit
51
- super
52
- ensure
53
- @service&.stop
54
- end
55
-
56
- private
57
-
58
- def create_capabilities(opts = {})
59
- caps = opts.delete(:desired_capabilities) { Remote::Capabilities.safari }
60
- options = opts.delete(:options) { Options.new }
61
- caps.merge!(options.as_json)
62
- caps
63
- end
64
-
65
43
  end # Driver
66
44
  end # Safari
67
45
  end # WebDriver
@@ -20,17 +20,16 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Safari
23
- module Bridge
24
-
23
+ module Features
25
24
  # https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/WebDriverEndpointDoc/Commands/Commands.html
26
- COMMANDS = {
25
+ SAFARI_COMMANDS = {
27
26
  get_permissions: [:get, 'session/:session_id/apple/permissions'],
28
27
  set_permissions: [:post, 'session/:session_id/apple/permissions'],
29
28
  attach_debugger: [:post, 'session/:session_id/apple/attach_debugger']
30
29
  }.freeze
31
30
 
32
31
  def commands(command)
33
- COMMANDS[command] || super
32
+ SAFARI_COMMANDS[command] || self.class::COMMANDS[command]
34
33
  end
35
34
 
36
35
  def permissions
@@ -44,7 +43,6 @@ module Selenium
44
43
  def attach_debugger
45
44
  execute :attach_debugger, {}, {}
46
45
  end
47
-
48
46
  end # Bridge
49
47
  end # Safari
50
48
  end # WebDriver
@@ -20,39 +20,24 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Safari
23
- class Options
24
- attr_accessor :automatic_inspection, :automatic_profiling
23
+ class Options < WebDriver::Options
24
+ attr_accessor :options
25
25
 
26
- #
27
- # Create a new Options instance for W3C-capable versions of Safari.
28
- #
29
- # @example
30
- # options = Selenium::WebDriver::Safari::Options.new(automatic_inspection: true)
31
- # driver = Selenium::WebDriver.for :safari, options: options
32
- #
33
- # @param [Hash] opts the pre-defined options to create the Safari::Options with
34
- # @option opts [Boolean] :automatic_inspection Preloads Web Inspector and JavaScript debugger. Default is false
35
- # @option opts [Boolean] :automatic_profiling Preloads Web Inspector and starts a timeline recording. Default is false
36
- #
37
26
  # @see https://developer.apple.com/documentation/webkit/about_webdriver_for_safari
38
- #
27
+ CAPABILITIES = {automatic_inspection: 'safari:automaticInspection',
28
+ automatic_profiling: 'safari:automaticProfiling'}.freeze
29
+ BROWSER = Selenium::WebDriver::Safari.technology_preview? ? 'Safari Technology Preview' : 'safari'
39
30
 
40
- def initialize(**opts)
41
- @automatic_inspection = opts.delete(:automatic_inspection) || false
42
- @automatic_profiling = opts.delete(:automatic_profiling) || false
43
- end
31
+ def add_option(name, value = nil)
32
+ key = name.is_a?(Hash) ? name.keys.first : name
33
+ raise ArgumentError, 'Safari does not support options that are not namespaced' unless key.to_s.include?(':')
44
34
 
45
- #
46
- # @api private
47
- #
35
+ super
36
+ end
48
37
 
49
38
  def as_json(*)
50
- opts = {}
51
-
52
- opts['safari:automaticInspection'] = true if @automatic_inspection
53
- opts['safari:automaticProfiling'] = true if @automatic_profiling
54
-
55
- opts
39
+ @options[:browser_name] = Safari.technology_preview? ? 'Safari Technology Preview' : 'safari'
40
+ super
56
41
  end
57
42
  end # Options
58
43
  end # Safari
@@ -20,18 +20,20 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Safari
23
- #
24
- # @api private
25
- #
26
-
27
23
  class Service < WebDriver::Service
28
- @default_port = 7050
29
- @executable = 'safaridriver'
30
- @missing_text = <<~ERROR
31
- Unable to find Apple's safaridriver which comes with Safari 10.
32
- More info at https://webkit.org/blog/6900/webdriver-support-in-safari-10/
33
- ERROR
34
- @shutdown_supported = false
24
+ DEFAULT_PORT = 7050
25
+ EXECUTABLE = 'safaridriver'
26
+ SHUTDOWN_SUPPORTED = false
27
+
28
+ def initialize(path: nil, port: nil, log: nil, args: nil)
29
+ raise Error::WebDriverError, 'Safari Service does not support setting log output' if log
30
+
31
+ super
32
+ end
33
+
34
+ def log=(*)
35
+ raise Error::WebDriverError, 'Safari Service does not support setting log output'
36
+ end
35
37
  end # Service
36
38
  end # Safari
37
39
  end # WebDriver
@@ -17,20 +17,28 @@
17
17
  # specific language governing permissions and limitations
18
18
  # under the License.
19
19
 
20
- require 'selenium/webdriver/safari/bridge'
21
- require 'selenium/webdriver/safari/driver'
22
- require 'selenium/webdriver/safari/options'
23
-
24
20
  module Selenium
25
21
  module WebDriver
26
22
  module Safari
23
+ autoload :Features, 'selenium/webdriver/safari/features'
24
+ autoload :Driver, 'selenium/webdriver/safari/driver'
25
+ autoload :Options, 'selenium/webdriver/safari/options'
26
+ autoload :Service, 'selenium/webdriver/safari/service'
27
+
27
28
  class << self
29
+ attr_accessor :use_technology_preview
30
+
28
31
  def technology_preview
29
- "/Applications/Safari\ Technology\ Preview.app/Contents/MacOS/safaridriver"
32
+ '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
30
33
  end
31
34
 
32
35
  def technology_preview!
33
- self.driver_path = technology_preview
36
+ Service.driver_path = technology_preview
37
+ @use_technology_preview = true
38
+ end
39
+
40
+ def technology_preview?
41
+ use_technology_preview
34
42
  end
35
43
 
36
44
  def path=(path)
@@ -45,21 +53,7 @@ module Selenium
45
53
 
46
54
  raise Error::WebDriverError, 'Unable to find Safari'
47
55
  end
48
-
49
- def driver_path=(path)
50
- WebDriver.logger.deprecate 'Selenium::WebDriver::Safari#driver_path=',
51
- 'Selenium::WebDriver::Safari::Service#driver_path='
52
- Selenium::WebDriver::Safari::Service.driver_path = path
53
- end
54
-
55
- def driver_path
56
- WebDriver.logger.deprecate 'Selenium::WebDriver::Safari#driver_path',
57
- 'Selenium::WebDriver::Safari::Service#driver_path'
58
- Selenium::WebDriver::Safari::Service.driver_path
59
- end
60
56
  end
61
57
  end # Safari
62
58
  end # WebDriver
63
59
  end # Selenium
64
-
65
- require 'selenium/webdriver/safari/service'
@@ -25,7 +25,7 @@ module Selenium
25
25
  @callback = callback
26
26
  end
27
27
 
28
- def method_missing(meth, *args) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
28
+ def method_missing(meth, *args) # rubocop:disable Style/MissingRespondToMissing
29
29
  @callback.call meth, *args
30
30
  end
31
31
  end # BlockEventListener
@@ -21,29 +21,29 @@ module Selenium
21
21
  module WebDriver
22
22
  module Support
23
23
  class Color
24
- RGB_PATTERN = %r{^\s*rgb\(\s*(\d{1,3})\s*,
24
+ RGB_PATTERN = /^\s*rgb\(\s*(\d{1,3})\s*,
25
25
  \s*(\d{1,3})\s*,
26
- \s*(\d{1,3})\s*\)\s*$}x.freeze
27
- RGB_PCT_PATTERN = %r{^\s*rgb\(\s*(\d{1,3}|\d{1,2}\.\d+)%\s*,
26
+ \s*(\d{1,3})\s*\)\s*$/x
27
+ RGB_PCT_PATTERN = /^\s*rgb\(\s*(\d{1,3}|\d{1,2}\.\d+)%\s*,
28
28
  \s*(\d{1,3}|\d{1,2}\.\d+)%\s*,
29
- \s*(\d{1,3}|\d{1,2}\.\d+)%\s*\)\s*$}x.freeze
30
- RGBA_PATTERN = %r{^\s*rgba\(\s*(\d{1,3})\s*,
29
+ \s*(\d{1,3}|\d{1,2}\.\d+)%\s*\)\s*$/x
30
+ RGBA_PATTERN = /^\s*rgba\(\s*(\d{1,3})\s*,
31
31
  \s*(\d{1,3})\s*,
32
32
  \s*(\d{1,3})\s*,
33
- \s*(0|1|0\.\d+)\s*\)\s*$}x.freeze
34
- RGBA_PCT_PATTERN = %r{^\s*rgba\(\s*(\d{1,3}|\d{1,2}\.\d+)
33
+ \s*(0|1|0\.\d+)\s*\)\s*$/x
34
+ RGBA_PCT_PATTERN = /^\s*rgba\(\s*(\d{1,3}|\d{1,2}\.\d+)
35
35
  %\s*,\s*(\d{1,3}|\d{1,2}\.\d+)
36
36
  %\s*,\s*(\d{1,3}|\d{1,2}\.\d+)
37
- %\s*,\s*(0|1|0\.\d+)\s*\)\s*$}x.freeze
38
- HEX_PATTERN = /#(\h{2})(\h{2})(\h{2})/.freeze
39
- HEX3_PATTERN = /#(\h)(\h)(\h)/.freeze
40
- HSL_PATTERN = %r{^\s*hsl\(\s*(\d{1,3})\s*,
37
+ %\s*,\s*(0|1|0\.\d+)\s*\)\s*$/x
38
+ HEX_PATTERN = /#(\h{2})(\h{2})(\h{2})/
39
+ HEX3_PATTERN = /#(\h)(\h)(\h)/
40
+ HSL_PATTERN = /^\s*hsl\(\s*(\d{1,3})\s*,
41
41
  \s*(\d{1,3})%\s*,
42
- \s*(\d{1,3})%\s*\)\s*$}x.freeze
43
- HSLA_PATTERN = %r{^\s*hsla\(\s*(\d{1,3})\s*,
42
+ \s*(\d{1,3})%\s*\)\s*$/x
43
+ HSLA_PATTERN = /^\s*hsla\(\s*(\d{1,3})\s*,
44
44
  \s*(\d{1,3})%\s*,
45
45
  \s*(\d{1,3})%\s*,
46
- \s*(0|1|0\.\d+)\s*\)\s*$}x.freeze
46
+ \s*(0|1|0\.\d+)\s*\)\s*$/x
47
47
 
48
48
  attr_reader :red, :green, :blue, :alpha
49
49
 
@@ -72,7 +72,7 @@ module Selenium
72
72
  end
73
73
  end
74
74
 
75
- def self.from_hsl(h, s, l, a) # rubocop:disable Naming/UncommunicativeMethodParamName
75
+ def self.from_hsl(h, s, l, a) # rubocop:disable Naming/MethodParameterName
76
76
  h = Float(h) / 360
77
77
  s = Float(s) / 100
78
78
  l = Float(l) / 100
@@ -83,12 +83,12 @@ module Selenium
83
83
  g = r
84
84
  b = r
85
85
  else
86
- luminocity2 = l < 0.5 ? l * (1 + s) : l + s - l * s
87
- luminocity1 = 2 * l - luminocity2
86
+ luminocity2 = l < 0.5 ? l * (s + 1) : l + s - (l * s)
87
+ luminocity1 = (l * 2) - luminocity2
88
88
 
89
- r = hue_to_rgb(luminocity1, luminocity2, h + 1.0 / 3.0)
89
+ r = hue_to_rgb(luminocity1, luminocity2, h + (1.0 / 3.0))
90
90
  g = hue_to_rgb(luminocity1, luminocity2, h)
91
- b = hue_to_rgb(luminocity1, luminocity2, h - 1.0 / 3.0)
91
+ b = hue_to_rgb(luminocity1, luminocity2, h - (1.0 / 3.0))
92
92
  end
93
93
 
94
94
  new (r * 255).round, (g * 255).round, (b * 255).round, a
@@ -99,11 +99,11 @@ module Selenium
99
99
  hue -= 1 if hue > 1.0
100
100
 
101
101
  if hue < 1.0 / 6.0
102
- (lum1 + (lum2 - lum1) * 6.0 * hue)
102
+ (lum1 + ((lum2 - lum1) * 6.0 * hue))
103
103
  elsif hue < 1.0 / 2.0
104
104
  lum2
105
105
  elsif hue < 2.0 / 3.0
106
- lum1 + (lum2 - lum1) * ((2.0 / 3.0) - hue) * 6.0
106
+ lum1 + ((lum2 - lum1) * ((2.0 / 3.0) - hue) * 6.0)
107
107
  else
108
108
  lum1
109
109
  end
@@ -122,10 +122,10 @@ module Selenium
122
122
 
123
123
  [red, green, blue, alpha] == [other.red, other.green, other.blue, other.alpha]
124
124
  end
125
- alias_method :eql?, :==
125
+ alias eql? ==
126
126
 
127
127
  def hash
128
- [red, green, blue, alpha].hash ^ self.class.hash
128
+ [red, green, blue, alpha, self.class].hash
129
129
  end
130
130
 
131
131
  def rgb
@@ -138,7 +138,7 @@ module Selenium
138
138
  end
139
139
 
140
140
  def hex
141
- format '#%02x%02x%02x', red, green, blue
141
+ format '#%<red>02x%<green>02x%<blue>02x', red: red, green: green, blue: blue
142
142
  end
143
143
  end # Color
144
144
  end # Support
@@ -76,7 +76,7 @@ module Selenium
76
76
  @delegate.find_element_by how, what, parent
77
77
  end
78
78
 
79
- Element.new self, e.ref
79
+ Element.new self, e.ref.last
80
80
  end
81
81
 
82
82
  def find_elements_by(how, what, parent = nil)
@@ -84,7 +84,7 @@ module Selenium
84
84
  @delegate.find_elements_by(how, what, parent)
85
85
  end
86
86
 
87
- es.map { |e| Element.new self, e.ref }
87
+ es.map { |e| Element.new self, e.ref.last }
88
88
  end
89
89
 
90
90
  def execute_script(script, *args)
@@ -109,7 +109,7 @@ module Selenium
109
109
  end
110
110
 
111
111
  def driver
112
- @driver ||= Driver.new(self)
112
+ @driver ||= Driver.new(bridge: self)
113
113
  end
114
114
 
115
115
  def dispatch(name, *args)
@@ -120,7 +120,7 @@ module Selenium
120
120
  returned
121
121
  end
122
122
 
123
- def method_missing(meth, *args, &blk) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
123
+ def method_missing(meth, *args, &blk) # rubocop:disable Style/MissingRespondToMissing
124
124
  @delegate.__send__(meth, *args, &blk)
125
125
  end
126
126
  end # EventFiringBridge
@@ -0,0 +1,87 @@
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 Support
23
+ class Guards
24
+ #
25
+ # Guard derived from RSpec example metadata.
26
+ # @api private
27
+ #
28
+
29
+ class Guard
30
+ attr_reader :guarded, :type, :messages, :reason
31
+
32
+ def initialize(guarded, type, guards = nil)
33
+ @guarded = guarded
34
+ @tracker = guards&.bug_tracker || ''
35
+ @messages = guards&.messages || {}
36
+ @messages[:unknown] = 'TODO: Investigate why this is failing and file a bug report'
37
+ @type = type
38
+
39
+ @reason = @guarded.delete(:reason)
40
+ end
41
+
42
+ def message
43
+ details = case @reason
44
+ when Integer
45
+ "Bug Filed: #{@tracker}/#{@reason}"
46
+ when Symbol
47
+ @messages[@reason]
48
+ when String
49
+ @reason
50
+ else
51
+ 'no reason given'
52
+ end
53
+
54
+ case @type
55
+ when :exclude
56
+ "Test not guarded because it breaks test run; #{details}"
57
+ when :exclusive
58
+ "Test does not apply to this configuration; #{details}"
59
+ else
60
+ "Test guarded; #{details}"
61
+ end
62
+ end
63
+
64
+ # Bug is present on all configurations specified
65
+ def except?
66
+ @type == :except
67
+ end
68
+
69
+ # Bug is present on all configurations not specified
70
+ def only?
71
+ @type == :only
72
+ end
73
+
74
+ # Bug is present on all configurations specified, but test can not be run because it breaks other tests
75
+ def exclude?
76
+ @type == :exclude
77
+ end
78
+
79
+ # Test only applies to configurations specified
80
+ def exclusive?
81
+ @type == :exclusive
82
+ end
83
+ end # Guard
84
+ end # Guards
85
+ end # Support
86
+ end # WebDriver
87
+ end # Selenium
@@ -19,31 +19,32 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- module Firefox
23
- module Marionette
24
- module Bridge
22
+ module Support
23
+ class Guards
24
+ #
25
+ # Guard derived from RSpec example metadata.
26
+ # @api private
27
+ #
25
28
 
26
- COMMANDS = {
27
- install_addon: [:post, 'session/:session_id/moz/addon/install'],
28
- uninstall_addon: [:post, 'session/:session_id/moz/addon/uninstall']
29
- }.freeze
29
+ class GuardCondition
30
+ attr_accessor :name, :execution
30
31
 
31
- def commands(command)
32
- COMMANDS[command] || super
32
+ def initialize(name, condition = nil, &blk)
33
+ @name = name
34
+ @execution = if blk
35
+ proc(&blk)
36
+ else
37
+ proc { |guarded| guarded.include?(condition) }
38
+ end
33
39
  end
34
40
 
35
- def install_addon(path, temporary)
36
- payload = {path: path}
37
- payload[:temporary] = temporary unless temporary.nil?
38
- execute :install_addon, {}, payload
39
- end
41
+ def satisfied?(guard)
42
+ list = Array(guard.guarded[@name])
40
43
 
41
- def uninstall_addon(id)
42
- execute :uninstall_addon, {}, {id: id}
44
+ list.empty? || @execution.call(list)
43
45
  end
44
-
45
- end # Bridge
46
- end # Marionette
47
- end # Firefox
46
+ end # GuardCondition
47
+ end # Guards
48
+ end # Support
48
49
  end # WebDriver
49
50
  end # Selenium