Skip to content

Commit d2bc489

Browse files
authored
fix: check that combobox is actually a select element before filling out options (#979)
Closes #975
1 parent c0009f7 commit d2bc489

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

src/tools/input.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ async function selectOption(
177177
}
178178
}
179179

180+
function hasOptionChildren(aXNode: TextSnapshotNode) {
181+
return aXNode.children.some(child => child.role === 'option');
182+
}
183+
180184
async function fillFormElement(
181185
uid: string,
182186
value: string,
@@ -185,7 +189,9 @@ async function fillFormElement(
185189
const handle = await context.getElementByUid(uid);
186190
try {
187191
const aXNode = context.getAXNodeByUid(uid);
188-
if (aXNode && aXNode.role === 'combobox') {
192+
// We assume that combobox needs to be handled as select if it has
193+
// role='combobox' and option children.
194+
if (aXNode && aXNode.role === 'combobox' && hasOptionChildren(aXNode)) {
189195
await selectOption(handle, aXNode, value);
190196
} else {
191197
// Increase timeout for longer input values.

tests/tools/input.test.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,13 +352,40 @@ describe('input', () => {
352352
});
353353
});
354354

355+
it('fills out a textarea marked as combobox', async () => {
356+
await withMcpContext(async (response, context) => {
357+
const page = context.getSelectedPage();
358+
await page.setContent(html`<textarea role="combobox" />`);
359+
await context.createTextSnapshot();
360+
await fill.handler(
361+
{
362+
params: {
363+
uid: '1_1',
364+
value: '1',
365+
},
366+
},
367+
response,
368+
context,
369+
);
370+
assert.strictEqual(
371+
response.responseLines[0],
372+
'Successfully filled out the element',
373+
);
374+
assert.ok(response.includeSnapshot);
375+
assert.ok(
376+
await page.evaluate(() => {
377+
return document.body.querySelector('textarea')?.value === '1';
378+
}),
379+
);
380+
});
381+
});
382+
355383
it('fills out a textarea with long text', async () => {
356384
await withMcpContext(async (response, context) => {
357385
const page = context.getSelectedPage();
358386
await page.setContent(html`<textarea />`);
359-
await page.focus('textarea');
360387
await context.createTextSnapshot();
361-
await page.setDefaultTimeout(1000);
388+
page.setDefaultTimeout(1000);
362389
await fill.handler(
363390
{
364391
params: {

0 commit comments

Comments
 (0)