chromedevtools--chrome-devtools-mcp
7e279f1b67
## **Usage statistics** Google collects usage statistics (such as tool invocation success rates, latency, and environment information) to improve the reliability and performance of Chrome DevTools MCP. Data collection is **enabled by default**. You can opt-out by passing the `--no-usage-statistics` flag when starting the server: ```json "args": ["-y", "chrome-devtools-mcp@latest", "--no-usage-statistics"] ``` Google handles this data in accordance with the [Google Privacy Policy](https://policies.google.com/privacy). Google's collection of usage statistics for Chrome DevTools MCP is independent from the Chrome browser's usage statistics. Opting out of Chrome metrics does not automatically opt you out of this tool, and vice-versa. The code determining statistics that are collected is in here https://github.com/ChromeDevTools/chrome-devtools-mcp/tree/main/src/telemetry.
276 行
7.1 KiB
TypeScript
276 行
7.1 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import assert from 'node:assert';
|
|
import {describe, it} from 'node:test';
|
|
|
|
import {parseArguments} from '../src/cli.js';
|
|
|
|
describe('cli args parsing', () => {
|
|
const defaultArgs = {
|
|
'category-emulation': true,
|
|
categoryEmulation: true,
|
|
'category-performance': true,
|
|
categoryPerformance: true,
|
|
'category-extensions': false,
|
|
categoryExtensions: false,
|
|
'category-network': true,
|
|
categoryNetwork: true,
|
|
'auto-connect': undefined,
|
|
autoConnect: undefined,
|
|
'usage-statistics': true,
|
|
usageStatistics: true,
|
|
};
|
|
|
|
it('parses with default args', async () => {
|
|
const args = parseArguments('1.0.0', ['node', 'main.js']);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
channel: 'stable',
|
|
});
|
|
});
|
|
|
|
it('parses with browser url', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--browserUrl',
|
|
'http://localhost:3000',
|
|
]);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
'browser-url': 'http://localhost:3000',
|
|
browserUrl: 'http://localhost:3000',
|
|
u: 'http://localhost:3000',
|
|
});
|
|
});
|
|
|
|
it('parses with user data dir', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--user-data-dir',
|
|
'/tmp/chrome-profile',
|
|
]);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
channel: 'stable',
|
|
'user-data-dir': '/tmp/chrome-profile',
|
|
userDataDir: '/tmp/chrome-profile',
|
|
});
|
|
});
|
|
|
|
it('parses an empty browser url', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--browserUrl',
|
|
'',
|
|
]);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
'browser-url': undefined,
|
|
browserUrl: undefined,
|
|
u: undefined,
|
|
channel: 'stable',
|
|
});
|
|
});
|
|
|
|
it('parses with executable path', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--executablePath',
|
|
'/tmp/test 123/chrome',
|
|
]);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
'executable-path': '/tmp/test 123/chrome',
|
|
e: '/tmp/test 123/chrome',
|
|
executablePath: '/tmp/test 123/chrome',
|
|
});
|
|
});
|
|
|
|
it('parses viewport', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--viewport',
|
|
'888x777',
|
|
]);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
channel: 'stable',
|
|
viewport: {
|
|
width: 888,
|
|
height: 777,
|
|
},
|
|
});
|
|
});
|
|
|
|
it('parses chrome args', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
`--chrome-arg='--no-sandbox'`,
|
|
`--chrome-arg='--disable-setuid-sandbox'`,
|
|
]);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
channel: 'stable',
|
|
'chrome-arg': ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
chromeArg: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
});
|
|
});
|
|
|
|
it('parses ignore chrome args', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
`--ignore-default-chrome-arg='--disable-extensions'`,
|
|
`--ignore-default-chrome-arg='--disable-cancel-all-touches'`,
|
|
]);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
channel: 'stable',
|
|
'ignore-default-chrome-arg': [
|
|
'--disable-extensions',
|
|
'--disable-cancel-all-touches',
|
|
],
|
|
ignoreDefaultChromeArg: [
|
|
'--disable-extensions',
|
|
'--disable-cancel-all-touches',
|
|
],
|
|
});
|
|
});
|
|
|
|
it('parses wsEndpoint with ws:// protocol', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--wsEndpoint',
|
|
'ws://127.0.0.1:9222/devtools/browser/abc123',
|
|
]);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
'ws-endpoint': 'ws://127.0.0.1:9222/devtools/browser/abc123',
|
|
wsEndpoint: 'ws://127.0.0.1:9222/devtools/browser/abc123',
|
|
w: 'ws://127.0.0.1:9222/devtools/browser/abc123',
|
|
});
|
|
});
|
|
|
|
it('parses wsEndpoint with wss:// protocol', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--wsEndpoint',
|
|
'wss://example.com:9222/devtools/browser/abc123',
|
|
]);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
'ws-endpoint': 'wss://example.com:9222/devtools/browser/abc123',
|
|
wsEndpoint: 'wss://example.com:9222/devtools/browser/abc123',
|
|
w: 'wss://example.com:9222/devtools/browser/abc123',
|
|
});
|
|
});
|
|
|
|
it('parses wsHeaders with valid JSON', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--wsEndpoint',
|
|
'ws://127.0.0.1:9222/devtools/browser/abc123',
|
|
'--wsHeaders',
|
|
'{"Authorization":"Bearer token","X-Custom":"value"}',
|
|
]);
|
|
assert.deepStrictEqual(args.wsHeaders, {
|
|
Authorization: 'Bearer token',
|
|
'X-Custom': 'value',
|
|
});
|
|
});
|
|
|
|
it('parses disabled category', async () => {
|
|
const args = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--no-category-emulation',
|
|
]);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
channel: 'stable',
|
|
'category-emulation': false,
|
|
categoryEmulation: false,
|
|
});
|
|
});
|
|
it('parses auto-connect', async () => {
|
|
const args = parseArguments('1.0.0', ['node', 'main.js', '--auto-connect']);
|
|
assert.deepStrictEqual(args, {
|
|
...defaultArgs,
|
|
_: [],
|
|
headless: false,
|
|
$0: 'npx chrome-devtools-mcp@latest',
|
|
channel: 'stable',
|
|
'auto-connect': true,
|
|
autoConnect: true,
|
|
});
|
|
});
|
|
|
|
it('parses usage statistics flag', async () => {
|
|
// Test default (should be true).
|
|
const defaultArgs = parseArguments('1.0.0', ['node', 'main.js']);
|
|
assert.strictEqual(defaultArgs.usageStatistics, true);
|
|
|
|
// Test enabling it
|
|
const enabledArgs = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--usage-statistics',
|
|
]);
|
|
assert.strictEqual(enabledArgs.usageStatistics, true);
|
|
|
|
// Test disabling it
|
|
const disabledArgs = parseArguments('1.0.0', [
|
|
'node',
|
|
'main.js',
|
|
'--no-usage-statistics',
|
|
]);
|
|
assert.strictEqual(disabledArgs.usageStatistics, false);
|
|
});
|
|
});
|