diff --git a/packages/injected/src/roleUtils.ts b/packages/injected/src/roleUtils.ts index b230fbf847444..6e9f8daa24929 100644 --- a/packages/injected/src/roleUtils.ts +++ b/packages/injected/src/roleUtils.ts @@ -123,12 +123,12 @@ const kImplicitRoleByTagName: { [tagName: string]: (e: Element) => AriaRole | nu 'IMG': (e: Element) => (e.getAttribute('alt') === '') && !e.getAttribute('title') && !hasGlobalAriaAttribute(e) && !hasTabIndex(e) ? 'presentation' : 'img', 'INPUT': (e: Element) => { const type = (e as HTMLInputElement).type.toLowerCase(); - if (type === 'search') - return e.hasAttribute('list') ? 'combobox' : 'searchbox'; - if (['email', 'tel', 'text', 'url', ''].includes(type)) { + if (['email', 'search', 'tel', 'text', 'url', ''].includes(type)) { // https://html.spec.whatwg.org/multipage/input.html#concept-input-list const list = getIdRefs(e, e.getAttribute('list'))[0]; - return (list && elementSafeTagName(list) === 'DATALIST') ? 'combobox' : 'textbox'; + if (list && elementSafeTagName(list) === 'DATALIST') + return 'combobox'; + return type === 'search' ? 'searchbox' : 'textbox'; } if (type === 'hidden') return null; diff --git a/tests/library/role-utils.spec.ts b/tests/library/role-utils.spec.ts index 39def083f217f..21594e7c06425 100644 --- a/tests/library/role-utils.spec.ts +++ b/tests/library/role-utils.spec.ts @@ -329,6 +329,21 @@ test('native controls', async ({ page }) => { expect.soft(await getNameAndRole(page, '#file2')).toEqual({ role: 'button', name: 'FILE2' }); }); +test('input type=search maps to searchbox unless list points at a datalist', { + annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/41899' }, +}, async ({ page }) => { + await page.setContent(` + + +
+ + `); + expect.soft(await getNameAndRole(page, '#search1')).toEqual({ role: 'searchbox', name: '' }); + expect.soft(await getNameAndRole(page, '#search2')).toEqual({ role: 'searchbox', name: '' }); + expect.soft(await getNameAndRole(page, '#search3')).toEqual({ role: 'searchbox', name: '' }); + expect.soft(await getNameAndRole(page, '#search4')).toEqual({ role: 'combobox', name: '' }); +}); + test('native controls labelled-by', async ({ page }) => { await page.setContent(`