Skip to content

Commit 85f935b

Browse files
authored
fix: do not use getSelectedMcpPage (#2039)
Drive-by: clean up formatting and arg use. Refs: #2033
1 parent 625dd51 commit 85f935b

3 files changed

Lines changed: 60 additions & 60 deletions

File tree

src/McpResponse.ts

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export function replaceHtmlElementsWithUids(schema: JSONSchema7Definition) {
100100

101101
async function getToolGroup(
102102
page: McpPage,
103-
): Promise<ToolGroup<ToolDefinition> | undefined> {
103+
): Promise<ToolGroup<ToolDefinition> | undefined | null> {
104104
// Check if there is a `devtoolstooldiscovery` event listener
105105
const windowHandle = await page.pptrPage.evaluateHandle(() => window);
106106
// @ts-expect-error internal API
@@ -114,39 +114,41 @@ async function getToolGroup(
114114
}
115115

116116
const toolGroup = await page.pptrPage.evaluate(() => {
117-
return new Promise<ToolGroup<ToolDefinition> | undefined>(resolve => {
118-
const event = new CustomEvent('devtoolstooldiscovery');
119-
// @ts-expect-error Adding custom property
120-
event.respondWith = (toolGroup: ToolGroup) => {
121-
if (!window.__dtmcp) {
122-
window.__dtmcp = {};
123-
}
124-
window.__dtmcp.toolGroup = toolGroup;
117+
return new Promise<ToolGroup<ToolDefinition> | undefined | null>(
118+
resolve => {
119+
const event = new CustomEvent('devtoolstooldiscovery');
120+
// @ts-expect-error Adding custom property
121+
event.respondWith = (toolGroup: ToolGroup) => {
122+
if (!window.__dtmcp) {
123+
window.__dtmcp = {};
124+
}
125+
window.__dtmcp.toolGroup = toolGroup;
125126

126-
// When receiving a toolGroup for the first time, expose a simple execution helper
127-
if (!window.__dtmcp.executeTool) {
128-
window.__dtmcp.executeTool = async (toolName, args) => {
129-
if (!window.__dtmcp?.toolGroup) {
130-
throw new Error('No tools found on the page');
131-
}
132-
const tool = window.__dtmcp.toolGroup.tools.find(
133-
t => t.name === toolName,
134-
);
135-
if (!tool) {
136-
throw new Error(`Tool ${toolName} not found`);
137-
}
138-
return await tool.execute(args);
139-
};
140-
}
127+
// When receiving a toolGroup for the first time, expose a simple execution helper
128+
if (!window.__dtmcp.executeTool) {
129+
window.__dtmcp.executeTool = async (toolName, args) => {
130+
if (!window.__dtmcp?.toolGroup) {
131+
throw new Error('No tools found on the page');
132+
}
133+
const tool = window.__dtmcp.toolGroup.tools.find(
134+
t => t.name === toolName,
135+
);
136+
if (!tool) {
137+
throw new Error(`Tool ${toolName} not found`);
138+
}
139+
return await tool.execute(args);
140+
};
141+
}
141142

142-
resolve(toolGroup);
143-
};
144-
window.dispatchEvent(event);
145-
// If the page does not synchronously call `event.respondWith`, return instead of timing out
146-
setTimeout(() => {
147-
resolve(undefined);
148-
}, 0);
149-
});
143+
resolve(toolGroup);
144+
};
145+
window.dispatchEvent(event);
146+
// If the page does not synchronously call `event.respondWith`, return instead of timing out
147+
setTimeout(() => {
148+
resolve(null);
149+
}, 0);
150+
},
151+
);
150152
});
151153

152154
for (const tool of toolGroup?.tools ?? []) {
@@ -245,9 +247,7 @@ export class McpResponse implements Response {
245247
}
246248

247249
setListThirdPartyDeveloperTools(): void {
248-
if (this.#args.categoryExperimentalThirdParty) {
249-
this.#listThirdPartyDeveloperTools = true;
250-
}
250+
this.#listThirdPartyDeveloperTools = true;
251251
}
252252

253253
setListWebMcpTools(): void {
@@ -552,17 +552,26 @@ export class McpResponse implements Response {
552552
extensions = await context.listExtensions();
553553
}
554554

555-
let thirdPartyDeveloperTools: ToolGroup<ToolDefinition> | undefined;
556-
if (this.#listThirdPartyDeveloperTools) {
557-
const page = this.#page ?? context.getSelectedMcpPage();
558-
thirdPartyDeveloperTools = await getToolGroup(page);
559-
page.thirdPartyDeveloperTools = thirdPartyDeveloperTools;
555+
// Null indicates no tools.
556+
let thirdPartyDeveloperTools: ToolGroup<ToolDefinition> | undefined | null;
557+
if (
558+
this.#args.categoryExperimentalThirdParty &&
559+
this.#listThirdPartyDeveloperTools &&
560+
this.#page
561+
) {
562+
thirdPartyDeveloperTools = await getToolGroup(this.#page);
563+
if (thirdPartyDeveloperTools) {
564+
this.#page.thirdPartyDeveloperTools = thirdPartyDeveloperTools;
565+
}
560566
}
561567

562568
let webmcpTools: WebMCPTool[] | undefined;
563-
if (this.#listWebMcpTools && this.#args.categoryExperimentalWebmcp) {
564-
const page = this.#page ?? context.getSelectedMcpPage();
565-
webmcpTools = page.getWebMcpTools();
569+
if (
570+
this.#args.categoryExperimentalWebmcp &&
571+
this.#listWebMcpTools &&
572+
this.#page
573+
) {
574+
webmcpTools = this.#page.getWebMcpTools();
566575
}
567576

568577
let consoleMessages: Array<ConsoleFormatter | IssueFormatter> | undefined;
@@ -688,7 +697,7 @@ export class McpResponse implements Response {
688697
traceInsight?: TraceInsightData;
689698
extensions?: Map<string, Extension>;
690699
lighthouseResult?: LighthouseData;
691-
thirdPartyDeveloperTools?: ToolGroup<ToolDefinition>;
700+
thirdPartyDeveloperTools?: ToolGroup<ToolDefinition> | null;
692701
webmcpTools?: WebMCPTool[];
693702
errorMessage?: string;
694703
},
@@ -1004,13 +1013,15 @@ Call ${handleDialog.name} to handle it before continuing.`);
10041013
}
10051014
}
10061015

1007-
if (this.#listThirdPartyDeveloperTools) {
1008-
structuredContent.thirdPartyDeveloperTools =
1009-
data.thirdPartyDeveloperTools ?? undefined;
1016+
if (data.thirdPartyDeveloperTools !== undefined) {
1017+
if (data.thirdPartyDeveloperTools) {
1018+
structuredContent.thirdPartyDeveloperTools =
1019+
data.thirdPartyDeveloperTools;
1020+
}
10101021
response.push('## Third-party developer tools');
10111022
if (
1012-
!data.thirdPartyDeveloperTools ||
1013-
!data.thirdPartyDeveloperTools.tools
1023+
data.thirdPartyDeveloperTools === null ||
1024+
!data.thirdPartyDeveloperTools?.tools
10141025
) {
10151026
response.push('No third-party developer tools available.');
10161027
} else {

tests/McpResponse.test.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,15 +1070,6 @@ describe('third-party developer tools', () => {
10701070
it('lists third-party developer tools', async t => {
10711071
await withMcpContext(
10721072
async (response, context) => {
1073-
response.setListThirdPartyDeveloperTools();
1074-
const emptyResult = await response.handle('test', context);
1075-
const emptyText = getTextContent(emptyResult.content[0]);
1076-
assert.ok(
1077-
emptyText.includes('No third-party developer tools available.'),
1078-
'Should show message for empty third-party developer tools',
1079-
);
1080-
1081-
response.resetResponseLineForTesting();
10821073
const mcpPage = context.getSelectedMcpPage();
10831074
stubToolDiscovery(mcpPage.pptrPage);
10841075
sinon.stub(mcpPage.pptrPage, 'evaluate').resolves({

tests/tools/thirdPartyDeveloper.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ describe('thirdPartyDeveloperTools', () => {
147147
'list_3p_developer_tools',
148148
context,
149149
);
150-
assert.ok('thirdPartyDeveloperTools' in result.structuredContent);
151150
assert.strictEqual(
152151
(
153152
result.structuredContent as {
@@ -177,7 +176,6 @@ describe('thirdPartyDeveloperTools', () => {
177176
'list_3p_developer_tools',
178177
context,
179178
);
180-
assert.ok('thirdPartyDeveloperTools' in result.structuredContent);
181179
assert.strictEqual(
182180
(result.structuredContent as {thirdPartyDeveloperTools: undefined})
183181
.thirdPartyDeveloperTools,

0 commit comments

Comments
 (0)