This also includes a fix memory leak for the stashedElements.
This commit is contained in:
+8
-1
@@ -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, {
|
||||
|
||||
@@ -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},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user