diff --git a/.changeset/shiny-windows-attack.md b/.changeset/shiny-windows-attack.md new file mode 100644 index 000000000..af7efd143 --- /dev/null +++ b/.changeset/shiny-windows-attack.md @@ -0,0 +1,5 @@ +--- +"@browserbasehq/stagehand": patch +--- + +remove debugDom diff --git a/lib/StagehandPage.ts b/lib/StagehandPage.ts index cf8d7a8e7..2d581ac00 100644 --- a/lib/StagehandPage.ts +++ b/lib/StagehandPage.ts @@ -149,10 +149,12 @@ export class StagehandPage { this.intPage = newStagehandPage.page; if (this.stagehand.debugDom) { - await this.intPage.evaluate( - (debugDom) => (window.showChunks = debugDom), - this.stagehand.debugDom, - ); + this.stagehand.log({ + category: "deprecation", + message: + "Warning: debugDom is not supported in this version of Stagehand", + level: 1, + }); } await this.intPage.waitForLoadState("domcontentloaded"); await this._waitForSettledDom(); @@ -268,10 +270,12 @@ export class StagehandPage { await this._refreshPageFromAPI(); } else { if (stagehand.debugDom) { - await target.evaluate( - (debugDom) => (window.showChunks = debugDom), - stagehand.debugDom, - ); + this.stagehand.log({ + category: "deprecation", + message: + "Warning: debugDom is not supported in this version of Stagehand", + level: 1, + }); } await target.waitForLoadState("domcontentloaded"); await this._waitForSettledDom(); @@ -400,48 +404,6 @@ export class StagehandPage { } } - public async startDomDebug() { - if (this.stagehand.debugDom) { - try { - await this.page - .evaluate(() => { - if (typeof window.debugDom === "function") { - window.debugDom(); - } else { - this.stagehand.log({ - category: "dom", - message: "debugDom is not defined", - level: 1, - }); - } - }) - .catch(() => {}); - } catch (e) { - this.stagehand.log({ - category: "dom", - message: "Error in startDomDebug", - level: 1, - auxiliary: { - error: { - value: e.message, - type: "string", - }, - trace: { - value: e.stack, - type: "string", - }, - }, - }); - } - } - } - - public async cleanupDomDebug() { - if (this.stagehand.debugDom) { - await this.page.evaluate(() => window.cleanupDebug()).catch(() => {}); - } - } - async act( actionOrOptions: string | ActOptions | ObserveResult, ): Promise { diff --git a/lib/dom/debug.ts b/lib/dom/debug.ts deleted file mode 100644 index 2bfaec863..000000000 --- a/lib/dom/debug.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { GlobalPageContainer } from "./GlobalPageContainer"; -import { getNodeFromXpath } from "./utils"; - -export async function debugDom() { - window.chunkNumber = 0; - - // 1) Build a container for the entire page - const container = new GlobalPageContainer(); - - // 2) Determine chunk size (e.g. container’s viewport height) - const chunkSize = container.getViewportHeight(); - - // 3) If we only want one chunk, - // define startOffset = chunkNumber * chunkSize, - // and set endOffset = startOffset => exactly 1 iteration - const startOffset = container.getScrollPosition(); - const endOffset = startOffset; - - // 4) BFS with collectAllDomChunks for exactly 1 chunk - const singleChunks = await container.collectDomChunks( - startOffset, - endOffset, - chunkSize, - false, - false, // Don't scroll back to top - container.getRootElement(), // BFS entire doc - ); - - // We expect exactly 1 chunk - const [singleChunk] = singleChunks; - if (!singleChunk) { - console.warn("No chunk was returned. Possibly empty doc?"); - return; - } - - // 5) Extract the multiSelectorMap and convert to old single‐string format - const multiSelectorMap = singleChunk.selectorMap; - const selectorMap = multiSelectorMapToSelectorMap(multiSelectorMap); - - drawChunk(selectorMap); -} - -function multiSelectorMapToSelectorMap( - multiSelectorMap: Record, -) { - return Object.fromEntries( - Object.entries(multiSelectorMap).map(([key, selectors]) => [ - Number(key), - selectors[0], - ]), - ); -} - -function drawChunk(selectorMap: Record) { - if (!window.showChunks) return; - cleanupMarkers(); - Object.values(selectorMap).forEach((selector) => { - const element = getNodeFromXpath(selector) as Element; - - if (element) { - let rect; - if (element.nodeType === Node.ELEMENT_NODE) { - rect = element.getBoundingClientRect(); - } else { - const range = document.createRange(); - range.selectNodeContents(element); - rect = range.getBoundingClientRect(); - } - const color = "grey"; - const overlay = document.createElement("div"); - overlay.style.position = "absolute"; - overlay.style.left = `${rect.left + window.scrollX}px`; - overlay.style.top = `${rect.top + window.scrollY}px`; - overlay.style.padding = "2px"; // Add 2px of padding to the overlay - - overlay.style.width = `${rect.width}px`; - overlay.style.height = `${rect.height}px`; - overlay.style.backgroundColor = color; - overlay.className = "stagehand-marker"; - overlay.style.opacity = "0.3"; - overlay.style.zIndex = "1000000000"; // Ensure it's above the element - overlay.style.border = "1px solid"; // Add a 1px solid border to the overlay - overlay.style.pointerEvents = "none"; // Ensure the overlay does not capture mouse events - document.body.appendChild(overlay); - } - }); -} - -async function cleanupDebug() { - cleanupMarkers(); -} - -function cleanupMarkers() { - const markers = document.querySelectorAll(".stagehand-marker"); - markers.forEach((marker) => { - marker.remove(); - }); -} - -window.debugDom = debugDom; -window.cleanupDebug = cleanupDebug; diff --git a/lib/dom/global.d.ts b/lib/dom/global.d.ts index dd2ca2e7d..ac898e18e 100644 --- a/lib/dom/global.d.ts +++ b/lib/dom/global.d.ts @@ -15,8 +15,6 @@ declare global { outputString: string; selectorMap: Record; }>; - debugDom: () => Promise; - cleanupDebug: () => void; createStagehandContainer: (obj: Window | HTMLElement) => StagehandContainer; waitForDomSettle: () => Promise; __playwright?: unknown; diff --git a/lib/dom/index.ts b/lib/dom/index.ts index 4f2ff8514..96b53216a 100644 --- a/lib/dom/index.ts +++ b/lib/dom/index.ts @@ -1,3 +1,2 @@ export * from "./process"; export * from "./utils"; -export * from "./debug"; diff --git a/lib/handlers/actHandler.ts b/lib/handlers/actHandler.ts index 2193ee53c..0d263e4a1 100644 --- a/lib/handlers/actHandler.ts +++ b/lib/handlers/actHandler.ts @@ -825,7 +825,6 @@ export class StagehandActHandler { }): Promise<{ success: boolean; message: string; action: string }> { try { await this.stagehandPage._waitForSettledDom(domSettleTimeoutMs); - await this.stagehandPage.startDomDebug(); if (timeoutMs && startTime) { const elapsedTime = Date.now() - startTime; @@ -916,8 +915,6 @@ export class StagehandActHandler { }, }); - await this.stagehandPage.cleanupDomDebug(); - if (!response) { if (chunksSeen.length + 1 < chunks.length) { chunksSeen.push(chunk); diff --git a/lib/handlers/extractHandler.ts b/lib/handlers/extractHandler.ts index 0f4916423..b66ebc19c 100644 --- a/lib/handlers/extractHandler.ts +++ b/lib/handlers/extractHandler.ts @@ -164,7 +164,6 @@ export class StagehandExtractHandler { private async extractPageText(): Promise<{ page_text?: string }> { await this.stagehandPage._waitForSettledDom(); - await this.stagehandPage.startDomDebug(); const originalDOM = await this.stagehandPage.page.evaluate(() => window.storeDOM(undefined), @@ -202,8 +201,6 @@ export class StagehandExtractHandler { containerDims.width, ); - await this.stagehandPage.cleanupDomDebug(); - const result = { page_text: formattedText }; return pageTextSchema.parse(result); } @@ -239,7 +236,6 @@ export class StagehandExtractHandler { // **1:** Wait for the DOM to settle and start DOM debugging await this.stagehandPage._waitForSettledDom(domSettleTimeoutMs); - await this.stagehandPage.startDomDebug(); const targetXpath = selector?.replace(/^xpath=/, "") ?? ""; @@ -364,9 +360,6 @@ export class StagehandExtractHandler { ...output } = extractionResponse; - // Clean up debug - await this.stagehandPage.cleanupDomDebug(); - // **11:** Handle the extraction response and log the results this.logger({ category: "extraction", @@ -439,7 +432,6 @@ export class StagehandExtractHandler { // **1:** Wait for the DOM to settle and start DOM debugging // This ensures the page is stable before extracting any data. await this.stagehandPage._waitForSettledDom(domSettleTimeoutMs); - await this.stagehandPage.startDomDebug(); // **2:** Call processDom() to handle chunk-based extraction // processDom determines which chunk of the page to process next. @@ -496,8 +488,6 @@ export class StagehandExtractHandler { ...output } = extractionResponse; - await this.stagehandPage.cleanupDomDebug(); - this.logger({ category: "extraction", message: "received extraction response", diff --git a/lib/handlers/observeHandler.ts b/lib/handlers/observeHandler.ts index 9b598b6ef..6e42dccfe 100644 --- a/lib/handlers/observeHandler.ts +++ b/lib/handlers/observeHandler.ts @@ -185,7 +185,6 @@ export class StagehandObserveHandler { }; }), ); - await this.stagehandPage.cleanupDomDebug(); this.logger({ category: "observation", diff --git a/types/stagehand.ts b/types/stagehand.ts index b419c6995..d297ab6af 100644 --- a/types/stagehand.ts +++ b/types/stagehand.ts @@ -12,6 +12,7 @@ export interface ConstructorParams { apiKey?: string; projectId?: string; verbose?: 0 | 1 | 2; + /** @deprecated Dom Debugging is no longer supported in this version of Stagehand. */ debugDom?: boolean; llmProvider?: LLMProvider; /** @deprecated Please use `localBrowserLaunchOptions` instead. That will override this. */