Complete documentation for the Playwriter public API.
Main Module: Playwriter
with_browser/2
Execute a function with a managed browser session.
@spec with_browser(keyword(), (context() -> result)) :: {:ok, result} | {:error, term()}Parameters:
opts- Keyword list of optionsfun- Function that receives the browser context
Options:
:mode-:local(default) or:remote:browser_type-:chromium(default),:firefox, or:webkit:headless-true(default) orfalse:ws_endpoint- WebSocket URL for remote mode:timeout- Operation timeout in milliseconds (default: 30000)
Returns:
{:ok, result}- The return value of the function{:error, reason}- If an error occurred
Example:
{:ok, titles} = Playwriter.with_browser([headless: false], fn ctx ->
:ok = Playwriter.goto(ctx, "https://news.ycombinator.com")
{:ok, html} = Playwriter.content(ctx)
html
|> Floki.parse_document!()
|> Floki.find(".titleline > a")
|> Enum.map(&Floki.text/1)
end)fetch_html/2
Fetch HTML content from a URL.
@spec fetch_html(String.t(), keyword()) :: {:ok, String.t()} | {:error, term()}Parameters:
url- The URL to fetchopts- Options (same aswith_browser/2)
Example:
{:ok, html} = Playwriter.fetch_html("https://example.com")
{:ok, html} = Playwriter.fetch_html("https://example.com", headless: false)screenshot/2
Take a screenshot of a URL.
@spec screenshot(String.t(), keyword()) :: {:ok, binary()} | {:error, term()}Parameters:
url- The URL to screenshotopts- Options including::full_page- Capture full scrollable page (default: false):type-:png(default) or:jpeg:quality- JPEG quality 0-100 (only for:jpeg)- All
with_browser/2options
Example:
{:ok, png_data} = Playwriter.screenshot("https://example.com")
File.write!("screenshot.png", png_data)
# Full page screenshot
{:ok, full} = Playwriter.screenshot("https://example.com", full_page: true)goto/3
Navigate to a URL within a browser session.
@spec goto(context(), String.t(), keyword()) :: :ok | {:error, term()}Parameters:
ctx- Browser context fromwith_browser/2url- URL to navigate toopts- Navigation options::timeout- Navigation timeout in ms:wait_until-:load,:domcontentloaded,:networkidle
Example:
Playwriter.with_browser([], fn ctx ->
:ok = Playwriter.goto(ctx, "https://example.com")
:ok = Playwriter.goto(ctx, "https://example.com/page2", wait_until: :networkidle)
end)content/1
Get the full HTML content of the current page.
@spec content(context()) :: {:ok, String.t()} | {:error, term()}Parameters:
ctx- Browser context fromwith_browser/2
Example:
Playwriter.with_browser([], fn ctx ->
:ok = Playwriter.goto(ctx, "https://example.com")
{:ok, html} = Playwriter.content(ctx)
String.contains?(html, "Example Domain")
end)click/3
Click an element matching a selector.
@spec click(context(), String.t(), keyword()) :: :ok | {:error, term()}Parameters:
ctx- Browser contextselector- CSS selector or text selectoropts- Click options::timeout- Wait timeout for element:button-:left,:right, or:middle:click_count- Number of clicks (default: 1):delay- Time between mousedown and mouseup in ms
Selectors:
# CSS selectors
Playwriter.click(ctx, "button.submit")
Playwriter.click(ctx, "#login-button")
Playwriter.click(ctx, "form input[type=submit]")
# Text selectors
Playwriter.click(ctx, "text=Sign In")
Playwriter.click(ctx, "text=Click here")Example:
Playwriter.with_browser([], fn ctx ->
:ok = Playwriter.goto(ctx, "https://example.com")
:ok = Playwriter.click(ctx, "a") # Click first link
end)fill/4
Fill an input field with text.
@spec fill(context(), String.t(), String.t(), keyword()) :: :ok | {:error, term()}Parameters:
ctx- Browser contextselector- Input element selectorvalue- Text to fillopts- Fill options::timeout- Wait timeout for element
Example:
Playwriter.with_browser([], fn ctx ->
:ok = Playwriter.goto(ctx, "https://example.com/login")
:ok = Playwriter.fill(ctx, "#username", "myuser")
:ok = Playwriter.fill(ctx, "#password", "mypass")
:ok = Playwriter.click(ctx, "button[type=submit]")
end)version/0
Returns the Playwriter version.
@spec version() :: String.t()Example:
Playwriter.version()
# => "0.1.0"Context Structure
The context passed to with_browser/2 callbacks contains:
%{
session: pid(), # Browser session GenServer
page: String.t(), # Page GUID for operations
frame: String.t() # Main frame GUID
}You typically don't need to access these directly; pass the context to Playwriter functions.
Server Discovery: Playwriter.Server.Discovery
discover/1
Automatically find a running Playwright server.
@spec discover(keyword()) :: {:ok, String.t()} | {:error, :not_found}Options:
:ports- List of ports to try (default: [3337, 3336, 3335, 3334, 9222]):hosts- List of hosts to try:timeout- Connection timeout per attempt
Example:
{:ok, endpoint} = Playwriter.Server.Discovery.discover()
# => {:ok, "ws://172.25.160.1:3337/"}
# Custom ports
{:ok, endpoint} = Playwriter.Server.Discovery.discover(ports: [9222])get_wsl2_host_ip/0
Get the Windows host IP from WSL.
@spec get_wsl2_host_ip() :: {:ok, String.t()} | {:error, term()}Example:
{:ok, ip} = Playwriter.Server.Discovery.get_wsl2_host_ip()
# => {:ok, "172.25.160.1"}Browser Session: Playwriter.Browser.Session
Low-level session management. Typically you don't use this directly.
start_link/1
Start a browser session.
@spec start_link(keyword()) :: {:ok, pid()} | {:error, term()}get_page/1
Get the current page GUID.
@spec get_page(pid()) :: {:ok, String.t()} | {:error, term()}stop/1
Stop a browser session.
@spec stop(pid()) :: :okTransport Behaviour
Both local and remote transports implement Playwriter.Transport.Behaviour:
@callback start_link(keyword()) :: {:ok, pid()} | {:error, term()}
@callback launch_browser(transport(), browser_type(), keyword()) :: {:ok, guid()}
@callback new_context(transport(), guid(), keyword()) :: {:ok, guid()}
@callback new_page(transport(), guid()) :: {:ok, map()}
@callback goto(transport(), guid(), String.t(), keyword()) :: result()
@callback content(transport(), guid()) :: {:ok, String.t()}
@callback click(transport(), guid(), String.t(), keyword()) :: result()
@callback fill(transport(), guid(), String.t(), String.t(), keyword()) :: result()
@callback screenshot(transport(), guid(), keyword()) :: {:ok, binary()}
@callback close_browser(transport(), guid()) :: :okError Handling
All functions return {:ok, result} or {:error, reason} tuples.
Common error reasons:
:timeout- Operation timed out:not_found- Element or server not found{:navigation_failed, reason}- Page navigation failed{:connection_error, reason}- WebSocket connection failed
Example:
case Playwriter.fetch_html(url) do
{:ok, html} ->
process_html(html)
{:error, :timeout} ->
Logger.warning("Request timed out")
{:error, :timeout}
{:error, reason} ->
Logger.error("Failed: #{inspect(reason)}")
{:error, reason}
endType Specifications
@type context() :: %{session: pid(), page: String.t(), frame: String.t()}
@type browser_type() :: :chromium | :firefox | :webkit
@type guid() :: String.t()
@type result() :: :ok | {:ok, term()} | {:error, term()}