diff --git a/src/common/AriaQueryHandler.ts b/src/common/AriaQueryHandler.ts index 9e9c69a0cedf0..cb3fd341dcde6 100644 --- a/src/common/AriaQueryHandler.ts +++ b/src/common/AriaQueryHandler.ts @@ -41,7 +41,7 @@ const normalizeValue = (value: string): string => value.replace(/ +/g, ' ').trim(); const knownAttributes = new Set(['name', 'role']); const attributeRegexp = - /\[\s*(?\w+)\s*=\s*"(?\\.|[^"\\]*)"\s*\]/g; + /\[\s*(?\w+)\s*=\s*(?"|')(?\\.|.*?(?=\k))\k\s*\]/g; /* * The selectors consist of an accessible name to query for and optionally @@ -58,7 +58,7 @@ function parseAriaSelector(selector: string): ariaQueryOption { const queryOptions: ariaQueryOption = {}; const defaultName = selector.replace( attributeRegexp, - (_, attribute: string, value: string) => { + (_, attribute: string, quote: string, value: string) => { attribute = attribute.trim(); if (!knownAttributes.has(attribute)) throw new Error(`Unknown aria attribute "${attribute}" in selector`); diff --git a/test/ariaqueryhandler.spec.ts b/test/ariaqueryhandler.spec.ts index 395978bc09553..2773520853716 100644 --- a/test/ariaqueryhandler.spec.ts +++ b/test/ariaqueryhandler.spec.ts @@ -46,6 +46,10 @@ describeChromeOnly('AriaQueryHandler', () => { 'aria/Submit button and some spaces[role="button"]' ); await expectFound(button); + button = await page.$( + "aria/Submit button and some spaces[role='button']" + ); + await expectFound(button); button = await page.$( 'aria/ Submit button and some spaces[role="button"]' ); @@ -70,6 +74,10 @@ describeChromeOnly('AriaQueryHandler', () => { 'aria/[name=" Submit button and some spaces"][role="button"]' ); await expectFound(button); + button = await page.$( + "aria/[name=' Submit button and some spaces'][role='button']" + ); + await expectFound(button); button = await page.$( 'aria/ignored[name="Submit button and some spaces"][role="button"]' );