diff --git a/packages/playwright-core/src/server/injected/injectedScript.ts b/packages/playwright-core/src/server/injected/injectedScript.ts index d1cd880e6b..4f2ec64745 100644 --- a/packages/playwright-core/src/server/injected/injectedScript.ts +++ b/packages/playwright-core/src/server/injected/injectedScript.ts @@ -298,6 +298,11 @@ export class InjectedScript { const allElements = this._evaluator._queryCSS({ scope: root as Document | Element, pierceShadow: true }, '*'); return allElements.filter(element => { let labels: Element[] | NodeListOf | null | undefined = getAriaLabelledByElements(element); + if (labels === null) { + const ariaLabel = element.getAttribute('aria-label'); + if (ariaLabel !== null) + return matcher({ full: ariaLabel, immediate: [ariaLabel] }); + } if (labels === null) labels = (element as HTMLInputElement).labels; return !!labels && [...labels].some(label => matcher(elementText(this._evaluator._cacheText, label))); diff --git a/tests/page/selectors-get-by.spec.ts b/tests/page/selectors-get-by.spec.ts index a6012888f8..4ff4d3ed37 100644 --- a/tests/page/selectors-get-by.spec.ts +++ b/tests/page/selectors-get-by.spec.ts @@ -112,6 +112,16 @@ it('getByLabel should prioritize aria-labelledby over native label', async ({ pa expect(await page.getByLabel('Name').evaluate(e => e.textContent)).toBe('Click me'); }); +it('getByLabel should work with aria-label', async ({ page }) => { + await page.setContent(``); + expect(await page.getByLabel('Name').evaluate(e => e.id)).toBe('target'); +}); + +it('getByLabel should prioritize aria-labelledby over aria-label', async ({ page }) => { + await page.setContent(``); + expect(await page.getByLabel('Other').evaluate(e => e.id)).toBe('target'); +}); + it('getByPlaceholder should work', async ({ page }) => { await page.setContent(`