From 664789f5c6a6490adc10e6efbb97e156c9c1e303 Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Mon, 16 Mar 2026 18:26:22 -0500 Subject: [PATCH] fix: use DOM textContent as fallback name for cursor-interactive snapshot nodes (#859) Generic elements (e.g.
) with cursor:pointer/onclick have empty ARIA names because their text lives in StaticText children, which get filtered in interactive mode. Fall back to the JS-collected textContent so the text appears on the rendered tree line. Fixes e2e_snapshot_cursor_many_elements CI failure from #855. --- cli/src/native/snapshot.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/cli/src/native/snapshot.rs b/cli/src/native/snapshot.rs index 660f425..7a6196f 100644 --- a/cli/src/native/snapshot.rs +++ b/cli/src/native/snapshot.rs @@ -98,6 +98,7 @@ struct TreeNode { struct CursorElementInfo { kind: String, // "clickable", "focusable", "editable" hints: Vec, + text: String, // textContent from the DOM element (fallback when ARIA name is empty) } struct RoleNameTracker { @@ -571,12 +572,20 @@ async fn find_cursor_interactive_elements( hints.push("contenteditable".to_string()); } + let text = elem + .get("text") + .and_then(|v| v.as_str()) + .unwrap_or("") + .trim() + .to_string(); + if let Some(bid) = backend_node_id { map.insert( bid, CursorElementInfo { kind: kind.to_string(), hints, + text, }, ); } @@ -727,8 +736,16 @@ fn render_tree( let prefix = " ".repeat(indent); let mut line = format!("{}- {}", prefix, role); - if !node.name.is_empty() { - line.push_str(&format!(" \"{}\"", node.name)); + // Use ARIA name if available, otherwise fall back to cursor-interactive textContent + let display_name = if !node.name.is_empty() { + &node.name + } else if let Some(ref ci) = node.cursor_info { + &ci.text + } else { + &node.name + }; + if !display_name.is_empty() { + line.push_str(&format!(" \"{}\"", display_name)); } // Properties