rubycdp/ferrum
66.1
Adequate · 19 September 2026
8.7k
lines of production code
Ruby
primary language
1
measurement over time
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.