lightdom-test
A lightweight Rust library for testing HTML interactions without browser automation.
Quick Start
1) Prepare HTML
2) Implement MockTransport
use ;
use Result;
;
3) Write Tests
use Dom;
async
API
Dom
Dom is the entry point for parsing HTML documents and manipulating forms and buttons.
| Method | Type | Description |
|---|---|---|
| new | (transport: impl HttpTransport) -> Dom |
Creates a new Dom instance. |
| parse | (html: String) -> anyhow::Result<Dom> |
Parses an HTML string and returns a Dom instance. |
| form | (locator: &str) -> anyhow::Result<Form> |
Gets a form based on the specified locator. |
| button | (locator: &str) -> anyhow::Result<Button> |
Gets a button based on the specified locator. |
| link | (locator: &str) -> anyhow::Result<Link> |
Gets a link based on the specified locator. |
| element | (locator: &str) -> anyhow::Result<Element> |
Gets an element with the specified locator. |
| elements | (locator: &str) -> Vec<Element> |
Gets all elements matching the specified locator. |
| text | (locator: &str) -> anyhow::Result<String> |
Gets the text of the element with the specified locator. |
| texts | (locator: &str) -> Vec<String> |
Gets the text of all elements matching the specified locator. |
| inner_html | (locator: &str) -> anyhow::Result<String> |
Gets the inner HTML of the element with the specified locator. |
| table | (locator: &str) -> anyhow::Result<Table> |
Gets the table with the specified locator. |
| list | (locator: &str) -> anyhow::Result<List> |
Gets the list with the specified locator. |
| title | () -> anyhow::Result<String> |
Gets the content of the <title> tag. |
| meta | (name: &str) -> anyhow::Result<String> |
Gets the content attribute of <meta name="..."> or <meta property="...">. |
| exists | (locator: &str) -> bool |
Checks if an element with the specified locator exists. |
| contains_text | (text: &str) -> bool |
Checks if an element containing the specified text exists. |
| select_element | (locator: &str) -> anyhow::Result<SelectElement> |
Gets the select element with the specified locator. |
| image | (locator: &str) -> anyhow::Result<Image> |
Gets the image with the specified locator. |
| images | (locator: &str) -> Vec<Image> |
Gets all images matching the specified locator. |
Locator types that can be specified for form:
| Locator | Description |
|---|---|
| @login-form | Identifies a form with test-id attribute login-form. |
| #login-form | Identifies a form with id attribute login-form. |
| /login | Identifies a form with action attribute /login. |
Locator types that can be specified for button:
| Locator | Description |
|---|---|
| @submit-btn | Identifies a button with test-id attribute submit-btn. |
| #submit-btn | Identifies a button with id attribute submit-btn. |
| Login | Identifies a button with display text Login. |
Locator types that can be specified for link:
| Locator | Description |
|---|---|
| @home-link | Identifies a link with test-id attribute home-link. |
| #home-link | Identifies a link with id attribute home-link. |
| Home | Identifies a link with display text Home. |
Form
Form represents an HTML form and provides methods for filling fields and submitting the form.
| Method | Type | Description |
|---|---|---|
| is_exist | (field_name: &str) -> bool |
Checks if the specified field exists in the form. |
| get_value | (field_name: &str) -> anyhow::Result<String> |
Gets the current value of the specified field. |
| fill | (field_name: &str, value: &str) -> anyhow::Result<&mut Form> |
Fills the specified field with a value. Returns an error if the field doesn't exist or the value doesn't match the field type. |
| check | (field_name: &str, value: &str) -> anyhow::Result<&mut Form> |
Checks a checkbox. For checkboxes with multiple values, call this method multiple times to select multiple options. |
| uncheck | (field_name: &str, value: &str) -> anyhow::Result<&mut Form> |
Unchecks a checkbox. |
| choose | (field_name: &str, value: &str) -> anyhow::Result<&mut Form> |
Selects a radio button. Other radio buttons with the same name attribute are automatically deselected. |
| select | (field_name: &str, value: &str) -> anyhow::Result<&mut Form> |
Selects an option in a select box. |
| submit | (&self) -> anyhow::Result<HttpResponse> |
Submits the form and returns an HTTP response. |
fill Method Validation
The fill method automatically validates input values based on the type attribute of the field:
| type attribute | Validation |
|---|---|
Checks if it contains @ |
|
| number | Checks if it can be parsed as a number |
| url | Checks if it starts with http:// or https:// |
| tel | Allows only digits, hyphens, spaces, parentheses, and + |
| date | Checks if it's in YYYY-MM-DD format |
| text, password, hidden, textarea, select, etc. | No validation |
// Valid cases
form.fill?; // OK
form.fill?; // OK
// Error cases
form.fill?; // Err: Invalid email format
form.fill?; // Err: Invalid number format
form.fill?; // Err: Field does not exist
is_exist Method Usage Example
// Check field existence
if form.is_exist
// Conditional processing
if form.is_exist && form.is_exist
Checkbox, Radio Button, and Select Box Usage Examples
// Checkbox (multiple selection)
form.check?
.check?;
// Uncheck checkbox
form.uncheck?;
// Radio button (single selection)
form.choose?;
// Select box
form.select?;
// Combined usage example
form.fill?
.fill?
.check?
.check?
.choose?
.select?
.submit.await?;
Button
Button represents an HTML button and provides methods for clicking.
| Method | Type | Description |
|---|---|---|
| click | (&self) -> anyhow::Result<HttpResponse> |
Clicks the button and submits the associated form. Returns an HTTP response. |
Usage Example
let button = dom.button?;
let response = button.click.await?;
assert!;
Link
Link represents an HTML link and provides methods for clicking.
| Method | Type | Description |
|---|---|---|
| click | (&self) -> anyhow::Result<HttpResponse> |
Clicks the link and sends a GET request to the href destination. Returns an HTTP response. |
Usage Example
let link = dom.link?;
let response = link.click.await?;
assert_eq!;
Data Retrieval APIs
The data retrieval APIs provide functionality for extracting data from HTML content.
Table
Table is an API for getting data from HTML tables (<table>).
| Method | Type | Description |
|---|---|---|
| headers | () -> Vec<String> |
Gets the table headers (th elements). |
| rows | () -> Vec<Row> |
Gets all rows of the table. |
| row | (index: usize) -> anyhow::Result<Row> |
Gets the row at the specified index. |
| cell | (row: usize, col: usize) -> anyhow::Result<String> |
Gets the text of the cell at the specified row and column. |
| find_row | (column: &str, value: &str) -> anyhow::Result<Row> |
Searches for a row where the specified column value matches. |
Row
Row represents one row of a table.
| Method | Type | Description |
|---|---|---|
| cells | () -> Vec<String> |
Gets the text of all cells in the row. |
| cell | (index: usize) -> anyhow::Result<String> |
Gets the text of the cell at the specified index. |
| get | (column: &str) -> anyhow::Result<String> |
Gets the text of a cell by specifying the header name. |
Usage Example
let table = dom.table?;
// Get headers
let headers = table.headers;
assert_eq!;
// Get all rows
for row in table.rows
// Access specific cell
let name = table.cell?; // Row 1, Column 1
assert_eq!;
// Search row by column name
let row = table.find_row?;
let status = row.get?;
assert_eq!;
List
List is an API for getting data from HTML lists (<ul>, <ol>).
| Method | Type | Description |
|---|---|---|
| items | () -> Vec<String> |
Gets the text of all list items. |
| item | (index: usize) -> anyhow::Result<String> |
Gets the text of the item at the specified index. |
| len | () -> usize |
Returns the number of list items. |
| contains | (text: &str) -> bool |
Checks if an item containing the specified text exists. |
Usage Example
let list = dom.list?;
// Get all items
let items = list.items;
assert_eq!;
// Access specific item
let first = list.item?;
assert_eq!;
// Check item existence
assert!;
Text
Text is an API for getting text content from HTML elements.
| Method | Type | Description |
|---|---|---|
| text | (locator: &str) -> anyhow::Result<String> |
Gets the text of the element with the specified locator. |
| texts | (locator: &str) -> Vec<String> |
Gets the text of all elements matching the specified locator. |
| inner_html | (locator: &str) -> anyhow::Result<String> |
Gets the inner HTML of the element with the specified locator. |
Locator types that can be specified for text:
| Locator | Description |
|---|---|
| @message | Identifies an element with test-id attribute message. |
| #message | Identifies an element with id attribute message. |
| .message | Identifies an element with class attribute message. |
Usage Example
let dom = new.parse?;
// Get text from single element
let message = dom.text?;
assert_eq!;
// Get text from multiple elements
let errors = dom.texts;
assert_eq!;
// Get inner HTML
let content = dom.inner_html?;
assert!;
Element
Element provides generic element retrieval and attribute access.
| Method | Type | Description |
|---|---|---|
| element | (locator: &str) -> anyhow::Result<Element> |
Gets the element with the specified locator. |
| elements | (locator: &str) -> Vec<Element> |
Gets all elements matching the specified locator. |
Element
Element represents a retrieved element.
| Method | Type | Description |
|---|---|---|
| text | () -> String |
Gets the text content of the element. |
| attr | (name: &str) -> Option<String> |
Gets the value of the specified attribute. |
| has_class | (class: &str) -> bool |
Checks if the element has the specified class. |
| inner_html | () -> String |
Gets the inner HTML of the element. |
| text_contains | (text: &str) -> bool |
Checks if the element's text contains the specified string. |
| is_disabled | () -> bool |
Checks if the element has the disabled attribute. |
| is_required | () -> bool |
Checks if the element has the required attribute. |
| is_readonly | () -> bool |
Checks if the element has the readonly attribute. |
| is_checked | () -> bool |
Checks if the element has the checked attribute. |
Usage Example
let element = dom.element?;
// Get text
let text = element.text;
// Get attribute
let user_id = element.attr;
assert_eq!;
// Check class
assert!;
// Process multiple elements
for elem in dom.elements
Meta Tags
Dom provides APIs for getting meta tags and title tags. Useful for SEO testing in SSR applications.
| Method | Type | Description |
|---|---|---|
| title | () -> anyhow::Result<String> |
Gets the content of the <title> tag. |
| meta | (name: &str) -> anyhow::Result<String> |
Gets the content attribute of <meta name="..."> or <meta property="...">. |
Usage Example
let dom = new.parse?;
// Get title
let title = dom.title?;
assert_eq!;
// Get meta tag
let description = dom.meta?;
assert_eq!;
// Get OGP tag
let og_title = dom.meta?;
assert_eq!;
Exists Check
API for checking element existence.
| Method | Type | Description |
|---|---|---|
| exists | (locator: &str) -> bool |
Checks if an element with the specified locator exists. |
| contains_text | (text: &str) -> bool |
Checks if an element containing the specified text exists. |
Usage Example
// Check element existence
assert!;
assert!;
// Check text existence
assert!;
assert!;
Select Element
SelectElement is an API for getting options from <select> elements.
| Method | Type | Description |
|---|---|---|
| select_element | (locator: &str) -> Result<SelectElement> |
Gets the select element with the specified locator. |
SelectElement
| Method | Type | Description |
|---|---|---|
| options | () -> Vec<SelectOption> |
Gets all options. |
| selected_option | () -> Result<SelectOption> |
Gets the selected option. |
SelectOption
| Method | Type | Description |
|---|---|---|
| value | () -> String |
Gets the value attribute of the option. |
| text | () -> String |
Gets the display text of the option. |
| is_selected | () -> bool |
Checks if the option is selected. |
Usage Example
let select = dom.select_element?;
// Get all options
let options = select.options;
assert_eq!;
assert_eq!;
assert_eq!;
// Get selected option
let selected = select.selected_option?;
assert_eq!;
assert!;
Image
Dom provides APIs for getting image elements.
| Method | Type | Description |
|---|---|---|
| image | (locator: &str) -> Result<Image> |
Gets the image with the specified locator. |
| images | (locator: &str) -> Vec<Image> |
Gets all images matching the specified locator. |
Image
| Method | Type | Description |
|---|---|---|
| src | () -> String |
Gets the src attribute of the image. |
| alt | () -> Option<String> |
Gets the alt attribute of the image. |
| width | () -> Option<String> |
Gets the width attribute of the image. |
| height | () -> Option<String> |
Gets the height attribute of the image. |
Usage Example
let img = dom.image?;
assert_eq!;
assert_eq!;
// Get all images
let images = dom.images;
for img in images
Transport Layer
lightdom-test abstracts HTTP sending operations into the HttpTransport trait. This allows you to use it with any HTTP client or framework.
HttpTransport Trait
HttpTransport is a trait for sending HTTP requests. Use it when implementing your own HTTP client.
HttpRequest
HttpRequest is a struct representing an HTTP request.
HttpResponse
HttpResponse is a struct representing an HTTP response.
Transport Implementation Examples
You can use MockTransport for testing and an actual HTTP client (e.g., reqwest) for production:
use ;
// For testing: MockTransport that captures requests
// For production: Implementation using reqwest
Framework Integration
lightdom-test provides integration with major Rust web frameworks as optional features.
Axum Integration
If you're using the Axum framework, you can use AxumTransport to test your Router directly without starting an HTTP server.
Enable
Add the axum feature to your Cargo.toml:
[]
= { = "0.1", = ["axum"] }
= "0.7"
= { = "1", = ["full"] }
Usage Example
use ;
use ;
use Deserialize;
async
async
Benefits
- Fast: Tests run quickly without needing to start an HTTP server
- No port management: No worries about random port allocation or port conflicts
- Simple: Just pass your
Routerdirectly
Rocket Integration
If you're using the Rocket framework, you can use RocketTransport to test your Rocket instance directly without starting an HTTP server.
Enable
Add the rocket feature to your Cargo.toml:
[]
= { = "0.1", = ["rocket"] }
= "0.5"
= { = "1", = ["full"] }
Usage Example
use ;
use ;
async
async
Benefits
- Fast: Tests run quickly without needing to start an HTTP server
- No port management: No worries about random port allocation or port conflicts
- Full Rocket features: Test all Rocket features including middleware, Fairings, and State
Philosophy
- Lightweight & Fast: Enables simple and fast testing without using large browser automation tools.
- Rust Native: Designed to integrate seamlessly with the Rust ecosystem.
- Simplicity: Provides an intuitive and easy-to-use API with minimal learning curve.
- Flexibility: Designed to work with any HTTP client or framework.