Class: Ferrum::Browser

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/ferrum/browser.rb,
lib/ferrum/browser/xvfb.rb,
lib/ferrum/browser/binary.rb,
lib/ferrum/browser/command.rb,
lib/ferrum/browser/options.rb,
lib/ferrum/browser/process.rb,
lib/ferrum/browser/options/base.rb,
lib/ferrum/browser/version_info.rb,
lib/ferrum/browser/options/chrome.rb,
lib/ferrum/browser/options/firefox.rb

Overview

Note:

A Browser can host multiple Contexts (like incognito profiles) and multiple Pages within each of them, reachable through #contexts and #create_page.

The main entry point of the library. Instantiating it spawns (or connects to) a browser process and opens a CDP connection to it, exposing a single default Page that most of the top-level methods (go_to, at_css, screenshot, etc.) are delegated to for convenience.

Defined Under Namespace

Modules: Binary Classes: Command, Options, Process, VersionInfo, Xvfb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = nil) ⇒ Browser

Initializes the browser.

Parameters:

  • options (Hash{Symbol => Object}, nil) (defaults to: nil)

    Additional browser options.

Options Hash (options):

  • :headless (Boolean) — default: true

    Set browser as headless or not.

  • :incognito (Boolean) — default: true

    Create an incognito profile for the browser startup window.

  • :dockerize (Boolean) — default: false

    Add CLI flags to a browser to run in a container.

  • :xvfb (Boolean) — default: false

    Run browser in a virtual framebuffer.

  • :flatten (Boolean) — default: true

    Use one websocket connection to the browser and all the pages in flatten mode.

  • :window_size ((Integer, Integer)) — default: [1024, 768]

    The dimensions of the browser window in which to test, expressed as a 2-element array, e.g. [1024, 768].

  • :extensions (Array<String, Hash>)

    An array of paths to files or JS source code to be preloaded into the browser e.g.: ["/path/to/script.js", { source: "window.secret = 'top'" }]

  • :logger (#puts)

    When present, debug output is written to this object.

  • :slowmo (Integer, Float)

    Set a delay in seconds to wait before sending a command. Useful companion of a headless option, so that you have time to see changes.

  • :timeout (Numeric) — default: 5

    The number of seconds we'll wait for a response when communicating with the browser: navigations, JS evaluation, DOM queries, dispatching input, etc.

  • :protocol_timeout (Numeric) — default: 5

    The number of seconds we'll wait for an individual internal CDP bookkeeping call to respond, e.g. Target.createTarget, Target.attachToTarget. These normally resolve in milliseconds.

  • :js_errors (Boolean)

    When true, JavaScript errors get re-raised in Ruby.

  • :pending_connection_errors (Boolean) — default: true

    When main frame is still waiting for slow responses while timeout is reached PendingConnectionsError is raised. It's better to figure out why you have slow responses and fix or block them rather than turn this setting off.

  • :browser_name (:chrome, :firefox) — default: :chrome

    Sets the browser's name. Note: only experimental support for :firefox for now.

  • :browser_path (String)

    Path to Chrome binary, you can also set ENV variable as BROWSER_PATH=some/path/chrome bundle exec rspec.

  • :browser_options (Hash)

    Additional command line options, see them all e.g. { "ignore-certificate-errors" => nil }

  • :ignore_default_browser_options (Boolean)

    Ferrum has a number of default options it passes to the browser, if you set this to true then only options you put in :browser_options will be passed to the browser, except required ones of course.

  • :port (Integer)

    Remote debugging port for headless Chrome.

  • :host (String)

    Remote debugging address for headless Chrome.

  • :url (String)

    URL for a running instance of Chrome. If this is set, a browser process will not be spawned.

  • :process_timeout (Integer)

    How long to wait for the Chrome process to respond on startup.

  • :ws_max_receive_size (Integer)

    How big messages to accept from Chrome over the web socket, in bytes. Defaults to 64MB. Incoming messages larger this will cause a DeadBrowserError.

  • :proxy (Hash)

    Specify proxy settings, read more.

  • :save_path (String)

    Path to save attachments with Content-Disposition header.

  • :env (Hash)

    Environment variables you'd like to pass through to the process.



152
153
154
155
156
157
# File 'lib/ferrum/browser.rb', line 152

def initialize(options = nil)
  @options = Options.new(options)
  @client = @process = @contexts = nil

  start
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



45
46
47
# File 'lib/ferrum/browser.rb', line 45

def client
  @client
end

#contextsObject (readonly)

Returns the value of attribute contexts.



45
46
47
# File 'lib/ferrum/browser.rb', line 45

def contexts
  @contexts
end

#optionsObject (readonly)

Returns the value of attribute options.



45
46
47
# File 'lib/ferrum/browser.rb', line 45

def options
  @options
end

#processObject (readonly)

Returns the value of attribute process.



45
46
47
# File 'lib/ferrum/browser.rb', line 45

def process
  @process
end

Instance Method Details

#closeObject

Close browser gracefully.

You should clean up resources/connections in ruby world manually, it's only a CDP command.



263
264
265
# File 'lib/ferrum/browser.rb', line 263

def close
  command("Browser.close")
end

#crashObject

Crashes browser.



254
255
256
# File 'lib/ferrum/browser.rb', line 254

def crash
  command("Browser.crash")
end

#create_page(new_context: false, proxy: nil) ⇒ Ferrum::Page

Creates a new page.

Parameters:

  • new_context (Boolean) (defaults to: false)

    Whether to create a page in a new context or not.

  • proxy (Hash) (defaults to: nil)

    Whether to use proxy for a page. The page will be created in a new context if so.

Returns:



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/ferrum/browser.rb', line 171

def create_page(new_context: false, proxy: nil)
  page = if new_context || proxy
           params = {}

           if proxy
             options.validate_proxy(proxy)
             params.merge!(proxyServer: "#{proxy[:host]}:#{proxy[:port]}")
             params.merge!(proxyBypassList: proxy[:bypass]) if proxy[:bypass]
           end

           context = contexts.create(**params)
           context.create_page(proxy: proxy)
         else
           default_context.create_page
         end

  block_given? ? yield(page) : page
ensure
  if block_given?
    page&.close
    context&.dispose if new_context
  end
end

#debug(bind = nil) ⇒ void

This method returns an undefined value.

Opens headless session in the browser devtools frontend.

Since:

  • 0.16



285
286
287
288
289
290
291
292
293
294
# File 'lib/ferrum/browser.rb', line 285

def debug(bind = nil)
  ::Process.spawn(process.path, debug_url)

  bind ||= binding
  if bind.respond_to?(:pry)
    Pry.start(bind)
  else
    bind.irb
  end
end

#evaluate_on_new_document(expression) ⇒ Object

Evaluate JavaScript to modify things before a page load.

Examples:

browser.evaluate_on_new_document <<~JS
  Object.defineProperty(navigator, "languages", {
    get: function() { return ["tlh"]; }
  });
JS

Parameters:

  • expression (String)

    The JavaScript to add to each new document.



208
209
210
# File 'lib/ferrum/browser.rb', line 208

def evaluate_on_new_document(expression)
  extensions << expression
end

#quitObject

Terminates the browser process and closes the client connection.



241
242
243
244
245
246
247
248
249
# File 'lib/ferrum/browser.rb', line 241

def quit
  return unless @client

  contexts.close_connections

  @client.close
  @process.stop
  @client = @process = @contexts = nil
end

#resetObject

Closes browser tabs opened by the Browser instance.

Examples:

# connect to a long-running Chrome process
browser = Ferrum::Browser.new(url: 'http://localhost:9222')

browser.go_to("https://github.com/")

# clean up, lest the tab stays there hanging forever
browser.reset

browser.quit


226
227
228
# File 'lib/ferrum/browser.rb', line 226

def reset
  contexts.reset
end

#restartObject

Restarts the browser process, keeping the same options.



233
234
235
236
# File 'lib/ferrum/browser.rb', line 233

def restart
  quit
  start
end

#versionVersionInfo

Gets the version information from the browser.

Returns:

Since:

  • 0.13



274
275
276
# File 'lib/ferrum/browser.rb', line 274

def version
  VersionInfo.new(command("Browser.getVersion"))
end