Skip to content

Commit 169e7ea

Browse files
Add link mapping (#648)
* remove redundant static text children * prettier * changeset * add link mapping to TreeResult * changeset
1 parent ca5467d commit 169e7ea

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

Diff for: .changeset/petite-worms-punch.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@browserbasehq/stagehand": patch
3+
---
4+
5+
add mapping of node id -> url

Diff for: lib/a11y/utils.ts

+19
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ export async function buildHierarchicalTree(
165165
page?: StagehandPage,
166166
logger?: (logLine: LogLine) => void,
167167
): Promise<TreeResult> {
168+
// Map to store nodeId -> URL for only those nodes that do have a URL.
169+
const idToUrl: Record<string, string> = {};
170+
168171
// Map to store processed nodes for quick lookup
169172
const nodeMap = new Map<string, AccessibilityNode>();
170173
const iframe_list: AccessibilityNode[] = [];
@@ -178,6 +181,11 @@ export async function buildHierarchicalTree(
178181
return;
179182
}
180183

184+
const url = extractUrlFromAXNode(node);
185+
if (url) {
186+
idToUrl[node.nodeId] = url;
187+
}
188+
181189
const hasChildren = node.childIds && node.childIds.length > 0;
182190
const hasValidName = node.name && node.name.trim() !== "";
183191
const isInteractive =
@@ -250,6 +258,7 @@ export async function buildHierarchicalTree(
250258
tree: finalTree,
251259
simplified: simplifiedFormat,
252260
iframes: iframe_list,
261+
idToUrl: idToUrl,
253262
};
254263
}
255264

@@ -294,6 +303,7 @@ export async function getAccessibilityTree(
294303
backendDOMNodeId: node.backendDOMNodeId,
295304
parentId: node.parentId,
296305
childIds: node.childIds,
306+
properties: node.properties,
297307
};
298308
}),
299309
page,
@@ -493,6 +503,15 @@ function removeRedundantStaticTextChildren(
493503
return children;
494504
}
495505

506+
function extractUrlFromAXNode(axNode: AccessibilityNode): string | undefined {
507+
if (!axNode.properties) return undefined;
508+
const urlProp = axNode.properties.find((prop) => prop.name === "url");
509+
if (urlProp && urlProp.value && typeof urlProp.value.value === "string") {
510+
return urlProp.value.value.trim();
511+
}
512+
return undefined;
513+
}
514+
496515
export async function performPlaywrightMethod(
497516
stagehandPage: Page,
498517
logger: (logLine: LogLine) => void,

Diff for: types/context.ts

+15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ export interface AXNode {
1010
backendDOMNodeId?: number;
1111
parentId?: string;
1212
childIds?: string[];
13+
properties?: {
14+
name: string;
15+
value: {
16+
type: string;
17+
value?: string;
18+
};
19+
}[];
1320
}
1421

1522
export type AccessibilityNode = {
@@ -22,12 +29,20 @@ export type AccessibilityNode = {
2229
parentId?: string;
2330
nodeId?: string;
2431
backendDOMNodeId?: number;
32+
properties?: {
33+
name: string;
34+
value: {
35+
type: string;
36+
value?: string;
37+
};
38+
}[];
2539
};
2640

2741
export interface TreeResult {
2842
tree: AccessibilityNode[];
2943
simplified: string;
3044
iframes?: AccessibilityNode[];
45+
idToUrl: Record<string, string>;
3146
}
3247

3348
export interface EnhancedContext

0 commit comments

Comments
 (0)