豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit f763da2

Browse files
authored
fix: simplify focus state management (#1063)
Simplify focus management by emulating focused state for all pages. This is especially useful in the new multi agent use case.
1 parent 9628dab commit f763da2

File tree

5 files changed

+6
-485
lines changed

5 files changed

+6
-485
lines changed

src/McpContext.ts

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,7 @@ import {Locator} from './third_party/index.js';
3434
import {PredefinedNetworkConditions} from './third_party/index.js';
3535
import {listPages} from './tools/pages.js';
3636
import {CLOSE_PAGE_ERROR} from './tools/ToolDefinition.js';
37-
import type {
38-
Context,
39-
DevToolsData,
40-
ContextPage,
41-
} from './tools/ToolDefinition.js';
37+
import type {Context, DevToolsData} from './tools/ToolDefinition.js';
4238
import type {TraceResult} from './trace-processing/parse.js';
4339
import type {
4440
EmulationSettings,
@@ -116,7 +112,6 @@ export class McpContext implements Context {
116112
#isRunningTrace = false;
117113
#screenRecorderData: {recorder: ScreenRecorder; filePath: string} | null =
118114
null;
119-
#focusedPagePerContext = new Map<BrowserContext, Page>();
120115

121116
#nextPageId = 1;
122117

@@ -302,10 +297,6 @@ export class McpContext implements Context {
302297
page.dispose();
303298
this.#mcpPages.delete(page.pptrPage);
304299
}
305-
const ctx = page.pptrPage.browserContext();
306-
if (this.#focusedPagePerContext.get(ctx) === page.pptrPage) {
307-
this.#focusedPagePerContext.delete(ctx);
308-
}
309300
await page.pptrPage.close({runBeforeUnload: false});
310301
}
311302

@@ -499,38 +490,9 @@ export class McpContext implements Context {
499490
return this.#selectedPage?.pptrPage === page;
500491
}
501492

502-
assertPageIsFocused(pageToCheck: Page | ContextPage): void {
503-
const page = 'pptrPage' in pageToCheck ? pageToCheck.pptrPage : pageToCheck;
504-
const ctx = page.browserContext();
505-
const focused = this.#focusedPagePerContext.get(ctx);
506-
if (focused && focused !== page) {
507-
const targetId = this.#mcpPages.get(page)?.id ?? '?';
508-
const focusedId = this.#mcpPages.get(focused)?.id ?? '?';
509-
throw new Error(
510-
`Page ${targetId} is not the active page in its browser context (page ${focusedId} is). ` +
511-
`Call select_page with pageId ${targetId} first.`,
512-
);
513-
}
514-
}
515-
516493
selectPage(newPage: McpPage): void {
517-
const ctx = newPage.pptrPage.browserContext();
518-
const oldFocused = this.#focusedPagePerContext.get(ctx);
519-
if (
520-
oldFocused &&
521-
oldFocused !== newPage.pptrPage &&
522-
!oldFocused.isClosed()
523-
) {
524-
void oldFocused.emulateFocusedPage(false).catch(error => {
525-
this.logger('Error turning off focused page emulation', error);
526-
});
527-
}
528-
this.#focusedPagePerContext.set(ctx, newPage.pptrPage);
529494
this.#selectedPage = newPage;
530495
this.#updateSelectedPageTimeouts();
531-
void newPage.pptrPage.emulateFocusedPage(true).catch(error => {
532-
this.logger('Error turning on focused page emulation', error);
533-
});
534496
}
535497

536498
#updateSelectedPageTimeouts() {
@@ -606,6 +568,10 @@ export class McpContext implements Context {
606568
if (!mcpPage) {
607569
mcpPage = new McpPage(page, this.#nextPageId++);
608570
this.#mcpPages.set(page, mcpPage);
571+
// We emulate a focused page for all pages to support multi-agent workflows.
572+
void page.emulateFocusedPage(true).catch(error => {
573+
this.logger('Error turning on focused page emulation', error);
574+
});
609575
}
610576
mcpPage.isolatedContextName = isolatedContextNames.get(page);
611577
}
@@ -618,12 +584,6 @@ export class McpContext implements Context {
618584
this.#mcpPages.delete(page);
619585
}
620586
}
621-
// Prune stale #focusedPagePerContext entries.
622-
for (const [ctx, page] of this.#focusedPagePerContext) {
623-
if (!currentPages.has(page)) {
624-
this.#focusedPagePerContext.delete(ctx);
625-
}
626-
}
627587

628588
this.#pages = allPages.filter(page => {
629589
return (

src/tools/ToolDefinition.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ export type Context = Readonly<{
142142
): Promise<ContextPage>;
143143
closePage(pageId: number): Promise<void>;
144144
selectPage(page: ContextPage): void;
145-
assertPageIsFocused(page: Page): void;
146145
restoreEmulation(page: ContextPage): Promise<void>;
147146
emulate(
148147
options: {

src/tools/input.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ export const clickAt = definePageTool({
9898
},
9999
handler: async (request, response, context) => {
100100
const page = request.page;
101-
context.assertPageIsFocused(page.pptrPage);
102101
await context.waitForEventsAfterAction(async () => {
103102
await page.pptrPage.mouse.click(request.params.x, request.params.y, {
104103
clickCount: request.params.dblClick ? 2 : 1,
@@ -263,7 +262,6 @@ export const typeText = definePageTool({
263262
},
264263
handler: async (request, response, context) => {
265264
const page = request.page;
266-
context.assertPageIsFocused(page.pptrPage);
267265
await context.waitForEventsAfterAction(async () => {
268266
await page.pptrPage.keyboard.type(request.params.text);
269267
if (request.params.submitKey) {
@@ -416,7 +414,6 @@ export const pressKey = definePageTool({
416414
},
417415
handler: async (request, response, context) => {
418416
const page = request.page;
419-
context.assertPageIsFocused(page.pptrPage);
420417
const tokens = parseKey(request.params.key);
421418
const [key, ...modifiers] = tokens;
422419

0 commit comments

Comments
 (0)