A #[derive(Querier)]
derive macro for generating the boilerplate code needed to query a
collection of elements by CSS selectors using
thirtyfour.
This library is highly experimental, and is initially developed for internal use.
```rust use thirtyfour::prelude::*; use thirtyfourquerierderive::Querier;
struct PageElements { #[querier(css = "#first")] first: WebElement,
#[querier(css = "#second")]
second: WebElement,
#[querier(all, css = "div")]
all_divs: WebElement,
}
let page_elements = PageElements::query(&driver).await.unwrap(); ```
The impl
blocks generated by the macro uses futures
and thirtyfour
libraries.
Since the a proc macro crate can't export items, these dependencies has to be added manually
by the user.
This may change in future versions.
The #[derive(Querier)]
macro generates an impl
block containing an async constructor for
the structure named query
, with the following signature.
rust
pub async fn query<T: ElementQueryable>(driver: &T)
-> Result<Self, WebDriverError>;
#[querier(wait = num_seconds)]
to add an explicit wait.Each field of the structure must have a #[querier(...)]
attribute.
The content of the attribute must match the type of the field in this way:
| Attribute | Field Type |
|------------------------------------------|---------------------------|
| #[querier(css = "...")]
| WebElement
|
| #[querier(maybe, css = "...")]
| Option<WebElement>
|
| #[querier(all, css = "...")]
| Vec<WebElement>
|
| #[querier(nested, css = "...")]
| (WebElement, Q)
|
| #[querier(maybe, nested, css = "...")]
| Option<(WebElement, Q)>
|
| #[querier(all, nested, css = "...")]
| Vec<(WebElement, Q)>
|
The type Q
in the table can be any type that also has #[derive(Querier)]
.
```rust use thirtyfourquerierderive::Querier; use thirtyfour::prelude::*;
const HTML: &str = r#" data:text/html;charset=utf-8,
<div class="many-elements">
<div class="nested-element"></div>
<div class="nested-element"></div>
</div>
<div class="many-elements">
<div class="nested-element"></div>
<div class="nested-element"></div>
</div>
<div class="not-queried nested-element"></div>
"#;
struct Page { #[querier(css = "#single-element")] single_elem: WebElement,
#[querier(wait = 5, css = "#single-element")]
single_elem_with_wait: WebElement,
#[querier(maybe, css = "#missing-element")]
missing_elem: Option<WebElement>,
#[querier(all, css = ".many-elements")]
many_elems: Vec<WebElement>,
#[querier(all, nested, css = ".many-elements")]
many_elems_nested: Vec<(WebElement, SubElement)>,
}
struct SubElement {
#[querier(all, css = ".nested-element")]
nested_elems: Vec
async fn main() { let driver = WebDriver::new("http://localhost:9100", DesiredCapabilities::chrome()) .await .unwrap();
// Load the html string
driver.get(HTML).await.unwrap();
// Query the elements specified in `struct Page`
let page = Page::query(&driver).await.unwrap();
// Count number of `.nested-element` within `many-element`s (should be 4)
let mut nest_elem_count = 0;
for (_, elem) in page.many_elems_nested {
nest_elem_count += elem.nested_elems.len();
}
assert_eq!(
nest_elem_count, 4,
"Number of nested-element within many-element is 4"
);
} ```