diff --git a/src/tools/input.ts b/src/tools/input.ts index cd8b2f4d0..c309326e4 100644 --- a/src/tools/input.ts +++ b/src/tools/input.ts @@ -177,6 +177,10 @@ async function selectOption( } } +function hasOptionChildren(aXNode: TextSnapshotNode) { + return aXNode.children.some(child => child.role === 'option'); +} + async function fillFormElement( uid: string, value: string, @@ -185,7 +189,9 @@ async function fillFormElement( const handle = await context.getElementByUid(uid); try { const aXNode = context.getAXNodeByUid(uid); - if (aXNode && aXNode.role === 'combobox') { + // We assume that combobox needs to be handled as select if it has + // role='combobox' and option children. + if (aXNode && aXNode.role === 'combobox' && hasOptionChildren(aXNode)) { await selectOption(handle, aXNode, value); } else { // Increase timeout for longer input values. diff --git a/tests/tools/input.test.ts b/tests/tools/input.test.ts index 06a752148..37f861add 100644 --- a/tests/tools/input.test.ts +++ b/tests/tools/input.test.ts @@ -352,13 +352,40 @@ describe('input', () => { }); }); + it('fills out a textarea marked as combobox', async () => { + await withMcpContext(async (response, context) => { + const page = context.getSelectedPage(); + await page.setContent(html`