Class: Browserctl::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/browserctl/client.rb

Overview

Thin IPC client that wraps each browserd command as a Ruby method call.

Instance Method Summary collapse

Constructor Details

#initialize(socket_path = Browserctl.socket_path) ⇒ Client

Returns a new instance of Client.



12
13
14
# File 'lib/browserctl/client.rb', line 12

def initialize(socket_path = Browserctl.socket_path)
  @socket_path = socket_path
end

Instance Method Details

#call(cmd, **params) ⇒ Object



16
17
18
19
20
21
22
# File 'lib/browserctl/client.rb', line 16

def call(cmd, **params)
  result = communicate(JSON.generate({ cmd: cmd }.merge(params)))
  Recording.append(cmd, **params) if result[:ok]
  result
rescue Errno::ENOENT, Errno::ECONNREFUSED
  raise "browserd is not running — start it with: browserd"
end

#clear_cookies(name) ⇒ Hash

Clears all cookies for a named page.

Parameters:

  • name (String)

    logical page name

Returns:

  • (Hash)

    ‘{ ok: true }` or `{ error: }`



165
# File 'lib/browserctl/client.rb', line 165

def clear_cookies(name) = call("clear_cookies", name: name)

#click(name, selector = nil, ref: nil) ⇒ Hash

Clicks an element identified by CSS selector or snapshot ref.

Parameters:

  • name (String)

    logical page name

  • selector (String, nil) (defaults to: nil)

    CSS selector

  • ref (String, nil) (defaults to: nil)

    snapshot ref (e.g. “e3”)

Returns:

  • (Hash)

    ‘{ ok: true }` or `{ error: }`

Raises:

  • (ArgumentError)


50
51
52
53
54
# File 'lib/browserctl/client.rb', line 50

def click(name, selector = nil, ref: nil)
  raise ArgumentError, "click: provide selector or ref:" unless selector || ref

  call("click", name: name, selector: selector, ref: ref)
end

#close_page(name) ⇒ Hash

Closes a named page and removes it from the session.

Parameters:

  • name (String)

    logical page name

Returns:

  • (Hash)

    ‘{ ok: true }` or `{ error: }`



33
# File 'lib/browserctl/client.rb', line 33

def close_page(name)           = call("close_page", name: name)

#cookies(name) ⇒ Hash

Returns all cookies for a named page.

Parameters:

  • name (String)

    logical page name

Returns:

  • (Hash)

    ‘{ ok: true, cookies: [Hash] }` or `{ error: }`



148
# File 'lib/browserctl/client.rb', line 148

def cookies(name) = call("cookies", name: name)

#evaluate(name, expression) ⇒ Hash

Evaluates a JavaScript expression and returns the result.

Parameters:

  • name (String)

    logical page name

  • expression (String)

    JavaScript expression

Returns:

  • (Hash)

    ‘{ ok: true, result: }` or `{ error: }`



109
# File 'lib/browserctl/client.rb', line 109

def evaluate(name, expression) = call("evaluate",    name: name, expression: expression)

#export_cookies(name, path) ⇒ Hash

Exports all cookies for a named page to a JSON file.

Parameters:

  • name (String)

    logical page name

  • path (String)

    file path to write cookies to

Returns:

  • (Hash)

    ‘{ ok: true, path:, count: }` or `{ error: }`



171
172
173
174
175
176
177
178
# File 'lib/browserctl/client.rb', line 171

def export_cookies(name, path)
  result = call("cookies", name: name)
  return result unless result[:ok]

  FileUtils.mkdir_p(File.dirname(path))
  File.open(path, "w", 0o600) { |f| f.write(JSON.generate(result[:cookies])) }
  { ok: true, path: path, count: result[:cookies].length }
end

#fetch(key) ⇒ Hash

Retrieves a value from the daemon-scoped key-value store.

Parameters:

  • key (String)

    storage key

Returns:

  • (Hash)

    ‘{ ok: true, value: }` or `{ error:, code: “key_not_found” }`



143
# File 'lib/browserctl/client.rb', line 143

def fetch(key) = call("fetch", key: key)

#fill(name, selector = nil, value = nil, ref: nil) ⇒ Hash

Fills an input element with a value.

Parameters:

  • name (String)

    logical page name

  • selector (String, nil) (defaults to: nil)

    CSS selector

  • value (String, nil) (defaults to: nil)

    text to type

  • ref (String, nil) (defaults to: nil)

    snapshot ref

Returns:

  • (Hash)

    ‘{ ok: true }` or `{ error: }`

Raises:

  • (ArgumentError)


62
63
64
65
66
# File 'lib/browserctl/client.rb', line 62

def fill(name, selector = nil, value = nil, ref: nil)
  raise ArgumentError, "fill: provide selector or ref:" unless selector || ref

  call("fill", name: name, selector: selector, ref: ref, value: value)
end

#goto(name, url) ⇒ Hash

Navigates a page to a URL. Returns ‘challenge: true` when Cloudflare is detected.

Parameters:

  • name (String)

    logical page name

  • url (String)

    destination URL

Returns:

  • (Hash)

    ‘{ ok: true, url:, challenge: }` or `{ error: }`



43
# File 'lib/browserctl/client.rb', line 43

def goto(name, url)            = call("goto", name: name, url: url)

#import_cookies(name, path) ⇒ Hash

Imports cookies from a JSON file into a named page.

Parameters:

  • name (String)

    logical page name

  • path (String)

    file path to read cookies from

Returns:

  • (Hash)

    ‘{ ok: true, count: }` or `{ error: }`



184
185
186
187
188
189
# File 'lib/browserctl/client.rb', line 184

def import_cookies(name, path)
  raise "cookie file not found: #{path}" unless File.exist?(path)

  cookies = JSON.parse(File.read(path), symbolize_names: true)
  call("import_cookies", name: name, cookies: cookies)
end

#inspect_page(name) ⇒ Hash

Returns the Chrome DevTools URL for a named page.

Parameters:

  • name (String)

    logical page name

Returns:

  • (Hash)

    ‘{ ok: true, devtools_url: }` or `{ error: }`



132
# File 'lib/browserctl/client.rb', line 132

def inspect_page(name)         = call("inspect", name: name)

#list_pagesHash

Lists all open page names.

Returns:

  • (Hash)

    ‘{ pages: [String] }`



37
# File 'lib/browserctl/client.rb', line 37

def list_pages                 = call("list_pages")

#open_page(name, url: nil) ⇒ Hash

Opens or focuses a named browser page.

Parameters:

  • name (String)

    logical page name

  • url (String, nil) (defaults to: nil)

    optional URL to navigate to after opening

Returns:

  • (Hash)

    ‘{ ok: true, name: }` or `{ error: }`



28
# File 'lib/browserctl/client.rb', line 28

def open_page(name, url: nil)  = call("open_page",  name: name, url: url)

#pause(name) ⇒ Hash

Pauses automation on a page so a human can interact directly.

Parameters:

  • name (String)

    logical page name

Returns:

  • (Hash)

    ‘{ ok: true, paused: true }` or `{ error: }`



122
# File 'lib/browserctl/client.rb', line 122

def pause(name)                = call("pause",   name: name)

#pingHash

Checks if browserd is alive.

Returns:

  • (Hash)

    ‘{ ok: true, pid: }` or raises if daemon is not running



113
# File 'lib/browserctl/client.rb', line 113

def ping                       = call("ping")

#resume(name) ⇒ Hash

Resumes automation on a paused page.

Parameters:

  • name (String)

    logical page name

Returns:

  • (Hash)

    ‘{ ok: true, paused: false }` or `{ error: }`



127
# File 'lib/browserctl/client.rb', line 127

def resume(name)               = call("resume",  name: name)

#screenshot(name, path: nil, full: false) ⇒ Hash

Takes a screenshot of a named page.

Parameters:

  • name (String)

    logical page name

  • path (String, nil) (defaults to: nil)

    output path (default: ~/.browserctl/screenshots/)

  • full (Boolean) (defaults to: false)

    capture full page (default: false)

Returns:

  • (Hash)

    ‘{ ok: true, path: }` or `{ error: }`



73
# File 'lib/browserctl/client.rb', line 73

def screenshot(name, path: nil, full: false) = call("screenshot", name: name, path: path, full: full)

Sets a cookie on a named page.

Parameters:

  • name (String)

    logical page name

  • cookie_name (String)

    cookie name (e.g. “cf_clearance”)

  • value (String)

    cookie value

  • domain (String)

    cookie domain (e.g. “.example.com”)

  • path (String) (defaults to: "/")

    cookie path (default: “/”)

Returns:

  • (Hash)

    ‘{ ok: true }` or `{ error: }`



157
158
159
160
# File 'lib/browserctl/client.rb', line 157

def set_cookie(name, cookie_name, value, domain, path: "/")
  call("set_cookie", name: name, cookie_name: cookie_name,
                     value: value, domain: domain, path: path)
end

#shutdownHash

Shuts down browserd gracefully.

Returns:

  • (Hash)

    ‘{ ok: true }`



117
# File 'lib/browserctl/client.rb', line 117

def shutdown                   = call("shutdown")

#snapshot(name, format: "elements", diff: false) ⇒ Hash

Takes a DOM snapshot. Returns ‘challenge: true` when Cloudflare is detected.

Parameters:

  • name (String)

    logical page name

  • format (String) (defaults to: "elements")

    “elements” (interactable elements JSON) or “html” (raw HTML)

  • diff (Boolean) (defaults to: false)

    return only elements changed since last snapshot

Returns:

  • (Hash)

    ‘{ ok: true, snapshot:, challenge: }` or `{ ok: true, html:, challenge: }` or `{ error: }`



80
81
82
# File 'lib/browserctl/client.rb', line 80

def snapshot(name, format: "elements", diff: false)
  call("snapshot", name: name, format: format, diff: diff)
end

#store(key, value) ⇒ Hash

Stores a value in the daemon-scoped key-value store.

Parameters:

  • key (String)

    storage key

  • value (Object)

    value to store (must be JSON-serialisable)

Returns:

  • (Hash)

    ‘{ ok: true }` or `{ error: }`



138
# File 'lib/browserctl/client.rb', line 138

def store(key, value) = call("store", key: key, value: value)

#url(name) ⇒ Hash

Returns the current URL of a named page.

Parameters:

  • name (String)

    logical page name

Returns:

  • (Hash)

    ‘{ ok: true, url: }` or `{ error: }`



103
# File 'lib/browserctl/client.rb', line 103

def url(name)                  = call("url",         name: name)

#wait_for(name, selector, timeout: 10) ⇒ Hash

Waits for a CSS selector to appear (short timeout).

Parameters:

  • name (String)

    logical page name

  • selector (String)

    CSS selector to wait for

  • timeout (Numeric) (defaults to: 10)

    seconds before giving up (default: 10)

Returns:

  • (Hash)

    ‘{ ok: true }` or `{ error: }`



89
# File 'lib/browserctl/client.rb', line 89

def wait_for(name, selector, timeout: 10) = call("wait_for", name: name, selector: selector, timeout: timeout)

#watch(name, selector, timeout: 30) ⇒ Hash

Polls for a CSS selector with a longer timeout (suitable for async operations).

Parameters:

  • name (String)

    logical page name

  • selector (String)

    CSS selector to poll for

  • timeout (Numeric) (defaults to: 30)

    seconds before giving up (default: 30)

Returns:

  • (Hash)

    ‘{ ok: true, selector: }` or `{ error: }`



96
97
98
# File 'lib/browserctl/client.rb', line 96

def watch(name, selector, timeout: 30)
  call("watch", name: name, selector: selector, timeout: timeout)
end