| Crates.io | thirtyfour-testing-library-ext |
| lib.rs | thirtyfour-testing-library-ext |
| version | 0.1.3 |
| created_at | 2025-07-17 18:31:00.143047+00 |
| updated_at | 2025-07-19 08:33:04.285272+00 |
| description | Extends Thirtyfour's crate capabilities with the Javascript Testing Library API that emphasizes accessibility and user-centric testing approaches. |
| homepage | https://github.com/Greedeuh/thirtyfour-testing-library-ext |
| repository | https://github.com/Greedeuh/thirtyfour-testing-library-ext |
| max_upload_size | |
| id | 1757911 |
| size | 390,073 |
Extends Thirtyfour's crate capabilities with the Javascript Testing Library API that emphasizes accessibility and user-centric testing approaches.
Find elements using testing library approches and relay on Thirtyfour library to get their properties, click on them, ect.
Testing Library is a family of packages that help you test UI components in a way that resembles how users interact with your application. The core philosophy is: "The more your tests resemble the way your software is used, the more confidence they can give you."
This extension brings Testing Library's semantic query approach to Rust WebDriver testing:
As The Thirtyfour Testing Library Extension is just a binding to the official Testing Library it is really recommended to rely on their doc to understand how to write your tests: official documentation.
get*, query*, and find* methods with different behaviorswithin()Add this crate to your Cargo.toml:
[dependencies]
thirtyfour = "0.36.1"
thirtyfour-testing-library-ext = "0.1"
Note: This crate is a extension that depends on the published
thirtyfourcrate from crates.io. So the thirtyfour doc is a good starting point.
use thirtyfour::prelude::*;
use thirtyfour_testing_library_ext::{Screen, By, Configure};
#[tokio::main]
async fn main() -> WebDriverResult<()> {
// Setup the thirtyfour WebDriver as need, https://docs.rs/thirtyfour/latest/thirtyfour/
let caps = DesiredCapabilities::chrome();
let driver = WebDriver::new("http://localhost:9515", caps).await?;
driver.goto("https://example.com").await?;
// Basic usage - create a screen instance
let screen = Screen::build_with_testing_library(driver.clone()).await?;
// Query by role (semantic selector)
let button = screen.get(By::role("button")).await?;
button.click().await?;
// Wait for elements to appear with find()
let heading = screen.find(By::text("Welcome")).await?;
println!("Found heading: {}", heading.text().await?);
// Get all matching elements (returns empty vec if none found)
let all_links = screen.query_all(By::role("link")).await?;
println!("Found {} links", all_links.len());
// Query with options for more specific matching
let submit_button = screen.find(By::role("button").name("Submit")).await?;
let error_messages = screen.find_all(By::title("Error").exact(false)).await?;
// Query within a specific element scope
let form = screen.get(By::role("form")).await?;
let form_screen = screen.within(form);
let input = form_screen.get(By::label_text("Email")).await?;
input.send_keys("test@example.com").await?;
// Configure testing library behavior
let config = Configure::new().timeout(5000).test_id_attribute("data-cy");
let configured_screen = Screen::build_with_testing_library_and_configure(driver.clone(), config).await?;
driver.quit().await?;
Ok(())
}
The Screen struct provides several query methods with different behaviors:
get() / get_all() - Throw errors if elements aren't foundquery() / query_all() - Return None / empty Vec for missing elementsfind() / find_all() - Wait for elements to appear with retriesLearn more about Testing Library queries on the official guide
By::role() - refBy::text() - refBy::label_text() - refBy::placeholder_text() - refBy::alt_text() - refBy::title() - refBy::test_id() - refBy::display_value() - refEach selector type supports options for advanced filtering and matching.
TextMatch from testing library allow regex matching, to use them prefix & suffix by /:
By::text("/Hello.*/"),
By::text("/hello world/i"),
By::label_text("/username|email/i"),
By::placeholder_text("/enter.*/i"),
By::alt_text("/profile|avatar/i"),
By::title("/click|tap/i"),
By::test_id("/submit|send/"),
By::display_value("/[0-9]+%/"),
By::role("button").name("/submit|send/i"),
By::role("textbox").description("/enter.*here/"),
This extension works by injecting the official Testing Library JavaScript code into the browser and bridging it with Thirtyfour's WebDriver capabilities. Here's what happens under the hood:
Screen instance, the extension injects the Testing Library JavaScript bundle into the current pageBy::role(), By::text(), etc. calls are translated into JavaScript Testing Library queriesWebElement objects that you can interact with normallyThis approach gives you:
.click(), .send_keys(), etc.)This approach is inspired by Webdriverio Testing Library, selenium-testing-library (Kotlin) and selenium-testing-library.
You only need to run the tests if you plan on contributing to the development of
thirtyfour-testing-library-ext. If you just want to use the crate in your own project, you can skip this section.
To run the tests, you need to have an instance of chromedriver running in the background, perhaps in separate tabs in your terminal.
Download chromedriver: https://chromedriver.chromium.org/downloads
In separate terminal tabs, run the following:
Tab 1:
chromedriver
Tab 2 (navigate to the root of this repository):
cargo test
This project is licensed under either of
at your option.