All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
0.2.2 - 2026-06-02
Added
- Documented
:launch_timeoutas a ceiling (not a fixed wait) onCDPEx.launch/1andCDPEx.with_page/3, plus a "Running in containers" README section (timeout tuning, the fresh-profile cold-start cost,/dev/shmsizing,--remote-allow-origins).
Changed
- Chrome readiness is now polled:
CDPEx.Chromechecks theDevToolsActivePortfile throughout the wait (not only at the deadline), so launch returns as soon as Chrome is reachable and:launch_timeoutacts as a ceiling rather than a fixed cost — robust to Chrome builds that don't print theDevTools listening on ws://…stderr line. - A launch that never exposes the DevTools endpoint now returns
{:error, {:debug_url_not_found, stderr_excerpt}}(was the bare atom:debug_url_not_found), carrying Chrome's captured stderr so the failure is self-diagnosing. Migration: code matching the bare:debug_url_not_foundatom (e.g. a retry classifier) must match{:debug_url_not_found, _}instead, or that error silently stops matching. CDPEx.with_page/3, given launch options, now contains a throwaway-browser crash: it returns{:error, reason}instead of letting the browser's linked exit propagate to and kill the caller. It briefly traps exits in the calling process for the duration of the call (see thewith_page/3docs for the foreign-EXIT caveat and escape hatch).
Fixed
CDPEx.Connectionno longer ignores an owning-process exit that arrives during the WebSocket upgrade — it aborts the connect at once instead of lingering until the upgrade timeout.CDPEx.Connectionnow stops when a WebSocket pong write fails (mirroring a failed command write), rather than continuing on a dead socket until the next command notices.CDPEx.Page.navigate/3prefers a just-arrived connection:DOWNover a best-effort readiness timeout when the two tie at the deadline, so a connection death surfaces as an error rather than a stale{:ok, page}.CDPEx.Browserno longer leaks Chrome if the browser connection drops in the window between connecting and its first subscribe — the init-time exit is caught and Chrome is reaped.CDPEx.Chromelaunch-failure cleanup waits for the OS process to exit before removing the temp profile (matchingstop/1), closing akill/rmrace.CDPEx.Connection.call/5andawait_event/4return the documented timeout tuple instead of crashing the caller if the outerGenServer.calldeadline fires first under scheduler starvation.CDPEx.Connectionaccumulates WebSocket upgrade headers across response chunks instead of replacing them (defensive; dormant for single-response101upgrades).
0.2.1 - 2026-06-02
Changed
CDPEx.Browsersetsshutdown: 10_000inchild_spec/1so a supervisor givesterminate/2enough time to reap Chrome.
Fixed
CDPEx.Protocol.parse_ws_url/1parses IPv6 hosts and raises a clearArgumentErroron a malformed URL (previously aMatchError).CDPEx.Connectionno longer crashes whencall/5/await_event/4is given a negative timeout (it fires immediately).CDPEx.Connectionteardown fails in-flight callers with{:error, {:ws_closed, _}}instead of{:error, :noproc}onclose/1.CDPEx.Page.navigate/3subscribes to lifecycle events before issuing the navigate, so a fast readiness event (e.g.loadon a cached/local page) can no longer be dropped — a register-after-navigate race.
0.2.0 - 2026-06-02
Added
- Opt-in
sessionIdmultiplexing:CDPEx.new_page(browser, transport: :session)drives many pages over the one browser WebSocket (default:dedicated= one socket per page).CDPEx.Connection.call/5andawait_event/4gain a:session_idoption. CDPEx.Page.wait_for_navigation/2— await a navigation lifecycle milestone without issuing a navigation (e.g. after a click that navigates).CDPEx.Page.wait_for_function/3— poll a JavaScript expression until it is truthy.CDPEx.Page.text/3,attribute/4,visible?/3— element text / attribute / visibility helpers.CDPEx.Page.cookies/2,set_cookies/3,clear_cookies/2— cookie get / set / clear (lazily enables theNetworkdomain).CDPEx.Page.set_extra_headers/3,set_user_agent/3— extra HTTP headers and User-Agent override.CDPEx.Page.set_viewport/4— viewport / device-metrics emulation.CDPEx.Page.pdf/2— render the page to PDF (Page.printToPDF); returns bytes or writes to:path.CDPEx.Page.call_function/4— call a JS function with JSON-serialized arguments.
Changed
- A clean browser-connection close (its socket dropping, e.g. Chrome exiting) now stops
CDPEx.Browserwith a:shutdownreason rather than a crash reason — no spurious error report on expected teardown. Abnormal connection failures still surface loudly.
Fixed
CDPEx.Connection.call/5andawait_event/4no longer crash the connection when given an:infinitytimeout (which is valid per thetimeout()spec).CDPEx.Connectionnow stops when its owning process exits, closing the socket even if the owner skipped its own teardown (e.g. a:brutal_kill).
0.1.0 - 2026-06-01
Added
- Initial OTP-native Chrome DevTools Protocol client.
CDPEx.launch/1andCDPEx.stop/1— supervised headless Chrome lifecycle.CDPEx.new_page/2,CDPEx.close_page/2,CDPEx.with_page/3.CDPEx.Page:navigate/3,wait_for_selector/3,evaluate/3,click/3,html/2,screenshot/2.