chromedevtools--chrome-devtools-mcp
32dc50d59b
Update the tools to all include the `heapsnapshot` term for easier handling. Renames UID to ID to reduce confusion with the snapshot UIDs. Renames Id to NodeId to better differentiate from the base Id. Remove EdgeIndex as it was not useful. Closes: https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1970
180 行
4.7 KiB
TypeScript
180 行
4.7 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2026 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import assert from 'node:assert';
|
|
import {existsSync} from 'node:fs';
|
|
import {rm} from 'node:fs/promises';
|
|
import {tmpdir} from 'node:os';
|
|
import {join} from 'node:path';
|
|
import {describe, it} from 'node:test';
|
|
|
|
import {
|
|
takeHeapSnapshot,
|
|
getHeapSnapshotSummary,
|
|
getHeapSnapshotDetails,
|
|
getHeapSnapshotClassNodes,
|
|
getHeapSnapshotRetainers,
|
|
} from '../../src/tools/memory.js';
|
|
import {withMcpContext} from '../utils.js';
|
|
|
|
describe('memory', () => {
|
|
describe('take_heapsnapshot', () => {
|
|
it('with default options', async () => {
|
|
await withMcpContext(async (response, context) => {
|
|
const filePath = join(tmpdir(), 'test-screenshot.heapsnapshot');
|
|
try {
|
|
await takeHeapSnapshot.handler(
|
|
{params: {filePath}, page: context.getSelectedMcpPage()},
|
|
response,
|
|
context,
|
|
);
|
|
assert.equal(
|
|
response.responseLines.at(0),
|
|
`Heap snapshot saved to ${filePath}`,
|
|
);
|
|
assert.ok(existsSync(filePath));
|
|
} finally {
|
|
await rm(filePath, {force: true});
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('get_heapsnapshot_summary', () => {
|
|
it('with default options', async t => {
|
|
await withMcpContext(async (response, context) => {
|
|
const filePath = join(
|
|
process.cwd(),
|
|
'tests/fixtures/example.heapsnapshot',
|
|
);
|
|
|
|
assert.ok(existsSync(filePath), `Fixture not found at ${filePath}`);
|
|
|
|
await getHeapSnapshotSummary.handler(
|
|
{params: {filePath}},
|
|
response,
|
|
context,
|
|
);
|
|
|
|
// Call handle to trigger formatting (similar to network tests)
|
|
const responseData = await response.handle(
|
|
getHeapSnapshotSummary.name,
|
|
context,
|
|
);
|
|
const output = responseData.content
|
|
.map(c => (c.type === 'text' ? c.text : ''))
|
|
.join('\n');
|
|
|
|
t.assert.snapshot?.(output);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('get_heapsnapshot_details', () => {
|
|
it('with default options', async t => {
|
|
await withMcpContext(async (response, context) => {
|
|
const filePath = join(
|
|
process.cwd(),
|
|
'tests/fixtures/example.heapsnapshot',
|
|
);
|
|
|
|
await getHeapSnapshotDetails.handler(
|
|
{params: {filePath}},
|
|
response,
|
|
context,
|
|
);
|
|
|
|
const responseData = await response.handle(
|
|
getHeapSnapshotDetails.name,
|
|
context,
|
|
);
|
|
const output = responseData.content
|
|
.map(c => (c.type === 'text' ? c.text : ''))
|
|
.join('\n');
|
|
|
|
t.assert.snapshot?.(output);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('get_heapsnapshot_class_nodes', () => {
|
|
it('with default options', async t => {
|
|
await withMcpContext(async (response, context) => {
|
|
const filePath = join(
|
|
process.cwd(),
|
|
'tests/fixtures/example.heapsnapshot',
|
|
);
|
|
|
|
await context.getHeapSnapshotAggregates(filePath);
|
|
|
|
await getHeapSnapshotClassNodes.handler(
|
|
{params: {filePath, id: 19}},
|
|
response,
|
|
context,
|
|
);
|
|
|
|
const responseData = await response.handle(
|
|
getHeapSnapshotClassNodes.name,
|
|
context,
|
|
);
|
|
|
|
const output = responseData.content
|
|
.map(c => (c.type === 'text' ? c.text : ''))
|
|
.join('\n');
|
|
|
|
t.assert.snapshot?.(output);
|
|
});
|
|
});
|
|
|
|
it('with non-existent class name', async () => {
|
|
await withMcpContext(async (response, context) => {
|
|
const filePath = join(
|
|
process.cwd(),
|
|
'tests/fixtures/example.heapsnapshot',
|
|
);
|
|
|
|
await context.getHeapSnapshotAggregates(filePath);
|
|
|
|
await assert.rejects(
|
|
getHeapSnapshotClassNodes.handler(
|
|
{params: {filePath, id: 999999}},
|
|
response,
|
|
context,
|
|
),
|
|
{message: 'Class with ID 999999 not found in heap snapshot'},
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('get_heapsnapshot_retainers', () => {
|
|
it('with valid nodeId', async t => {
|
|
await withMcpContext(async (response, context) => {
|
|
const filePath = join(
|
|
process.cwd(),
|
|
'tests/fixtures/example.heapsnapshot',
|
|
);
|
|
|
|
await getHeapSnapshotRetainers.handler(
|
|
{params: {filePath, nodeId: 25341}},
|
|
response,
|
|
context,
|
|
);
|
|
|
|
const responseData = await response.handle(
|
|
getHeapSnapshotRetainers.name,
|
|
context,
|
|
);
|
|
const output = responseData.content
|
|
.map(c => (c.type === 'text' ? c.text : ''))
|
|
.join('\n');
|
|
|
|
t.assert.snapshot?.(output);
|
|
});
|
|
});
|
|
});
|
|
});
|