use crate::test_server::TestServer;
use playwright_rs::server::channel_owner::ChannelOwner;
#[tokio::test]
async fn test_frame_locator() -> Result<(), Box<dyn std::error::Error>> {
let server = TestServer::start().await;
let (_pw, browser, page) = crate::common::setup().await;
page.goto(&format!("{}/button.html", server.url()), None)
.await?;
let frame = page.main_frame().await?;
let btn = frame.locator("#btn");
let text = btn.text_content().await?;
assert_eq!(text, Some("Click me".to_string()));
browser.close().await?;
server.shutdown();
Ok(())
}
#[tokio::test]
async fn test_frame_get_by_text() -> Result<(), Box<dyn std::error::Error>> {
let server = TestServer::start().await;
let (_pw, browser, page) = crate::common::setup().await;
page.goto(&format!("{}/button.html", server.url()), None)
.await?;
let frame = page.main_frame().await?;
let btn = frame.get_by_text("Click me", true);
let text = btn.text_content().await?;
assert_eq!(text, Some("Click me".to_string()));
browser.close().await?;
server.shutdown();
Ok(())
}
#[tokio::test]
async fn test_frame_name() -> Result<(), Box<dyn std::error::Error>> {
let (_pw, browser, page) = crate::common::setup().await;
let frame = page.main_frame().await?;
assert_eq!(frame.name(), "");
browser.close().await?;
Ok(())
}
#[tokio::test]
async fn test_frame_page() -> Result<(), Box<dyn std::error::Error>> {
let (_pw, browser, page) = crate::common::setup().await;
let frame = page.main_frame().await?;
let frame_page = frame.page().expect("Frame should have an owning page");
assert_eq!(frame_page.url(), page.url());
browser.close().await?;
Ok(())
}
#[tokio::test]
async fn test_frame_is_detached() -> Result<(), Box<dyn std::error::Error>> {
let (_pw, browser, page) = crate::common::setup().await;
let frame = page.main_frame().await?;
assert!(!frame.is_detached());
browser.close().await?;
Ok(())
}
#[tokio::test]
async fn test_frame_parent_frame() -> Result<(), Box<dyn std::error::Error>> {
let (_pw, browser, page) = crate::common::setup().await;
let frame = page.main_frame().await?;
assert!(frame.parent_frame().is_none());
browser.close().await?;
Ok(())
}
#[tokio::test]
async fn test_frame_evaluate_handle() -> Result<(), Box<dyn std::error::Error>> {
let (_pw, browser, page) = crate::common::setup().await;
page.goto(
"data:text/html,<html><body><h1>Hello</h1></body></html>",
None,
)
.await?;
let frame = page.main_frame().await?;
let handle = frame.evaluate_handle("document.body").await?;
let _screenshot = handle.screenshot(None).await?;
assert!(
!_screenshot.is_empty(),
"ElementHandle screenshot should return bytes"
);
browser.close().await?;
Ok(())
}
#[tokio::test]
async fn test_frame_child_frames_empty_on_simple_page() -> Result<(), Box<dyn std::error::Error>> {
let (_pw, browser, page) = crate::common::setup().await;
page.goto(
"data:text/html,<html><body><p>No iframes here</p></body></html>",
None,
)
.await?;
let frame = page.main_frame().await?;
let children = frame.child_frames();
assert!(
children.is_empty(),
"Main frame on a simple page should have no child frames, got {}",
children.len()
);
browser.close().await?;
Ok(())
}
#[tokio::test]
async fn test_frame_child_frames_with_iframes() -> Result<(), Box<dyn std::error::Error>> {
let server = TestServer::start().await;
let (_pw, browser, page) = crate::common::setup().await;
let frame_waiter = page.expect_event("frameattached", Some(5000.0)).await?;
page.goto(&format!("{}/iframe-test.html", server.url()), None)
.await?;
frame_waiter
.wait()
.await
.expect("frameattached did not fire");
page.wait_for_load_state(None).await?;
let frame = page.main_frame().await?;
let children = frame.child_frames();
assert!(
!children.is_empty(),
"Main frame should have child frames when iframes are present"
);
assert_eq!(
children.len(),
2,
"iframe-test.html has 2 iframes, got {}",
children.len()
);
for child in &children {
let url = child.url();
assert!(!url.is_empty(), "Child frame URL should not be empty");
assert!(
url.contains("iframe-content") || url.contains("about:blank"),
"Child frame URL '{}' should contain iframe-content",
url
);
}
browser.close().await?;
server.shutdown();
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn test_frame_child_frames_parent_reference() -> Result<(), Box<dyn std::error::Error>> {
let server = TestServer::start().await;
let (_pw, browser, page) = crate::common::setup().await;
let frame_waiter = page.expect_event("frameattached", Some(5000.0)).await?;
page.goto(&format!("{}/iframe-test.html", server.url()), None)
.await?;
frame_waiter
.wait()
.await
.expect("frameattached did not fire");
page.wait_for_load_state(None).await?;
let frame = page.main_frame().await?;
let children = frame.child_frames();
for child in &children {
let parent = child.parent_frame();
assert!(parent.is_some(), "Child frame should have a parent frame");
assert_eq!(
parent.unwrap().guid(),
frame.guid(),
"Child frame's parent_frame() GUID should match the main frame's GUID"
);
}
browser.close().await?;
server.shutdown();
Ok(())
}
#[tokio::test]
async fn test_frame_get_by_methods() -> Result<(), Box<dyn std::error::Error>> {
let server = TestServer::start().await;
let (_pw, browser, page) = crate::common::setup().await;
page.goto(
"data:text/html,<html><body>\
<input type='text' placeholder='Enter email' data-testid='email-input' />\
<label for='name'>Full Name</label>\
<input id='name' type='text' />\
<img src='data:,' alt='Logo Image' />\
<span title='Tooltip Text'>item</span>\
<button role='button'>Submit</button>\
</body></html>",
None,
)
.await?;
let frame = page.main_frame().await?;
let by_placeholder = frame.get_by_placeholder("Enter email", true);
assert_eq!(by_placeholder.count().await?, 1);
let by_label = frame.get_by_label("Full Name", true);
assert_eq!(by_label.count().await?, 1);
let by_alt = frame.get_by_alt_text("Logo Image", true);
assert_eq!(by_alt.count().await?, 1);
let by_title = frame.get_by_title("Tooltip Text", true);
assert_eq!(by_title.count().await?, 1);
let by_test_id = frame.get_by_test_id("email-input");
assert_eq!(by_test_id.count().await?, 1);
use playwright_rs::protocol::locator::AriaRole;
let by_role = frame.get_by_role(AriaRole::Button, None);
assert_eq!(by_role.count().await?, 1);
browser.close().await?;
server.shutdown();
Ok(())
}