Skip to content

Commit ca5467d

Browse files
remove redundant static text children (#647)
* remove redundant static text children * prettier * changeset
1 parent bf823a3 commit ca5467d

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

Diff for: .changeset/cute-kings-stare.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@browserbasehq/stagehand": patch
3+
---
4+
5+
collapse redundant text nodes into parent elements

Diff for: lib/a11y/utils.ts

+46-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ async function cleanStructuralNodes(
5454
cleanStructuralNodes(child, page, logger),
5555
);
5656
const resolvedChildren = await Promise.all(cleanedChildrenPromises);
57-
const cleanedChildren = resolvedChildren.filter(
57+
let cleanedChildren = resolvedChildren.filter(
5858
(child): child is AccessibilityNode => child !== null,
5959
);
6060

@@ -136,6 +136,17 @@ async function cleanStructuralNodes(
136136
}
137137
}
138138

139+
// rm redundant StaticText children
140+
cleanedChildren = removeRedundantStaticTextChildren(node, cleanedChildren);
141+
142+
if (cleanedChildren.length === 0) {
143+
if (node.role === "generic" || node.role === "none") {
144+
return null;
145+
} else {
146+
return { ...node, children: [] };
147+
}
148+
}
149+
139150
// 6) Return the updated node.
140151
// If it has children, update them; otherwise keep it as-is.
141152
return cleanedChildren.length > 0
@@ -448,6 +459,40 @@ export async function findScrollableElementIds(
448459
return scrollableBackendIds;
449460
}
450461

462+
/**
463+
* Removes any StaticText children whose combined text equals the parent's name.
464+
* This is most often used to avoid duplicating a link's accessible name in separate child nodes.
465+
*
466+
* @param parent The parent accessibility node whose `.name` we check.
467+
* @param children The parent's current children list, typically after cleaning.
468+
* @returns A filtered list of children with redundant StaticText nodes removed.
469+
*/
470+
function removeRedundantStaticTextChildren(
471+
parent: AccessibilityNode,
472+
children: AccessibilityNode[],
473+
): AccessibilityNode[] {
474+
if (!parent.name) {
475+
return children;
476+
}
477+
478+
const parentName = parent.name.replace(/\s+/g, " ").trim();
479+
480+
// Gather all StaticText children and combine their text
481+
const staticTextChildren = children.filter(
482+
(child) => child.role === "StaticText" && child.name,
483+
);
484+
const combinedChildText = staticTextChildren
485+
.map((child) => child.name!.replace(/\s+/g, " ").trim())
486+
.join("");
487+
488+
// If the combined text exactly matches the parent's name, remove those child nodes
489+
if (combinedChildText === parentName) {
490+
return children.filter((child) => child.role !== "StaticText");
491+
}
492+
493+
return children;
494+
}
495+
451496
export async function performPlaywrightMethod(
452497
stagehandPage: Page,
453498
logger: (logLine: LogLine) => void,

0 commit comments

Comments
 (0)