2个版本
0.1.4 | 2022年7月20日 |
---|---|
0.1.3 | 2022年7月19日 |
0.1.2 |
|
0.1.1 |
|
#687 在 过程宏
16KB
249 行
一个#[derive(Querier)]
宏,用于生成使用thirtyfour通过CSS选择器查询元素集合所需的基本代码。
这个库高度实验性,最初是为内部使用开发的。
示例
use thirtyfour::prelude::*;
use thirtyfour_querier_derive::Querier;
#[derive(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();
依赖关系
宏生成的impl
块使用了futures
和thirtyfour
库。由于过程宏crate不能导出项目,这些依赖项必须由用户手动添加。这可能在未来的版本中改变。
详细信息
#[derive(Querier)]
宏生成一个包含名为query
的结构体的异步构造函数的impl
块,以下是其签名。
pub async fn query<T: ElementQueryable>(driver: &T)
-> Result<Self, WebDriverError>;
-
仅支持具有命名字段的struct。
-
默认情况下,查询是立即执行的。使用
#[querier(wait = num_seconds)]
添加显式等待。 -
结构体的每个字段都必须有一个
#[querier(...)]
属性。属性的值必须与字段的类型匹配,如下所示属性 字段类型 #[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)>
表中的类型
Q
可以是任何具有#[derive(Querier)]
特性的类型。
完整示例
use thirtyfour_querier_derive::Querier;
use thirtyfour::prelude::*;
const HTML: &str = r#"
data:text/html;charset=utf-8,<html>
<body>
<div id="single-element"></div>
<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>
</body>
</html>
"#;
#[derive(Debug, Querier)]
#[allow(dead_code)]
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)>,
}
#[derive(Debug, Querier)]
struct SubElement {
#[querier(all, css = ".nested-element")]
nested_elems: Vec<WebElement>,
}
#[tokio::main]
async fn main() {
let driver = WebDriver::new("http://127.0.0.1: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"
);
}
依赖关系
~3.5–5MB
~96K SLoC