chrome

An actor that manages an instance of the chrome browser via an erlang port. The browser is started to allow remote debugging via pipes, once the pipe is disconnected, chrome should quit automatically.

All messages to the browser are sent through this actor to the port, and responses are returned to the sender. The actor manages associating responses with the correct request by adding auto-incrementing ids to the requests, so callers don’t need to worry about this.

When the browser managed by this actor is closed, the actor will also exit.

To start a browser, it’s preferrable to use the launch functions from the root chrobot module, which perform additional checks and validations.

Types

pub type BrowserConfig {
  BrowserConfig(
    path: String,
    args: List(String),
    start_timeout: Int,
  )
}

Constructors

  • BrowserConfig(
      path: String,
      args: List(String),
      start_timeout: Int,
    )
pub type BrowserInstance {
  BrowserInstance(port: Port)
}

Constructors

  • BrowserInstance(port: Port)
pub type BrowserVersion {
  BrowserVersion(
    protocol_version: String,
    product: String,
    revision: String,
    user_agent: String,
    js_version: String,
  )
}

Constructors

  • BrowserVersion(
      protocol_version: String,
      product: String,
      revision: String,
      user_agent: String,
      js_version: String,
    )

Errors that may occur during launch of the browser instance

pub type LaunchError {
  UnknowOperatingSystem
  CouldNotFindExecutable
  FailedToStart
  UnresponsiveAfterStart
  ProtocolVersionMismatch(
    supported_version: String,
    got_version: String,
  )
}

Constructors

  • UnknowOperatingSystem
  • CouldNotFindExecutable
  • FailedToStart
  • UnresponsiveAfterStart

    This is used by the launch functions of the root chrobot module

  • ProtocolVersionMismatch(
      supported_version: String,
      got_version: String,
    )

    Arguments

    • supported_version

      Version supported by the protocol

    • got_version

      Version the browser reported

pub type Message {
  Shutdown(reply_with: Subject(Nil))
  Kill
  Call(
    reply_with: Subject(Result(d.Dynamic, RequestError)),
    method: String,
    params: Option(Json),
    session_id: Option(String),
  )
  Send(method: String, params: Option(Json))
  AddListener(listener: Subject(d.Dynamic), method: String)
  RemoveListener(listener: Subject(d.Dynamic))
  UnexpectedPortMessage(d.Dynamic)
  PortResponse(String)
  PortExit(Int)
}

Constructors

  • Shutdown(reply_with: Subject(Nil))

    Initiate graceful shutdown of the browser

  • Kill

    Kill by shutting down actor

  • Call(
      reply_with: Subject(Result(d.Dynamic, RequestError)),
      method: String,
      params: Option(Json),
      session_id: Option(String),
    )

    Make a protocol call and receive response

  • Send(method: String, params: Option(Json))

    Make a protocol call and ignore response

  • AddListener(listener: Subject(d.Dynamic), method: String)
  • RemoveListener(listener: Subject(d.Dynamic))
  • UnexpectedPortMessage(d.Dynamic)

    (From Port) Message that could not be matched

  • PortResponse(String)

    (From Port) Protocol Message

  • PortExit(Int)

    (From Port) Port has exited

Errors that may occur when a protocol request is made

pub type RequestError {
  PortError
  ChromeAgentTimeout
  ChromeAgentDown
  ProtocolError
  BrowserError(code: Int, message: String, data: String)
  NotFoundError
  RuntimeException(text: String, line: Int, column: Int)
}

Constructors

  • PortError
  • ChromeAgentTimeout

    OTP actor timeout

  • ChromeAgentDown

    OTP actor down

  • ProtocolError

    The ProtocolError variant is used by /protocol domains to return a homogeneous error type for all requests.

  • BrowserError(code: Int, message: String, data: String)

    This is an error response from the browser itself

  • NotFoundError

    A requested resource could not be found

  • RuntimeException(text: String, line: Int, column: Int)

    A runtime exception thrown by JavaScript code being evaluated in the browser

Functions

pub fn add_listener(
  browser: Subject(Message),
  method: String,
) -> Subject(Dynamic)
pub fn call(
  browser: Subject(Message),
  method: String,
  params: Option(Json),
  session_id: Option(String),
  time_out: Int,
) -> Result(Dynamic, RequestError)

Issue a protocol call to the browser and expect a response

pub fn get_default_chrome_args() -> List(String)

Get the default arguments the browser should be started with, to be used inside the launch_with_config function

pub fn get_local_chrome_path() -> Result(String, LaunchError)

Try to find a hermetic chrome installation in the current directory, of the kind installed by npx @puppeteer/browsers install chrome. The installation must be in a directory called chrome.

pub fn get_system_chrome_path() -> Result(String, LaunchError)

Try to find a system chrome installation in some obvious places.

pub fn get_version(
  browser: Subject(Message),
) -> Result(BrowserVersion, RequestError)

Hardcoded protocol call to get the browser version See: https://chromedevtools.github.io/devtools-protocol/tot/Browser/#method-getVersion

pub fn is_local_chrome_path(
  relative_path: String,
  os_family: OsFamily,
) -> Bool

Returns whether the given path is a local chrome installation, of the kind created by npx @puppeteer/browsers install chrome. This can be used to scan a directory with simplifile.get_files.

pub fn launch() -> Result(Subject(Message), LaunchError)

Try to find a chrome installation and launch it with default arguments.

First, it will try to find a local chrome installation, like that created by npx @puppeteer/browsers install chrome If that fails, it will try to find a system chrome installation in some common places.

For consistency it would be preferrable to not use this function and instead use launch_with_config with a BrowserConfig that specifies the path to the chrome executable.

Be aware that this function will not validate that the browser launched successfully, please use the higher level functions from the root chrobot module instead if you want these guarantees.

pub fn launch_with_config(
  cfg: BrowserConfig,
) -> Result(Subject(Message), LaunchError)

Launch a browser with the given configuration, to populate the arguments, use get_default_chrome_args.

Be aware that this function will not validate that the browser launched successfully, please use the higher level functions from the root chrobot module instead if you want these guarantees.

Example

let config =
BrowserConfig(
  path: "chrome/linux-116.0.5793.0/chrome-linux64/chrome",
  args: get_default_chrome_args(),
  start_timeout: 5000,
)
let assert Ok(browser_subject) = launch_with_config(config)
pub fn listen_once(
  browser: Subject(Message),
  method: String,
  time_out: Int,
) -> Result(Dynamic, RequestError)

A blocking call that waits for a specified event to arrive once, and then resolves, removing the event listener.

pub fn quit(
  browser: Subject(Message),
) -> Result(Nil, CallError(Nil))

Quit the browser and shut down the actor.
This function will attempt graceful shutdown, if the browser does not respond in time, it will also send a kill signal to the actor to force it to shut down. The result typing reflects the success of graceful shutdown.

pub fn remove_listener(
  browser: Subject(Message),
  listener: Subject(Dynamic),
) -> Nil
pub fn send(
  browser: Subject(Message),
  method: String,
  params: Option(Json),
) -> Nil

Issue a protocol call to the browser without waiting for a response, when the response arrives, it will be discarded. It’s probably best to not use this and instead just use call and discard unneeded responses. All protocol calls yield a response and can be used with call, even if they don’t specify any response parameters.

Search Document