Thirtyfour is a Selenium / WebDriver library for Rust, for automated website UI testing.
It supports the full W3C WebDriver spec. Tested with Chrome and Firefox although any W3C-compatible WebDriver should work.
This crate provides a synchronous (i.e. not async) interface for thirtyfour
.
For async, see the thirtyfour crate instead.
It is named after the atomic number for the Selenium chemical element (Se).
The example assumes you have a WebDriver running at localhost:4444.
You can use chromedriver directly by downloading the chromedriver that matches your Chrome version, from here: https://chromedriver.chromium.org/downloads
Then run it like this:
chromedriver --port=4444
To run this example:
cargo run --example sync
```rust use thirtyfour_sync::prelude::*;
fn main() -> WebDriverResult<()> { let caps = DesiredCapabilities::chrome(); let driver = WebDriver::new("http://localhost:4444", &caps)?;
// Navigate to https://wikipedia.org.
driver.get("https://wikipedia.org")?;
let elem_form = driver.find_element(By::Id("search-form"))?;
// Find element from element.
let elem_text = elem_form.find_element(By::Id("searchInput"))?;
// Type in the search terms.
elem_text.send_keys("selenium")?;
// Click the search button.
let elem_button = elem_form.find_element(By::Css("button[type='submit']"))?;
elem_button.click()?;
// Look for header to implicitly wait for the page to load.
driver.find_element(By::ClassName("firstHeading"))?;
assert_eq!(driver.title()?, "Selenium - Wikipedia");
// Close the browser.
driver.quit()?;
Ok(())
} ```
The WebDriver::query()
and WebElement::query()
methods return an ElementQuery
struct.
Using ElementQuery
, you can do things like:
rust
let elem_text =
driver.query(By::Css("match.this")).or(By::Id("orThis")).first()?;
This will execute both queries once per poll iteration and return the first one that matches. You can also filter on one or both query branches like this:
rust
driver.query(By::Css("branch.one")).with_text("testing")
.or(By::Id("branchTwo")).with_class("search").and_not_enabled()
.first()?;
The all()
method will return an empty Vec if no elements were found.
In order to return an error in this scenario, use the all_required()
method instead.
ElementQuery
also allows the use of custom predicates that take a &WebElement
argument
and return a WebDriverResult<bool>
.
As noted above, the query()
method is also available on WebElement
structs as well for querying elements
in relation to a particular element in the DOM.
The WebElement::wait_until()
method returns an ElementWaiter
struct.
Using ElementWaiter
you can do things like this:
```rust elem.waituntil().displayed()?; // You can optionally provide a nicer error message like this. elem.waituntil().error("Timed out waiting for element to disappear").not_displayed()?;
elem.waituntil().enabled()?; elem.waituntil().clickable()?; ```
And so on. See the ElementWaiter
docs for the full list of predicates available.
ElementWaiter
also allows the use of custom predicates that take a &WebElement
argument
and return a WebDriverResult<bool>
.
A range of pre-defined predicates are also supplied for convenience in the
thirtyfour_sync::query::conditions
module.
```rust use thirtyfour_sync::query::conditions;
elem.waituntil().conditions(vec![ conditions::elementisdisplayed(true), conditions::elementis_clickable(true) ])?; ```
These predicates (or your own) can also be supplied as filters to ElementQuery
.
thirtyfour_sync
, including doctestsYou generally only need to run the tests if you plan on contributing to the development of thirtyfour_sync
. If you just want to use the crate in your own project, you can skip this section.
Just like the examples above, the tests in this crate require a running instance of Selenium at http://localhost:4444
.
The tests also require a small web app called thirtyfour_testapp
that was purpose-built for testing the thirtyfour
crate.
This can be run using docker and docker-compose.
To install docker, see https://docs.docker.com/install/ (follow the SERVER section if you're on Linux, then look for the Community Edition)
To install docker-compose, see https://docs.docker.com/compose/install/
Once you have docker-compose installed, you can start the required containers, as follows:
docker-compose up -d --build
Then, to run the tests:
cargo test -- --test-threads=1
We need to limit the tests to a single thread because the selenium server only supports 1 browser instance at a time.
(You can increase this limit in the docker-compose.yml
file if you want. Remember to restart the containers afterwards)
If you need to restart the docker containers:
docker-compose restart
And finally, to remove them:
docker-compose down
This work is dual-licensed under MIT or Apache 2.0. You can choose either license if you use this work.
See the NOTICE file for more details.
SPDX-License-Identifier: MIT OR Apache-2.0