Expand description
playwright: High-level Rust bindings for Microsoft Playwright
This crate provides the public API for browser automation using Playwright.
§Quick tour
§Object model
Playwright start here — Playwright::launch().await?
└── BrowserType .chromium() / .firefox() / .webkit()
└── Browser .launch().await? → owns the browser process
└── BrowserContext isolated cookies / storage
└── Page one tab
└── Locator selector with auto-waitLocator is the workhorse. Build one with Page::locator or one
of the semantic helpers (get_by_role, get_by_text, get_by_label,
get_by_placeholder, get_by_test_id, get_by_alt_text,
get_by_title), then call action / assertion methods on it — they
wait for the element to be actionable automatically.
§API conventions
Result<T>everywhere. One error type,Error.- Builders for option-heavy methods.
goto,click,screenshot,tracing.start, etc. take anOptionsstruct (..Default::default()). - Auto-wait by default. Locator-based actions wait until the
element is actionable;
expectassertions auto-retry until the condition holds or times out. You almost never need a manualsleep. - Async/await on
tokio. Every method that does I/O isasync. - Selectors validated at compile time. Prefer the
locator!macro (re-exported when the defaultmacrosfeature is on) over raw&str: empty / malformed selectors fail atcargo build, not at runtime.
§Debugging failures
Fastest path to “what happened” is tracing:
- Wrap the test body with
BrowserContext::tracing—start({ snapshots, screenshots, sources })→ run →stop({ path }). - Open the resulting
.trace.zipwithplaywright show-trace path/to/trace.zip— the trace viewer is language-agnostic, the same UI JS / Python users see. - To inspect a trace programmatically (CI bots, agent feedback
loops), pull in
playwright-rs-traceas a[dev-dependencies].
See examples/trace_on_failure.rs
for the canonical Rust pattern (Rust has no async Drop, so cleanup
is explicit).
§Companion crates
playwright-rs-macros— compile-time-validatedlocator!macro. Default-on via themacrosfeature; surfaced here asplaywright_rs::locator!.playwright-rs-trace— pure-Rust parser for.trace.zipfiles. Standalone; add to[dev-dependencies]for post-mortem analysis.
§For AI coding agents
If you’re using this crate with Claude Code or another coding agent,
see docs/agent/
for a copy-paste CLAUDE.md snippet and the
playwright-rs-usage skill
you can drop into your project’s .claude/skills/.
§Examples
§Basic Navigation and Interaction
use playwright_rs::{Playwright, SelectOption};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let playwright = Playwright::launch().await?;
let browser = playwright.chromium().launch().await?;
let page = browser.new_page().await?;
// Navigate using data URL for self-contained test
let _ = page.goto(
"data:text/html,<html><body>\
<h1 id='title'>Welcome</h1>\
<button id='btn' onclick='this.textContent=\"Clicked\"'>Click me</button>\
</body></html>",
None
).await;
// Query elements with locators
let heading = page.locator("#title").await;
let text = heading.text_content().await?;
assert_eq!(text, Some("Welcome".to_string()));
// Click button and verify result
let button = page.locator("#btn").await;
button.click(None).await?;
let button_text = button.text_content().await?;
assert_eq!(button_text, Some("Clicked".to_string()));
browser.close().await?;
Ok(())
}§Form Interaction
use playwright_rs::{Playwright, SelectOption};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let playwright = Playwright::launch().await?;
let browser = playwright.chromium().launch().await?;
let page = browser.new_page().await?;
// Create form with data URL
let _ = page.goto(
"data:text/html,<html><body>\
<input type='text' id='name' />\
<input type='checkbox' id='agree' />\
<select id='country'>\
<option value='us'>USA</option>\
<option value='uk'>UK</option>\
<option value='ca'>Canada</option>\
</select>\
</body></html>",
None
).await;
// Fill text input
let name = page.locator("#name").await;
name.fill("John Doe", None).await?;
assert_eq!(name.input_value(None).await?, "John Doe");
// Check checkbox
let checkbox = page.locator("#agree").await;
checkbox.set_checked(true, None).await?;
assert!(checkbox.is_checked().await?);
// Select option
let select = page.locator("#country").await;
select.select_option("uk", None).await?;
assert_eq!(select.input_value(None).await?, "uk");
browser.close().await?;
Ok(())
}§Element Screenshots
use playwright_rs::Playwright;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let playwright = Playwright::launch().await?;
let browser = playwright.chromium().launch().await?;
let page = browser.new_page().await?;
// Create element to screenshot
let _ = page.goto(
"data:text/html,<html><body>\
<div id='box' style='width:100px;height:100px;background:blue'></div>\
</body></html>",
None
).await;
// Take screenshot of specific element
let element = page.locator("#box").await;
let screenshot = element.screenshot(None).await?;
assert!(!screenshot.is_empty());
browser.close().await?;
Ok(())
}§Assertions (expect API)
use playwright_rs::{expect, Playwright};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let playwright = Playwright::launch().await?;
let browser = playwright.chromium().launch().await?;
let page = browser.new_page().await?;
let _ = page.goto(
"data:text/html,<html><body>\
<button id='enabled'>Enabled</button>\
<button id='disabled' disabled>Disabled</button>\
<input type='checkbox' id='checked' checked />\
</body></html>",
None
).await;
// Assert button states with auto-retry
let enabled_btn = page.locator("#enabled").await;
expect(enabled_btn.clone()).to_be_enabled().await?;
let disabled_btn = page.locator("#disabled").await;
expect(disabled_btn).to_be_disabled().await?;
// Assert checkbox state
let checkbox = page.locator("#checked").await;
expect(checkbox).to_be_checked().await?;
browser.close().await?;
Ok(())
}§Observability
Every public async method on the user-facing types
(Browser, BrowserContext, BrowserType, Page, Frame, Locator,
ElementHandle, Tracing, CDPSession, Debugger, Screencast, plus
Request, Response, Dialog, Download, Worker, FileChooser)
is instrumented with the tracing crate. Wire up any
tracing_subscriber and you get spans for free, with cardinality-bounded
identifiers (guid, selector, url, name) and selected
completion-time fields (status, bytes_len, count, version).
Internal tokio::spawn sites propagate the caller’s span via
Instrument::in_current_span() so user-registered handlers and event
fan-out tasks inherit the surrounding context.
Levels: top-level user operations (goto, click, fill, screenshot,
pdf, evaluate, tracing.start/stop, browser_type.launch) are at
info; everything else is at debug. Sensitive payloads — input
values, eval expressions, request/response bodies — are deliberately
excluded from span fields.
use tracing_subscriber::EnvFilter;
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::new("playwright_rs=info"))
.init();Re-exports§
pub use protocol::Browser;pub use protocol::BrowserContext;pub use protocol::BrowserType;pub use protocol::FrameLocator;pub use protocol::HeaderEntry;pub use protocol::Page;pub use protocol::Playwright;pub use protocol::Response;pub use protocol::Selectors;pub use protocol::Keyboard;pub use protocol::Mouse;pub use protocol::Touchscreen;pub use protocol::Request;pub use protocol::ResourceTiming;pub use protocol::AriaRole;pub use protocol::AriaSnapshotMode;pub use protocol::AriaSnapshotOptions;pub use protocol::BoundingBox;pub use protocol::ElementHandle;pub use protocol::FilterOptions;pub use protocol::GetByRoleOptions;pub use protocol::JSHandle;pub use protocol::Locator;pub use protocol::GotoOptions;pub use protocol::WaitUntil;pub use protocol::CheckOptions;pub use protocol::ClickOptions;pub use protocol::DragToOptions;pub use protocol::FillOptions;pub use protocol::HoverOptions;pub use protocol::PressOptions;pub use protocol::PressSequentiallyOptions;pub use protocol::SelectOptions;pub use protocol::TapOptions;pub use protocol::WaitForOptions;pub use protocol::WaitForState;pub use protocol::Position;pub use protocol::FilePayload;pub use protocol::SelectOption;pub use protocol::ScreenshotClip;pub use protocol::ScreenshotOptions;pub use protocol::ScreenshotType;pub use protocol::ActionPosition;pub use protocol::ChapterOptions;pub use protocol::OverlayId;pub use protocol::Screencast;pub use protocol::ScreencastFrame;pub use protocol::ScreencastSize;pub use protocol::ScreencastStartOptions;pub use protocol::ShowActionsOptions;pub use protocol::ShowOverlayOptions;pub use protocol::AddScriptTagOptions;pub use protocol::ColorScheme;pub use protocol::EmulateMediaOptions;pub use protocol::ForcedColors;pub use protocol::Media;pub use protocol::PdfMargin;pub use protocol::PdfOptions;pub use protocol::ReducedMotion;pub use protocol::BrowserContextOptions;pub use protocol::Cookie;pub use protocol::Geolocation;pub use protocol::LocalStorageItem;pub use protocol::Origin;pub use protocol::RecordHar;pub use protocol::RecordVideo;pub use protocol::StorageState;pub use protocol::Viewport;pub use protocol::EventWaiter;pub use protocol::EventValue;pub use protocol::ConsoleMessage;pub use protocol::ConsoleMessageLocation;pub use protocol::DeviceDescriptor;pub use protocol::DeviceViewport;pub use protocol::WebError;pub use protocol::WebSocketRoute;pub use protocol::WebSocketRouteCloseOptions;pub use protocol::FileChooser;pub use protocol::Accessibility;pub use protocol::AccessibilitySnapshotOptions;pub use protocol::CSSCoverageEntry;pub use protocol::Coverage;pub use protocol::CoverageRange;pub use protocol::JSCoverageEntry;pub use protocol::JSCoverageRange;pub use protocol::JSFunctionCoverage;pub use protocol::StartCSSCoverageOptions;pub use protocol::StartJSCoverageOptions;pub use protocol::Clock;pub use protocol::ClockInstallOptions;pub use protocol::Video;pub use protocol::FetchOptions;pub use protocol::FetchResponse;pub use protocol::FulfillOptions;pub use protocol::Route;pub use protocol::UnrouteBehavior;pub use protocol::APIRequest;pub use protocol::APIRequestContext;pub use protocol::APIRequestContextOptions;pub use protocol::APIResponse;pub use api::ConnectOverCdpOptions;pub use api::LaunchOptions;
Modules§
Macros§
- locator
- Compile-time-validated Playwright selector. Expands to a
&'static strcontaining the same selector verbatim, with the validation a one-time compile-time check.
Structs§
- Page
Expectation - Page-level expectation for screenshot assertions.
Enums§
- Error
- Errors that can occur when using playwright-core
Constants§
- DEFAULT_
TIMEOUT_ MS - Default timeout in milliseconds for Playwright operations.
- PLAYWRIGHT_
VERSION - Playwright server version bundled with this crate.
Functions§
- expect
- Creates an expectation for a locator with auto-retry behavior.
- expect_
page - Creates a page-level expectation for screenshot assertions.
- install_
browsers - Install Playwright browsers programmatically.
- install_
browsers_ with_ deps - Install Playwright browsers and their system dependencies.
Type Aliases§
- Result
- Result type alias for playwright-core operations