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

Commit 4cb5a17

Browse files
authored
refactor: remove page passing via context (#1061)
- removes several redundant getters on the context. - removes passing page instances via context.
1 parent d6c06c5 commit 4cb5a17

File tree

12 files changed

+234
-237
lines changed

12 files changed

+234
-237
lines changed

src/McpContext.ts

Lines changed: 42 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,6 @@ export class McpContext implements Context {
120120
null;
121121
#focusedPagePerContext = new Map<BrowserContext, Page>();
122122

123-
#requestPage?: ContextPage;
124-
125123
#nextPageId = 1;
126124

127125
#extensionServiceWorkerMap = new WeakMap<Target, string>();
@@ -196,17 +194,6 @@ export class McpContext implements Context {
196194
return context;
197195
}
198196

199-
// TODO: Refactor away mutable request state (e.g. per-request facade,
200-
// per-request context object, or another approach). Once resolved, the
201-
// global toolMutex could become per-BrowserContext for parallel execution.
202-
setRequestPage(page?: ContextPage): void {
203-
this.#requestPage = page;
204-
}
205-
206-
#resolveTargetPage(): Page {
207-
return this.#requestPage?.pptrPage ?? this.getSelectedPptrPage();
208-
}
209-
210197
resolveCdpRequestId(page: McpPage, cdpRequestId: string): number | undefined {
211198
if (!cdpRequestId) {
212199
this.logger('no network request');
@@ -250,20 +237,28 @@ export class McpContext implements Context {
250237
return;
251238
}
252239

253-
getNetworkRequests(includePreservedRequests?: boolean): HTTPRequest[] {
254-
const page = this.#resolveTargetPage();
255-
return this.#networkCollector.getData(page, includePreservedRequests);
240+
getNetworkRequests(
241+
page: McpPage,
242+
includePreservedRequests?: boolean,
243+
): HTTPRequest[] {
244+
return this.#networkCollector.getData(
245+
page.pptrPage,
246+
includePreservedRequests,
247+
);
256248
}
257249

258250
getConsoleData(
251+
page: McpPage,
259252
includePreservedMessages?: boolean,
260253
): Array<ConsoleMessage | Error | DevTools.AggregatedIssue | UncaughtError> {
261-
const page = this.#resolveTargetPage();
262-
return this.#consoleCollector.getData(page, includePreservedMessages);
254+
return this.#consoleCollector.getData(
255+
page.pptrPage,
256+
includePreservedMessages,
257+
);
263258
}
264259

265-
getDevToolsUniverse(): TargetUniverse | null {
266-
return this.#devtoolsUniverseManager.get(this.#resolveTargetPage());
260+
getDevToolsUniverse(page: McpPage): TargetUniverse | null {
261+
return this.#devtoolsUniverseManager.get(page.pptrPage);
267262
}
268263

269264
getConsoleMessageStableId(
@@ -273,15 +268,16 @@ export class McpContext implements Context {
273268
}
274269

275270
getConsoleMessageById(
271+
page: McpPage,
276272
id: number,
277273
): ConsoleMessage | Error | DevTools.AggregatedIssue | UncaughtError {
278-
return this.#consoleCollector.getById(this.#resolveTargetPage(), id);
274+
return this.#consoleCollector.getById(page.pptrPage, id);
279275
}
280276

281277
async newPage(
282278
background?: boolean,
283279
isolatedContextName?: string,
284-
): Promise<ContextPage> {
280+
): Promise<McpPage> {
285281
let page: Page;
286282
if (isolatedContextName !== undefined) {
287283
let ctx = this.#isolatedContexts.get(isolatedContextName);
@@ -316,15 +312,13 @@ export class McpContext implements Context {
316312
await page.close({runBeforeUnload: false});
317313
}
318314

319-
getNetworkRequestById(reqid: number): HTTPRequest {
320-
return this.#networkCollector.getById(this.#resolveTargetPage(), reqid);
315+
getNetworkRequestById(page: McpPage, reqid: number): HTTPRequest {
316+
return this.#networkCollector.getById(page.pptrPage, reqid);
321317
}
322318

323-
async restoreEmulation(targetPage?: Page) {
324-
const page = targetPage ?? this.getSelectedPptrPage();
325-
const mcpPage = this.#getMcpPage(page);
326-
const currentSetting = mcpPage.emulationSettings;
327-
await this.emulate(currentSetting, targetPage);
319+
async restoreEmulation(page: McpPage) {
320+
const currentSetting = page.emulationSettings;
321+
await this.emulate(currentSetting, page.pptrPage);
328322
}
329323

330324
async emulate(
@@ -440,30 +434,6 @@ export class McpContext implements Context {
440434
}
441435
}
442436

443-
getNetworkConditions(): string | null {
444-
return this.#getMcpPage(this.#resolveTargetPage()).networkConditions;
445-
}
446-
447-
getCpuThrottlingRate(): number {
448-
return this.#getMcpPage(this.#resolveTargetPage()).cpuThrottlingRate;
449-
}
450-
451-
getGeolocation(): GeolocationOptions | null {
452-
return this.#getMcpPage(this.#resolveTargetPage()).geolocation;
453-
}
454-
455-
getViewport(): Viewport | null {
456-
return this.#getMcpPage(this.#resolveTargetPage()).viewport;
457-
}
458-
459-
getUserAgent(): string | null {
460-
return this.#getMcpPage(this.#resolveTargetPage()).userAgent;
461-
}
462-
463-
getColorScheme(): 'dark' | 'light' | null {
464-
return this.#getMcpPage(this.#resolveTargetPage()).colorScheme;
465-
}
466-
467437
setIsRunningPerformanceTrace(x: boolean): void {
468438
this.#isRunningTrace = x;
469439
}
@@ -573,23 +543,20 @@ export class McpContext implements Context {
573543
}
574544

575545
#updateSelectedPageTimeouts() {
576-
const page = this.getSelectedPptrPage();
546+
const page = this.#getSelectedMcpPage();
577547
// For waiters 5sec timeout should be sufficient.
578548
// Increased in case we throttle the CPU
579-
const cpuMultiplier = this.getCpuThrottlingRate();
580-
page.setDefaultTimeout(DEFAULT_TIMEOUT * cpuMultiplier);
549+
const cpuMultiplier = page.cpuThrottlingRate;
550+
page.pptrPage.setDefaultTimeout(DEFAULT_TIMEOUT * cpuMultiplier);
581551
// 10sec should be enough for the load event to be emitted during
582552
// navigations.
583553
// Increased in case we throttle the network requests
584554
const networkMultiplier = getNetworkMultiplierFromString(
585-
this.getNetworkConditions(),
555+
page.networkConditions,
556+
);
557+
page.pptrPage.setDefaultNavigationTimeout(
558+
NAVIGATION_TIMEOUT * networkMultiplier,
586559
);
587-
page.setDefaultNavigationTimeout(NAVIGATION_TIMEOUT * networkMultiplier);
588-
}
589-
590-
getNavigationTimeout() {
591-
const page = this.#resolveTargetPage();
592-
return page.getDefaultNavigationTimeout();
593560
}
594561

595562
// Linear scan over per-page snapshots. The page count is small (typically
@@ -858,11 +825,10 @@ export class McpContext implements Context {
858825
return this.#mcpPages.get(page)?.devToolsPage;
859826
}
860827

861-
async getDevToolsData(): Promise<DevToolsData> {
828+
async getDevToolsData(page: McpPage): Promise<DevToolsData> {
862829
try {
863830
this.logger('Getting DevTools UI data');
864-
const selectedPage = this.#resolveTargetPage();
865-
const devtoolsPage = this.getDevToolsPage(selectedPage);
831+
const devtoolsPage = this.getDevToolsPage(page.pptrPage);
866832
if (!devtoolsPage) {
867833
this.logger('No DevTools page detected');
868834
return {};
@@ -896,21 +862,19 @@ export class McpContext implements Context {
896862
* Creates a text snapshot of a page.
897863
*/
898864
async createTextSnapshot(
865+
page: McpPage,
899866
verbose = false,
900867
devtoolsData: DevToolsData | undefined = undefined,
901-
targetPage?: Page,
902868
): Promise<void> {
903-
const page = targetPage ?? this.getSelectedPptrPage();
904-
const mcpPage = this.#getMcpPage(page);
905-
const rootNode = await page.accessibility.snapshot({
869+
const rootNode = await page.pptrPage.accessibility.snapshot({
906870
includeIframes: true,
907871
interestingOnly: !verbose,
908872
});
909873
if (!rootNode) {
910874
return;
911875
}
912876

913-
const {uniqueBackendNodeIdToMcpId} = mcpPage;
877+
const {uniqueBackendNodeIdToMcpId} = page;
914878

915879
const snapshotId = this.#nextSnapshotId++;
916880
// Iterate through the whole accessibility node tree and assign node ids that
@@ -961,12 +925,12 @@ export class McpContext implements Context {
961925
hasSelectedElement: false,
962926
verbose,
963927
};
964-
mcpPage.textSnapshot = snapshot;
965-
const data = devtoolsData ?? (await this.getDevToolsData());
928+
page.textSnapshot = snapshot;
929+
const data = devtoolsData ?? (await this.getDevToolsData(page));
966930
if (data?.cdpBackendNodeId) {
967931
snapshot.hasSelectedElement = true;
968932
snapshot.selectedElementUid = this.resolveCdpElementId(
969-
mcpPage,
933+
page,
970934
data?.cdpBackendNodeId,
971935
);
972936
}
@@ -1041,13 +1005,13 @@ export class McpContext implements Context {
10411005
action: () => Promise<unknown>,
10421006
options?: {timeout?: number},
10431007
): Promise<void> {
1044-
const page = this.getSelectedPptrPage();
1045-
const cpuMultiplier = this.getCpuThrottlingRate();
1008+
const page = this.#getSelectedMcpPage();
1009+
const cpuMultiplier = page.cpuThrottlingRate;
10461010
const networkMultiplier = getNetworkMultiplierFromString(
1047-
this.getNetworkConditions(),
1011+
page.networkConditions,
10481012
);
10491013
const waitForHelper = this.getWaitForHelper(
1050-
page,
1014+
page.pptrPage,
10511015
cpuMultiplier,
10521016
networkMultiplier,
10531017
);

src/McpResponse.ts

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,13 @@ export class McpResponse implements Response {
266266

267267
let snapshot: SnapshotFormatter | string | undefined;
268268
if (this.#snapshotParams) {
269+
if (!this.#page) {
270+
throw new Error('Response must have a page');
271+
}
269272
await context.createTextSnapshot(
273+
this.#page,
270274
this.#snapshotParams.verbose,
271275
this.#devToolsData,
272-
this.#snapshotParams.page?.pptrPage,
273276
);
274277
const textSnapshot = context.getTextSnapshot(
275278
this.#snapshotParams.page?.pptrPage,
@@ -290,7 +293,11 @@ export class McpResponse implements Response {
290293

291294
let detailedNetworkRequest: NetworkFormatter | undefined;
292295
if (this.#attachedNetworkRequestId) {
296+
if (!this.#page) {
297+
throw new Error(`Response must have an McpPage`);
298+
}
293299
const request = context.getNetworkRequestById(
300+
this.#page,
294301
this.#attachedNetworkRequestId,
295302
);
296303
const formatter = await NetworkFormatter.from(request, {
@@ -307,22 +314,24 @@ export class McpResponse implements Response {
307314
let detailedConsoleMessage: ConsoleFormatter | IssueFormatter | undefined;
308315

309316
if (this.#attachedConsoleMessageId) {
317+
if (!this.#page) {
318+
throw new Error(`Response must have an McpPage`);
319+
}
320+
310321
const message = context.getConsoleMessageById(
322+
this.#page,
311323
this.#attachedConsoleMessageId,
312324
);
313325
const consoleMessageStableId = this.#attachedConsoleMessageId;
314326
if ('args' in message || message instanceof UncaughtError) {
315327
const consoleMessage = message as ConsoleMessage | UncaughtError;
316-
const devTools = context.getDevToolsUniverse();
328+
const devTools = context.getDevToolsUniverse(this.#page);
317329
detailedConsoleMessage = await ConsoleFormatter.from(consoleMessage, {
318330
id: consoleMessageStableId,
319331
fetchDetailedData: true,
320332
devTools: devTools ?? undefined,
321333
});
322334
} else if (message instanceof DevTools.AggregatedIssue) {
323-
if (!this.#page) {
324-
throw new Error(`Response must have an McpPage`);
325-
}
326335
const formatter = new IssueFormatter(message, {
327336
id: consoleMessageStableId,
328337
requestIdResolver: context.resolveCdpRequestId.bind(
@@ -349,7 +358,12 @@ export class McpResponse implements Response {
349358
}
350359
let consoleMessages: Array<ConsoleFormatter | IssueFormatter> | undefined;
351360
if (this.#consoleDataOptions?.include) {
361+
if (!this.#page) {
362+
throw new Error(`Response must have an McpPage`);
363+
}
364+
const page = this.#page;
352365
let messages = context.getConsoleData(
366+
this.#page,
353367
this.#consoleDataOptions.includePreservedMessages,
354368
);
355369

@@ -374,7 +388,7 @@ export class McpResponse implements Response {
374388
context.getConsoleMessageStableId(item);
375389
if ('args' in item || item instanceof UncaughtError) {
376390
const consoleMessage = item as ConsoleMessage | UncaughtError;
377-
const devTools = context.getDevToolsUniverse();
391+
const devTools = context.getDevToolsUniverse(page);
378392
return await ConsoleFormatter.from(consoleMessage, {
379393
id: consoleMessageStableId,
380394
fetchDetailedData: false,
@@ -399,7 +413,11 @@ export class McpResponse implements Response {
399413

400414
let networkRequests: NetworkFormatter[] | undefined;
401415
if (this.#networkRequestsOptions?.include) {
416+
if (!this.#page) {
417+
throw new Error(`Response must have an McpPage`);
418+
}
402419
let requests = context.getNetworkRequests(
420+
this.#page,
403421
this.#networkRequestsOptions?.includePreservedRequests,
404422
);
405423

@@ -493,39 +511,38 @@ export class McpResponse implements Response {
493511
response.push(...this.#textResponseLines);
494512
}
495513

496-
const networkConditions = context.getNetworkConditions();
514+
const networkConditions = this.#page?.networkConditions;
497515
if (networkConditions) {
516+
const timeout = this.#page!.pptrPage.getDefaultNavigationTimeout();
498517
response.push(`## Network emulation`);
499518
response.push(`Emulating: ${networkConditions}`);
500-
response.push(
501-
`Default navigation timeout set to ${context.getNavigationTimeout()} ms`,
502-
);
519+
response.push(`Default navigation timeout set to ${timeout} ms`);
503520
structuredContent.networkConditions = networkConditions;
504-
structuredContent.navigationTimeout = context.getNavigationTimeout();
521+
structuredContent.navigationTimeout = timeout;
505522
}
506523

507-
const viewport = context.getViewport();
524+
const viewport = this.#page?.viewport;
508525
if (viewport) {
509526
response.push(`## Viewport emulation`);
510527
response.push(`Emulating viewport: ${JSON.stringify(viewport)}`);
511528
structuredContent.viewport = viewport;
512529
}
513530

514-
const userAgent = context.getUserAgent();
531+
const userAgent = this.#page?.userAgent;
515532
if (userAgent) {
516533
response.push(`## UserAgent emulation`);
517534
response.push(`Emulating userAgent: ${userAgent}`);
518535
structuredContent.userAgent = userAgent;
519536
}
520537

521-
const cpuThrottlingRate = context.getCpuThrottlingRate();
538+
const cpuThrottlingRate = this.#page?.cpuThrottlingRate ?? 1;
522539
if (cpuThrottlingRate > 1) {
523540
response.push(`## CPU emulation`);
524541
response.push(`Emulating: ${cpuThrottlingRate}x slowdown`);
525542
structuredContent.cpuThrottlingRate = cpuThrottlingRate;
526543
}
527544

528-
const colorScheme = context.getColorScheme();
545+
const colorScheme = this.#page?.colorScheme;
529546
if (colorScheme) {
530547
response.push(`## Color Scheme emulation`);
531548
response.push(`Emulating: ${colorScheme}`);

0 commit comments

Comments
 (0)