(
client: &mut CdpClient,
session_id: &str,
selector: &str,
)
| 5 | use crate::result::CommandResult; |
| 6 | |
| 7 | async fn get_element_center( |
| 8 | client: &mut CdpClient, |
| 9 | session_id: &str, |
| 10 | selector: &str, |
| 11 | ) -> Result<(f64, f64)> { |
| 12 | let escaped = serde_json::to_string(selector)?; |
| 13 | let expr = format!( |
| 14 | r#"(() => {{ |
| 15 | const el = document.querySelector({escaped}); |
| 16 | if (!el) return JSON.stringify({{error: "Element not found: " + {escaped}}}); |
| 17 | const rect = el.getBoundingClientRect(); |
| 18 | return JSON.stringify({{x: rect.x + rect.width/2, y: rect.y + rect.height/2}}); |
| 19 | }})()"# |
| 20 | ); |
| 21 | |
| 22 | let result = client |
| 23 | .send_to_target( |
| 24 | session_id, |
| 25 | "Runtime.evaluate", |
| 26 | json!({"expression": expr, "returnByValue": true}), |
| 27 | ) |
| 28 | .await?; |
| 29 | |
| 30 | if let Some(exception) = result.get("exceptionDetails") { |
| 31 | let text = exception["text"].as_str().unwrap_or("Unknown error"); |
| 32 | let desc = exception["exception"]["description"] |
| 33 | .as_str() |
| 34 | .unwrap_or(text); |
| 35 | bail!("JavaScript error evaluating element position: {desc}"); |
| 36 | } |
| 37 | |
| 38 | let val_str = result["result"]["value"] |
| 39 | .as_str() |
| 40 | .ok_or_else(|| anyhow::anyhow!("Failed to evaluate element position"))?; |
| 41 | |
| 42 | let val: serde_json::Value = serde_json::from_str(val_str)?; |
| 43 | if let Some(err) = val.get("error").and_then(|v| v.as_str()) { |
| 44 | bail!("{err}"); |
| 45 | } |
| 46 | |
| 47 | let x = val["x"] |
| 48 | .as_f64() |
| 49 | .ok_or_else(|| anyhow::anyhow!("Missing x coordinate"))?; |
| 50 | let y = val["y"] |
| 51 | .as_f64() |
| 52 | .ok_or_else(|| anyhow::anyhow!("Missing y coordinate"))?; |
| 53 | Ok((x, y)) |
| 54 | } |
| 55 | |
| 56 | async fn dispatch_mouse( |
| 57 | client: &mut CdpClient, |
no test coverage detected