MCPcopy Create free account
hub / github.com/aeroxy/chrome-devtools-cli / click

Function click

src/commands/input.rs:82–144  ·  view source on GitHub ↗

Click an element identified by CSS selector.

(
    client: &mut CdpClient,
    session_id: &str,
    selector: &str,
)

Source from the content-addressed store, hash-verified

80
81/// Click an element identified by CSS selector.
82pub async fn click(
83 client: &mut CdpClient,
84 session_id: &str,
85 selector: &str,
86) -> Result<CommandResult> {
87 let initial_url = client.current_url(session_id).await?;
88 // Special handling for native <option> elements which don't always respond to mouse clicks
89 let escaped = serde_json::to_string(selector)?;
90 let check_expr = format!(
91 r#"(() => {{
92 const el = document.querySelector({escaped});
93 if (!el) return 'not_found';
94 if (el.tagName.toLowerCase() === 'option') {{
95 if (el.disabled) return 'option_disabled';
96 const select = el.closest('select');
97 if (!select) return 'option_no_select';
98 if (select.disabled) return 'select_disabled';
99 if (select.multiple) return 'select_multiple';
100
101 select.value = el.value;
102 select.dispatchEvent(new Event('input', {{bubbles: true}}));
103 select.dispatchEvent(new Event('change', {{bubbles: true}}));
104 return 'selected';
105 }}
106 return 'not_option';
107 }})()"#
108 );
109
110 let result = client
111 .send_to_target(
112 session_id,
113 "Runtime.evaluate",
114 json!({"expression": check_expr, "returnByValue": true}),
115 )
116 .await?;
117
118 if let Some(exception) = result.get("exceptionDetails") {
119 let text = exception["text"].as_str().unwrap_or("Unknown error");
120 let desc = exception["exception"]["description"]
121 .as_str()
122 .unwrap_or(text);
123 bail!("JavaScript error during click handling: {desc}");
124 }
125
126 let res_val = result["result"]["value"].as_str().unwrap_or("error");
127 match res_val {
128 "not_found" => bail!("Element not found: {selector}"),
129 "selected" => {
130 let new_url = client.current_url(session_id).await?;
131 Ok(CommandResult::output(format!("Selected option: {selector}"))
132 .with_navigated_to_if_changed(new_url, initial_url))
133 }
134 "option_disabled" => bail!("Cannot click disabled option: {selector}"),
135 "option_no_select" => bail!("Option element is not inside a select: {selector}"),
136 "select_disabled" => bail!("Cannot click option in disabled select: {selector}"),
137 "select_multiple" => bail!("Manual clicking on <option> is not supported for <select multiple>. Use `evaluate` to update selection instead: {selector}"),
138 "not_option" => {
139 let (x, y) = get_element_center(client, session_id, selector).await?;

Callers 2

run_directFunction · 0.85
inner_executeFunction · 0.85

Calls 5

get_element_centerFunction · 0.85
click_atFunction · 0.85
current_urlMethod · 0.80
send_to_targetMethod · 0.80

Tested by

no test coverage detected