项目文件夹

文件
T
Alex Rudenko 7e279f1b67 feat: enable usage statistics by default with opt-out (#855)
## **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.
2026-01-28 10:18:10 +00:00

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);
});
});