browser-use-typescript
Version:
A TypeScript-based browser automation framework
218 lines • 7.56 kB
JavaScript
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