selenium-webdriver 4.0.0.alpha5 → 4.0.0.beta3

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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/lib/selenium/devtools.rb +30 -0
  3. data/lib/selenium/server.rb +18 -26
  4. data/lib/selenium/webdriver.rb +1 -3
  5. data/lib/selenium/webdriver/atoms/findElements.js +93 -93
  6. data/lib/selenium/webdriver/atoms/getAttribute.js +75 -59
  7. data/lib/selenium/webdriver/atoms/isDisplayed.js +72 -72
  8. data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
  9. data/lib/selenium/webdriver/chrome.rb +1 -1
  10. data/lib/selenium/webdriver/chrome/driver.rb +28 -6
  11. data/lib/selenium/webdriver/chrome/{bridge.rb → features.rb} +6 -8
  12. data/lib/selenium/webdriver/chrome/options.rb +54 -37
  13. data/lib/selenium/webdriver/chrome/profile.rb +6 -3
  14. data/lib/selenium/webdriver/chrome/service.rb +4 -2
  15. data/lib/selenium/webdriver/common.rb +7 -2
  16. data/lib/selenium/webdriver/common/driver.rb +86 -26
  17. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +89 -0
  18. data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +6 -1
  19. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -8
  20. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +149 -0
  21. data/lib/selenium/webdriver/{edge_chrome/bridge.rb → common/driver_extensions/has_logs.rb} +7 -7
  22. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +6 -27
  23. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +67 -0
  24. data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +1 -0
  25. data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
  26. data/lib/selenium/webdriver/common/element.rb +66 -12
  27. data/lib/selenium/webdriver/common/interactions/interaction.rb +4 -1
  28. data/lib/selenium/webdriver/common/logger.rb +6 -3
  29. data/lib/selenium/webdriver/common/manager.rb +11 -1
  30. data/lib/selenium/webdriver/common/options.rb +90 -11
  31. data/lib/selenium/webdriver/common/platform.rb +3 -1
  32. data/lib/selenium/webdriver/common/port_prober.rb +4 -6
  33. data/lib/selenium/webdriver/common/proxy.rb +4 -1
  34. data/lib/selenium/webdriver/common/search_context.rb +4 -1
  35. data/lib/selenium/webdriver/common/service.rb +13 -114
  36. data/lib/selenium/webdriver/common/service_manager.rb +151 -0
  37. data/lib/selenium/webdriver/common/socket_poller.rb +19 -30
  38. data/lib/selenium/webdriver/common/takes_screenshot.rb +63 -0
  39. data/lib/selenium/webdriver/common/target_locator.rb +4 -4
  40. data/lib/selenium/webdriver/devtools.rb +144 -0
  41. data/lib/selenium/webdriver/devtools/console_event.rb +38 -0
  42. data/lib/selenium/webdriver/{edge_html/driver.rb → devtools/exception_event.rb} +10 -13
  43. data/lib/selenium/webdriver/devtools/mutation_event.rb +37 -0
  44. data/lib/selenium/webdriver/devtools/request.rb +57 -0
  45. data/lib/selenium/webdriver/edge.rb +7 -29
  46. data/lib/selenium/webdriver/{edge_chrome → edge}/driver.rb +10 -4
  47. data/lib/selenium/webdriver/edge/features.rb +39 -0
  48. data/lib/selenium/webdriver/{edge_chrome → edge}/options.rb +12 -3
  49. data/lib/selenium/webdriver/{edge_chrome → edge}/profile.rb +2 -2
  50. data/lib/selenium/webdriver/{edge_chrome → edge}/service.rb +2 -2
  51. data/lib/selenium/webdriver/firefox.rb +5 -1
  52. data/lib/selenium/webdriver/firefox/driver.rb +19 -3
  53. data/lib/selenium/webdriver/firefox/{bridge.rb → features.rb} +3 -3
  54. data/lib/selenium/webdriver/firefox/options.rb +25 -31
  55. data/lib/selenium/webdriver/firefox/profile.rb +12 -2
  56. data/lib/selenium/webdriver/firefox/service.rb +1 -1
  57. data/lib/selenium/webdriver/ie/driver.rb +1 -2
  58. data/lib/selenium/webdriver/ie/options.rb +7 -20
  59. data/lib/selenium/webdriver/ie/service.rb +4 -2
  60. data/lib/selenium/webdriver/remote/bridge.rb +50 -42
  61. data/lib/selenium/webdriver/remote/capabilities.rb +127 -71
  62. data/lib/selenium/webdriver/remote/commands.rb +3 -0
  63. data/lib/selenium/webdriver/remote/driver.rb +10 -3
  64. data/lib/selenium/webdriver/remote/http/common.rb +0 -5
  65. data/lib/selenium/webdriver/remote/http/default.rb +8 -7
  66. data/lib/selenium/webdriver/remote/http/persistent.rb +6 -0
  67. data/lib/selenium/webdriver/safari.rb +8 -1
  68. data/lib/selenium/webdriver/safari/driver.rb +3 -4
  69. data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +3 -3
  70. data/lib/selenium/webdriver/safari/options.rb +1 -33
  71. data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
  72. data/lib/selenium/webdriver/support/color.rb +2 -2
  73. data/lib/selenium/webdriver/support/event_firing_bridge.rb +1 -1
  74. data/lib/selenium/webdriver/support/guards.rb +95 -0
  75. data/lib/selenium/webdriver/support/guards/guard.rb +89 -0
  76. data/lib/selenium/webdriver/support/guards/guard_condition.rb +52 -0
  77. data/lib/selenium/webdriver/support/select.rb +2 -2
  78. data/lib/selenium/webdriver/version.rb +1 -1
  79. metadata +69 -32
  80. data/CHANGES +0 -1725
  81. data/Gemfile +0 -4
  82. data/LICENSE +0 -202
  83. data/README.md +0 -35
  84. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -65
  85. data/lib/selenium/webdriver/edge_html/options.rb +0 -91
  86. data/lib/selenium/webdriver/edge_html/service.rb +0 -47
  87. data/selenium-webdriver.gemspec +0 -48
@@ -21,14 +21,23 @@ require 'selenium/webdriver/chrome/options'
21
21
 
22
22
  module Selenium
23
23
  module WebDriver
24
- module EdgeChrome
24
+ module Edge
25
25
  class Options < Selenium::WebDriver::Chrome::Options
26
+ KEY = 'ms:edgeOptions'
27
+ BROWSER = 'MicrosoftEdge'
28
+
29
+ protected
30
+
31
+ def enable_logging(browser_options)
32
+ browser_options['ms:loggingPrefs'] = @logging_prefs
33
+ end
34
+
26
35
  private
27
36
 
28
37
  def binary_path
29
- EdgeChrome.path
38
+ Edge.path
30
39
  end
31
40
  end # Options
32
- end # EdgeChrome
41
+ end # Edge
33
42
  end # WebDriver
34
43
  end # Selenium
@@ -21,13 +21,13 @@ require 'selenium/webdriver/chrome/profile'
21
21
 
22
22
  module Selenium
23
23
  module WebDriver
24
- module EdgeChrome
24
+ module Edge
25
25
  #
26
26
  # @private
27
27
  #
28
28
 
29
29
  class Profile < Selenium::WebDriver::Chrome::Profile
30
30
  end # Profile
31
- end # EdgeChrome
31
+ end # Edge
32
32
  end # WebDriver
33
33
  end # Selenium
@@ -21,7 +21,7 @@ require 'selenium/webdriver/chrome/service'
21
21
 
22
22
  module Selenium
23
23
  module WebDriver
24
- module EdgeChrome
24
+ module Edge
25
25
  class Service < Selenium::WebDriver::Chrome::Service
26
26
  DEFAULT_PORT = 9515
27
27
  EXECUTABLE = 'msedgedriver'
@@ -31,6 +31,6 @@ module Selenium
31
31
  ERROR
32
32
  SHUTDOWN_SUPPORTED = true
33
33
  end # Service
34
- end # EdgeChrome
34
+ end # Edge
35
35
  end # WebDriver
36
36
  end # Selenium
@@ -27,7 +27,7 @@ module Selenium
27
27
  autoload :Extension, 'selenium/webdriver/firefox/extension'
28
28
  autoload :ProfilesIni, 'selenium/webdriver/firefox/profiles_ini'
29
29
  autoload :Profile, 'selenium/webdriver/firefox/profile'
30
- autoload :Bridge, 'selenium/webdriver/firefox/bridge'
30
+ autoload :Features, 'selenium/webdriver/firefox/features'
31
31
  autoload :Driver, 'selenium/webdriver/firefox/driver'
32
32
  autoload :Options, 'selenium/webdriver/firefox/options'
33
33
  autoload :Service, 'selenium/webdriver/firefox/service'
@@ -38,6 +38,10 @@ module Selenium
38
38
  DEFAULT_ASSUME_UNTRUSTED_ISSUER = true
39
39
  DEFAULT_LOAD_NO_FOCUS_LIB = false
40
40
 
41
+ # Mozilla Automation Team asked to only support 85
42
+ # until WebDriver Bidi is available.
43
+ DEVTOOLS_VERSION = 85
44
+
41
45
  def self.driver_path=(path)
42
46
  WebDriver.logger.deprecate 'Selenium::WebDriver::Firefox#driver_path=',
43
47
  'Selenium::WebDriver::Firefox::Service#driver_path=',
@@ -27,13 +27,29 @@ module Selenium
27
27
  #
28
28
 
29
29
  class Driver < WebDriver::Driver
30
- include DriverExtensions::HasAddons
31
- include DriverExtensions::HasWebStorage
32
- include DriverExtensions::TakesScreenshot
30
+ EXTENSIONS = [DriverExtensions::HasAddons,
31
+ DriverExtensions::HasDevTools,
32
+ DriverExtensions::HasLogEvents,
33
+ DriverExtensions::HasNetworkInterception,
34
+ DriverExtensions::HasWebStorage,
35
+ DriverExtensions::PrintsPage].freeze
33
36
 
34
37
  def browser
35
38
  :firefox
36
39
  end
40
+
41
+ private
42
+
43
+ def devtools_url
44
+ uri = URI("http://#{capabilities['moz:debuggerAddress']}")
45
+ response = Net::HTTP.get(uri.hostname, '/json/version', uri.port)
46
+
47
+ JSON.parse(response)['webSocketDebuggerUrl']
48
+ end
49
+
50
+ def devtools_version
51
+ Firefox::DEVTOOLS_VERSION
52
+ end
37
53
  end # Driver
38
54
  end # Firefox
39
55
  end # WebDriver
@@ -20,15 +20,15 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Firefox
23
- module Bridge
23
+ module Features
24
24
 
25
- COMMANDS = {
25
+ FIREFOX_COMMANDS = {
26
26
  install_addon: [:post, 'session/:session_id/moz/addon/install'],
27
27
  uninstall_addon: [:post, 'session/:session_id/moz/addon/uninstall']
28
28
  }.freeze
29
29
 
30
30
  def commands(command)
31
- COMMANDS[command] || super
31
+ FIREFOX_COMMANDS[command] || self.class::COMMANDS[command]
32
32
  end
33
33
 
34
34
  def install_addon(path, temporary)
@@ -21,24 +21,19 @@ module Selenium
21
21
  module WebDriver
22
22
  module Firefox
23
23
  class Options < WebDriver::Options
24
+ attr_accessor :debugger_address
25
+
24
26
  KEY = 'moz:firefoxOptions'
25
27
 
26
28
  # see: https://firefox-source-docs.mozilla.org/testing/geckodriver/Capabilities.html
27
29
  CAPABILITIES = {binary: 'binary',
28
30
  args: 'args',
29
- profile: 'profile',
30
31
  log: 'log',
31
32
  prefs: 'prefs'}.freeze
33
+ BROWSER = 'firefox'
32
34
 
33
- CAPABILITIES.each_key do |key|
34
- define_method key do
35
- @options[key]
36
- end
37
-
38
- define_method "#{key}=" do |value|
39
- @options[key] = value
40
- end
41
- end
35
+ # NOTE: special handling of 'profile' to validate when set instead of when used
36
+ attr_reader :profile
42
37
 
43
38
  #
44
39
  # Create a new Options instance, only for W3C-capable versions of Firefox.
@@ -57,10 +52,15 @@ module Selenium
57
52
  #
58
53
 
59
54
  def initialize(log_level: nil, **opts)
60
- super(opts)
55
+ @debugger_address = opts.delete(:debugger_address)
56
+
57
+ super(**opts)
61
58
 
59
+ @options[:args] ||= []
60
+ @options[:prefs] ||= {}
62
61
  @options[:log] ||= {level: log_level} if log_level
63
- process_profile(@options[:profile]) if @options.key?(:profile)
62
+
63
+ process_profile(@options.delete(:profile))
64
64
  end
65
65
 
66
66
  #
@@ -74,7 +74,6 @@ module Selenium
74
74
  #
75
75
 
76
76
  def add_argument(arg)
77
- @options[:args] ||= []
78
77
  @options[:args] << arg
79
78
  end
80
79
 
@@ -90,7 +89,6 @@ module Selenium
90
89
  #
91
90
 
92
91
  def add_preference(name, value)
93
- @options[:prefs] ||= {}
94
92
  @options[:prefs][name] = value
95
93
  end
96
94
 
@@ -121,7 +119,6 @@ module Selenium
121
119
  # @param [Profile, String] profile Profile to be used
122
120
  #
123
121
 
124
- undef profile=
125
122
  def profile=(profile)
126
123
  process_profile(profile)
127
124
  end
@@ -134,27 +131,24 @@ module Selenium
134
131
  @options[:log] = {level: level}
135
132
  end
136
133
 
137
- #
138
- # @api private
139
- #
134
+ private
140
135
 
141
- def as_json(*)
142
- options = super
136
+ def process_browser_options(browser_options)
137
+ browser_options['moz:debuggerAddress'] = true if @debugger_address
138
+ options = browser_options[KEY]
143
139
  options['binary'] ||= Firefox.path if Firefox.path
144
-
145
- {KEY => generate_as_json(options)}
140
+ options['profile'] = @profile if @profile
146
141
  end
147
142
 
148
- private
149
-
150
143
  def process_profile(profile)
151
- @options[:profile] = if profile.nil?
152
- nil
153
- elsif profile.is_a? Profile
154
- profile
155
- else
156
- Profile.from_name(profile)
157
- end
144
+ @profile = case profile
145
+ when nil
146
+ nil
147
+ when Profile
148
+ profile
149
+ else
150
+ Profile.from_name(profile)
151
+ end
158
152
  end
159
153
  end # Options
160
154
  end # Firefox
@@ -25,6 +25,14 @@ module Selenium
25
25
 
26
26
  VALID_PREFERENCE_TYPES = [TrueClass, FalseClass, Integer, Float, String].freeze
27
27
 
28
+ DEFAULT_PREFERENCES = {
29
+ "browser.newtabpage.enabled" => false,
30
+ "browser.startup.homepage" => "about:blank",
31
+ "browser.usedOnWindows10.introURL" => "about:blank",
32
+ "network.captive-portal-service.enabled" => false,
33
+ "security.csp.enable" => false
34
+ }.freeze
35
+
28
36
  attr_reader :name, :log_file
29
37
  attr_writer :secure_ssl, :load_no_focus_lib
30
38
 
@@ -179,10 +187,12 @@ module Selenium
179
187
 
180
188
  def update_user_prefs_in(directory)
181
189
  path = File.join(directory, 'user.js')
182
- prefs = read_user_prefs(path).merge(@additional_prefs)
190
+ prefs = read_user_prefs(path)
191
+ prefs.merge! self.class::DEFAULT_PREFERENCES
192
+ prefs.merge!(@additional_prefs)
183
193
 
184
194
  # If the user sets the home page, we should also start up there
185
- prefs['startup.homepage_welcome_url'] = prefs['browser.startup.homepage']
195
+ prefs['startup.homepage_welcome_url'] ||= prefs['browser.startup.homepage']
186
196
 
187
197
  write_prefs prefs, path
188
198
  end
@@ -32,7 +32,7 @@ module Selenium
32
32
 
33
33
  private
34
34
 
35
- # Note: This processing is deprecated
35
+ # NOTE: This processing is deprecated
36
36
  def extract_service_args(driver_opts)
37
37
  driver_args = super
38
38
  driver_opts = driver_opts.dup
@@ -28,8 +28,7 @@ module Selenium
28
28
  #
29
29
 
30
30
  class Driver < WebDriver::Driver
31
- include DriverExtensions::HasWebStorage
32
- include DriverExtensions::TakesScreenshot
31
+ EXTENSIONS = [DriverExtensions::HasWebStorage].freeze
33
32
 
34
33
  def browser
35
34
  :internet_explorer
@@ -41,16 +41,7 @@ module Selenium
41
41
  use_per_process_proxy: 'ie.usePerProcessProxy',
42
42
  validate_cookie_document_type: 'ie.validateCookieDocumentType'
43
43
  }.freeze
44
-
45
- CAPABILITIES.each_key do |key|
46
- define_method key do
47
- @options[key]
48
- end
49
-
50
- define_method "#{key}=" do |value|
51
- @options[key] = value
52
- end
53
- end
44
+ BROWSER = 'internet explorer'
54
45
 
55
46
  attr_reader :args
56
47
 
@@ -85,10 +76,10 @@ module Selenium
85
76
  # @option opts [Boolean] validate_cookie_document_type
86
77
  #
87
78
 
88
- def initialize(args: nil, **opts)
89
- super(opts)
79
+ def initialize(**opts)
80
+ @args = (opts.delete(:args) || []).to_set
81
+ super(**opts)
90
82
 
91
- @args = (args || []).to_set
92
83
  @options[:native_events] = true if @options[:native_events].nil?
93
84
  end
94
85
 
@@ -102,15 +93,11 @@ module Selenium
102
93
  @args << arg
103
94
  end
104
95
 
105
- #
106
- # @api private
107
- #
96
+ private
108
97
 
109
- def as_json(*)
110
- options = super
98
+ def process_browser_options(browser_options)
99
+ options = browser_options[KEY]
111
100
  options['ie.browserCommandLineSwitches'] = @args.to_a.join(' ') if @args.any?
112
-
113
- {KEY => generate_as_json(options)}
114
101
  end
115
102
  end # Options
116
103
  end # IE
@@ -32,13 +32,15 @@ module Selenium
32
32
 
33
33
  private
34
34
 
35
- # Note: This processing is deprecated
35
+ # NOTE: This processing is deprecated
36
36
  def extract_service_args(driver_opts)
37
37
  driver_args = super
38
38
  driver_opts = driver_opts.dup
39
39
  driver_args << "--log-level=#{driver_opts[:log_level].to_s.upcase}" if driver_opts.key?(:log_level)
40
40
  driver_args << "--log-file=#{driver_opts[:log_file]}" if driver_opts.key?(:log_file)
41
- driver_args << "--implementation=#{driver_opts[:implementation].to_s.upcase}" if driver_opts.key?(:implementation)
41
+ if driver_opts.key?(:implementation)
42
+ driver_args << "--implementation=#{driver_opts[:implementation].to_s.upcase}"
43
+ end
42
44
  driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key?(:host)
43
45
  driver_args << "--extract_path=#{driver_opts[:extract_path]}" if driver_opts.key?(:extract_path)
44
46
  driver_args << "--silent" if driver_opts[:silent] == true
@@ -35,9 +35,9 @@ module Selenium
35
35
  # @api private
36
36
  #
37
37
 
38
- def initialize(http_client: nil, url:)
38
+ def initialize(url:, http_client: nil)
39
39
  uri = url.is_a?(URI) ? url : URI.parse(url)
40
- uri.path += '/' unless %r{\/$}.match?(uri.path)
40
+ uri.path += '/' unless uri.path.end_with?('/')
41
41
 
42
42
  @http = http_client || Http::Default.new
43
43
  @http.server_url = uri
@@ -48,8 +48,8 @@ module Selenium
48
48
  # Creates session.
49
49
  #
50
50
 
51
- def create_session(desired_capabilities, options = nil)
52
- response = execute(:new_session, {}, merged_capabilities(desired_capabilities, options))
51
+ def create_session(capabilities)
52
+ response = execute(:new_session, {}, prepare_capabilities_payload(capabilities))
53
53
 
54
54
  @session_id = response['sessionId']
55
55
  capabilities = response['capabilities']
@@ -57,6 +57,17 @@ module Selenium
57
57
  raise Error::WebDriverError, 'no sessionId in returned payload' unless @session_id
58
58
 
59
59
  @capabilities = Capabilities.json_create(capabilities)
60
+
61
+ case @capabilities[:browser_name]
62
+ when 'chrome'
63
+ extend(WebDriver::Chrome::Features)
64
+ when 'firefox'
65
+ extend(WebDriver::Firefox::Features)
66
+ when 'msedge'
67
+ extend(WebDriver::Edge::Features)
68
+ when 'Safari', 'Safari Technology Preview'
69
+ extend(WebDriver::Safari::Features)
70
+ end
60
71
  end
61
72
 
62
73
  #
@@ -70,7 +81,7 @@ module Selenium
70
81
  def browser
71
82
  @browser ||= begin
72
83
  name = @capabilities.browser_name
73
- name ? name.tr(' ', '_').to_sym : 'unknown'
84
+ name ? name.tr(' ', '_').downcase.to_sym : 'unknown'
74
85
  end
75
86
  end
76
87
 
@@ -207,7 +218,10 @@ module Selenium
207
218
  end
208
219
 
209
220
  def window_size(handle = :current)
210
- raise Error::UnsupportedOperationError, 'Switch to desired window before getting its size' unless handle == :current
221
+ unless handle == :current
222
+ raise Error::UnsupportedOperationError,
223
+ 'Switch to desired window before getting its size'
224
+ end
211
225
 
212
226
  data = execute :get_window_rect
213
227
  Dimension.new data['width'], data['height']
@@ -218,7 +232,10 @@ module Selenium
218
232
  end
219
233
 
220
234
  def maximize_window(handle = :current)
221
- raise Error::UnsupportedOperationError, 'Switch to desired window before changing its size' unless handle == :current
235
+ unless handle == :current
236
+ raise Error::UnsupportedOperationError,
237
+ 'Switch to desired window before changing its size'
238
+ end
222
239
 
223
240
  execute :maximize_window
224
241
  end
@@ -251,6 +268,10 @@ module Selenium
251
268
  execute :take_screenshot
252
269
  end
253
270
 
271
+ def element_screenshot(element)
272
+ execute :take_element_screenshot, id: element.ref
273
+ end
274
+
254
275
  #
255
276
  # HTML 5
256
277
  #
@@ -303,22 +324,6 @@ module Selenium
303
324
  execute_script('return sessionStorage.length')
304
325
  end
305
326
 
306
- def location
307
- raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting location'
308
- end
309
-
310
- def set_location(_lat, _lon, _alt)
311
- raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting location'
312
- end
313
-
314
- def network_connection
315
- raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting network connection'
316
- end
317
-
318
- def network_connection=(_type)
319
- raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting network connection'
320
- end
321
-
322
327
  #
323
328
  # javascript execution
324
329
  #
@@ -389,6 +394,10 @@ module Selenium
389
394
  execute :release_actions
390
395
  end
391
396
 
397
+ def print_page(options = {})
398
+ execute :print_page, {}, {options: options}
399
+ end
400
+
392
401
  def click_element(element)
393
402
  execute :element_click, id: element
394
403
  end
@@ -428,14 +437,6 @@ module Selenium
428
437
  'if (arguments[0].dispatchEvent(e)) { arguments[0].submit() }', form.as_json)
429
438
  end
430
439
 
431
- def screen_orientation=(orientation)
432
- execute :set_screen_orientation, {}, {orientation: orientation}
433
- end
434
-
435
- def screen_orientation
436
- execute :get_screen_orientation
437
- end
438
-
439
440
  #
440
441
  # element properties
441
442
  #
@@ -449,10 +450,22 @@ module Selenium
449
450
  execute_atom :getAttribute, element, name
450
451
  end
451
452
 
453
+ def element_dom_attribute(element, name)
454
+ execute :get_element_attribute, id: element.ref, name: name
455
+ end
456
+
452
457
  def element_property(element, name)
453
458
  execute :get_element_property, id: element.ref, name: name
454
459
  end
455
460
 
461
+ def element_aria_role(element)
462
+ execute :get_element_aria_role, id: element.ref
463
+ end
464
+
465
+ def element_aria_label(element)
466
+ execute :get_element_aria_label, id: element.ref
467
+ end
468
+
456
469
  def element_value(element)
457
470
  element_property element, 'value'
458
471
  end
@@ -571,16 +584,6 @@ module Selenium
571
584
  COMMANDS[command]
572
585
  end
573
586
 
574
- def merged_capabilities(capabilities, options = nil)
575
- capabilities.merge!(options.as_json) if options
576
-
577
- {
578
- capabilities: {
579
- firstMatch: [capabilities]
580
- }
581
- }
582
- end
583
-
584
587
  def unwrap_script_result(arg)
585
588
  case arg
586
589
  when Array
@@ -599,6 +602,11 @@ module Selenium
599
602
  id['ELEMENT'] || id['element-6066-11e4-a52e-4f735466cecf']
600
603
  end
601
604
 
605
+ def prepare_capabilities_payload(capabilities)
606
+ capabilities = {firstMatch: [capabilities]} if !capabilities['alwaysMatch'] && !capabilities['firstMatch']
607
+ {capabilities: capabilities}
608
+ end
609
+
602
610
  def convert_locator(how, what)
603
611
  how = SearchContext::FINDERS[how.to_sym] || how
604
612
 
@@ -626,7 +634,7 @@ module Selenium
626
634
  [how, what]
627
635
  end
628
636
 
629
- ESCAPE_CSS_REGEXP = /(['"\\#.:;,!?+<>=~*^$|%&@`{}\-\[\]\(\)])/.freeze
637
+ ESCAPE_CSS_REGEXP = /(['"\\#.:;,!?+<>=~*^$|%&@`{}\-\[\]()])/.freeze
630
638
  UNICODE_CODE_POINT = 30
631
639
 
632
640
  # Escapes invalid characters in CSS selector.