Skip to content

Commit 2753432

Browse files
committed
fix(input): include page list when click opens new tab
1 parent 8d765c0 commit 2753432

2 files changed

Lines changed: 86 additions & 12 deletions

File tree

src/tools/input.ts

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ export const click = defineTool({
5252
handler: async (request, response, context) => {
5353
const uid = request.params.uid;
5454
const handle = await context.getElementByUid(uid);
55+
const page = context.getSelectedPage();
56+
let popupOpened = false;
57+
const popupListener = () => {
58+
popupOpened = true;
59+
};
60+
page.on('popup', popupListener);
5561
try {
5662
await context.waitForEventsAfterAction(async () => {
5763
await handle.asLocator().click({
@@ -63,12 +69,16 @@ export const click = defineTool({
6369
? `Successfully double clicked on the element`
6470
: `Successfully clicked on the element`,
6571
);
72+
if (popupOpened) {
73+
response.setIncludePages(true);
74+
}
6675
if (request.params.includeSnapshot) {
6776
response.includeSnapshot();
6877
}
6978
} catch (error) {
7079
handleActionError(error, uid);
7180
} finally {
81+
page.off('popup', popupListener);
7282
void handle.dispose();
7383
}
7484
},
@@ -90,18 +100,30 @@ export const clickAt = defineTool({
90100
},
91101
handler: async (request, response, context) => {
92102
const page = context.getSelectedPage();
93-
await context.waitForEventsAfterAction(async () => {
94-
await page.mouse.click(request.params.x, request.params.y, {
95-
clickCount: request.params.dblClick ? 2 : 1,
103+
let popupOpened = false;
104+
const popupListener = () => {
105+
popupOpened = true;
106+
};
107+
page.on('popup', popupListener);
108+
try {
109+
await context.waitForEventsAfterAction(async () => {
110+
await page.mouse.click(request.params.x, request.params.y, {
111+
clickCount: request.params.dblClick ? 2 : 1,
112+
});
96113
});
97-
});
98-
response.appendResponseLine(
99-
request.params.dblClick
100-
? `Successfully double clicked at the coordinates`
101-
: `Successfully clicked at the coordinates`,
102-
);
103-
if (request.params.includeSnapshot) {
104-
response.includeSnapshot();
114+
response.appendResponseLine(
115+
request.params.dblClick
116+
? `Successfully double clicked at the coordinates`
117+
: `Successfully clicked at the coordinates`,
118+
);
119+
if (popupOpened) {
120+
response.setIncludePages(true);
121+
}
122+
if (request.params.includeSnapshot) {
123+
response.includeSnapshot();
124+
}
125+
} finally {
126+
page.off('popup', popupListener);
105127
}
106128
},
107129
});

tests/tools/input.test.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
} from '../../src/tools/input.js';
2323
import {parseKey} from '../../src/utils/keyboard.js';
2424
import {serverHooks} from '../server.js';
25-
import {html, withMcpContext} from '../utils.js';
25+
import {getTextContent, html, withMcpContext} from '../utils.js';
2626

2727
describe('input', () => {
2828
const server = serverHooks();
@@ -205,6 +205,31 @@ describe('input', () => {
205205
assert.notStrictEqual(response.snapshotParams, undefined);
206206
});
207207
});
208+
209+
it('includes pages if click opens a new tab', async () => {
210+
await withMcpContext(async (response, context) => {
211+
const page = context.getSelectedPage();
212+
await page.setContent(
213+
html`<button onclick="window.open('about:blank', '_blank')"
214+
>open</button
215+
>`,
216+
);
217+
await context.createTextSnapshot();
218+
await click.handler(
219+
{
220+
params: {
221+
uid: '1_1',
222+
},
223+
},
224+
response,
225+
context,
226+
);
227+
assert.ok(response.includePages);
228+
const formattedResponse = await response.handle('test', context);
229+
const textContent = getTextContent(formattedResponse.content[0]);
230+
assert.ok(textContent.includes('## Pages'));
231+
});
232+
});
208233
});
209234

210235
describe('hover', () => {
@@ -293,6 +318,33 @@ describe('input', () => {
293318
assert.ok(await page.$('text/dblclicked'));
294319
});
295320
});
321+
322+
it('includes pages if click at coordinates opens a new tab', async () => {
323+
await withMcpContext(async (response, context) => {
324+
const page = context.getSelectedPage();
325+
await page.setContent(
326+
html`<div
327+
style="width: 100px; height: 100px; background: red;"
328+
onclick="window.open('about:blank', '_blank')"
329+
></div>`,
330+
);
331+
await context.createTextSnapshot();
332+
await clickAt.handler(
333+
{
334+
params: {
335+
x: 50,
336+
y: 50,
337+
},
338+
},
339+
response,
340+
context,
341+
);
342+
assert.ok(response.includePages);
343+
const formattedResponse = await response.handle('test', context);
344+
const textContent = getTextContent(formattedResponse.content[0]);
345+
assert.ok(textContent.includes('## Pages'));
346+
});
347+
});
296348
});
297349

298350
describe('fill', () => {

0 commit comments

Comments
 (0)