A browser tab/page — navigation, V8 evaluation, element ops, and callbacks.
Each page runs on a dedicated OS thread with its own current_thread tokio
runtime and V8 isolate. The synchronous-feeling API blocks the caller while
async operations run on the page thread; V8 evaluation is scheduled on dirty
CPU schedulers so it never blocks the BEAM.
Navigation and evaluation
:ok = Obscurax.Page.goto(page, "https://example.com")
{:ok, title} = Obscurax.Page.evaluate(page, "document.title")
{:ok, html} = Obscurax.Page.content(page)Element operations
Element operations take a node_id returned by query_selector/2 or
wait_for_selector/3:
{:ok, node_id} = Obscurax.Page.query_selector(page, "h1")
{:ok, text} = Obscurax.Page.element_text(page, node_id)
:ok = Obscurax.Page.element_click(page, node_id)Request observers
{:ok, _pid} = Obscurax.Page.on_request(page, fn req ->
IO.inspect(req.url)
end)Request interception
:ok = Obscurax.Page.enable_interception(page)
receive do
{:obscurax_intercept, ref, %{url: url}} ->
:ok = Obscurax.reply_intercept(page, ref, :continue)
end
Summary
Functions
Register a response observer. The callback receives a map with :url,
:method, :resource_type, and :status for each response.
Types
@type t() :: %Obscurax.Page{ref: reference()}
Functions
@spec add_preload_script(t(), String.t()) :: :ok | {:error, Obscurax.Error.t()}
@spec close(t()) :: :ok
@spec content(t()) :: {:ok, String.t()} | {:error, Obscurax.Error.t()}
@spec element_attribute(t(), non_neg_integer(), String.t()) :: {:ok, String.t() | nil} | {:error, Obscurax.Error.t()}
@spec element_click(t(), non_neg_integer()) :: :ok | {:error, Obscurax.Error.t()}
@spec element_text(t(), non_neg_integer()) :: {:ok, String.t()} | {:error, Obscurax.Error.t()}
@spec enable_interception(t()) :: :ok | {:error, Obscurax.Error.t()}
@spec evaluate(t(), String.t()) :: {:ok, term()} | {:error, Obscurax.Error.t()}
@spec goto(t(), String.t(), keyword()) :: :ok | {:error, Obscurax.Error.t()}
@spec on_request(t(), (map() -> term())) :: {:ok, pid()} | {:error, Obscurax.Error.t()}
@spec on_response(t(), (map() -> term())) :: {:ok, pid()} | {:error, Obscurax.Error.t()}
Register a response observer. The callback receives a map with :url,
:method, :resource_type, and :status for each response.
@spec query_selector(t(), String.t()) :: {:ok, non_neg_integer() | nil} | {:error, Obscurax.Error.t()}
@spec settle(t(), non_neg_integer()) :: :ok | {:error, Obscurax.Error.t()}
@spec url(t()) :: {:ok, String.t()} | {:error, Obscurax.Error.t()}
@spec wait_for_selector(t(), String.t(), non_neg_integer()) :: {:ok, non_neg_integer()} | {:error, Obscurax.Error.t()}
@spec wait_for_selector!(t(), String.t(), non_neg_integer()) :: non_neg_integer()