1use chromedriver_api::{ prelude::*, Session };
2use tokio::time::{ sleep, Duration };
3use macron::path;
4
5#[tokio::main]
6async fn main() -> Result<()> {
7 let free_port = std::net::TcpListener::bind("127.0.0.1:0")?.local_addr()?.port();
8 let chrome_path = path!("bin/chromedriver/chromedriver.exe");
9 let session_path = path!("%/ChromeDriver/Profile");
10
11 let session = Session::run(
12 free_port,
13 chrome_path,
14 Some(session_path),
15 false ).await?;
17 println!("[INFO]: session launched on port [{free_port}]");
18
19 let tab1 = session.open("https://example.com").await?;
21 let tab1 = tab1.lock().await;
22 println!("[INFO]: tab1: form page loaded");
23
24 sleep(Duration::from_secs(2)).await;
25
26 let tab2 = session.open("https://html-online.com/editor/").await?;
28 let tab2 = tab2.lock().await;
29 tab2.inject::<()>(r#"
30 window.addEventListener('beforeunload', function(e) {
31 e.preventDefault();
32 e.returnValue = 'Are you sure?';
33 return 'Are you sure?';
34 });
35 "#).await?;
36 println!("[INFO]: tab2: beforeunload hook installed");
37
38 sleep(Duration::from_secs(2)).await;
39
40 let tab3 = session.open("https://httpbin.org/html").await?;
42 let tab3 = tab3.lock().await;
43 tab3.inject::<()>(r#"
44 // Delayed alert 3s after close attempt
45 setTimeout(() => {
46 alert('Late alert!');
47 }, 3000);
48
49 // Confirm after 1s
50 setTimeout(() => {
51 if (confirm('Close tab?')) {
52 console.log('User confirmed');
53 }
54 }, 1000);
55 "#).await?;
56 println!("[INFO]: tab3: delayed alert + confirm injected");
57
58 sleep(Duration::from_secs(2)).await;
59
60 println!("\n[TEST]: Closing tab1 (should be ✅ fast)");
61 tab1.close().await?;
62 println!("[✅] tab1 closed successfully\n");
63
64 println!("[TEST]: Closing tab2 (should trigger ⚠️ beforeunload retry)");
65 tab2.close().await?;
66 println!("[✅] tab2 closed (retry worked)\n");
67
68 println!("[TEST]: Closing tab3 (should trigger ⚠️ alert/confirm retries)");
69 tab3.close().await?;
70 println!("[✅] tab3 closed (multiple retries succeeded)\n");
71
72 let handles = session.get_tabs_ids().await?;
74 println!("[INFO]: Remaining tabs: {}", handles.len());
75
76 sleep(Duration::from_secs(1)).await;
77
78 session.close().await?;
79 println!("[INFO]: Session closed");
80
81 Ok(())
82}