diff --git a/src/browser/interactive.zig b/src/browser/interactive.zig
index 5e0b36c20..5d4ac1322 100644
--- a/src/browser/interactive.zig
+++ b/src/browser/interactive.zig
@@ -222,8 +222,10 @@ fn walkInteractive(
if (!std.ascii.eqlIgnoreCase(r, rf)) continue;
}
- // Names walk labels and text; filter on role first.
- const name = (try axn.getName(frame, arena, &label_index)) orelse try getTextContent(node, arena);
+ // Names walk labels and text; filter on role first. Role-less elements
+ // (listener/tabindex only) sit outside AccName; their text is the only handle.
+ const name = try axn.getName(frame, arena, &label_index) orelse
+ if (role == null) try getTextContent(node, arena) else null;
if (filter.name) |nf| {
const n = name orelse continue;
if (std.ascii.indexOfIgnoreCase(n, nf) == null) continue;
@@ -516,6 +518,24 @@ test "browser.interactive: an element with no role keeps its text as name" {
try testing.expectEqual("Open menu", elements[0].name.?);
}
+test "browser.interactive: an element with a role takes only its accessible name" {
+ const elements = try testInteractive(
+ \\
+ \\
+ \\More