puppeteer-browser-agent
Version:
Puppeteer browser agent for use in AI agent systems
124 lines (107 loc) • 2.65 kB
text/typescript
import type { IAgentDriver } from "../agent";
import type { DebugOpts } from "../types";
export class ElementEvaluator {
element?: Element;
id: number;
selector: string;
role?: string | null = "null";
placeholder?: string;
textContent?: string;
type?: string;
value?: string;
href?: string;
title?: string;
driver: IAgentDriver;
debug: boolean;
opts: DebugOpts;
maxAttrLength = 32;
constructor(
driver: IAgentDriver,
element: any,
id: number,
selector: string,
opts: DebugOpts = {},
) {
this.driver = driver;
this.element = element;
this.id = id;
this.selector = selector;
this.debug = Boolean(opts.debug);
this.opts = opts;
}
evaluate() {
if (this.ignoreElement()) {
return;
}
this.configureElement();
return this.element;
}
protected configureElement() {
this.addMarkerClass();
this.externalRefElem();
this.elemRole();
this.formElement();
this.titledElement();
this.text();
}
protected get markerClass() {
return this.driver.markerClass(this.id);
}
protected addMarkerClass() {
this.element?.classList.add(this.markerClass);
}
protected elemRole() {
this.role = this.element?.role;
}
protected titledElement() {
const element = this.element as HTMLAnchorElement;
this.title = element.title;
}
protected externalRefElem() {
const element = this.element as HTMLAnchorElement;
this.href = this.sliceOff(element.href);
}
protected formElement() {
const element = this.element as HTMLFormElement;
const placeholder = element.placeholder;
this.type = element.type;
this.value = element.value;
this.placeholder = this.sliceOff(placeholder);
}
protected text() {
const textContent = this.textContent;
let title = this.title;
if (!textContent && title) {
title = this.sliceOff(title);
}
this.textContent = this.sliceOff(textContent, 200);
this.title = title;
}
protected sliceOff(text?: string, length?: number) {
const maxLength = this.maxAttrLength || length || 32;
return text && text.length > maxLength
? `${text.substring(0, maxLength)}[..]`
: text;
}
ignoreElement() {
const element = this.element;
if (!element) {
throw new Error("Missing element");
}
if (!element.matches(this.selector)) {
return true;
}
const tagName = element.tagName;
if (tagName === "BODY") {
return true;
}
const textContent = this.trimWhiteSpaces(element.textContent);
if (textContent === "" && !element.matches("select, input, textarea")) {
return true;
}
return false;
}
trimWhiteSpaces(textContent: string | null) {
return textContent ? textContent?.replace(/\s+/g, " ").trim() : "";
}
}