use viewpoint_js::js;
use super::Locator;
use crate::error::LocatorError;
impl<'a> Locator<'a> {
pub async fn text_content(&self) -> Result<Option<String>, LocatorError> {
let info = self.query_element_info().await?;
Ok(info.text)
}
pub async fn is_visible(&self) -> Result<bool, LocatorError> {
let info = self.query_element_info().await?;
Ok(info.visible.unwrap_or(false))
}
pub async fn is_checked(&self) -> Result<bool, LocatorError> {
let selector_expr = self.selector.to_js_expression();
let js_code = js! {
(function() {
const elements = @{selector_expr};
if (elements.length === 0) return { found: false, checked: false };
const el = elements[0];
return { found: true, checked: el.checked || false };
})()
};
let result = self.evaluate_js(&js_code).await?;
let checked: bool = result
.get("checked")
.and_then(serde_json::Value::as_bool)
.unwrap_or(false);
Ok(checked)
}
pub async fn count(&self) -> Result<usize, LocatorError> {
let info = self.query_element_info().await?;
Ok(info.count)
}
pub async fn all(&self) -> Result<Vec<Locator<'a>>, LocatorError> {
let count = self.count().await?;
let mut locators = Vec::with_capacity(count);
for i in 0..count {
locators.push(self.nth(i as i32));
}
Ok(locators)
}
pub async fn all_inner_texts(&self) -> Result<Vec<String>, LocatorError> {
let selector_expr = self.selector.to_js_expression();
let js_code = js! {
(function() {
const elements = Array.from(@{selector_expr});
return elements.map(el => el.innerText || "");
})()
};
let result = self.evaluate_js(&js_code).await?;
result
.as_array()
.map(|arr| {
arr.iter()
.map(|v| v.as_str().unwrap_or("").to_string())
.collect()
})
.ok_or_else(|| LocatorError::EvaluationError("Expected array result".to_string()))
}
pub async fn all_text_contents(&self) -> Result<Vec<String>, LocatorError> {
let selector_expr = self.selector.to_js_expression();
let js_code = js! {
(function() {
const elements = Array.from(@{selector_expr});
return elements.map(el => el.textContent || "");
})()
};
let result = self.evaluate_js(&js_code).await?;
result
.as_array()
.map(|arr| {
arr.iter()
.map(|v| v.as_str().unwrap_or("").to_string())
.collect()
})
.ok_or_else(|| LocatorError::EvaluationError("Expected array result".to_string()))
}
pub async fn inner_text(&self) -> Result<String, LocatorError> {
let selector_expr = self.selector.to_js_expression();
let js_code = js! {
(function() {
const elements = @{selector_expr};
if (elements.length === 0) return { found: false };
return { found: true, text: elements[0].innerText || "" };
})()
};
let result = self.evaluate_js(&js_code).await?;
let found = result
.get("found")
.and_then(serde_json::Value::as_bool)
.unwrap_or(false);
if !found {
return Err(LocatorError::NotFound(format!("{:?}", self.selector)));
}
Ok(result
.get("text")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string())
}
pub async fn get_attribute(&self, name: &str) -> Result<Option<String>, LocatorError> {
let selector_expr = self.selector.to_js_expression();
let js_code = js! {
(function() {
const elements = @{selector_expr};
if (elements.length === 0) return { found: false };
const attr = elements[0].getAttribute(#{name});
return { found: true, value: attr };
})()
};
let result = self.evaluate_js(&js_code).await?;
let found = result
.get("found")
.and_then(serde_json::Value::as_bool)
.unwrap_or(false);
if !found {
return Err(LocatorError::NotFound(format!("{:?}", self.selector)));
}
Ok(result
.get("value")
.and_then(|v| if v.is_null() { None } else { v.as_str() })
.map(std::string::ToString::to_string))
}
pub async fn input_value(&self) -> Result<String, LocatorError> {
let selector_expr = self.selector.to_js_expression();
let js_code = js! {
(function() {
const elements = @{selector_expr};
if (elements.length === 0) return { found: false };
const el = elements[0];
return { found: true, value: el.value || "" };
})()
};
let result = self.evaluate_js(&js_code).await?;
let found = result
.get("found")
.and_then(serde_json::Value::as_bool)
.unwrap_or(false);
if !found {
return Err(LocatorError::NotFound(format!("{:?}", self.selector)));
}
Ok(result
.get("value")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string())
}
}