diff --git a/src/__tests__/element-queries.js b/src/__tests__/element-queries.js index 8a8bc35f..253a64a4 100644 --- a/src/__tests__/element-queries.js +++ b/src/__tests__/element-queries.js @@ -412,6 +412,7 @@ test('queryAllByRole returns semantic html elements', () => {
+
`) @@ -433,6 +434,9 @@ test('queryAllByRole returns semantic html elements', () => { expect(queryAllByRole(/rowgroup/i)).toHaveLength(2) expect(queryAllByRole(/(table)|(textbox)/i)).toHaveLength(3) expect(queryAllByRole(/img/i)).toHaveLength(1) + expect(queryAllByRole('meter')).toHaveLength(1) + expect(queryAllByRole('progressbar')).toHaveLength(0) + expect(queryAllByRole('progressbar', {queryFallbacks: true})).toHaveLength(1) }) test('getAll* matchers return an array', () => { @@ -471,6 +475,7 @@ test('getAll* matchers return an array', () => { +
, `) expect(getAllByAltText(/finding.*poster$/i)).toHaveLength(2) @@ -482,6 +487,8 @@ test('getAll* matchers return an array', () => { expect(getAllByDisplayValue(/cars$/)).toHaveLength(2) expect(getAllByText(/^where/i)).toHaveLength(1) expect(getAllByRole(/container/i)).toHaveLength(1) + expect(getAllByRole('meter')).toHaveLength(1) + expect(getAllByRole('progressbar', {queryFallbacks: true})).toHaveLength(1) }) test('getAll* matchers throw for 0 matches', () => { @@ -658,6 +665,18 @@ test('using jest helpers to check element role', () => { expect(getByRole('dialog')).toHaveTextContent('Contents') }) +test('using jest helpers to check element fallback roles', () => { + const {getByRole} = render(` +
+ Contents +
+ `) + + expect(getByRole('progressbar', {queryFallbacks: true})).toHaveTextContent( + 'Contents', + ) +}) + test('test the debug helper prints the dom state here', () => { const originalDebugPrintLimit = process.env.DEBUG_PRINT_LIMIT const Large = `
diff --git a/src/__tests__/queries.find.js b/src/__tests__/queries.find.js index facceba2..d3d59832 100644 --- a/src/__tests__/queries.find.js +++ b/src/__tests__/queries.find.js @@ -33,6 +33,7 @@ test('find asynchronously finds elements', async () => { test alt text
+
`) await expect(findByLabelText('test-label')).resolves.toBeTruthy() @@ -56,6 +57,15 @@ test('find asynchronously finds elements', async () => { await expect(findByRole('dialog')).resolves.toBeTruthy() await expect(findAllByRole('dialog')).resolves.toHaveLength(1) + await expect(findByRole('meter')).resolves.toBeTruthy() + await expect(findAllByRole('meter')).resolves.toHaveLength(1) + await expect( + findByRole('progressbar', {queryFallbacks: true}), + ).resolves.toBeTruthy() + await expect( + findAllByRole('progressbar', {queryFallbacks: true}), + ).resolves.toHaveLength(1) + await expect(findByTestId('test-id')).resolves.toBeTruthy() await expect(findAllByTestId('test-id')).resolves.toHaveLength(1) }) diff --git a/src/queries/role.js b/src/queries/role.js index dfc8a331..55e50e10 100644 --- a/src/queries/role.js +++ b/src/queries/role.js @@ -21,6 +21,7 @@ function queryAllByRole( hidden = getConfig().defaultHidden, trim, normalizer, + queryFallbacks = false, } = {}, ) { const matcher = exact ? matches : fuzzyMatches @@ -40,7 +41,20 @@ function queryAllByRole( const isRoleSpecifiedExplicitly = node.hasAttribute('role') if (isRoleSpecifiedExplicitly) { - return matcher(node.getAttribute('role'), node, role, matchNormalizer) + const roleValue = node.getAttribute('role') + if (queryFallbacks) { + return roleValue + .split(' ') + .filter(Boolean) + .some(text => matcher(text, node, role, matchNormalizer)) + } + // if a custom normalizer is passed then let normalizer handle the role value + if (normalizer) { + return matcher(roleValue, node, role, matchNormalizer) + } + // other wise only send the first word to match + const [firstWord] = roleValue.split(' ') + return matcher(firstWord, node, role, matchNormalizer) } const implicitRoles = getImplicitAriaRoles(node)