#![cfg(feature = "integration")]
mod common;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::Mutex;
use viewpoint_core::{Browser, DialogType};
use viewpoint_js::js;
use common::init_tracing;
const ALERT_HTML: &str = r#"
<!DOCTYPE html>
<html>
<body>
<button id="alert" onclick="alert('Hello from alert!')">Show Alert</button>
<button id="multiple-alerts" onclick="alert('First'); alert('Second'); alert('Third');">Multiple Alerts</button>
</body>
</html>
"#;
const CONFIRM_HTML: &str = r#"
<!DOCTYPE html>
<html>
<body>
<button id="confirm" onclick="window.result = confirm('Are you sure?')">Show Confirm</button>
<div id="result"></div>
<script>
document.getElementById('confirm').addEventListener('click', function() {
setTimeout(function() {
document.getElementById('result').textContent = window.result ? 'true' : 'false';
}, 10);
});
</script>
</body>
</html>
"#;
#[tokio::test]
async fn test_dialog_alert_event() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.set_content(ALERT_HTML)
.set()
.await
.expect("Failed to set content");
let dialog_received = Arc::new(Mutex::new(false));
let dialog_received_clone = dialog_received.clone();
let dialog_message = Arc::new(Mutex::new(String::new()));
let dialog_message_clone = dialog_message.clone();
page.on_dialog(move |dialog| {
let received = dialog_received_clone.clone();
let message = dialog_message_clone.clone();
async move {
*received.lock().await = true;
*message.lock().await = dialog.message().to_string();
dialog.accept().await
}
})
.await;
page.locator("#alert")
.click()
.await
.expect("Failed to click button");
tokio::time::sleep(Duration::from_millis(200)).await;
assert!(
*dialog_received.lock().await,
"Dialog handler should have been called"
);
assert_eq!(*dialog_message.lock().await, "Hello from alert!");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_dialog_type_alert() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.set_content(ALERT_HTML)
.set()
.await
.expect("Failed to set content");
let dialog_type = Arc::new(Mutex::new(None::<DialogType>));
let dialog_type_clone = dialog_type.clone();
page.on_dialog(move |dialog| {
let dtype = dialog_type_clone.clone();
async move {
*dtype.lock().await = Some(dialog.type_());
dialog.accept().await
}
})
.await;
page.locator("#alert")
.click()
.await
.expect("Failed to click button");
tokio::time::sleep(Duration::from_millis(200)).await;
let received_type = *dialog_type.lock().await;
assert!(
matches!(received_type, Some(DialogType::Alert)),
"Expected Alert dialog type"
);
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_dialog_accept_alert() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.set_content(ALERT_HTML)
.set()
.await
.expect("Failed to set content");
let accepted = Arc::new(Mutex::new(false));
let accepted_clone = accepted.clone();
page.on_dialog(move |dialog| {
let acc = accepted_clone.clone();
async move {
let result = dialog.accept().await;
*acc.lock().await = result.is_ok();
result
}
})
.await;
page.locator("#alert")
.click()
.await
.expect("Failed to click button");
tokio::time::sleep(Duration::from_millis(200)).await;
assert!(
*accepted.lock().await,
"Dialog should be accepted successfully"
);
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_dialog_confirm_event() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.set_content(CONFIRM_HTML)
.set()
.await
.expect("Failed to set content");
let dialog_type = Arc::new(Mutex::new(None::<DialogType>));
let dialog_type_clone = dialog_type.clone();
page.on_dialog(move |dialog| {
let dtype = dialog_type_clone.clone();
async move {
*dtype.lock().await = Some(dialog.type_());
dialog.accept().await
}
})
.await;
page.locator("#confirm")
.click()
.await
.expect("Failed to click button");
tokio::time::sleep(Duration::from_millis(200)).await;
let received_type = *dialog_type.lock().await;
assert!(
matches!(received_type, Some(DialogType::Confirm)),
"Expected Confirm dialog type"
);
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_dialog_accept_confirm_returns_true() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.set_content(CONFIRM_HTML)
.set()
.await
.expect("Failed to set content");
page.on_dialog(|dialog| async move { dialog.accept().await })
.await;
page.locator("#confirm")
.click()
.await
.expect("Failed to click button");
tokio::time::sleep(Duration::from_millis(300)).await;
let result: String = page
.evaluate(js! { document.getElementById("result").textContent })
.await
.expect("Failed to get result");
assert_eq!(result, "true", "Confirm should return true when accepted");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_dialog_dismiss_confirm_returns_false() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.set_content(CONFIRM_HTML)
.set()
.await
.expect("Failed to set content");
page.on_dialog(|dialog| async move { dialog.dismiss().await })
.await;
page.locator("#confirm")
.click()
.await
.expect("Failed to click button");
tokio::time::sleep(Duration::from_millis(300)).await;
let result: String = page
.evaluate(js! { document.getElementById("result").textContent })
.await
.expect("Failed to get result");
assert_eq!(
result, "false",
"Confirm should return false when dismissed"
);
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_dialog_auto_dismiss_when_no_listener() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.set_content(ALERT_HTML)
.set()
.await
.expect("Failed to set content");
page.locator("#alert")
.click()
.await
.expect("Failed to click button");
tokio::time::sleep(Duration::from_millis(200)).await;
let _title: String = page
.evaluate(js! { document.title || "no-title" })
.await
.expect("Page should still be responsive after auto-dismiss");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_dialog_auto_dismiss_multiple_alerts() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.set_content(ALERT_HTML)
.set()
.await
.expect("Failed to set content");
page.locator("#multiple-alerts")
.click()
.await
.expect("Failed to click button");
tokio::time::sleep(Duration::from_millis(500)).await;
let _title: String = page
.evaluate(js! { document.title || "no-title" })
.await
.expect("Page should still be responsive after multiple auto-dismisses");
browser.close().await.expect("Failed to close browser");
}