diff --git a/docs/tool-reference.md b/docs/tool-reference.md index ad9410a2d..070cd548e 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -200,11 +200,11 @@ ### `emulate_network` -**Description:** Emulates network conditions such as throttling on the selected page. +**Description:** Emulates network conditions such as throttling or offline mode on the selected page. **Parameters:** -- **throttlingOption** (enum: "No emulation", "Slow 3G", "Fast 3G", "Slow 4G", "Fast 4G") **(required)**: The network throttling option to emulate. Available throttling options are: No emulation, Slow 3G, Fast 3G, Slow 4G, Fast 4G. Set to "No emulation" to disable. +- **throttlingOption** (enum: "No emulation", "Offline", "Slow 3G", "Fast 3G", "Slow 4G", "Fast 4G") **(required)**: The network throttling option to emulate. Available throttling options are: No emulation, Offline, Slow 3G, Fast 3G, Slow 4G, Fast 4G. Set to "No emulation" to disable. Set to "Offline" to simulate offline network conditions. --- diff --git a/package-lock.json b/package-lock.json index 2435a3f22..77e6717d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,8 +12,9 @@ "@modelcontextprotocol/sdk": "1.19.1", "core-js": "3.45.1", "debug": "4.4.3", - "puppeteer-core": "24.23.0", - "yargs": "18.0.0" + "puppeteer-core": "^24.23.0", + "yargs": "18.0.0", + "zod": "^3.25.76" }, "bin": { "chrome-devtools-mcp": "build/src/index.js" @@ -4735,7 +4736,6 @@ "version": "24.23.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.23.0.tgz", "integrity": "sha512-yl25C59gb14sOdIiSnJ08XiPP+O2RjuyZmEG+RjYmCXO7au0jcLf7fRiyii96dXGUBW7Zwei/mVKfxMx/POeFw==", - "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.10.10", "chromium-bidi": "9.1.0", @@ -6194,19 +6194,17 @@ } }, "node_modules/zod": { - "version": "3.24.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.3.tgz", - "integrity": "sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==", - "license": "MIT", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "funding": { "url": "https://github.com/sponsors/colinhacks" } }, "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "license": "ISC", + "version": "3.24.6", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", + "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", "peerDependencies": { "zod": "^3.24.1" } diff --git a/package.json b/package.json index fe960cf4e..807b8f446 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,9 @@ "@modelcontextprotocol/sdk": "1.19.1", "core-js": "3.45.1", "debug": "4.4.3", - "puppeteer-core": "24.23.0", - "yargs": "18.0.0" + "puppeteer-core": "^24.23.0", + "yargs": "18.0.0", + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.35.0", diff --git a/src/tools/emulation.ts b/src/tools/emulation.ts index 9228c59b3..92b949e91 100644 --- a/src/tools/emulation.ts +++ b/src/tools/emulation.ts @@ -12,12 +12,13 @@ import {defineTool} from './ToolDefinition.js'; const throttlingOptions: [string, ...string[]] = [ 'No emulation', + 'Offline', ...Object.keys(PredefinedNetworkConditions), ]; export const emulateNetwork = defineTool({ name: 'emulate_network', - description: `Emulates network conditions such as throttling on the selected page.`, + description: `Emulates network conditions such as throttling or offline mode on the selected page.`, annotations: { category: ToolCategories.EMULATION, readOnlyHint: false, @@ -26,7 +27,7 @@ export const emulateNetwork = defineTool({ throttlingOption: z .enum(throttlingOptions) .describe( - `The network throttling option to emulate. Available throttling options are: ${throttlingOptions.join(', ')}. Set to "No emulation" to disable.`, + `The network throttling option to emulate. Available throttling options are: ${throttlingOptions.join(', ')}. Set to "No emulation" to disable. Set to "Offline" to simulate offline network conditions.`, ), }, handler: async (request, _response, context) => { @@ -39,6 +40,17 @@ export const emulateNetwork = defineTool({ return; } + if (conditions === 'Offline') { + await page.emulateNetworkConditions({ + offline: true, + download: 0, + upload: 0, + latency: 0, + }); + context.setNetworkConditions('Offline'); + return; + } + if (conditions in PredefinedNetworkConditions) { const networkCondition = PredefinedNetworkConditions[ diff --git a/tests/tools/emulation.test.ts b/tests/tools/emulation.test.ts index 151a621b8..0b64e4847 100644 --- a/tests/tools/emulation.test.ts +++ b/tests/tools/emulation.test.ts @@ -11,6 +11,21 @@ import {withBrowser} from '../utils.js'; describe('emulation', () => { describe('network', () => { + it('emulates offline network conditions', async () => { + await withBrowser(async (response, context) => { + await emulateNetwork.handler( + { + params: { + throttlingOption: 'Offline', + }, + }, + response, + context, + ); + + assert.strictEqual(context.getNetworkConditions(), 'Offline'); + }); + }); it('emulates network throttling when the throttling option is valid ', async () => { await withBrowser(async (response, context) => { await emulateNetwork.handler(