Skip to main content

game_test/
game_test.rs

1use clawser_browser::Browser;
2use chromiumoxide::cdp::browser_protocol::network::{
3    EnableParams, EventWebSocketCreated, EventWebSocketClosed,
4};
5use futures_util::StreamExt;
6
7fn api_url() -> String {
8    std::env::var("GAME_API_URL").unwrap_or_else(|_| "https://api.abb1211.com/endpoint/play".into())
9}
10fn api_token() -> String {
11    std::env::var("GAME_API_TOKEN").expect("Set GAME_API_TOKEN in .env or env var")
12}
13
14fn load_dotenv() {
15    for path in ["clawser-browser/.env", ".env"] {
16        if let Ok(content) = std::fs::read_to_string(path) {
17            for line in content.lines() {
18                let line = line.trim();
19                if line.is_empty() || line.starts_with('#') { continue; }
20                if let Some((k, v)) = line.split_once('=') {
21                    std::env::set_var(k.trim(), v.trim());
22                }
23            }
24            break;
25        }
26    }
27}
28
29#[tokio::main]
30async fn main() {
31    load_dotenv();
32    println!("=== Game Test + WS Detection ===\n");
33
34    // 1. Fetch game URL
35    println!("Fetching game URL...");
36    let client = reqwest::Client::new();
37    let resp = client
38        .post(api_url())
39        .header("Authorization", format!("Bearer {}", api_token()))
40        .header("Content-Type", "application/json")
41        .header("Accept", "application/json")
42        .body(r#"{"user_id": "beezsbee"}"#)
43        .send()
44        .await
45        .expect("API request failed");
46
47    let body: serde_json::Value = resp.json().await.expect("JSON parse failed");
48    let game_url = body["url"].as_str().expect("no 'url' in response");
49    println!("Game URL: {game_url}\n");
50
51    // 2. Launch browser
52    let browser = Browser::builder()
53        .headful()
54        .profile(42, 12345)
55        .build()
56        .await
57        .expect("browser launch failed");
58
59    // 3. Open blank page first so we can set up listeners before navigation
60    let page = browser.new_page("about:blank").await.expect("page failed");
61
62    // Enable network domain for WS events
63    page.cdp().execute(EnableParams::default()).await.expect("network enable failed");
64
65    // Set up WS event listeners
66    let mut ws_created = page.cdp().event_listener::<EventWebSocketCreated>().await.expect("listener failed");
67    let mut ws_closed = page.cdp().event_listener::<EventWebSocketClosed>().await.expect("listener failed");
68
69    // Spawn listener tasks
70    tokio::spawn(async move {
71        while let Some(ev) = ws_created.next().await {
72            println!("[WS CREATED] request_id={:?} url={}", ev.request_id, ev.url);
73        }
74    });
75
76    tokio::spawn(async move {
77        while let Some(ev) = ws_closed.next().await {
78            println!("[WS CLOSED]  request_id={:?}", ev.request_id);
79        }
80    });
81
82    // 4. Navigate to game (human simulation runs automatically)
83    println!("Navigating to game...");
84    page.navigate(game_url).await.expect("nav failed");
85
86    // 5. Wait and monitor
87    println!("Watching for WebSocket connections...\n");
88    loop {
89        tokio::time::sleep(std::time::Duration::from_secs(60)).await;
90    }
91}