Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Writing Your First Browser Automation Code

Before we begin, you’ll need to install Rust. You can do so by using the rustup tool.

Let’s start a new project. Open your terminal application and navigate to the directory where you usually put your source code. Then run these commands:

cargo new --bin my-automation-project
cd my-automation-project

You will see a Cargo.toml file and a src/ directory there already.

First, let’s edit the Cargo.toml file in your editor (e.g. Visual Studio Code) and add some dependencies:

[dependencies]
thirtyfour = "0.37.2"
tokio = { version = "1", features = ["full"] }

Great! Now let’s open src/main.rs and add the following code.

NOTE: Make sure you remove any existing code from main.rs.

Don’t worry, we’ll go through what it does soon.

/src/main.rs

use std::error::Error;

use thirtyfour::prelude::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
    let driver = WebDriver::managed(DesiredCapabilities::chrome()).await?;

    // Navigate to https://wikipedia.org.
    driver.goto("https://wikipedia.org").await?;
    let elem_form = driver
        .query(By::Id("search-form"))
        .desc("Wikipedia search form")
        .single()
        .await?;

    // Querying from an element scopes the search to its subtree.
    let elem_text = elem_form
        .query(By::Id("searchInput"))
        .desc("Wikipedia search input")
        .single()
        .await?;

    // Type in the search terms.
    elem_text.send_keys("selenium").await?;

    // Click the search button.
    let elem_button = elem_form
        .query(By::Css("button[type='submit']"))
        .desc("Wikipedia search button")
        .single()
        .await?;
    elem_button.click().await?;

    // Wait for the unique article heading before checking the title.
    driver
        .query(By::ClassName("firstHeading"))
        .desc("Wikipedia article heading")
        .single()
        .await?;
    assert_eq!(driver.title().await?, "Selenium - Wikipedia");

    // Always explicitly close the browser.
    driver.quit().await?;

    Ok(())
}

Selector note: Wikipedia is a third-party site, so this example uses the stable IDs, element types, and classes that the real page exposes. In an app you control, add stable data-testid hooks to important controls and prefer By::Testid:

#![allow(unused)]
fn main() {
let save_button = driver
    .query(By::Testid("settings-save"))
    .desc("settings save button")
    .single()
    .await?;
}

See Element Queries for the selector priority and guidance on text matching and XPath.

Make sure Chrome is installed, then run:

cargo run

If everything worked correctly you should have seen a Chrome browser window open up, navigate to the “Selenium” article on Wikipedia, and then close again.

The first run will take a few seconds longer than subsequent runs — thirtyfour downloads a matching chromedriver into your system cache directory the first time, then reuses it on every later run. See WebDriver Manager for the version-pinning, offline-mode, and observability options that the manager provides.

Running on Firefox

To run the code using Firefox instead, change the capabilities in main:

#![allow(unused)]
fn main() {
    let driver = WebDriver::managed(DesiredCapabilities::firefox()).await?;
}

Make sure Firefox is installed, and re-run:

cargo run

If everything worked correctly, you should have seen the Wikipedia page open up on Firefox this time.

Congratulations! You successfully automated a web browser.

Before building a larger suite, copy the short Reliable AI-Generated Tests checklist into your coding-agent instructions or project guidance. It captures the reliability rules used by this example and links to the deeper documentation for each one.