fix: regression after the #2443 (#2462)

This also includes a fix memory leak for the stashedElements.
This commit is contained in:
Nikolay Vitkov
2026-08-04 11:13:15 +02:00
committed by GitHub
parent e10932ff75
commit 4c80ce46f3
2 changed files with 81 additions and 1 deletions
+8 -1
View File
@@ -471,6 +471,7 @@ export class McpPage implements ContextPage {
if (!window.__dtmcp?.executeTool) {
throw new Error('No tools found on the page');
}
const toolResult = await window.__dtmcp.executeTool(name, args);
const stashDOMElement = (el: Element) => {
@@ -561,9 +562,15 @@ export class McpPage implements ContextPage {
elementHandles.push(elementHandle);
}
await this.pptrPage.evaluate(() => {
if (window.__dtmcp) {
window.__dtmcp.stashedElements = undefined;
}
});
if (elementHandles.length) {
using stack = new DisposableStack();
for (const handle of elementHandles) {
for (const handle of this.extraHandles) {
stack.use(handle);
}
this.textSnapshot = await TextSnapshot.create(this, {
+73
View File
@@ -886,5 +886,78 @@ describe('thirdPartyDeveloperTools', () => {
{categoryExperimentalThirdParty: true},
);
});
it('disposes old handles when executing third party developer tools', async () => {
await withMcpContext(
async (response, context) => {
await setupThirdPartyDeveloperTools(response, context, () => {
const mockToolGroup = {
name: 'test-group',
description: 'test description',
tools: [
{
name: 'test-tool',
description: 'test tool description',
inputSchema: {},
execute: () => {
const div = document.createElement('div');
document.body.appendChild(div);
return div;
},
},
],
};
window.addEventListener('devtoolstooldiscovery', (e: Event) => {
// @ts-expect-error Event has `respondWith`
e.respondWith(mockToolGroup);
});
});
const page = context.getSelectedMcpPage();
if (!page) {
assert.fail('No page found');
}
await executeThirdPartyDeveloperTool.handler(
{
params: {
toolName: 'test-tool',
params: JSON.stringify({}),
},
page,
},
response,
context,
);
const firstHandles = [...page.extraHandles];
assert.strictEqual(firstHandles.length, 1);
// @ts-expect-error Internal Puppeteer API
assert.ok(!firstHandles[0].disposed);
await executeThirdPartyDeveloperTool.handler(
{
params: {
toolName: 'test-tool',
params: JSON.stringify({}),
},
page,
},
response,
context,
);
const secondHandles = [...page.extraHandles];
assert.strictEqual(secondHandles.length, 1);
assert.notStrictEqual(firstHandles[0], secondHandles[0]);
// @ts-expect-error Internal Puppeteer API
assert.ok(!secondHandles[0].disposed);
// @ts-expect-error Internal Puppeteer API
assert.ok(firstHandles[0].disposed);
},
undefined,
{categoryExperimentalThirdParty: true},
);
});
});
});