UNPKG

browser-use-typescript

Version:

A TypeScript-based browser automation framework

218 lines 7.56 kB
import { BrowserContext } from "../browser/playwrightBrowser/browserContext"; import { DOMElementNode } from "../domTypes/domClass"; import { createHash } from "crypto"; function sha256(data) { return createHash('sha256').update(data).digest('hex'); } /** * Hash of the dom element to be used as a unique identifier */ export class HashedDomElement { branchPathHash; attributesHash; xpathHash; constructor(branchPathHash, attributesHash, xpathHash) { this.branchPathHash = branchPathHash; this.attributesHash = attributesHash; this.xpathHash = xpathHash; } } /** * Represents a set of coordinates */ export class Coordinates { x; y; constructor(x, y) { this.x = x; this.y = y; } } /** * Represents a set of coordinates for an element */ export class CoordinateSet { topLeft; topRight; bottomLeft; bottomRight; center; width; height; constructor(topLeft, topRight, bottomLeft, bottomRight, center, width, height) { this.topLeft = topLeft; this.topRight = topRight; this.bottomLeft = bottomLeft; this.bottomRight = bottomRight; this.center = center; this.width = width; this.height = height; } } /** * Represents information about the viewport */ export class ViewportInfo { scrollX; scrollY; width; height; constructor(width, height, scrollX, scrollY) { this.scrollX = scrollX; this.scrollY = scrollY; this.width = width; this.height = height; } } /** * Represents a DOM history element */ export class DOMHistoryElement { tagName; xpath; highlightIndex; entireParentBranchPath; attributes; shadowRoot; cssSelector; pageCoordinates; viewportCoordinates; viewportInfo; constructor(tagName, xpath, highlightIndex, entireParentBranchPath, attributes, shadowRoot = false, cssSelector, pageCoordinates, viewportCoordinates, viewportInfo) { this.tagName = tagName; this.xpath = xpath; this.highlightIndex = highlightIndex; this.entireParentBranchPath = entireParentBranchPath; this.attributes = attributes; this.shadowRoot = shadowRoot; this.cssSelector = cssSelector; this.pageCoordinates = pageCoordinates; this.viewportCoordinates = viewportCoordinates; this.viewportInfo = viewportInfo; } /** * Converts the DOM history element to a dictionary */ toDict() { const pageCoordinates = this.pageCoordinates ? this.pageCoordinates : null; const viewportCoordinates = this.viewportCoordinates ? this.viewportCoordinates : null; const viewportInfo = this.viewportInfo ? this.viewportInfo : null; return { tagName: this.tagName, xpath: this.xpath, highlightIndex: this.highlightIndex, entireParentBranchPath: this.entireParentBranchPath, attributes: this.attributes, shadowRoot: this.shadowRoot, cssSelector: this.cssSelector, pageCoordinates, viewportCoordinates, viewportInfo, }; } } /** * Processor for the DOM history tree */ export class HistoryTreeProcessor { /** * Converts a DOM element to a DOM history element */ static async convertDomElementToHistoryElement(domElement) { const parentBranchPath = HistoryTreeProcessor.getParentBranchPath(domElement); const cssSelector = await new BrowserContext()._enhanced_css_selector_for_element(domElement); return new DOMHistoryElement(domElement.tagName, domElement.xpath, domElement.highlightIndex ?? undefined, parentBranchPath, domElement.attributes, domElement.shadowRoot, cssSelector, domElement.pageCoordinates ?? undefined, domElement.viewportCoordinates ?? undefined, domElement.viewportInfo ?? undefined); } /** * Finds a DOM history element in the DOM tree */ static findHistoryElementInTree(domHistoryElement, tree) { const hashedDomHistoryElement = HistoryTreeProcessor.hashDomHistoryElement(domHistoryElement); function processNode(node) { if (node.highlightIndex !== undefined) { const hashedNode = HistoryTreeProcessor.hashDomElement(node); if (hashedNode === hashedDomHistoryElement) { return node; } } for (const child of node.children) { if (child instanceof DOMElementNode) { const result = processNode(child); if (result !== undefined) { return result; } } } return undefined; } return processNode(tree); } /** * Compares a DOM history element with a DOM element */ static compareHistoryElementAndDomElement(domHistoryElement, domElement) { const hashedDomHistoryElement = HistoryTreeProcessor.hashDomHistoryElement(domHistoryElement); const hashedDomElement = HistoryTreeProcessor.hashDomElement(domElement); return hashedDomHistoryElement === hashedDomElement; } /** * Hashes a DOM history element */ static hashDomHistoryElement(domHistoryElement) { const branchPathHash = HistoryTreeProcessor.parentBranchPathHash(domHistoryElement.entireParentBranchPath); const attributesHash = HistoryTreeProcessor.attributesHash(domHistoryElement.attributes); const xpathHash = HistoryTreeProcessor.xpathHash(domHistoryElement.xpath); return new HashedDomElement(branchPathHash, attributesHash, xpathHash); } /** * Hashes a DOM element */ static hashDomElement(domElement) { const parentBranchPath = HistoryTreeProcessor.getParentBranchPath(domElement); const branchPathHash = HistoryTreeProcessor.parentBranchPathHash(parentBranchPath); const attributesHash = HistoryTreeProcessor.attributesHash(domElement.attributes); const xpathHash = HistoryTreeProcessor.xpathHash(domElement.xpath); return new HashedDomElement(branchPathHash, attributesHash, xpathHash); } /** * Gets the parent branch path of a DOM element */ static getParentBranchPath(domElement) { const parents = []; let currentElement = domElement; while (currentElement.parent !== null) { parents.push(currentElement); currentElement = currentElement.parent; } parents.reverse(); return parents.map(parent => parent.tagName); } /** * Hashes a parent branch path */ static parentBranchPathHash(parentBranchPath) { const parentBranchPathString = parentBranchPath.join('/'); return sha256(parentBranchPathString).toString(); } /** * Hashes a set of attributes */ static attributesHash(attributes) { const attributesString = Object.entries(attributes).map(([key, value]) => `${key}=${value}`).join(''); return sha256(attributesString).toString(); } /** * Hashes an XPath */ static xpathHash(xpath) { return sha256(xpath).toString(); } /** * Hashes the text of a DOM element */ static textHash(domElement) { const textString = domElement.getAllTextTillNextClickableElement(); return sha256(textString).toString(); } } //# sourceMappingURL=historyTypes.js.map