class Playwright::Connection

def async_run

def async_run
  @transport.async_run
end

def async_send_message_to_server(guid, method, params, metadata: nil)

def async_send_message_to_server(guid, method, params, metadata: nil)
  return if @closed_error
  callback = Concurrent::Promises.resolvable_future
  with_generated_id do |id|
    # register callback promise object first.
    # @see https://github.com/YusukeIwaki/puppeteer-ruby/pull/34
    @callbacks[id] = callback
    _metadata = {}
    frames = []
    if metadata
      frames = metadata[:stack]
      _metadata[:wallTime] = metadata[:wallTime]
      _metadata[:apiName] = metadata[:apiName]
      _metadata[:location] = metadata[:stack].first
      _metadata[:internal] = !metadata[:apiName]
    end
    _metadata.compact!
    message = {
      id: id,
      guid: guid,
      method: method,
      params: replace_channels_with_guids(params),
      metadata: _metadata,
    }
    begin
      @transport.send_message(message)
    rescue => err
      @callbacks.delete(id)
      callback.reject(err)
      raise unless err.is_a?(Transport::AlreadyDisconnectedError)
    end
    if @tracing_count > 0 && !frames.empty? && guid != 'localUtils'
      @local_utils.add_stack_to_tracing_no_reply(id, frames)
    end
  end
  callback
end

def cleanup(cause: nil)

def cleanup(cause: nil)
  @closed_error = cause || TargetClosedError.new
  @callbacks.each_value do |callback|
    callback.reject(@closed_error)
  end
  @callbacks.clear
end

def create_remote_object(parent_guid:, type:, guid:, initializer:)

Returns:
  • (Playwright::ChannelOwner|nil) -
def create_remote_object(parent_guid:, type:, guid:, initializer:)
  parent = @objects[parent_guid]
  unless parent
    raise "Cannot find parent object #{parent_guid} to create #{guid}"
  end
  initializer = replace_guids_with_channels(initializer)
  result =
    begin
      ChannelOwners.const_get(type).new(
        parent,
        type,
        guid,
        initializer,
      )
    rescue NameError
      raise "Missing type #{type}"
    end
  callback = @waiting_for_object.delete(guid)
  callback&.fulfill(result)
  result
end

def delete_object_from_channel_owner(guid)

Other tags:
    Note: - This method should be used internally. Accessed via .send method from Playwright::ChannelOwner, so keep private!

Parameters:
  • guid (String) --
def delete_object_from_channel_owner(guid)
  @objects.delete(guid)
end

def dispatch(msg)

def dispatch(msg)
  return if @closed_error
  id = msg['id']
  if id
    callback = @callbacks.delete(id)
    unless callback
      raise "Cannot find command to respond: #{id}"
    end
    error = msg['error']
    if error && !msg['result']
      parsed_error = ::Playwright::Error.parse(error['error'])
      parsed_error.log = msg['log']
      callback.reject(parsed_error)
    else
      result = replace_guids_with_channels(msg['result'])
      callback.fulfill(result)
    end
    return
  end
  guid = msg['guid']
  method = msg['method']
  params = msg['params']
  if method == "__create__"
    remote_object = create_remote_object(
      parent_guid: guid,
      type: params["type"],
      guid: params["guid"],
      initializer: params["initializer"],
    )
    if remote_object.is_a?(ChannelOwners::LocalUtils)
      @local_utils = remote_object
    end
    return
  end
  object = @objects[guid]
  unless object
    raise "Cannot find object to \"#{method}\": #{guid}"
  end
  if method == "__adopt__"
    child = @objects[params["guid"]]
    unless child
      raise "Unknown new child: #{params['guid']}"
    end
    object.send(:adopt!, child)
    return
  end
  if method == "__dispose__"
    object.send(:dispose!, reason: params["reason"])
    return
  end
  object.channel.emit(method, replace_guids_with_channels(params))
end

def initialize(transport)

def initialize(transport)
  @transport = transport
  @transport.on_message_received do |message|
    dispatch(message)
  end
  @transport.on_driver_crashed do
    @callbacks.each_value do |callback|
      callback.reject(::Playwright::DriverCrashedError.new)
    end
    raise ::Playwright::DriverCrashedError.new
  end
  @objects = {} # Hash[ guid => ChannelOwner ]
  @waiting_for_object = {} # Hash[ guid => Promise<ChannelOwner> ]
  @callbacks = {} # Hash [ guid => Promise<ChannelOwner> ]
  @root_object = RootChannelOwner.new(self)
  @remote = false
  @tracing_count = 0
  @closed_error = nil
end

def initialize_playwright

def initialize_playwright
  # Avoid Error: sdkLanguage: expected one of (javascript|python|java|csharp)
  # ref: https://github.com/microsoft/playwright/pull/18308
  # ref: https://github.com/YusukeIwaki/playwright-ruby-client/issues/228
  result = send_message_to_server('', 'initialize', { sdkLanguage: 'python' })
  ChannelOwners::Playwright.from(result['playwright'])
end

def mark_as_remote

def mark_as_remote
  @remote = true
end

def remote?

def remote?
  @remote
end

def replace_channels_with_guids(payload)

def replace_channels_with_guids(payload)
  if payload.nil?
    return nil
  end
  if payload.is_a?(Array)
    return payload.map{ |pl| replace_channels_with_guids(pl) }
  end
  if payload.is_a?(Channel)
    return { guid: payload.guid }
  end
  if payload.is_a?(Hash)
    return payload.map { |k, v| [k, replace_channels_with_guids(v)] }.to_h
  end
  payload
end

def replace_guids_with_channels(payload)

def replace_guids_with_channels(payload)
  if payload.nil?
    return nil
  end
  if payload.is_a?(Array)
    return payload.map{ |pl| replace_guids_with_channels(pl) }
  end
  if payload.is_a?(Hash)
    guid = payload['guid']
    if guid && @objects[guid]
      return @objects[guid].channel
    end
    return payload.map { |k, v| [k, replace_guids_with_channels(v)] }.to_h
  end
  payload
end

def send_message_to_server(guid, method, params, metadata: nil)

def send_message_to_server(guid, method, params, metadata: nil)
  async_send_message_to_server(guid, method, params, metadata: metadata).value!
end

def set_in_tracing(value)

def set_in_tracing(value)
  if value
    @tracing_count += 1
  else
    @tracing_count -= 1
  end
end

def stop

def stop
  @transport.stop
  cleanup
end

def update_object_from_channel_owner(guid, parent)

Other tags:
    Note: - This method should be used internally. Accessed via .send method from Playwright::ChannelOwner, so keep private!

Parameters:
  • parent (Playwright::ChannelOwner) --
  • guid (String) --
def update_object_from_channel_owner(guid, parent)
  @objects[guid] = parent
end

def with_generated_id(&block)

````
end
# play with id
connection.with_generated_id do |id|
```usage
def with_generated_id(&block)
  @last_id ||= 0
  block.call(@last_id += 1)
end