-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathutils.ts
96 lines (88 loc) · 2.83 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { ObserveResult, Page } from "@browserbasehq/stagehand";
import boxen from "boxen";
import { z } from "zod";
export function announce(message: string, title?: string) {
console.log(
boxen(message, {
padding: 1,
margin: 3,
title: title || "Stagehand",
})
);
}
/**
* Get an environment variable and throw an error if it's not found
* @param name - The name of the environment variable
* @returns The value of the environment variable
*/
export function getEnvVar(name: string, required = true): string | undefined {
const value = process.env[name];
if (!value && required) {
throw new Error(`${name} not found in environment variables`);
}
return value;
}
/**
* Validate a Zod schema against some data
* @param schema - The Zod schema to validate against
* @param data - The data to validate
* @returns Whether the data is valid against the schema
*/
export function validateZodSchema(schema: z.ZodTypeAny, data: unknown) {
try {
schema.parse(data);
return true;
} catch {
return false;
}
}
export async function drawObserveOverlay(page: Page, results: ObserveResult[]) {
// Convert single xpath to array for consistent handling
const xpathList = results.map((result) => result.selector);
// Filter out empty xpaths
const validXpaths = xpathList.filter((xpath) => xpath !== "xpath=");
await page.evaluate((selectors) => {
selectors.forEach((selector) => {
let element;
if (selector.startsWith("xpath=")) {
const xpath = selector.substring(6);
element = document.evaluate(
xpath,
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
).singleNodeValue;
} else {
element = document.querySelector(selector);
}
if (element instanceof HTMLElement) {
const overlay = document.createElement("div");
overlay.setAttribute("stagehandObserve", "true");
const rect = element.getBoundingClientRect();
overlay.style.position = "absolute";
overlay.style.left = rect.left + "px";
overlay.style.top = rect.top + "px";
overlay.style.width = rect.width + "px";
overlay.style.height = rect.height + "px";
overlay.style.backgroundColor = "rgba(255, 255, 0, 0.3)";
overlay.style.pointerEvents = "none";
overlay.style.zIndex = "10000";
document.body.appendChild(overlay);
}
});
}, validXpaths);
}
export async function clearOverlays(page: Page) {
// remove existing stagehandObserve attributes
await page.evaluate(() => {
const elements = document.querySelectorAll('[stagehandObserve="true"]');
elements.forEach((el) => {
const parent = el.parentNode;
while (el.firstChild) {
parent?.insertBefore(el.firstChild, el);
}
parent?.removeChild(el);
});
});
}