Manages a browser session lifecycle.
A session owns:
- A transport connection
- A browser instance
- Multiple browser contexts
- Pages within those contexts
Example
{:ok, session} = Session.start_link(mode: :local, headless: true)
{:ok, page} = Session.new_page(session)
:ok = Session.goto(session, page, "https://example.com")
{:ok, html} = Session.content(session, page)
:ok = Session.close(session)
Summary
Functions
Add cookies to a context (guid from new_context/2). Each cookie is a map
using Playwright's field names (name, value, and either url or
domain+path; optionally httpOnly, secure, sameSite, expires).
Add an init script to a context (identified by the guid returned from
new_context/2). The script runs before any page scripts on every page and
navigation in that context, so it must be added before the page is created.
Send a CDP command over a session opened with new_cdp_session/2.
Returns a specification to start this module under a supervisor.
Click an element.
Close the entire session.
Close a page.
Get page HTML content.
Evaluate a JavaScript expression in a page's main frame and return the result.
Expose an Elixir callback to the page as a binding (experimental,
:windows-only). The page can call window.<name>(...args) and the callback
is invoked with the argument list; its return value is passed back to the page.
Fill an input field.
Navigate to a URL.
Open a Chrome DevTools Protocol session for a page. Returns an opaque CDP
session id to use with cdp_send/4.
Create a new browser context.
Create a new page in the default context.
Take a screenshot.
Start a new browser session.
Return a context's storage state (cookies + localStorage). Capture it after a
UI login and re-seed it with add_cookies/3 in later runs.
Wait until a JavaScript predicate becomes truthy in a page's main frame.
Types
Functions
@spec add_cookies(GenServer.server(), String.t(), [map()]) :: :ok | {:error, term()}
Add cookies to a context (guid from new_context/2). Each cookie is a map
using Playwright's field names (name, value, and either url or
domain+path; optionally httpOnly, secure, sameSite, expires).
This is the fast way past an auth gate: seed a pre-signed session cookie instead of driving the login UI.
Examples
{:ok, ctx} = Session.new_context(session, [])
:ok = Session.add_cookies(session, ctx, [
%{name: "_listener_web_key", value: signed, domain: "localhost", path: "/", sameSite: "Lax"}
])
{:ok, page} = Session.new_page(session, context_guid: ctx) # starts past the gate
@spec add_init_script(GenServer.server(), String.t(), String.t(), keyword()) :: :ok | {:error, term()}
Add an init script to a context (identified by the guid returned from
new_context/2). The script runs before any page scripts on every page and
navigation in that context, so it must be added before the page is created.
Examples
{:ok, ctx} = Session.new_context(session, [])
:ok = Session.add_init_script(session, ctx, "window.__debug = 1")
{:ok, page} = Session.new_page(session, context_guid: ctx)
@spec cdp_send(GenServer.server(), String.t(), String.t(), map()) :: {:ok, term()} | {:error, term()}
Send a CDP command over a session opened with new_cdp_session/2.
Examples
{:ok, cdp} = Session.new_cdp_session(session, page)
{:ok, _} = Session.cdp_send(session, cdp, "Network.emulateNetworkConditions", %{
offline: false, latency: 200, downloadThroughput: 100_000, uploadThroughput: 100_000
})
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec click(GenServer.server(), String.t(), String.t(), keyword()) :: :ok | {:error, term()}
Click an element.
Options
:timeout- Click timeout in ms (default: 30000)
@spec close(GenServer.server()) :: :ok
Close the entire session.
@spec close_page(GenServer.server(), String.t()) :: :ok | {:error, term()}
Close a page.
@spec content(GenServer.server(), String.t()) :: {:ok, String.t()} | {:error, term()}
Get page HTML content.
@spec evaluate(GenServer.server(), String.t(), String.t(), keyword()) :: {:ok, term()} | {:error, term()}
Evaluate a JavaScript expression in a page's main frame and return the result.
Options
:is_function- treat the expression as a function body (default: false):arg- argument passed to the function:timeout- evaluation timeout in ms (default: 30000)
Examples
{:ok, true} = Session.evaluate(session, page, "crossOriginIsolated")
{:ok, 3} = Session.evaluate(session, page, "(a) => a + 1", arg: 2, is_function: true)
@spec expose_binding(GenServer.server(), String.t(), String.t(), (list() -> term())) :: :ok | {:error, term()}
Expose an Elixir callback to the page as a binding (experimental,
:windows-only). The page can call window.<name>(...args) and the callback
is invoked with the argument list; its return value is passed back to the page.
Register the binding on a context (guid from new_context/2) before creating
the page. :local/:remote return {:error, :not_supported}.
@spec fill(GenServer.server(), String.t(), String.t(), String.t(), keyword()) :: :ok | {:error, term()}
Fill an input field.
Options
:timeout- Fill timeout in ms (default: 30000)
@spec goto(GenServer.server(), String.t(), String.t(), keyword()) :: :ok | {:error, term()}
Navigate to a URL.
Options
:timeout- Navigation timeout in ms (default: 30000):wait_until- When to consider navigation complete (:load, :domcontentloaded, :networkidle)
@spec new_cdp_session(GenServer.server(), String.t()) :: {:ok, String.t()} | {:error, term()}
Open a Chrome DevTools Protocol session for a page. Returns an opaque CDP
session id to use with cdp_send/4.
Only supported by the :windows transport; :local returns
{:error, :not_supported}.
@spec new_context( GenServer.server(), keyword() ) :: {:ok, String.t()} | {:error, term()}
Create a new browser context.
Options
:viewport- Viewport dimensions%{width: 1920, height: 1080}:user_agent- Custom user agent string:locale- User locale (e.g., "en-US"):color_scheme- Color scheme preference (:light, :dark)
@spec new_page( GenServer.server(), keyword() ) :: {:ok, String.t()} | {:error, term()}
Create a new page in the default context.
Returns a page_id that can be used with other Session functions.
@spec screenshot(GenServer.server(), String.t(), keyword()) :: {:ok, binary()} | {:error, term()}
Take a screenshot.
Options
:full_page- Capture full scrollable page (default: false):omit_background- Omit background for transparent screenshots (default: false)
Start a new browser session.
Options
:mode-:local,:remote, or:auto(default::auto):ws_endpoint- WebSocket URL for remote mode:headless- Run browser in headless mode (default: true):browser_type-:chromium,:firefox, or:webkit(default::chromium):name- Optional name for the GenServer
@spec storage_state(GenServer.server(), String.t()) :: {:ok, map()} | {:error, term()}
Return a context's storage state (cookies + localStorage). Capture it after a
UI login and re-seed it with add_cookies/3 in later runs.
@spec wait_for_function(GenServer.server(), String.t(), String.t(), keyword()) :: :ok | {:error, term()}
Wait until a JavaScript predicate becomes truthy in a page's main frame.
Options
:is_function- treat the expression as a function body (default: false):arg- argument passed to the function:polling- a number of ms, or"raf"(default:"raf"):timeout- timeout in ms (default: 30000)
Examples
:ok = Session.wait_for_function(session, page, "window.__ready === true", timeout: 60_000)