Skip to content

Commit

Permalink
Fix NullHttpClient, and improve the size of WebDriverError from 184 b…
Browse files Browse the repository at this point in the history
…ytes down to 8 bytes

Signed-off-by: Vrtgs <[email protected]>
  • Loading branch information
Vrtgs committed Oct 22, 2024
1 parent ac8fea2 commit a9a1daa
Show file tree
Hide file tree
Showing 18 changed files with 409 additions and 291 deletions.
2 changes: 1 addition & 1 deletion thirtyfour-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "thirtyfour-macros"
version = "0.1.3"
version = "0.2.0"
authors = ["Steve Pryde <[email protected]>", "Vrtgs"]
edition = "2021"
license = "MIT OR Apache-2.0"
Expand Down
10 changes: 2 additions & 8 deletions thirtyfour-macros/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,10 +802,7 @@ impl ToTokens for SingleResolverArgs {
match &self.options {
SingleResolverOptions::CustomFn(f) => {
tokens.append_all(quote!(
#ty::new_custom(base.clone(), move |elem: &WebElement| {
let elem = ::std::clone::Clone::clone(elem);
async move { (#f)(&elem).await }
})
#ty::new_custom(base.clone(), #f)
));
}
SingleResolverOptions::Opts {
Expand Down Expand Up @@ -919,10 +916,7 @@ impl ToTokens for MultiResolverArgs {
match &self.options {
MultiResolverOptions::CustomFn(f) => {
tokens.append_all(quote!(
#ty::new_custom(base.clone(), move |elem: &WebElement| {
let elem = ::std::clone::Clone::clone(elem);
async move { (#f)(&elem).await }
})
#ty::new_custom(base.clone(), #f)
));
}
MultiResolverOptions::Opts {
Expand Down
4 changes: 2 additions & 2 deletions thirtyfour/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "thirtyfour"
version = "0.34.2"
version = "0.35.0"
authors = ["Steve Pryde <[email protected]>", "Vrtgs"]
edition = "2021"
license = "MIT OR Apache-2.0"
Expand Down Expand Up @@ -48,7 +48,7 @@ serde = { version = "1.0.210", features = ["derive", "rc"] }
serde_json = { version = "1.0.132", features = ["preserve_order"] }
serde_repr = "0.1.19"
stringmatch = "0.4"
thirtyfour-macros = { path = "../thirtyfour-macros", version = "0.1.3", optional = true }
thirtyfour-macros = { path = "../thirtyfour-macros", version = "0.2.0", optional = true }
thiserror = "1.0.64"
arc-swap = "1"
tokio = { version = "1", features = [
Expand Down
2 changes: 1 addition & 1 deletion thirtyfour/examples/components/playground.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub struct Header {
///
/// NOTE: This particular example could be done with a single XPath but sometimes you
/// may want something more complex.
async fn resolve_run_button(elem: &WebElement) -> WebDriverResult<WebElement> {
async fn resolve_run_button(elem: WebElement) -> WebDriverResult<WebElement> {
elem.query(By::Tag("button")).with_text("Run".match_partial().case_insensitive()).first().await
}

Expand Down
8 changes: 4 additions & 4 deletions thirtyfour/src/common/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,17 +286,17 @@ pub trait ElementQueryFn<T>: Send + Sync {
type Fut: Future<Output = WebDriverResult<T>> + Send;

/// the implementation of the query function
fn call(&self, arg: &WebElement) -> Self::Fut;
fn call(&self, arg: WebElement) -> Self::Fut;
}

impl<T, Fut, Fun> ElementQueryFn<T> for Fun
where
Fun: Fn(&WebElement) -> Fut + Send + Sync + ?Sized,
Fun: Fn(WebElement) -> Fut + Send + Sync + ?Sized,
Fut: Future<Output = WebDriverResult<T>> + Send,
{
type Fut = Fut;

fn call(&self, arg: &WebElement) -> Fut {
fn call(&self, arg: WebElement) -> Fut {
self(arg)
}
}
Expand All @@ -316,7 +316,7 @@ impl<T: 'static> DynElementQueryFn<T> {
fn wrap<F: ElementQueryFn<T, Fut: 'static>>(
fun: F,
) -> impl ElementQueryFn<T, Fut = BoxFuture<'static, WebDriverResult<T>>> {
move |arg: &WebElement| fun.call(arg).boxed()
move |arg: WebElement| fun.call(arg).boxed()
}

/// erases the type of ElementQueryFn, and dynamically dispatches it using a Box smart pointer
Expand Down
12 changes: 3 additions & 9 deletions thirtyfour/src/components/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::error::{no_such_element, WebDriverError, WebDriverResult};
use crate::error::{no_such_element, WebDriverErrorInner, WebDriverResult};
use crate::{By, WebElement};
use std::fmt::{Display, Formatter};

Expand Down Expand Up @@ -63,13 +63,7 @@ pub fn escape_string(value: &str) -> String {

/// Get the longest word in the specified string.
fn get_longest_token(value: &str) -> &str {
let mut longest = "";
for item in value.split(' ') {
if item.len() > longest.len() {
longest = item;
}
}
longest
value.split(' ').max_by_key(|x| x.len()).unwrap_or("")
}

/// Convenience wrapper for `<select>` elements.
Expand Down Expand Up @@ -159,7 +153,7 @@ impl SelectElement {
let mut xpath = format!(".//option[normalize-space(.) = {}]", escape_string(text));
let options = match self.element.find_all(By::XPath(&*xpath)).await {
Ok(elems) => elems,
Err(WebDriverError::NoSuchElement(_)) => Vec::new(),
Err(e) if matches!(*e, WebDriverErrorInner::NoSuchElement(_)) => Vec::new(),
Err(e) => return Err(e),
};

Expand Down
51 changes: 17 additions & 34 deletions thirtyfour/src/components/wrapper/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl<T: Clone + 'static> ElementResolver<T> {
pub async fn resolve(&self) -> WebDriverResult<T> {
self.element
.load()
.get_or_try_init(|| self.query_fn.call(&self.base_element))
.get_or_try_init(|| self.query_fn.call(self.base_element.clone()))
.await
.cloned()
}
Expand Down Expand Up @@ -158,8 +158,7 @@ impl<T: Resolve + Clone + 'static> ElementResolver<T> {
impl ElementResolver<WebElement> {
/// Create a new element resolver that must return a single element.
pub fn new_single(base_element: WebElement, by: By) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
async move { elem.query(by).single().await }
};
Expand All @@ -168,8 +167,7 @@ impl ElementResolver<WebElement> {

/// Create a new element resolver that must return a single element, with extra options.
pub fn new_single_opts(base_element: WebElement, by: By, options: ElementQueryOptions) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
let options = options.clone();
async move { elem.query(by).options(options).single().await }
Expand All @@ -179,8 +177,7 @@ impl ElementResolver<WebElement> {

/// Create a new element resolver that returns the first element.
pub fn new_first(base_element: WebElement, by: By) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
async move { elem.query(by).first().await }
};
Expand All @@ -189,8 +186,7 @@ impl ElementResolver<WebElement> {

/// Create a new element resolver that returns the first element, with extra options.
pub fn new_first_opts(base_element: WebElement, by: By, options: ElementQueryOptions) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
let options = options.clone();
async move { elem.query(by).options(options).first().await }
Expand All @@ -204,8 +200,7 @@ impl ElementResolver<Vec<WebElement>> {
///
/// If no elements were found, this will resolve to an empty Vec.
pub fn new_allow_empty(base_element: WebElement, by: By) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
async move { elem.query(by).all_from_selector().await }
};
Expand All @@ -218,8 +213,7 @@ impl ElementResolver<Vec<WebElement>> {
by: By,
options: ElementQueryOptions,
) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
let options = options.clone();
async move { elem.query(by).options(options).all_from_selector().await }
Expand All @@ -232,8 +226,7 @@ impl ElementResolver<Vec<WebElement>> {
/// If no elements were found, a NoSuchElement error will be returned by the resolver's
/// `resolve()` method.
pub fn new_not_empty(base_element: WebElement, by: By) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
async move { elem.query(by).all_from_selector_required().await }
};
Expand All @@ -249,8 +242,7 @@ impl ElementResolver<Vec<WebElement>> {
by: By,
options: ElementQueryOptions,
) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
let options = options.clone();
async move { elem.query(by).options(options).all_from_selector_required().await }
Expand All @@ -262,8 +254,7 @@ impl ElementResolver<Vec<WebElement>> {
impl<T: Component + Clone + 'static> ElementResolver<T> {
/// Create a new element resolver that must return a single component.
pub fn new_single(base_element: WebElement, by: By) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
async move {
let elem = elem.query(by).single().await?;
Expand All @@ -275,8 +266,7 @@ impl<T: Component + Clone + 'static> ElementResolver<T> {

/// Create a new element resolver that must return a single component, with extra options.
pub fn new_single_opts(base_element: WebElement, by: By, options: ElementQueryOptions) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
let options = options.clone();
async move {
Expand All @@ -289,8 +279,7 @@ impl<T: Component + Clone + 'static> ElementResolver<T> {

/// Create a new element resolver that returns the first component.
pub fn new_first(base_element: WebElement, by: By) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
async move {
let elem = elem.query(by).first().await?;
Expand All @@ -302,8 +291,7 @@ impl<T: Component + Clone + 'static> ElementResolver<T> {

/// Create a new element resolver that returns the first component, with extra options.
pub fn new_first_opts(base_element: WebElement, by: By, options: ElementQueryOptions) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
let options = options.clone();
async move {
Expand All @@ -320,10 +308,8 @@ impl<T: Component + Clone + 'static> ElementResolver<Vec<T>> {
///
/// If no components were found, this will resolve to an empty Vec.
pub fn new_allow_empty(base_element: WebElement, by: By) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
let elem = elem.clone();
async move {
let elems = elem.query(by).all_from_selector().await?;
Ok(elems.into_iter().map(T::from).collect())
Expand All @@ -338,9 +324,8 @@ impl<T: Component + Clone + 'static> ElementResolver<Vec<T>> {
by: By,
options: ElementQueryOptions,
) -> Self {
let resolver = move |elem: &WebElement| {
let resolver = move |elem: WebElement| {
let by = by.clone();
let elem = elem.clone();
let options = options.clone();
async move {
let elems = elem.query(by).options(options).all_from_selector().await?;
Expand All @@ -355,8 +340,7 @@ impl<T: Component + Clone + 'static> ElementResolver<Vec<T>> {
/// If no components were found, a NoSuchElement error will be returned by the resolver's
/// `resolve()` method.
pub fn new_not_empty(base_element: WebElement, by: By) -> Self {
let resolver = move |elem: &WebElement| {
let elem = elem.clone();
let resolver = move |elem: WebElement| {
let by = by.clone();
async move {
let elems = elem.query(by).all_from_selector_required().await?;
Expand All @@ -375,10 +359,9 @@ impl<T: Component + Clone + 'static> ElementResolver<Vec<T>> {
by: By,
options: ElementQueryOptions,
) -> Self {
let resolver = move |elem: &WebElement| {
let resolver = move |elem: WebElement| {
let by = by.clone();
let options = options.clone();
let elem = elem.clone();
async move {
let elems = elem.query(by).options(options).all_from_selector_required().await?;
Ok(elems.into_iter().map(T::from).collect())
Expand Down
Loading

0 comments on commit a9a1daa

Please sign in to comment.