Skip to content
CAI
Software that uses CAICheck a score

rubycdp/ferrum

66.1

Adequate · 19 September 2026

8.7k

lines of production code

Ruby

primary language

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

Ferrum is a Ruby library that automates headless Chrome and Chromium browsers via the Chrome DevTools Protocol. It provides a structured API for managing browser contexts, pages, and frames, while supporting advanced capabilities such as network request interception, accessibility tree inspection, and JavaScript evaluation. The system ensures robust process lifecycle management and thread-safe concurrency to handle complex web automation tasks reliably.

How it got here

2019 — Architectural refactor and context support

15 changes.

This period focused on a major architectural refactor of the Ferrum gem, introducing a multi-context architecture with isolated browser profiles and a unified CDP client. The library expanded its capabilities to include comprehensive network interception, accessibility APIs, and refined process management, while simultaneously raising the minimum Ruby version to 3.1. Extensive test coverage was added to validate these new core features and ensure thread safety.

2020–2023 — Infrastructure hardening and test expansion

7 changes.

This period focused on stabilizing the core browser interaction layer by refactoring Chrome CLI options for improved security and cross-platform compatibility, alongside introducing robust utility modules for retries and thread safety. Significant effort was dedicated to expanding test coverage across critical components such as network requests, page interactions, and JavaScript execution to ensure reliability. Additionally, developer experience was enhanced through the introduction of VS Code dev container support for consistent local environments.

2024–2026 — Stability and type safety improvements

5 changes.

This period focused on hardening the library's core infrastructure by stabilizing WebSocket event dispatching and implementing robust browser process termination with safe cleanup logic. Concurrently, the project expanded its reliability through comprehensive test coverage for browser options and process finalization, while introducing RBS type signatures to enhance static analysis and IDE support.

Features

Add RBS type signatures for the sig directory

This change introduces RBS type signature files for the \sig\ directory, covering the Ferrum browser automation library (e.g., \Browser\, \Page\, \Client\, \Network\, \Accessibility\) and concurrent primitives (\Concurrent::IVar\, \Concurrent::Event\). These signatures define the public API shapes, enabling static type checking and improved IDE support for users of the library.

sig · high confidence

Added VS Code dev container configuration for Ruby development

Developers can now use VS Code Dev Containers to run the application in a consistent, isolated environment. The new configuration includes a Dockerfile and base image setup for Ruby (defaulting to version 3 on Bullseye) with optional Node.js support, pre-installed system dependencies for Chrome, and the rebornix.Ruby extension. This allows for immediate local development without manual environment setup.

.devcontainer · high confidence

Added binstubs and browser helper in console script

Bundler-generated binstubs for rake and rspec have been added to the bin directory to facilitate running these tools. Additionally, the console script now includes a helper method to launch a Ferrum browser instance, allowing users to easily interact with a headless browser during development sessions.

bin · high confidence

Initial project scaffolding and documentation overhaul

This change establishes the foundational configuration for the Ferrum gem, introducing \.editorconfig\, \.rubocop.yml\ (targeting Ruby 3.1), \.rspec\, \.yardopts\, and a new \logo.svg\ with dark-mode support. It replaces the legacy \.ruby-version\ file with an RBS type collection (\rbs\_collection.yaml\/\lock.yaml\) and significantly rewrites \README.md\ to reflect the current high-level CDP API (e.g., \go\_to\ instead of \goto\, \create\_page\ usage) while moving documentation to a dedicated website. The \Rakefile\ is updated to include YARD documentation tasks and CI-specific RSpec formatting.

(repo-wide) · high confidence

Introduces browser contexts, accessibility API, and dedicated input classes

Ferrum now supports browser contexts (isolated profiles similar to incognito windows) via new Context and Contexts classes, allowing creation, disposal, and management of separate cookie and storage scopes. A new Accessibility API (Ferrum::Accessibility and Ferrum::Accessibility::AXNode) exposes the Chrome DevTools Protocol's Accessibility domain for querying the accessibility tree. Input simulation is refactored into dedicated Keyboard and Mouse classes, and the library adds support for JavaScript dialogs, file downloads, and frame-level navigation.

lib/ferrum · high confidence

New DOM and Runtime modules for frame interaction

This change introduces two new modules, \Ferrum::Frame::DOM\ and \Ferrum::Frame::Runtime\, which provide the underlying mechanisms for interacting with a frame's content. The \DOM\ module adds methods to retrieve the current URL, title, doctype, and HTML body, as well as finding elements via CSS and XPath selectors and injecting script or style tags. The \Runtime\ module handles JavaScript evaluation, introducing \evaluate\_async\ for asynchronous expressions, \execute\ for side-effect-only scripts, and robust handling of cyclic JavaScript objects via a \CyclicObject\ placeholder to prevent hangs or errors during serialization.

lib/ferrum/frame · high confidence

New utility modules for retries, timing, platform detection, and thread safety

Ferrum introduces four new utility modules in the \lib/ferrum/utils\ directory to support internal operations. \Ferrum::Utils::Attempt\ provides a retry-with-backoff helper for re-running blocks on specific exceptions. \Ferrum::Utils::ElapsedTime\ offers a monotonic-clock helper for tracking elapsed time and checking timeouts, including a new \reset\ method. \Ferrum::Utils::Platform\ adds OS and Ruby engine detection helpers, specifically supporting macOS on Apple Silicon (arm64). Finally, \Ferrum::Utils::Thread\ provides a thread-spawning helper with configurable exception handling behavior to prevent Ferrum's internal threads from taking down the host process.

lib/ferrum/utils · high confidence

Behavioural changes

Major architectural refactor: new context/page model and unified CDP client

Ferrum has been refactored to support a multi-context architecture, allowing users to create and manage multiple browser contexts (such as incognito profiles) and multiple pages within each context via the new \Browser\#contexts\ and \Browser\#create\_page\ APIs. The internal communication layer has been unified into a single \Client\ and \SessionClient\ structure that manages the WebSocket connection and scopes commands/events to specific sessions, replacing the previous fragmented client setup. Additionally, cookie handling has been extracted into a dedicated \Ferrum::Cookies::Cookie\ class with explicit attribute accessors, and the error handling system has been expanded with specific error types like \NoSuchPageError\, \PendingConnectionsError\, and \TimeoutError\ to provide clearer diagnostics.

ferrum · high confidence

Major page API restructuring with new capabilities

The page module has been refactored into distinct components, introducing new capabilities for CSS animation playback control, live page screencasting, and performance tracing, while also adding support for WebP screenshots, MHTML snapshots, and streaming PDF generation to improve memory efficiency. This change replaces the previous monolithic page implementation with specialized modules for frames, screenshots, and input, and removes the legacy DOM, Frame, Input, Net, and Runtime modules.

lib/ferrum/page · high confidence

Refactored Chrome default CLI flags and added platform-specific binary detection

The library now uses a structured \Options::Chrome\ class to manage Chrome-specific command-line arguments, replacing the previous ad-hoc flag assembly. This change introduces a hardened set of default flags (e.g., disabling background networking, extensions, and specific Blink features) to improve stability and security in automated environments. It also adds automatic detection of Chrome/Chromium binaries on macOS, Linux, and Windows, and applies platform-specific optimizations such as using the Metal renderer on Apple Silicon and disabling GPU acceleration on Windows. Users benefit from more reliable headless execution and better out-of-the-box compatibility across different operating systems.

lib/ferrum/browser/options · high confidence

Refactored browser launch and process management

The browser launch logic has been restructured to improve reliability and configuration handling. A new \Binary\ module replaces the previous \Cliver\ dependency to locate browser executables on the system PATH. Browser command-line arguments are now constructed by a dedicated \Command\ class that merges default flags with user options, and an \Options\ class centralizes configuration resolution. The \Process\ class has been updated to use these new components, supporting explicit \ws\_url\ connections and improved process lifecycle management, including better cleanup of temporary user data directories.

lib/ferrum/browser · high confidence

Removes global thread exception handling and adds concurrency utilities

The library no longer globally sets \Thread.abort\_on\_exception\ and \Thread.report\_on\_exception\, preventing Ferrum from altering the global Ruby thread behavior which could affect other parts of an application. Instead, it introduces a \concurrent-ruby\ dependency and new utility modules (\ferrum/utils/thread\, \ferrum/utils/event\, etc.) to manage concurrency and error reporting more locally and safely within the library itself.

lib · high confidence

Rewritten network request and response handling with interception support

The network layer has been refactored to provide a more robust and feature-rich API for inspecting and controlling HTTP traffic. A new \Exchange\ class now pairs requests with their responses, errors, and interception status, exposing methods like \navigation\_request?\, \blocked?\, \redirect?\, and \ping?\ to help users understand the lifecycle of each request. Request interception is now fully supported via the \InterceptedRequest\ class, allowing users to fulfill requests with fake responses, continue them with overrides, or abort them before they reach the network. Authentication challenges are handled through a dedicated \AuthRequest\ class, enabling users to provide credentials or cancel auth prompts. The \Request\ and \Response\ classes have been expanded with additional attributes such as \type\, \frame\_id\, \loader\_id\, \content\_type\, and \to\_h\, while the \Response\#body\ method now safely returns \nil\ instead of raising an error if the body is unavailable.

lib/ferrum/network · high confidence

Fixes

Robust browser process termination and user data cleanup

A new \Killer\ module handles OS-level process termination and user-data-directory removal, ensuring the browser process is killed before its data directory is deleted to prevent file locks from blocking cleanup. The implementation escalates from TERM to KILL signals if the process does not exit within a timeout, handles process groups to avoid orphaning child processes, and uses bounded polling instead of blocking waits to prevent deadlocks during garbage collection finalization. Directory removal is retried with exponential backoff to handle transient file locks, and the logic is structured as free functions to avoid reference cycles that would prevent the finalizer from running.

lib/ferrum/browser/process · high confidence

Stabilize WebSocket JSON parsing and event dispatch against crashes

The client now prevents malformed or deeply nested JSON responses from crashing the background reader thread, ensuring the browser connection remains alive even when the server sends invalid payloads. Additionally, event callbacks that raise exceptions no longer terminate the dispatch threads, allowing other events to continue processing and preventing cascading failures like lost target registrations.

lib/ferrum/client · high confidence

Test coverage

Added comprehensive test coverage for network request and response objects; Added comprehensive test suite for Ferrum's core capabilities; Added test coverage for Ferrum::Cookies::Cookie; Added test coverage for page animation, screencast, screenshot, stream, and tracing features; Added test support infrastructure and updated test server configuration; Added tests for Chrome browser options and version detection; Added tests for Frame Runtime JavaScript execution and evaluation; Added tests for browser binary resolution, protocol timeout options, and version info parsing; Added tests for browser process cleanup and finalization logic; Added unit tests for thread safety, timeout handling, and process management; Updated test fixtures for accessibility, animations, and iframe scenarios.

Dependencies

Update runtime dependencies and raise minimum Ruby version

The gem now requires Ruby 3.1 or higher, dropping support for older versions. Runtime dependencies have been updated to include base64 (\~\> 0.2) and concurrent-ruby (\~\> 1.1), while addressable has been relaxed to \~\> 2.5. Development dependencies such as rubocop, sinatra, and puma have been moved to the Gemfile with updated version constraints, and the project homepage and metadata have been updated to reflect the rubycdp organization.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 66.

Lenses

  • Code Health 96
  • Architecture 100
  • Maturity 57
  • Readiness 55
  • Security 94

Changes since last survey

  • 300 commits — 207 feature/other, 93 fixes

By area

  • lib/ferrum — 153 commits
  • (root) — 95 commits
  • (repo) — 13 commits
  • spec/support — 8 commits
  • .github/workflows — 5 commits
  • spec/browser_spec.rb — 3 commits
  • spec/network — 2 commits
  • spec/network_spec.rb — 2 commits
  • spec/page — 2 commits
  • spec/page_spec.rb — 2 commits
  • spec/spec_helper.rb — 2 commits
  • .github/FUNDING.yml — 1 commit
  • .github/ISSUE_TEMPLATE — 1 commit
  • bin/console — 1 commit
  • docs/1-introduction.md — 1 commit
  • docs/15-frames.md — 1 commit
  • sig/ferrum — 1 commit
  • spec/browser — 1 commit
  • spec/cookies — 1 commit
  • spec/cookies_spec.rb — 1 commit

Notable commits

  • fix: Add dockerize option, make pending_connection_errors false by default, fix build (#561)
  • fix: Fix Browser#create_page masking original error when context creation fails (#582)
  • fix: Fix Ferrum::Network::Response#loaded? for redirect response (#338)
  • fix: Fix Target.targetCreated handler for existing targets (#539)
  • fix: Fix build
  • fix: Fix build
  • fix: Fix down and up methods (#288)
  • fix: Fix for nextwork_spec.rb:512 "#offline_mode" (#536)
  • fix: Fix intercepted request string matching (#604)
  • fix: Fix rubocop
  • fix: Fix rubocop
  • fix: Fix rubocop warns
  • fix: Fix select/selected to work properly within frame scope
  • fix: Fix specs for Ruby 3.0
  • fix: Fix truncated Chrome WS URL that results in Ferrum::DeadBrowserError (#327)
  • fix: Fix wss urls and session_id lost (#559)
  • fix: Fix: Do not expect response for initiatorType Ping requests (#417)
  • fix: Fix: Safe call body method (DOM) when page is empty (#522)
  • fix: Fixed a broken JSON in log output (#464)
  • fix: Merge pull request #239 from rubycdp/bugfix/issue#238-methods-select-and-selected-raises-an-exception-when-fires-within-frame-scope
  • …and 280 more

Architecture

  • 0 containers · 1 bounded contexts · 0 dependency edges (baseline)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

rubycdp/ferrum was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit ea9330859aa08b6217d75abc8a917b2c98d1a627 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.