diff --git a/src/__tests__/element-queries.js b/src/__tests__/element-queries.js index 3e3ee6de..4a07156f 100644 --- a/src/__tests__/element-queries.js +++ b/src/__tests__/element-queries.js @@ -22,6 +22,26 @@ test('query can return null', () => { expect(queryByAltText('LucyRicardo')).toBeNull() }) +test('query by text outside `aria-hidden` tags', () => { + const {queryByText} = render('
LucyRicardo
') + expect(queryByText('LucyRicardo')).not.toBeNull() + const {queryByText: queryByTextRoot} = render( + '
LucyRicardo
', + ) + expect(queryByTextRoot('LucyRicardo')).not.toBeNull() +}) + +test('query by text inside `aria-hidden` tags', () => { + const {queryByText} = render( + '', + ) + expect(queryByText('LucyRicardo')).toBeNull() + const {queryByText: queryByTextRoot} = render( + '', + ) + expect(queryByTextRoot('LucyRicardo')).toBeNull() +}) + test('get throws a useful error message', () => { const { getByLabelText, diff --git a/src/queries/text.js b/src/queries/text.js index 903bba25..b2470210 100644 --- a/src/queries/text.js +++ b/src/queries/text.js @@ -9,6 +9,31 @@ import { buildQueries, } from './all-utils' +function ignoreHiddenElements(container, selector, baseArray) { + const hiddenElements = [ + ...Array.from(container.querySelectorAll("[aria-hidden='true']")), + ] + baseArray.forEach(base => { + if (base.getAttribute('aria-hidden') === 'true') { + hiddenElements.push(base) + } + }) + let foundHiddenChildren = [...hiddenElements] + hiddenElements.forEach(hiddenElement => { + foundHiddenChildren = [ + ...foundHiddenChildren, + ...Array.from(hiddenElement.querySelectorAll(selector)), + ] + }) + const findSameNode = foundElement => + !foundHiddenChildren.find(foundHiddenElement => + foundElement.isSameNode(foundHiddenElement), + ) + return [...baseArray, ...container.querySelectorAll(selector)].filter( + findSameNode, + ) +} + function queryAllByText( container, text, @@ -28,7 +53,10 @@ function queryAllByText( if (typeof container.matches === 'function' && container.matches(selector)) { baseArray = [container] } - return [...baseArray, ...Array.from(container.querySelectorAll(selector))] + + const foundElements = ignoreHiddenElements(container, selector, baseArray) + + return foundElements .filter(node => !ignore || !node.matches(ignore)) .filter(node => matcher(getNodeText(node), node, text, matchNormalizer)) }