class Selenium::WebDriver::Remote::Bridge

w3c.github.io/webdriver/#endpoints @api private

Constants

COMMANDS
ESCAPE_CSS_REGEXP
PORT
QUIT_ERRORS
UNICODE_CODE_POINT

Attributes

capabilities[R]
file_detector[RW]
http[RW]

Public Class Methods

new(url:, http_client: nil) click to toggle source

Initializes the bridge with the given server URL @param [String, URI] url url for the remote server @param [Object] http_client an HTTP client instance that implements the same protocol as Http::Default @api private

# File lib/selenium/webdriver/remote/bridge.rb, line 38
def initialize(url:, http_client: nil)
  uri = url.is_a?(URI) ? url : URI.parse(url)
  uri.path += '/' unless uri.path.end_with?('/')

  @http = http_client || Http::Default.new
  @http.server_url = uri
  @file_detector = nil
end

Public Instance Methods

accept_alert() click to toggle source

alerts

# File lib/selenium/webdriver/remote/bridge.rb, line 112
def accept_alert
  execute :accept_alert
end
action(deprecated_async = nil, async: false, devices: [], duration: 250) click to toggle source

actions

# File lib/selenium/webdriver/remote/bridge.rb, line 370
def action(deprecated_async = nil, async: false, devices: [], duration: 250)
  ActionBuilder.new self, nil, nil, deprecated_async, async: async, devices: devices, duration: duration
end
Also aliased as: actions
actions(deprecated_async = nil, async: false, devices: [], duration: 250)
Alias for: action
active_element() click to toggle source

finding elements

# File lib/selenium/webdriver/remote/bridge.rb, line 524
def active_element
  Element.new self, element_id_from(execute(:get_active_element))
end
Also aliased as: switch_to_active_element
add_credential(credential, id) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 584
def add_credential(credential, id)
  execute :add_credential, {authenticatorId: id}, credential
end
add_virtual_authenticator(options) click to toggle source

virtual-authenticator

# File lib/selenium/webdriver/remote/bridge.rb, line 575
def add_virtual_authenticator(options)
  authenticator_id = execute :add_virtual_authenticator, {}, options.as_json
  VirtualAuthenticator.new(self, authenticator_id, options)
end
alert=(keys) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 120
def alert=(keys)
  execute :send_alert_text, {}, {value: keys.chars, text: keys}
end
alert_text() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 124
def alert_text
  execute :get_alert_text
end
browser() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 81
def browser
  @browser ||= begin
    name = @capabilities.browser_name
    name ? name.tr(' ', '_').downcase.to_sym : 'unknown'
  end
end
clear_element(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 423
def clear_element(element)
  execute :element_clear, id: element
end
clear_local_storage() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 292
def clear_local_storage
  execute_script('localStorage.clear()')
end
clear_session_storage() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 316
def clear_session_storage
  execute_script('sessionStorage.clear()')
end
click_element(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 395
def click_element(element)
  execute :element_click, id: element
end
close() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 191
def close
  execute :close_window
end
cookies() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 358
def cookies
  execute :get_all_cookies
end
create_session(capabilities) click to toggle source

Creates session.

# File lib/selenium/webdriver/remote/bridge.rb, line 51
def create_session(capabilities)
  response = execute(:new_session, {}, prepare_capabilities_payload(capabilities))

  @session_id = response['sessionId']
  capabilities = response['capabilities']

  raise Error::WebDriverError, 'no sessionId in returned payload' unless @session_id

  @capabilities = Capabilities.json_create(capabilities)

  case @capabilities[:browser_name]
  when 'chrome'
    extend(WebDriver::Chrome::Features)
  when 'firefox'
    extend(WebDriver::Firefox::Features)
  when 'msedge'
    extend(WebDriver::Edge::Features)
  when 'Safari', 'Safari Technology Preview'
    extend(WebDriver::Safari::Features)
  end
end
credentials(authenticator_id) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 588
def credentials(authenticator_id)
  execute :get_credentials, {authenticatorId: authenticator_id}
end
delete_all_cookies() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 362
def delete_all_cookies
  execute :delete_all_cookies
end
dismiss_alert() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 116
def dismiss_alert
  execute :dismiss_alert
end
element_aria_label(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 468
def element_aria_label(element)
  execute :get_element_aria_label, id: element
end
element_aria_role(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 464
def element_aria_role(element)
  execute :get_element_aria_role, id: element
end
element_attribute(element, name) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 451
def element_attribute(element, name)
  WebDriver.logger.info "Using script for :getAttribute of #{name}"
  execute_atom :getAttribute, element, name
end
element_displayed?(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 511
def element_displayed?(element)
  WebDriver.logger.info 'Using script for :isDisplayed'
  execute_atom :isDisplayed, element
end
element_dom_attribute(element, name) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 456
def element_dom_attribute(element, name)
  execute :get_element_attribute, id: element, name: name
end
element_enabled?(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 503
def element_enabled?(element)
  execute :is_element_enabled, id: element
end
element_location(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 480
def element_location(element)
  data = execute :get_element_rect, id: element

  Point.new data['x'], data['y']
end
element_location_once_scrolled_into_view(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 492
def element_location_once_scrolled_into_view(element)
  send_keys_to_element(element, [''])
  element_location(element)
end
element_property(element, name) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 460
def element_property(element, name)
  execute :get_element_property, id: element, name: name
end
element_rect(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 486
def element_rect(element)
  data = execute :get_element_rect, id: element

  Rectangle.new data['x'], data['y'], data['width'], data['height']
end
element_screenshot(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 268
def element_screenshot(element)
  execute :take_element_screenshot, id: element
end
element_selected?(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 507
def element_selected?(element)
  execute :is_element_selected, id: element
end
element_size(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 497
def element_size(element)
  data = execute :get_element_rect, id: element

  Dimension.new data['width'], data['height']
end
element_tag_name(element) click to toggle source

element properties

# File lib/selenium/webdriver/remote/bridge.rb, line 447
def element_tag_name(element)
  execute :get_element_tag_name, id: element
end
element_text(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 476
def element_text(element)
  execute :get_element_text, id: element
end
element_value(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 472
def element_value(element)
  element_property element, 'value'
end
element_value_of_css_property(element, prop) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 516
def element_value_of_css_property(element, prop)
  execute :get_element_css_value, id: element, property_name: prop
end
execute_async_script(script, *args) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 333
def execute_async_script(script, *args)
  result = execute :execute_async_script, {}, {script: script, args: args}
  unwrap_script_result result
end
execute_script(script, *args) click to toggle source

javascript execution

# File lib/selenium/webdriver/remote/bridge.rb, line 328
def execute_script(script, *args)
  result = execute :execute_script, {}, {script: script, args: args}
  unwrap_script_result result
end
find_element_by(how, what, parent_ref = []) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 530
def find_element_by(how, what, parent_ref = [])
  how, what = convert_locator(how, what)

  return execute_atom(:findElements, Support::RelativeLocator.new(what).as_json).first if how == 'relative'

  parent_type, parent_id = parent_ref
  id = case parent_type
       when :element
         execute :find_child_element, {id: parent_id}, {using: how, value: what.to_s}
       when :shadow_root
         execute :find_shadow_child_element, {id: parent_id}, {using: how, value: what.to_s}
       else
         execute :find_element, {}, {using: how, value: what.to_s}
       end

  Element.new self, element_id_from(id)
end
find_elements_by(how, what, parent_ref = []) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 548
def find_elements_by(how, what, parent_ref = [])
  how, what = convert_locator(how, what)

  return execute_atom :findElements, Support::RelativeLocator.new(what).as_json if how == 'relative'

  parent_type, parent_id = parent_ref
  ids = case parent_type
        when :element
          execute :find_child_elements, {id: parent_id}, {using: how, value: what.to_s}
        when :shadow_root
          execute :find_shadow_child_elements, {id: parent_id}, {using: how, value: what.to_s}
        else
          execute :find_elements, {}, {using: how, value: what.to_s}
        end

  ids.map { |id| Element.new self, element_id_from(id) }
end
full_screen_window() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 240
def full_screen_window
  execute :fullscreen_window
end
get(url) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 92
def get(url)
  execute :get, {}, {url: url}
end
go_back() click to toggle source

navigation

# File lib/selenium/webdriver/remote/bridge.rb, line 132
def go_back
  execute :back
end
go_forward() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 136
def go_forward
  execute :forward
end
keyboard() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 379
def keyboard
  raise Error::UnsupportedOperationError, '#keyboard is no longer supported, use #action instead'
end
local_storage_item(key, value = nil) click to toggle source

HTML 5

# File lib/selenium/webdriver/remote/bridge.rb, line 276
def local_storage_item(key, value = nil)
  if value
    execute_script("localStorage.setItem('#{key}', '#{value}')")
  else
    execute_script("return localStorage.getItem('#{key}')")
  end
end
local_storage_keys() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 288
def local_storage_keys
  execute_script('return Object.keys(localStorage)')
end
local_storage_size() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 296
def local_storage_size
  execute_script('return localStorage.length')
end
manage() click to toggle source

cookies

# File lib/selenium/webdriver/remote/bridge.rb, line 342
def manage
  @manage ||= WebDriver::Manager.new(self)
end
maximize_window(handle = :current) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 231
def maximize_window(handle = :current)
  unless handle == :current
    raise Error::UnsupportedOperationError,
          'Switch to desired window before changing its size'
  end

  execute :maximize_window
end
minimize_window() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 227
def minimize_window
  execute :minimize_window
end
mouse() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 375
def mouse
  raise Error::UnsupportedOperationError, '#mouse is no longer supported, use #action instead'
end
new_window(type) click to toggle source

Create a new top-level browsing context w3c.github.io/webdriver/#new-window @param type [String] Supports two values: ‘tab’ and ‘window’.

Use 'tab' if you'd like the new window to share an OS-level window
with the current browsing context.
Use 'window' otherwise

@return [Hash] Containing ‘handle’ with the value of the window handle

and 'type' with the value of the created window type
# File lib/selenium/webdriver/remote/bridge.rb, line 162
def new_window(type)
  execute :new_window, {}, {type: type}
end
page_source() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 148
def page_source
  execute :get_page_source
end
print_page(options = {}) click to toggle source
quit() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 185
def quit
  execute :delete_session
  http.close
rescue *QUIT_ERRORS
end
refresh() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 195
def refresh
  execute :refresh
end
release_actions() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 387
def release_actions
  execute :release_actions
end
remove_all_credentials(authenticator_id) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 596
def remove_all_credentials(authenticator_id)
  execute :remove_all_credentials, {authenticatorId: authenticator_id}
end
remove_credential(credential_id, authenticator_id) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 592
def remove_credential(credential_id, authenticator_id)
  execute :remove_credential, {credentialId: credential_id, authenticatorId: authenticator_id}
end
remove_local_storage_item(key) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 284
def remove_local_storage_item(key)
  execute_script("localStorage.removeItem('#{key}')")
end
remove_session_storage_item(key) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 308
def remove_session_storage_item(key)
  execute_script("sessionStorage.removeItem('#{key}')")
end
remove_virtual_authenticator(id) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 580
def remove_virtual_authenticator(id)
  execute :remove_virtual_authenticator, {authenticatorId: id}
end
reposition_window(x, y) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 244
def reposition_window(x, y)
  set_window_rect(x: x, y: y)
end
resize_window(width, height, handle = :current) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 211
def resize_window(width, height, handle = :current)
  raise Error::WebDriverError, 'Switch to desired window before changing its size' unless handle == :current

  set_window_rect(width: width, height: height)
end
screenshot() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 264
def screenshot
  execute :take_screenshot
end
send_actions(data) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 383
def send_actions(data)
  execute :actions, {}, {actions: data}
end
send_keys_to_element(element, keys) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 399
def send_keys_to_element(element, keys)
  # TODO: rework file detectors before Selenium 4.0
  if @file_detector
    local_files = keys.first&.split("\n")&.map { |key| @file_detector.call(Array(key)) }&.compact
    if local_files.any?
      keys = local_files.map { |local_file| upload(local_file) }
      keys = Array(keys.join("\n"))
    end
  end

  # Keep .split(//) for backward compatibility for now
  text = keys.join
  execute :element_send_keys, {id: element}, {value: text.chars, text: text}
end
session_id() click to toggle source

Returns the current session ID.

# File lib/selenium/webdriver/remote/bridge.rb, line 77
def session_id
  @session_id || raise(Error::WebDriverError, 'no current session exists')
end
session_storage_item(key, value = nil) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 300
def session_storage_item(key, value = nil)
  if value
    execute_script("sessionStorage.setItem('#{key}', '#{value}')")
  else
    execute_script("return sessionStorage.getItem('#{key}')")
  end
end
session_storage_keys() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 312
def session_storage_keys
  execute_script('return Object.keys(sessionStorage)')
end
session_storage_size() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 320
def session_storage_size
  execute_script('return sessionStorage.length')
end
set_window_rect(x: nil, y: nil, width: nil, height: nil) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 253
def set_window_rect(x: nil, y: nil, width: nil, height: nil)
  params = {x: x, y: y, width: width, height: height}
  params.update(params) { |_k, v| Integer(v) unless v.nil? }
  execute :set_window_rect, {}, params
end
shadow_root(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 566
def shadow_root(element)
  id = execute :get_element_shadow_root, id: element
  ShadowRoot.new self, shadow_root_id_from(id)
end
status() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 88
def status
  execute :status
end
submit_element(element) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 427
def submit_element(element)
  script = "var form = arguments[0];\n" \
           "while (form.nodeName != \"FORM\" && form.parentNode) {\n  " \
           "form = form.parentNode;\n" \
           "}\n" \
           "if (!form) { throw Error('Unable to find containing form element'); }\n" \
           "if (!form.ownerDocument) { throw Error('Unable to find owning document'); }\n" \
           "var e = form.ownerDocument.createEvent('Event');\n" \
           "e.initEvent('submit', true, true);\n" \
           "if (form.dispatchEvent(e)) { HTMLFormElement.prototype.submit.call(form) }\n"

  execute_script(script, Element::ELEMENT_KEY => element)
rescue Error::JavascriptError
  raise Error::UnsupportedOperationError, "To submit an element, it must be nested inside a form element"
end
switch_to_active_element()
Alias for: active_element
switch_to_default_content() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 179
def switch_to_default_content
  switch_to_frame nil
end
switch_to_frame(id) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 170
def switch_to_frame(id)
  id = find_element_by('id', id) if id.is_a? String
  execute :switch_to_frame, {}, {id: id}
end
switch_to_parent_frame() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 175
def switch_to_parent_frame
  execute :switch_to_parent_frame
end
switch_to_window(name) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 166
def switch_to_window(name)
  execute :switch_to_window, {}, {handle: name}
end
timeouts() click to toggle source

timeouts

# File lib/selenium/webdriver/remote/bridge.rb, line 100
def timeouts
  execute :get_timeouts, {}
end
timeouts=(timeouts) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 104
def timeouts=(timeouts)
  execute :set_timeout, {}, timeouts
end
title() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 144
def title
  execute :get_title
end
upload(local_file) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 414
def upload(local_file)
  unless File.file?(local_file)
    WebDriver.logger.debug("File detector only works with files. #{local_file.inspect} isn`t a file!")
    raise Error::WebDriverError, "You are trying to work with something that isn't a file."
  end

  execute :upload_file, {}, {file: Zipper.zip_file(local_file)}
end
url() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 140
def url
  execute :get_current_url
end
user_verified(verified, authenticator_id) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 600
def user_verified(verified, authenticator_id)
  execute :set_user_verified, {authenticatorId: authenticator_id}, {isUserVerified: verified}
end
window_handle() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 207
def window_handle
  execute :get_window_handle
end
window_handles() click to toggle source

window handling

# File lib/selenium/webdriver/remote/bridge.rb, line 203
def window_handles
  execute :get_window_handles
end
window_position() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 248
def window_position
  data = execute :get_window_rect
  Point.new data['x'], data['y']
end
window_rect() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 259
def window_rect
  data = execute :get_window_rect
  Rectangle.new data['x'], data['y'], data['width'], data['height']
end
window_size(handle = :current) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 217
def window_size(handle = :current)
  unless handle == :current
    raise Error::UnsupportedOperationError,
          'Switch to desired window before getting its size'
  end

  data = execute :get_window_rect
  Dimension.new data['width'], data['height']
end

Private Instance Methods

commands(command) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 632
def commands(command)
  COMMANDS[command]
end
convert_locator(how, what) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 666
def convert_locator(how, what)
  how = SearchContext::FINDERS[how.to_sym] || how

  case how
  when 'class name'
    how = 'css selector'
    what = ".#{escape_css(what.to_s)}"
  when 'id'
    how = 'css selector'
    what = "##{escape_css(what.to_s)}"
  when 'name'
    how = 'css selector'
    what = "*[name='#{escape_css(what.to_s)}']"
  end

  if what.is_a?(Hash)
    what = what.each_with_object({}) do |(h, w), hash|
      h, w = convert_locator(h.to_s, w)
      hash[h] = w
    end
  end

  [how, what]
end
element_id_from(id) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 653
def element_id_from(id)
  id['ELEMENT'] || id[Element::ELEMENT_KEY]
end
escape_css(string) click to toggle source

Escapes invalid characters in CSS selector. @see mathiasbynens.be/notes/css-escapes

# File lib/selenium/webdriver/remote/bridge.rb, line 696
def escape_css(string)
  string = string.gsub(ESCAPE_CSS_REGEXP) { |match| "\\#{match}" }
  string = "\\#{UNICODE_CODE_POINT + Integer(string[0])} #{string[1..]}" if string[0]&.match?(/[[:digit:]]/)

  string
end
escaper() click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 628
def escaper
  @escaper ||= defined?(URI::Parser) ? URI::DEFAULT_PARSER : URI
end
execute(command, opts = {}, command_hash = nil) click to toggle source

executes a command on the remote server.

@return [WebDriver::Remote::Response]

# File lib/selenium/webdriver/remote/bridge.rb, line 612
def execute(command, opts = {}, command_hash = nil)
  verb, path = commands(command) || raise(ArgumentError, "unknown command: #{command.inspect}")
  path = path.dup

  path[':session_id'] = session_id if path.include?(':session_id')

  begin
    opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s) }
  rescue IndexError
    raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
  end

  WebDriver.logger.info("-> #{verb.to_s.upcase} #{path}")
  http.call(verb, path, command_hash)['value']
end
prepare_capabilities_payload(capabilities) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 661
def prepare_capabilities_payload(capabilities)
  capabilities = {alwaysMatch: capabilities} if !capabilities['alwaysMatch'] && !capabilities['firstMatch']
  {capabilities: capabilities}
end
shadow_root_id_from(id) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 657
def shadow_root_id_from(id)
  id[ShadowRoot::ROOT_KEY]
end
unwrap_script_result(arg) click to toggle source
# File lib/selenium/webdriver/remote/bridge.rb, line 636
def unwrap_script_result(arg)
  case arg
  when Array
    arg.map { |e| unwrap_script_result(e) }
  when Hash
    element_id = element_id_from(arg)
    return Element.new(self, element_id) if element_id

    shadow_root_id = shadow_root_id_from(arg)
    return ShadowRoot.new self, shadow_root_id if shadow_root_id

    arg.each { |k, v| arg[k] = unwrap_script_result(v) }
  else
    arg
  end
end