refactor: clean up McpContext getters (#2340)
This commit is contained in:
@@ -304,37 +304,6 @@ export class McpContext implements Context {
|
||||
await this.validatePath(outputPath);
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
resolveCdpRequestId(page: McpPage, cdpRequestId: string): number | undefined {
|
||||
if (!cdpRequestId) {
|
||||
this.logger?.('no network request');
|
||||
return;
|
||||
}
|
||||
const request = page.networkCollector.find(request => {
|
||||
// @ts-expect-error id is internal.
|
||||
return request.id === cdpRequestId;
|
||||
});
|
||||
if (!request) {
|
||||
this.logger?.('no network request for ' + cdpRequestId);
|
||||
return;
|
||||
}
|
||||
return page.networkCollector.getIdForResource(request);
|
||||
}
|
||||
|
||||
getNetworkRequests(
|
||||
page: McpPage,
|
||||
includePreservedRequests?: boolean,
|
||||
): HTTPRequest[] {
|
||||
return page.networkCollector.getData(includePreservedRequests);
|
||||
}
|
||||
|
||||
getConsoleData(
|
||||
page: McpPage,
|
||||
includePreservedMessages?: boolean,
|
||||
): Array<ConsoleMessage | Error | DevTools.AggregatedIssue | UncaughtError> {
|
||||
return page.consoleCollector.getData(includePreservedMessages);
|
||||
}
|
||||
|
||||
getDevToolsUniverse(page: McpPage): TargetUniverse | null {
|
||||
return this.#devtoolsUniverseManager.get(page.pptrPage);
|
||||
}
|
||||
@@ -345,13 +314,6 @@ export class McpContext implements Context {
|
||||
return (message as WithSymbolId<typeof message>)[stableIdSymbol] ?? -1;
|
||||
}
|
||||
|
||||
getConsoleMessageById(
|
||||
page: McpPage,
|
||||
id: number,
|
||||
): ConsoleMessage | Error | DevTools.AggregatedIssue | UncaughtError {
|
||||
return page.consoleCollector.getById(id);
|
||||
}
|
||||
|
||||
async newPage(
|
||||
background?: boolean,
|
||||
isolatedContextName?: string,
|
||||
@@ -384,10 +346,6 @@ export class McpContext implements Context {
|
||||
await page.pptrPage.close({runBeforeUnload: false});
|
||||
}
|
||||
|
||||
getNetworkRequestById(page: McpPage, reqid: number): HTTPRequest {
|
||||
return page.networkCollector.getById(reqid);
|
||||
}
|
||||
|
||||
async restoreEmulation(page: McpPage) {
|
||||
const currentSetting = page.emulationSettings;
|
||||
await this.emulate(currentSetting, page);
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
ConsoleCollector,
|
||||
NetworkCollector,
|
||||
type ListenerMap,
|
||||
type UncaughtError,
|
||||
} from './PageCollector.js';
|
||||
import {TextSnapshot} from './TextSnapshot.js';
|
||||
import type {
|
||||
@@ -18,6 +19,9 @@ import type {
|
||||
WebMCPTool,
|
||||
Protocol,
|
||||
Page,
|
||||
ConsoleMessage,
|
||||
HTTPRequest,
|
||||
DevTools,
|
||||
} from './third_party/index.js';
|
||||
import {takeSnapshot} from './tools/snapshot.js';
|
||||
import type {ToolGroups} from './tools/thirdPartyDeveloper.js';
|
||||
@@ -119,6 +123,42 @@ export class McpPage implements ContextPage {
|
||||
return this.pptrPage.webmcp.tools();
|
||||
}
|
||||
|
||||
resolveCdpRequestId(cdpRequestId: string): number | undefined {
|
||||
if (!cdpRequestId) {
|
||||
logger?.('no network request');
|
||||
return;
|
||||
}
|
||||
const request = this.networkCollector.find(request => {
|
||||
// @ts-expect-error id is internal.
|
||||
return request.id === cdpRequestId;
|
||||
});
|
||||
if (!request) {
|
||||
logger?.('no network request for ' + cdpRequestId);
|
||||
return;
|
||||
}
|
||||
return this.networkCollector.getIdForResource(request);
|
||||
}
|
||||
|
||||
getNetworkRequests(includePreservedRequests?: boolean): HTTPRequest[] {
|
||||
return this.networkCollector.getData(includePreservedRequests);
|
||||
}
|
||||
|
||||
getConsoleData(
|
||||
includePreservedMessages?: boolean,
|
||||
): Array<ConsoleMessage | Error | DevTools.AggregatedIssue | UncaughtError> {
|
||||
return this.consoleCollector.getData(includePreservedMessages);
|
||||
}
|
||||
|
||||
getConsoleMessageById(
|
||||
id: number,
|
||||
): ConsoleMessage | Error | DevTools.AggregatedIssue | UncaughtError {
|
||||
return this.consoleCollector.getById(id);
|
||||
}
|
||||
|
||||
getNetworkRequestById(reqid: number): HTTPRequest {
|
||||
return this.networkCollector.getById(reqid);
|
||||
}
|
||||
|
||||
get networkConditions(): string | null {
|
||||
return this.emulationSettings.networkConditions ?? null;
|
||||
}
|
||||
|
||||
+5
-12
@@ -610,8 +610,7 @@ export class McpResponse implements Response {
|
||||
if (!this.#page) {
|
||||
throw new Error(`Response must have an McpPage`);
|
||||
}
|
||||
const request = context.getNetworkRequestById(
|
||||
this.#page,
|
||||
const request = this.#page.getNetworkRequestById(
|
||||
this.#attachedNetworkRequestId,
|
||||
);
|
||||
const formatter = await NetworkFormatter.from(request, {
|
||||
@@ -634,8 +633,7 @@ export class McpResponse implements Response {
|
||||
throw new Error(`Response must have an McpPage`);
|
||||
}
|
||||
|
||||
const message = context.getConsoleMessageById(
|
||||
this.#page,
|
||||
const message = this.#page.getConsoleMessageById(
|
||||
this.#attachedConsoleMessageId,
|
||||
);
|
||||
const consoleMessageStableId = this.#attachedConsoleMessageId;
|
||||
@@ -650,10 +648,7 @@ export class McpResponse implements Response {
|
||||
} else if (message instanceof DevTools.AggregatedIssue) {
|
||||
const formatter = new IssueFormatter(message, {
|
||||
id: consoleMessageStableId,
|
||||
requestIdResolver: context.resolveCdpRequestId.bind(
|
||||
context,
|
||||
this.#page,
|
||||
),
|
||||
requestIdResolver: this.#page.resolveCdpRequestId.bind(this.#page),
|
||||
elementIdResolver: this.#page.textSnapshot?.resolveCdpElementId.bind(
|
||||
this.#page.textSnapshot,
|
||||
),
|
||||
@@ -707,8 +702,7 @@ export class McpResponse implements Response {
|
||||
if (!page) {
|
||||
throw new Error(`Response must have an McpPage`);
|
||||
}
|
||||
messages = context.getConsoleData(
|
||||
page,
|
||||
messages = page.getConsoleData(
|
||||
this.#consoleDataOptions.includePreservedMessages,
|
||||
);
|
||||
}
|
||||
@@ -764,8 +758,7 @@ export class McpResponse implements Response {
|
||||
if (!this.#page) {
|
||||
throw new Error(`Response must have an McpPage`);
|
||||
}
|
||||
let requests = context.getNetworkRequests(
|
||||
this.#page,
|
||||
let requests = this.#page.getNetworkRequests(
|
||||
this.#networkRequestsOptions?.includePreservedRequests,
|
||||
);
|
||||
|
||||
|
||||
@@ -232,13 +232,7 @@ export type Context = Readonly<{
|
||||
timeout?: number,
|
||||
mcpPage?: ContextPage,
|
||||
): Promise<Element>;
|
||||
/**
|
||||
* Returns a reqid for a cdpRequestId.
|
||||
*/
|
||||
resolveCdpRequestId(
|
||||
page: ContextPage,
|
||||
cdpRequestId: string,
|
||||
): number | undefined;
|
||||
|
||||
getScreenRecorder(): {recorder: ScreenRecorder; filePath: string} | null;
|
||||
setScreenRecorder(
|
||||
data: {recorder: ScreenRecorder; filePath: string} | null,
|
||||
@@ -312,6 +306,11 @@ export type ContextPage = Readonly<{
|
||||
getAXNodeByUid(uid: string): TextSnapshotNode | undefined;
|
||||
getElementByUid(uid: string): Promise<ElementHandle<Element>>;
|
||||
|
||||
/**
|
||||
* Returns a reqid for a cdpRequestId.
|
||||
*/
|
||||
resolveCdpRequestId(cdpRequestId: string): number | undefined;
|
||||
|
||||
getDialog(): Dialog | undefined;
|
||||
clearDialog(): void;
|
||||
throwIfDialogOpen(): void;
|
||||
|
||||
@@ -72,11 +72,11 @@ export const listNetworkRequests = definePageTool({
|
||||
},
|
||||
blockedByDialog: false,
|
||||
verifyFilesSchema: [],
|
||||
handler: async (request, response, context) => {
|
||||
handler: async (request, response) => {
|
||||
const data = await request.page.getDevToolsData();
|
||||
response.attachDevToolsData(data);
|
||||
const reqid = data?.cdpRequestId
|
||||
? context.resolveCdpRequestId(request.page, data.cdpRequestId)
|
||||
? request.page.resolveCdpRequestId(data.cdpRequestId)
|
||||
: undefined;
|
||||
response.setIncludeNetworkRequests(true, {
|
||||
pageSize: request.params.pageSize,
|
||||
@@ -117,7 +117,7 @@ export const getNetworkRequest = definePageTool({
|
||||
},
|
||||
blockedByDialog: true,
|
||||
verifyFilesSchema: ['requestFilePath', 'responseFilePath'],
|
||||
handler: async (request, response, context) => {
|
||||
handler: async (request, response) => {
|
||||
if (request.params.reqid) {
|
||||
response.attachNetworkRequest(request.params.reqid, {
|
||||
requestFilePath: request.params.requestFilePath,
|
||||
@@ -127,7 +127,7 @@ export const getNetworkRequest = definePageTool({
|
||||
const data = await request.page.getDevToolsData();
|
||||
response.attachDevToolsData(data);
|
||||
const reqid = data?.cdpRequestId
|
||||
? context.resolveCdpRequestId(request.page, data.cdpRequestId)
|
||||
? request.page.resolveCdpRequestId(data.cdpRequestId)
|
||||
: undefined;
|
||||
if (reqid) {
|
||||
response.attachNetworkRequest(reqid, {
|
||||
|
||||
@@ -207,7 +207,9 @@ describe('McpContext', () => {
|
||||
stableId: 123,
|
||||
});
|
||||
|
||||
sinon.stub(context, 'getNetworkRequests').returns([mockRequest]);
|
||||
sinon
|
||||
.stub(context.getSelectedMcpPage(), 'getNetworkRequests')
|
||||
.returns([mockRequest]);
|
||||
sinon.stub(context, 'getNetworkRequestStableId').returns(123);
|
||||
|
||||
response.setIncludeNetworkRequests(true);
|
||||
@@ -223,7 +225,9 @@ describe('McpContext', () => {
|
||||
stableId: 456,
|
||||
});
|
||||
|
||||
sinon.stub(context, 'getNetworkRequestById').returns(mockRequest);
|
||||
sinon
|
||||
.stub(context.getSelectedMcpPage(), 'getNetworkRequestById')
|
||||
.returns(mockRequest);
|
||||
sinon.stub(context, 'getNetworkRequestStableId').returns(456);
|
||||
|
||||
response.attachNetworkRequest(456);
|
||||
@@ -247,7 +251,9 @@ describe('McpContext', () => {
|
||||
} as unknown as HTTPResponse,
|
||||
});
|
||||
|
||||
sinon.stub(context, 'getNetworkRequestById').returns(mockRequest);
|
||||
sinon
|
||||
.stub(context.getSelectedMcpPage(), 'getNetworkRequestById')
|
||||
.returns(mockRequest);
|
||||
sinon.stub(context, 'getNetworkRequestStableId').returns(789);
|
||||
|
||||
// Use os.tmpdir() so validatePath passes on all platforms (macOS tmpdir
|
||||
|
||||
+17
-17
@@ -462,7 +462,7 @@ describe('McpResponse', () => {
|
||||
it('add network requests when setting is true', async t => {
|
||||
await withMcpContext(async (response, context) => {
|
||||
response.setIncludeNetworkRequests(true);
|
||||
context.getNetworkRequests = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => {
|
||||
return [getMockRequest({stableId: 1}), getMockRequest({stableId: 2})];
|
||||
};
|
||||
const {content, structuredContent} = await response.handle(
|
||||
@@ -479,7 +479,7 @@ describe('McpResponse', () => {
|
||||
it('does not include network requests when setting is false', async t => {
|
||||
await withMcpContext(async (response, context) => {
|
||||
response.setIncludeNetworkRequests(false);
|
||||
context.getNetworkRequests = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => {
|
||||
return [getMockRequest()];
|
||||
};
|
||||
const {content, structuredContent} = await response.handle(
|
||||
@@ -511,10 +511,10 @@ describe('McpResponse', () => {
|
||||
postData: JSON.stringify({request: 'body'}),
|
||||
response: httpResponse,
|
||||
});
|
||||
context.getNetworkRequests = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => {
|
||||
return [request];
|
||||
};
|
||||
context.getNetworkRequestById = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequestById = () => {
|
||||
return request;
|
||||
};
|
||||
response.attachNetworkRequest(1);
|
||||
@@ -535,10 +535,10 @@ describe('McpResponse', () => {
|
||||
await withMcpContext(async (response, context) => {
|
||||
response.setIncludeNetworkRequests(true);
|
||||
const request = getMockRequest();
|
||||
context.getNetworkRequests = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => {
|
||||
return [request];
|
||||
};
|
||||
context.getNetworkRequestById = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequestById = () => {
|
||||
return request;
|
||||
};
|
||||
response.attachNetworkRequest(1);
|
||||
@@ -602,7 +602,7 @@ describe('McpResponse', () => {
|
||||
};
|
||||
mockAggregatedIssue.getDescription.returns(mockDescription);
|
||||
response.setIncludeConsoleData(true);
|
||||
context.getConsoleData = () => {
|
||||
context.getSelectedMcpPage().getConsoleData = () => {
|
||||
return [mockAggregatedIssue];
|
||||
};
|
||||
|
||||
@@ -627,7 +627,7 @@ describe('McpResponse', () => {
|
||||
};
|
||||
mockAggregatedIssue.getDescription.returns(mockDescription);
|
||||
response.attachConsoleMessage(1);
|
||||
context.getConsoleMessageById = () => {
|
||||
context.getSelectedMcpPage().getConsoleMessageById = () => {
|
||||
return mockAggregatedIssue;
|
||||
};
|
||||
|
||||
@@ -646,7 +646,7 @@ describe('McpResponse network request filtering', () => {
|
||||
response.setIncludeNetworkRequests(true, {
|
||||
resourceTypes: ['script', 'stylesheet'],
|
||||
});
|
||||
context.getNetworkRequests = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => {
|
||||
return [
|
||||
getMockRequest({resourceType: 'script'}),
|
||||
getMockRequest({resourceType: 'image'}),
|
||||
@@ -670,7 +670,7 @@ describe('McpResponse network request filtering', () => {
|
||||
response.setIncludeNetworkRequests(true, {
|
||||
resourceTypes: ['image'],
|
||||
});
|
||||
context.getNetworkRequests = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => {
|
||||
return [
|
||||
getMockRequest({resourceType: 'script'}),
|
||||
getMockRequest({resourceType: 'image'}),
|
||||
@@ -693,7 +693,7 @@ describe('McpResponse network request filtering', () => {
|
||||
response.setIncludeNetworkRequests(true, {
|
||||
resourceTypes: ['font'],
|
||||
});
|
||||
context.getNetworkRequests = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => {
|
||||
return [
|
||||
getMockRequest({resourceType: 'script'}),
|
||||
getMockRequest({resourceType: 'image'}),
|
||||
@@ -714,7 +714,7 @@ describe('McpResponse network request filtering', () => {
|
||||
it('shows all requests when no filters are provided', async t => {
|
||||
await withMcpContext(async (response, context) => {
|
||||
response.setIncludeNetworkRequests(true);
|
||||
context.getNetworkRequests = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => {
|
||||
return [
|
||||
getMockRequest({resourceType: 'script'}),
|
||||
getMockRequest({resourceType: 'image'}),
|
||||
@@ -740,7 +740,7 @@ describe('McpResponse network request filtering', () => {
|
||||
response.setIncludeNetworkRequests(true, {
|
||||
resourceTypes: [],
|
||||
});
|
||||
context.getNetworkRequests = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => {
|
||||
return [
|
||||
getMockRequest({resourceType: 'script'}),
|
||||
getMockRequest({resourceType: 'image'}),
|
||||
@@ -765,7 +765,7 @@ describe('McpResponse network pagination', () => {
|
||||
it('returns all requests when pagination is not provided', async t => {
|
||||
await withMcpContext(async (response, context) => {
|
||||
const requests = Array.from({length: 5}, () => getMockRequest());
|
||||
context.getNetworkRequests = () => requests;
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => requests;
|
||||
response.setIncludeNetworkRequests(true);
|
||||
const {content, structuredContent} = await response.handle(
|
||||
'test',
|
||||
@@ -786,7 +786,7 @@ describe('McpResponse network pagination', () => {
|
||||
const requests = Array.from({length: 30}, (_, idx) =>
|
||||
getMockRequest({method: `GET-${idx}`}),
|
||||
);
|
||||
context.getNetworkRequests = () => {
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => {
|
||||
return requests;
|
||||
};
|
||||
response.setIncludeNetworkRequests(true, {pageSize: 10});
|
||||
@@ -809,7 +809,7 @@ describe('McpResponse network pagination', () => {
|
||||
const requests = Array.from({length: 25}, (_, idx) =>
|
||||
getMockRequest({method: `GET-${idx}`}),
|
||||
);
|
||||
context.getNetworkRequests = () => requests;
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => requests;
|
||||
response.setIncludeNetworkRequests(true, {
|
||||
pageSize: 10,
|
||||
pageIdx: 1,
|
||||
@@ -831,7 +831,7 @@ describe('McpResponse network pagination', () => {
|
||||
it('handles invalid page number by showing first page', async t => {
|
||||
await withMcpContext(async (response, context) => {
|
||||
const requests = Array.from({length: 5}, () => getMockRequest());
|
||||
context.getNetworkRequests = () => requests;
|
||||
context.getSelectedMcpPage().getNetworkRequests = () => requests;
|
||||
response.setIncludeNetworkRequests(true, {
|
||||
pageSize: 2,
|
||||
pageIdx: 10, // Invalid page number
|
||||
|
||||
@@ -403,7 +403,7 @@ describe('console', () => {
|
||||
`);
|
||||
page.textSnapshot = await TextSnapshot.create(page);
|
||||
await issuePromise;
|
||||
const messages = context.getConsoleData(page);
|
||||
const messages = page.getConsoleData();
|
||||
let issueMsg;
|
||||
for (const message of messages) {
|
||||
if (message instanceof DevTools.AggregatedIssue) {
|
||||
|
||||
Reference in New Issue
Block a user