Skip to content

Commit 2a437b9

Browse files
committed
use CDP listener instead of playwright
1 parent 2924d71 commit 2a437b9

File tree

2 files changed

+54
-32
lines changed

2 files changed

+54
-32
lines changed

lib/StagehandContext.ts

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import type {
22
BrowserContext as PlaywrightContext,
3+
CDPSession,
34
Page as PlaywrightPage,
45
} from "playwright";
56
import { Stagehand } from "./index";
67
import { StagehandPage } from "./StagehandPage";
78
import { Page } from "../types/page";
89
import { EnhancedContext } from "../types/context";
10+
import { Protocol } from "devtools-protocol";
911

1012
export class StagehandContext {
1113
private readonly stagehand: Stagehand;
@@ -84,20 +86,32 @@ export class StagehandContext {
8486
const existingPages = context.pages();
8587
for (const page of existingPages) {
8688
const stagehandPage = await instance.createStagehandPage(page);
89+
await instance.attachFrameNavigatedListener(page);
8790
// Set the first page as active
8891
if (!instance.activeStagehandPage) {
8992
instance.setActivePage(stagehandPage);
9093
}
9194
}
9295

9396
context.on("page", (pwPage) => {
94-
instance.handleNewPlaywrightPage(pwPage).catch((err) =>
95-
stagehand.logger({
96-
category: "context",
97-
message: `Failed to initialise new page: ${err}`,
98-
level: 0,
99-
}),
100-
);
97+
instance
98+
.attachFrameNavigatedListener(pwPage)
99+
.catch((err) =>
100+
stagehand.logger({
101+
category: "cdp",
102+
message: `Failed to attach frameNavigated listener: ${err}`,
103+
level: 0,
104+
}),
105+
)
106+
.finally(() =>
107+
instance.handleNewPlaywrightPage(pwPage).catch((err) =>
108+
stagehand.logger({
109+
category: "context",
110+
message: `Failed to initialise new page: ${err}`,
111+
level: 0,
112+
}),
113+
),
114+
);
101115
});
102116

103117
return instance;
@@ -156,4 +170,33 @@ export class StagehandContext {
156170
}
157171
this.setActivePage(stagehandPage);
158172
}
173+
174+
private async attachFrameNavigatedListener(
175+
pwPage: PlaywrightPage,
176+
): Promise<void> {
177+
const shPage = this.pageMap.get(pwPage);
178+
if (!shPage) return;
179+
const session: CDPSession = await this.intContext.newCDPSession(pwPage);
180+
await session.send("Page.enable");
181+
182+
pwPage.once("close", () => {
183+
this.unregisterFrameId(shPage.frameId);
184+
});
185+
186+
session.on(
187+
"Page.frameNavigated",
188+
(evt: Protocol.Page.FrameNavigatedEvent): void => {
189+
const { frame } = evt;
190+
191+
if (!frame.parentId) {
192+
const oldId = shPage.frameId;
193+
if (frame.id !== oldId) {
194+
if (oldId) this.unregisterFrameId(oldId);
195+
this.registerFrameId(frame.id, shPage);
196+
shPage.updateRootFrameId(frame.id);
197+
}
198+
}
199+
},
200+
);
201+
}
159202
}

lib/StagehandPage.ts

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ export class StagehandPage {
6262
return this.rootFrameId;
6363
}
6464

65+
public updateRootFrameId(newId: string): void {
66+
this.rootFrameId = newId;
67+
}
68+
6569
constructor(
6670
page: PlaywrightPage,
6771
stagehand: Stagehand,
@@ -434,31 +438,6 @@ ${scriptContent} \
434438

435439
this.intPage = new Proxy(page, handler) as unknown as Page;
436440
this.initialized = true;
437-
const { frameTree } =
438-
await this.sendCDP<Protocol.Page.GetFrameTreeResponse>(
439-
"Page.getFrameTree",
440-
);
441-
this.rootFrameId = frameTree.frame.id;
442-
this.intContext.registerFrameId(this.rootFrameId, this);
443-
444-
this.page.once("close", () => {
445-
this.intContext.unregisterFrameId(this.rootFrameId);
446-
});
447-
448-
this.page.on("framenavigated", async (frame) => {
449-
if (frame.parentFrame() === null) {
450-
const { frameTree: ft } =
451-
await this.sendCDP<Protocol.Page.GetFrameTreeResponse>(
452-
"Page.getFrameTree",
453-
);
454-
const newId = ft.frame.id;
455-
if (newId !== this.rootFrameId) {
456-
this.intContext.unregisterFrameId(this.rootFrameId);
457-
this.rootFrameId = newId;
458-
this.intContext.registerFrameId(this.rootFrameId, this);
459-
}
460-
}
461-
});
462441
return this;
463442
} catch (err: unknown) {
464443
if (err instanceof StagehandError || err instanceof StagehandAPIError) {

0 commit comments

Comments
 (0)