feat(network): implement listing network requests (#247)

Fixes: https://github.com/microsoft/playwright-mcp/issues/242
This commit is contained in:
Pavel Feldman
2025-04-22 16:04:25 -07:00
committed by GitHub
parent c80f7cf222
commit 1bc3c761de
11 changed files with 401 additions and 4 deletions

View File

@@ -317,6 +317,7 @@ export class Tab {
readonly context: Context;
readonly page: playwright.Page;
private _console: playwright.ConsoleMessage[] = [];
private _requests: Map<playwright.Request, playwright.Response | null> = new Map();
private _snapshot: PageSnapshot | undefined;
private _onPageClose: (tab: Tab) => void;
@@ -325,9 +326,11 @@ export class Tab {
this.page = page;
this._onPageClose = onPageClose;
page.on('console', event => this._console.push(event));
page.on('request', request => this._requests.set(request, null));
page.on('response', response => this._requests.set(response.request(), response));
page.on('framenavigated', frame => {
if (!frame.parentFrame())
this._console.length = 0;
this._clearCollectedArtifacts();
});
page.on('close', () => this._onClose());
page.on('filechooser', chooser => {
@@ -342,8 +345,13 @@ export class Tab {
page.setDefaultTimeout(5000);
}
private _onClose() {
private _clearCollectedArtifacts() {
this._console.length = 0;
this._requests.clear();
}
private _onClose() {
this._clearCollectedArtifacts();
this._onPageClose(this);
}
@@ -367,6 +375,10 @@ export class Tab {
return this._console;
}
async requests(): Promise<Map<playwright.Request, playwright.Response | null>> {
return this._requests;
}
async captureSnapshot() {
this._snapshot = await PageSnapshot.create(this.page);
}

View File

@@ -26,6 +26,7 @@ import files from './tools/files';
import install from './tools/install';
import keyboard from './tools/keyboard';
import navigate from './tools/navigate';
import network from './tools/network';
import pdf from './tools/pdf';
import snapshot from './tools/snapshot';
import tabs from './tools/tabs';
@@ -43,6 +44,7 @@ const snapshotTools: Tool<any>[] = [
...install,
...keyboard(true),
...navigate(true),
...network,
...pdf,
...snapshot,
...tabs(true),
@@ -56,6 +58,7 @@ const screenshotTools: Tool<any>[] = [
...install,
...keyboard(false),
...navigate(false),
...network,
...pdf,
...screen,
...tabs(false),

57
src/tools/network.ts Normal file
View File

@@ -0,0 +1,57 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { z } from 'zod';
import { defineTool } from './tool';
import type * as playwright from 'playwright';
const requests = defineTool({
capability: 'core',
schema: {
name: 'browser_network_requests',
description: 'Returns all network requests since loading the page',
inputSchema: z.object({}),
},
handle: async context => {
const requests = await context.currentTabOrDie().requests();
const log = [...requests.entries()].map(([request, response]) => renderRequest(request, response)).join('\n');
return {
code: [`// <internal code to list network requests>`],
action: async () => {
return {
content: [{ type: 'text', text: log }]
};
},
captureSnapshot: false,
waitForNetwork: false,
};
},
});
function renderRequest(request: playwright.Request, response: playwright.Response | null) {
const result: string[] = [];
result.push(`[${request.method().toUpperCase()}] ${request.url()}`);
if (response)
result.push(`=> [${response.status()}] ${response.statusText()}`);
return result.join(' ');
}
export default [
requests,
];