getElementHierarchy
Retrieve the hierarchical structure of webpage elements to analyze parent-child relationships and DOM organization for web automation tasks.
Instructions
Get the hierarchical structure of page elements with parent-child relationships
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| selector | No | CSS selector for root element (default: 'body') | |
| maxDepth | No | Maximum depth to traverse (-1 for unlimited, default: 3) | |
| includeText | No | Include text content of elements (default: false) | |
| includeAttributes | No | Include element attributes (default: false) |
Implementation Reference
- src/controllers/playwright.ts:519-602 (handler)The primary handler function that implements the getElementHierarchy tool logic by evaluating JavaScript in the browser to traverse and build the DOM element hierarchy.async getElementHierarchy( selector: string = 'body', maxDepth: number = 3, includeText: boolean = false, includeAttributes: boolean = false ): Promise<any> { try { if (!this.isInitialized()) { throw new Error('Browser not initialized'); } this.log('Getting element hierarchy', { selector, maxDepth, includeText, includeAttributes }); const hierarchy = await this.state.page?.evaluate((args: { selector: string, maxDepth: number, includeText: boolean, includeAttributes: boolean }) => { const { selector, maxDepth, includeText, includeAttributes } = args; function getElementInfo(element: Element) { const info: any = { tagName: element.tagName.toLowerCase(), id: element.id || undefined, className: element.className || undefined, children: [] }; if (includeText && element.textContent) { // Get only direct text content, not from children const directText = Array.from(element.childNodes) .filter(node => node.nodeType === Node.TEXT_NODE) .map(node => node.textContent?.trim()) .filter(text => text) .join(' '); if (directText) { info.text = directText; } } if (includeAttributes && element.attributes.length > 0) { info.attributes = {}; for (let i = 0; i < element.attributes.length; i++) { const attr = element.attributes[i]; if (attr.name !== 'id' && attr.name !== 'class') { info.attributes[attr.name] = attr.value; } } } return info; } function traverseElement(element: Element, currentDepth: number): any { const elementInfo = getElementInfo(element); if (currentDepth < maxDepth || maxDepth === -1) { const children = Array.from(element.children); elementInfo.children = children.map(child => traverseElement(child, currentDepth + 1) ); } else if (element.children.length > 0) { elementInfo.childrenCount = element.children.length; } return elementInfo; } const rootElement = document.querySelector(selector); if (!rootElement) { throw new Error(`Element not found: ${selector}`); } return traverseElement(rootElement, 0); }, { selector, maxDepth, includeText, includeAttributes }); this.log('Element hierarchy retrieved'); return hierarchy; } catch (error: any) { console.error('Get element hierarchy error:', error); throw new BrowserError('Failed to get element hierarchy', 'Check if the selector exists'); } }
- src/server.ts:233-258 (schema)The Tool object definition including name, description, and detailed inputSchema for parameter validation in the MCP protocol.const GET_ELEMENT_HIERARCHY_TOOL: Tool = { name: "getElementHierarchy", description: "Get the hierarchical structure of page elements with parent-child relationships", inputSchema: { type: "object", properties: { selector: { type: "string", description: "CSS selector for root element (default: 'body')" }, maxDepth: { type: "number", description: "Maximum depth to traverse (-1 for unlimited, default: 3)" }, includeText: { type: "boolean", description: "Include text content of elements (default: false)" }, includeAttributes: { type: "boolean", description: "Include element attributes (default: false)" } }, required: [] } };
- src/server.ts:533-533 (registration)Registration of the getElementHierarchy tool in the main tools object passed to the MCP server capabilities.getElementHierarchy: GET_ELEMENT_HIERARCHY_TOOL,
- src/server.ts:760-770 (registration)MCP server request handler (switch case) that dispatches calls to the controller's getElementHierarchy method and formats the response.case 'getElementHierarchy': { const hierarchy = await playwrightController.getElementHierarchy( args.selector as string || 'body', args.maxDepth as number || 3, args.includeText as boolean || false, args.includeAttributes as boolean || false ); return { content: [{ type: "text", text: JSON.stringify(hierarchy, null, 2) }] }; }