AI/LLM Quickstart
Use this page as the compact source of truth when asking an AI coding tool to
write thirtyfour automation. It keeps the reliable defaults in one place and
links to the deeper documentation when a task needs more detail.
Minimal Setup
[dependencies]
thirtyfour = "0.37.4"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
The default thirtyfour features include the local
WebDriver::managed setup used below. Use
WebDriver::new or WebDriver::builder
instead when a remote Selenium or Grid service owns the driver process.
Install Chrome before running the test; the manager downloads a matching
chromedriver automatically on first use.
Starter Test
This example is marked no_run because example.test represents your
application and cannot be exercised as written.
#![allow(unused)]
fn main() {
use thirtyfour::{
prelude::*,
testing::{BrowserTestError, run_browser_test},
};
#[tokio::test]
async fn saves_profile_settings() -> Result<(), BrowserTestError> {
let mut caps = DesiredCapabilities::chrome();
caps.set_headless()?;
run_browser_test(WebDriver::managed(caps), |driver| async move {
driver.goto("https://example.test/settings").await?;
let form = driver
.query(By::Testid("profile-settings"))
.desc("profile settings form")
.single()
.await?;
form.query(By::Testid("display-name"))
.desc("display name input")
.single()
.await?
.send_keys("Ada")
.await?;
let save_button = form
.query(By::Testid("save-profile"))
.desc("save profile button")
.single()
.await?;
save_button.click_when_ready().await?;
// Assert the user-visible outcome. This query polls until the saved
// state appears, so it replaces a brittle fixed sleep.
driver
.query(By::Testid("settings-status"))
.with_text("Saved")
.and_displayed()
.desc("saved settings status")
.single()
.await?;
Ok(())
})
.await
}
}
Rules For Generated Automation
- Prefer app-owned
By::Testidselectors, then stable semantic CSS. Match visible text when the copy is the behavior under test; use XPath only when CSS cannot reasonably express the target. - Use
query()for normal lookup,.single()when uniqueness is a page contract, and.desc(...)on important user-facing elements. - Never use a fixed sleep for readiness. Poll for the required state with
query()or usewait_until()on an element you already have. - Scope queries through a container or Component, and assert a user-visible outcome rather than only checking that a click returned successfully.
- Prefer
run_browser_testin tests so asynchronous cleanup still runs after early errors and panicking assertions. Otherwise explicitly quit every session. Do not run independent concurrent flows through clones of the sameWebDriver. - On an error path, call
FailureArtifactCollector::capture()before cleanup for bounded, best-effort URL, title, screenshot, source, and log context. See the diagnostics recipe for capability and feature limits.
The copyable Reliable AI-Generated Tests checklist is the review gate for generated code. Apply it before accepting a test.
Deeper Documentation
- Task-Oriented Recipes — copyable starting points for common application flows, browser contexts, diagnostics, CDP, and BiDi.
- Selenium And Playwright Translation Guide — map familiar APIs to queries, waits, Components, and managed sessions without inventing APIs from another ecosystem.
- Element Queries — stable selectors, descriptions,
filters, scoping, cardinality, and intentional one-shot
find()calls. - Waiting For Element Changes — state waits for an element that has already been located.
- Components — reusable UI areas with private selectors and resilient element resolution.
- WebDriver Manager — local driver downloads, process lifetime, configuration, and separate sessions.
- Failure Artifacts And Logs — bounded portable failure context suitable for CI and AI-assisted debugging.
- Chrome DevTools Protocol — Chromium-only typed commands and optional event support.
- WebDriver BiDi — cross-browser bidirectional commands and events, with feature and capability opt-in.