Ferrum Documentation

repository·main·Indexed 24 days ago

https://github.com/rubycdp/ferrum

A high-level, pure Ruby API for controlling Chrome or Chromium via the Chrome DevTools Protocol (CDP). Ferrum serves as a lightweight, fast, and thread-safe alternative to Selenium/WebDriver, operating without a dependency on WebDriver or ChromeDriver. It provides comprehensive tools for browser automation, including page and context management, mouse and keyboard simulation, JavaScript evaluation, and management of cookies and HTTP headers.

Tokens
17.6K
Snippets
63
Records
116
Agent score
84%

What's inside Ferrum

  1. Use Browser Contexts for Thread Safety

    main

    Ferrum is fully thread-safe. To manage multiple independent sessions within a single browser instance, use browser.contexts.create.

    A Context acts like an incognito profile. You can create multiple pages within one context to share session data, or create multiple contexts to ensure complete isolation between threads. Always remember to call context.dispose to clean up the context resources.

    browser = Ferrum::Browser.new
    context = browser.contexts.create
    
    t1 = Thread.new(context) do |c|
      page = c.create_page
      page.go_to("https://www.google.com/search?q=Ruby+headless+driver+for+Capybara")
      page.screenshot(path: "t1.png")
    end
    
    t2 = Thread.new(context) do |c|
      page = c.create_page
      page.go_to("https://www.google.com/search?q=Ruby+static+typing")
      page.screenshot(path: "t2.png")
    end
    
    t1.join
    t2.join
    
    context.dispose
    browser.quit
  2. How frames work in Ferrum

    main
    Frames allow you to interact with iframes and nested documents within a page. Each frame operates in its own execution context, meaning JavaScript evaluates within the context of the specific frame. You can navigate the frame tree starting from the main_frame (the top-level parent) or by retrieving all frames via frames.
  3. How Ferrum and Chrome interact

    main
    Ferrum is a high-level Ruby API that communicates with Chrome or Chromium via the CDP (Chrome DevTools Protocol). Unlike Selenium, it has no dependency on WebDriver or ChromeDriver. This direct connection allows Ferrum to access advanced Chrome features that are often unavailable or limited in WebDriver-based tools. By default, Ferrum runs in headless mode, but this can be configured to headful mode.
  4. Handle browser dialogs with page.on(:dialog)

    main

    To interact with browser dialogs (like alerts, confirms, or prompts), register an event listener on the page object using page.on(:dialog). The listener receives a dialog object, which you can inspect and act upon.

    Common workflow:

    1. Use dialog.match?(regex) to check the dialog's text.
    2. Use dialog.accept(text) to accept the dialog. If it is a prompt, pass the desired response string as the text argument. If it is a standard alert, call accept without arguments.
    3. Use dialog.dismiss to close the dialog without interacting with it.
    page.on(:dialog) do |dialog|
      if dialog.match?(/bla-bla/)
        dialog.accept
      else
        dialog.dismiss
      end
    end
    page.go_to("https://google.com")
  5. Configure Ferrum for Docker

    main

    When running Ferrum inside a Docker container as the root user, you must enable the dockerize: true option to pass the necessary CLI flags to the browser.

    For CI environments, you can set the FERRUM_CHROME_DOCKERIZE=true environment variable to automatically apply this setting to all browser instances.

    Ferrum::Browser.new(dockerize: true)
  6. Use the Ferrum interactive CLI console

    main

    The bin/console script provides an interactive IRB (Interactive Ruby) session pre-loaded with the ferrum library. This allows you to manipulate a Chrome browser instance manually through a Ruby REPL.

    To start a session, run the script from your terminal. Once inside the IRB session, you can use the helper method browser to initialize a Ferrum::Browser instance. By default, browser starts in headless: true mode, but you can pass options to change this.

  7. Set custom timeout and slowmo for debugging

    main

    When debugging, you can increase the communication timeout and use slowmo to add a delay (in seconds) before every command, making it easier to follow the browser's actions.

    # Set custom timeout and slowmo for debugging
    Ferrum::Browser.new(timeout: 10, slowmo: 0.5)
  8. Run in headful mode with custom window size

    main

    To see the browser actions visually, set headless: false. You can also specify the window dimensions using the window_size array.

    # Run in headful mode with custom window size
    Ferrum::Browser.new(headless: false, window_size: [1920, 1080])
  9. Type text and use keyboard shortcuts

    main

    To interact with web forms or use shortcuts, focus the target element and use page.keyboard.

    Type text into an input

    page.go_to("https://google.com")
    input = page.at_css("input[name='q']")
    input.focus
    page.keyboard.type("Hello World")

    Press Enter

    page.keyboard.type(:Enter)

    Use keyboard shortcuts (e.g., Shift + text)

    page.keyboard.down(:Shift)
    page.keyboard.type("h", "e", "l", "l", "o")
    page.keyboard.up(:Shift)
    # Type text into an input
    page.go_to("https://google.com")
    input = page.at_css("input[name='q']")
    input.focus
    page.keyboard.type("Hello World")
    
    # Press Enter
    page.keyboard.type(:Enter)
    
    # Use keyboard shortcuts
    page.keyboard.down(:Shift)
    page.keyboard.type("h", "e", "l", "l", "o")
    page.keyboard.up(:Shift)
  10. Use a custom Chrome binary

    main

    If Chrome is not in your default path, specify the location using browser_path. Alternatively, you can set the BROWSER_PATH environment variable.

    # Use custom Chrome binary
    Ferrum::Browser.new(browser_path: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome")
  11. Control the mouse with `page.mouse`

    main

    Ferrum provides a mouse API to simulate user interactions like moving the cursor, clicking, and dragging. Methods are chainable.

    # Trace a 100x100 square
    browser = Ferrum::Browser.new
    page = browser.create_page
    page.go_to("https://google.com")
    browser.mouse
      .move(x: 0, y: 0)
      .down
      .move(x: 0, y: 100)
      .move(x: 100, y: 100)
      .move(x: 100, y: 0)
      .move(x: 0, y: 0)
      .up
    
    browser.quit