use crate::options::GetByRoleOptions;
use crate::page::Page;
use crate::types::AriaRole;
#[derive(Clone)]
pub struct FrameLocator {
page: Page,
frame_chain: Vec<String>,
}
impl FrameLocator {
pub(crate) fn new(page: Page, frame_selector: String) -> Self {
Self {
page,
frame_chain: vec![frame_selector],
}
}
pub fn page(&self) -> Page {
self.page.clone()
}
pub fn frame_selector(&self) -> &str {
self.frame_chain
.first()
.map(String::as_str)
.unwrap_or("")
}
pub fn locator(&self, selector: impl Into<String>) -> crate::locator::Locator {
crate::locator::Locator::new_in_frame(
self.page.clone(),
self.frame_chain.clone(),
selector.into(),
true,
None,
)
}
pub fn get_by_text(&self, text: &str, exact: bool) -> crate::locator::Locator {
let sel = if exact {
format!("text=\"{text}\"")
} else {
format!("text={text}")
};
self.locator(sel)
}
pub fn get_by_label(&self, text: &str) -> crate::locator::Locator {
self.locator(format!("[aria-label=\"{}\"]", esc(text)))
}
pub fn get_by_placeholder(&self, text: &str) -> crate::locator::Locator {
self.locator(format!("[placeholder=\"{}\"]", esc(text)))
}
pub fn get_by_alt_text(&self, text: &str) -> crate::locator::Locator {
self.locator(format!("[alt=\"{}\"]", esc(text)))
}
pub fn get_by_title(&self, text: &str) -> crate::locator::Locator {
self.locator(format!("[title=\"{}\"]", esc(text)))
}
pub fn get_by_test_id(&self, test_id: &str) -> crate::locator::Locator {
self.locator(format!("[data-testid=\"{}\"]", esc(test_id)))
}
pub fn get_by_role(
&self,
role: AriaRole,
opts: Option<GetByRoleOptions>,
) -> crate::locator::Locator {
let opts = opts.unwrap_or_default();
let mut sel = format!("role={}", role.as_str());
if let Some(name) = &opts.name {
sel.push_str(&format!("[name=\"{name}\"]"));
}
if opts.exact == Some(true) {
sel.push_str("[exact=\"true\"]");
}
self.locator(sel)
}
pub fn first(&self) -> FrameLocator {
self.clone()
}
pub fn last(&self) -> FrameLocator {
self.clone()
}
pub fn nth(&self, _index: i32) -> FrameLocator {
self.clone()
}
pub fn frame_locator(&self, selector: impl Into<String>) -> FrameLocator {
let mut chain = self.frame_chain.clone();
chain.push(selector.into());
FrameLocator {
page: self.page.clone(),
frame_chain: chain,
}
}
}
fn esc(s: &str) -> String {
s.replace('\\', "\\\\").replace('"', "\\\"")
}