browser_use/tools/
wait.rs

1use crate::error::{BrowserError, Result};
2use crate::tools::{Tool, ToolContext, ToolResult};
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5use std::time::Duration;
6
7#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
8pub struct WaitParams {
9    /// CSS selector to wait for
10    pub selector: String,
11
12    /// Timeout in milliseconds (default: 30000)
13    #[serde(default = "default_timeout")]
14    pub timeout_ms: u64,
15}
16
17fn default_timeout() -> u64 {
18    30000
19}
20
21#[derive(Default)]
22pub struct WaitTool;
23
24impl Tool for WaitTool {
25    type Params = WaitParams;
26
27    fn name(&self) -> &str {
28        "wait"
29    }
30
31    fn execute_typed(&self, params: WaitParams, context: &mut ToolContext) -> Result<ToolResult> {
32        let start = std::time::Instant::now();
33
34        context
35            .session
36            .tab()
37            .wait_for_element_with_custom_timeout(
38                &params.selector,
39                Duration::from_millis(params.timeout_ms),
40            )
41            .map_err(|e| {
42                BrowserError::Timeout(format!(
43                    "Element '{}' not found within {} ms: {}",
44                    params.selector, params.timeout_ms, e
45                ))
46            })?;
47
48        let elapsed = start.elapsed().as_millis() as u64;
49
50        Ok(ToolResult::success_with(serde_json::json!({
51            "selector": params.selector,
52            "found": true,
53            "elapsed_ms": elapsed
54        })))
55    }
56}