axtree: add improvements

This commit is contained in:
Pierre Tachoire
2026-01-05 15:59:55 +01:00
parent 9775b39a8d
commit b6df85da7a
2 changed files with 88 additions and 5 deletions

View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<title>Test Page</title>
</head>
<body>
<h1>Test Page</h1>
<nav>
<a href="/page1" id="link1">First Link</a>
<a href="/page2" id="link2">Second Link</a>
</nav>
<form id="testForm" action="/submit" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username" placeholder="Enter username">
<label for="email">Email:</label>
<input type="email" id="email" name="email" placeholder="Enter email">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<button type="submit">Submit</button>
</form>
</body>
</html>

View File

@@ -267,6 +267,7 @@ pub const Writer = struct {
// Children // Children
const skip_children = axn.ignoreChildren(); const skip_children = axn.ignoreChildren();
const skip_text = ignoreText(axn.dom);
try w.objectField("childIds"); try w.objectField("childIds");
try w.beginArray(); try w.beginArray();
@@ -275,7 +276,7 @@ pub const Writer = struct {
var it = n.childrenIterator(); var it = n.childrenIterator();
while (it.next()) |child| { while (it.next()) |child| {
// ignore non-elements or text. // ignore non-elements or text.
if (child.is(DOMNode.Element.Html) == null and child.is(DOMNode.CData.Text) == null) { if (child.is(DOMNode.Element.Html) == null and (child.is(DOMNode.CData.Text) == null or skip_text)) {
continue; continue;
} }
@@ -619,13 +620,41 @@ fn isHidden(elt: *DOMNode.Element) bool {
fn ignoreText(node: *DOMNode) bool { fn ignoreText(node: *DOMNode) bool {
if (node.is(DOMNode.Element.Html) == null) { if (node.is(DOMNode.Element.Html) == null) {
return false; return true;
} }
const elt = node.as(DOMNode.Element); const elt = node.as(DOMNode.Element);
// Only ignore text for structural/container elements that typically
// don't have meaningful direct text content
return switch (elt.getTag()) { return switch (elt.getTag()) {
.p => false, // Structural containers
else => true, .html,
.body,
.head,
// Lists (text is in li elements, not in ul/ol)
.ul,
.ol,
.menu,
// Tables (text is in cells, not in table/tbody/thead/tfoot/tr)
.table,
.thead,
.tbody,
.tfoot,
.tr,
// Form containers
.form,
.fieldset,
.datalist,
// Grouping elements
.details,
.figure,
// Other containers
.select,
.optgroup,
.colgroup,
=> true,
// All other elements should include their text content
else => false,
}; };
} }
@@ -792,7 +821,7 @@ test "AXNode: writer" {
var registry = Node.Registry.init(testing.allocator); var registry = Node.Registry.init(testing.allocator);
defer registry.deinit(); defer registry.deinit();
var page = try testing.pageTest("cdp/dom1.html"); var page = try testing.pageTest("cdp/dom3.html");
defer page._session.removePage(); defer page._session.removePage();
var doc = page.window._document; var doc = page.window._document;
@@ -803,4 +832,33 @@ test "AXNode: writer" {
.page = page, .page = page,
}, .{}); }, .{});
defer testing.allocator.free(json); defer testing.allocator.free(json);
// Check that the document node is present with proper structure
const parsed = try std.json.parseFromSlice(std.json.Value, testing.allocator, json, .{});
defer parsed.deinit();
const nodes = parsed.value.array.items;
try testing.expect(nodes.len > 0);
// First node should be the document
const doc_node = nodes[0].object;
try testing.expectEqual(1, doc_node.get("nodeId").?.integer);
try testing.expectEqual(1, doc_node.get("backendDOMNodeId").?.integer);
try testing.expectEqual(false, doc_node.get("ignored").?.bool);
const role = doc_node.get("role").?.object;
try testing.expectEqual("role", role.get("type").?.string);
try testing.expectEqual("RootWebArea", role.get("value").?.string);
const name = doc_node.get("name").?.object;
try testing.expectEqual("computedString", name.get("type").?.string);
try testing.expectEqual("Test Page", name.get("value").?.string);
// Check properties array exists
const properties = doc_node.get("properties").?.array.items;
try testing.expect(properties.len >= 1);
// Check childIds array exists
const child_ids = doc_node.get("childIds").?.array.items;
try testing.expect(child_ids.len > 0);
} }