use playwright_rs::api::LaunchOptions;
use playwright_rs::protocol::Playwright;
#[tokio::test]
async fn test_browser_object_creation_via_launch() {
crate::common::init_tracing();
let playwright = Playwright::launch()
.await
.expect("Failed to launch Playwright");
let chromium = playwright.chromium();
let browser = chromium.launch().await.expect("Failed to launch browser");
assert_eq!(browser.name(), "chromium");
assert!(!browser.version().is_empty());
tracing::info!(
"✅ Browser created: {} version {}",
browser.name(),
browser.version()
);
browser.close().await.expect("Failed to close browser");
}
#[test]
fn test_browser_type_exists() {
crate::common::init_tracing();
use playwright_rs::protocol::Browser;
use playwright_rs::server::channel_owner::ChannelOwner;
use std::any::TypeId;
assert_eq!(TypeId::of::<Browser>(), TypeId::of::<Browser>());
fn assert_channel_owner<T: ChannelOwner + 'static>() {}
assert_channel_owner::<Browser>();
tracing::info!("✅ Browser struct exists and implements ChannelOwner");
}
#[tokio::test]
async fn test_launch_chromium() {
crate::common::init_tracing();
tracing::debug!("[TEST] test_launch_chromium: Starting");
tracing::debug!("[TEST] Launching Playwright server...");
let playwright = Playwright::launch()
.await
.expect("Failed to launch Playwright");
tracing::debug!("[TEST] Playwright server launched successfully");
let chromium = playwright.chromium();
tracing::debug!("[TEST] Launching Chromium browser...");
let browser = chromium.launch().await.expect("Failed to launch Chromium");
tracing::debug!("[TEST] Chromium browser launched successfully");
assert_eq!(browser.name(), "chromium");
assert!(!browser.version().is_empty());
tracing::info!("Launched Chromium version: {}", browser.version());
tracing::debug!("[TEST] Closing browser...");
browser.close().await.expect("Failed to close browser");
tracing::debug!("[TEST] Browser closed successfully");
tracing::debug!("[TEST] test_launch_chromium: Complete");
}
#[tokio::test]
async fn test_launch_with_headless_option() {
crate::common::init_tracing();
tracing::debug!("[TEST] test_launch_with_headless_option: Starting");
tracing::debug!("[TEST] Launching Playwright server...");
let playwright = Playwright::launch()
.await
.expect("Failed to launch Playwright");
tracing::debug!("[TEST] Playwright server launched successfully");
let chromium = playwright.chromium();
let options = LaunchOptions::default().headless(true);
tracing::debug!("[TEST] Launching Chromium browser with headless option...");
let browser = chromium
.launch_with_options(options)
.await
.expect("Failed to launch Chromium with options");
tracing::debug!("[TEST] Chromium browser launched successfully");
assert_eq!(browser.name(), "chromium");
assert!(!browser.version().is_empty());
tracing::debug!("[TEST] Closing browser...");
browser.close().await.expect("Failed to close browser");
tracing::debug!("[TEST] Browser closed successfully");
tracing::debug!("[TEST] test_launch_with_headless_option: Complete");
}
#[tokio::test]
async fn test_launch_all_three_browsers() {
crate::common::init_tracing();
tracing::debug!("[TEST] test_launch_all_three_browsers: Starting");
tracing::debug!("[TEST] Launching Playwright server...");
let playwright = Playwright::launch()
.await
.expect("Failed to launch Playwright");
tracing::debug!("[TEST] Playwright server launched successfully");
tracing::debug!("[TEST] === Testing Chromium ===");
let chromium = playwright.chromium();
tracing::debug!("[TEST] Launching Chromium browser...");
let chromium_browser = chromium.launch().await.expect("Failed to launch Chromium");
assert_eq!(chromium_browser.name(), "chromium");
tracing::info!("✓ Chromium: {}", chromium_browser.version());
tracing::debug!("[TEST] Closing Chromium...");
chromium_browser
.close()
.await
.expect("Failed to close Chromium");
tracing::debug!("[TEST] Chromium closed successfully");
tracing::debug!("[TEST] === Testing Firefox ===");
let firefox = playwright.firefox();
tracing::debug!("[TEST] Launching Firefox browser...");
let firefox_browser = firefox.launch().await.expect("Failed to launch Firefox");
assert_eq!(firefox_browser.name(), "firefox");
tracing::info!("✓ Firefox: {}", firefox_browser.version());
tracing::debug!("[TEST] Closing Firefox...");
firefox_browser
.close()
.await
.expect("Failed to close Firefox");
tracing::debug!("[TEST] Firefox closed successfully");
tracing::debug!("[TEST] === Testing WebKit ===");
let webkit = playwright.webkit();
tracing::debug!("[TEST] Launching WebKit browser...");
let webkit_browser = webkit.launch().await.expect("Failed to launch WebKit");
assert_eq!(webkit_browser.name(), "webkit");
tracing::info!("✓ WebKit: {}", webkit_browser.version());
tracing::debug!("[TEST] Closing WebKit...");
webkit_browser
.close()
.await
.expect("Failed to close WebKit");
tracing::debug!("[TEST] WebKit closed successfully");
tracing::debug!("[TEST] test_launch_all_three_browsers: Complete");
}
#[tokio::test]
async fn test_browser_close() {
let (_pw, browser, _page) = crate::common::setup().await;
assert_eq!(browser.name(), "chromium");
browser.close().await.expect("Failed to close browser");
tracing::info!("✓ Browser closed successfully");
}
#[tokio::test]
async fn test_close_multiple_browsers() {
crate::common::init_tracing();
let playwright = Playwright::launch()
.await
.expect("Failed to launch Playwright");
let chromium = playwright.chromium();
let browser1 = chromium
.launch()
.await
.expect("Failed to launch Chromium 1");
let browser2 = chromium
.launch()
.await
.expect("Failed to launch Chromium 2");
tracing::info!("Launched 2 browsers");
browser1.close().await.expect("Failed to close browser 1");
tracing::info!("✓ Browser 1 closed");
browser2.close().await.expect("Failed to close browser 2");
tracing::info!("✓ Browser 2 closed");
}
#[tokio::test]
async fn test_browser_is_connected() {
let (_pw, browser, _page) = crate::common::setup().await;
assert!(
browser.is_connected(),
"Browser should be connected after launch"
);
browser.close().await.expect("Failed to close browser");
if browser.is_connected() {
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
}
assert!(
!browser.is_connected(),
"Browser should be disconnected after close"
);
}
#[tokio::test]
async fn test_browser_bind_and_unbind() {
use playwright_rs::protocol::BindOptions;
let (_pw, browser, _page) = crate::common::setup().await;
let result = browser
.bind(
"playwright-rs-bind-test",
Some(BindOptions {
host: Some("127.0.0.1".to_string()),
port: Some(0), ..Default::default()
}),
)
.await
.expect("bind should succeed");
assert!(
result.endpoint.starts_with("ws://"),
"endpoint should be a WebSocket URL, got: {}",
result.endpoint
);
assert!(
result.endpoint.contains("127.0.0.1"),
"endpoint should reference the bound host, got: {}",
result.endpoint
);
browser.unbind().await.expect("unbind should succeed");
browser
.unbind()
.await
.expect("second unbind should be a no-op");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_browser_contexts() {
crate::common::init_tracing();
let playwright = Playwright::launch()
.await
.expect("Failed to launch Playwright");
let browser = playwright
.chromium()
.launch()
.await
.expect("Failed to launch Chromium");
let initial = browser.contexts();
assert_eq!(initial.len(), 0, "Expected 0 contexts after launch");
let ctx1 = browser
.new_context()
.await
.expect("Failed to create context 1");
let after_first = browser.contexts();
assert_eq!(
after_first.len(),
1,
"Expected 1 context after first new_context"
);
let ctx2 = browser
.new_context()
.await
.expect("Failed to create context 2");
let after_second = browser.contexts();
assert_eq!(
after_second.len(),
2,
"Expected 2 contexts after second new_context"
);
ctx1.close().await.expect("Failed to close context 1");
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
let after_close_first = browser.contexts();
assert_eq!(
after_close_first.len(),
1,
"Expected 1 context after closing first"
);
ctx2.close().await.expect("Failed to close context 2");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_browser_type_property() {
let (_pw, browser, _page) = crate::common::setup().await;
let bt = browser.browser_type();
assert_eq!(
bt.name(),
"chromium",
"browser_type() should return chromium"
);
assert!(
!bt.executable_path().is_empty(),
"browser_type().executable_path() should be non-empty"
);
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_browser_on_disconnected() {
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use tokio::sync::Notify;
let (_pw, browser, _page) = crate::common::setup().await;
let fired = Arc::new(AtomicBool::new(false));
let fired_clone = Arc::clone(&fired);
let notify = Arc::new(Notify::new());
let notify_clone = notify.clone();
browser
.on_disconnected(move || {
let f = Arc::clone(&fired_clone);
let n = notify_clone.clone();
async move {
f.store(true, Ordering::SeqCst);
n.notify_one();
Ok(())
}
})
.await
.expect("Failed to register on_disconnected handler");
browser.close().await.expect("Failed to close browser");
tokio::time::timeout(std::time::Duration::from_secs(5), notify.notified())
.await
.expect("on_disconnected handler did not fire");
assert!(
fired.load(Ordering::SeqCst),
"on_disconnected handler should have fired after browser.close()"
);
}
#[tokio::test]
async fn test_browser_tracing() {
let (_pw, browser, _page) = crate::common::setup().await;
use playwright_rs::protocol::StartTracingOptions;
let options = StartTracingOptions {
screenshots: Some(true),
categories: None,
page: None,
};
browser
.start_tracing(Some(options))
.await
.expect("start_tracing should succeed on Chromium");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.goto("about:blank", None)
.await
.expect("Failed to navigate");
context.close().await.expect("Failed to close context");
let trace_data = browser
.stop_tracing()
.await
.expect("stop_tracing should succeed on Chromium");
assert!(
!trace_data.is_empty(),
"stop_tracing should return non-empty trace data"
);
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_browser_new_browser_cdp_session() {
let (_pw, browser, _page) = crate::common::setup().await;
let session = browser
.new_browser_cdp_session()
.await
.expect("new_browser_cdp_session should succeed on Chromium");
let result = session
.send("Browser.getVersion", None)
.await
.expect("CDP Browser.getVersion should succeed");
assert!(
result.get("product").is_some() || result.get("result").is_some(),
"CDP response should contain version info"
);
session.detach().await.expect("detach should succeed");
browser.close().await.expect("Failed to close browser");
}