Skip to content

Commit 5f9b024

Browse files
author
Bianca Del Carretto
committed
match even superclass roles in queryAllByRole (testing-library#448)
1 parent 2b34806 commit 5f9b024

File tree

2 files changed

+55
-10
lines changed

2 files changed

+55
-10
lines changed

src/__tests__/role.js

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,9 @@ Here are the accessible roles:
346346
test('has no useful error message in findBy', async () => {
347347
const {findByRole} = render(`<li />`)
348348

349-
await expect(findByRole('option', {timeout: 1})).rejects.toThrow('Unable to find role="option"')
349+
await expect(findByRole('option', {timeout: 1})).rejects.toThrow(
350+
'Unable to find role="option"',
351+
)
350352
})
351353

352354
test('explicit role is most specific', () => {
@@ -378,6 +380,46 @@ Here are the accessible roles:
378380
`)
379381
})
380382

383+
test('superclass roles are retrieved when are abstract roles', () => {
384+
const {getAllByRole} = render(`
385+
<>
386+
<input type="text" />
387+
<input type="checkbox" />
388+
<textarea />
389+
</>`)
390+
expect(getAllByRole('textbox')).toHaveLength(2)
391+
expect(getAllByRole('input')).toHaveLength(3)
392+
})
393+
394+
test('superclass roles are retrieved for explicitly defined roles', () => {
395+
const {getAllByRole} = render(`
396+
<>
397+
<input type="checkbox" />
398+
<span role="switch" aria-checked="true" />
399+
</>
400+
`)
401+
expect(getAllByRole('switch')).toHaveLength(1)
402+
expect(getAllByRole('checkbox')).toHaveLength(2)
403+
})
404+
405+
test('superclass list has found when the defined role is feed', () => {
406+
const {getAllByRole} = render(`
407+
<>
408+
<ul>
409+
<li>abc</li>
410+
</ul>
411+
<div role="feed">
412+
<article role="listitem">xyz</article>
413+
</div>
414+
<ul role="feed">
415+
<li role="article">def</li>
416+
</ul>
417+
</>
418+
`)
419+
expect(getAllByRole('list')).toHaveLength(3)
420+
expect(getAllByRole('feed')).toHaveLength(2)
421+
})
422+
381423
describe('configuration', () => {
382424
let originalConfig
383425
beforeEach(() => {

src/queries/role.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
prettyRoles,
77
isInaccessible,
88
isSubtreeInaccessible,
9+
getRolesAndSuperClassByRoles,
910
} from '../role-helpers'
1011
import {wrapAllByQueryWithSuggestion} from '../query-helpers'
1112
import {checkContainerType} from '../helpers'
@@ -58,22 +59,24 @@ function queryAllByRole(
5859
if (isRoleSpecifiedExplicitly) {
5960
const roleValue = node.getAttribute('role')
6061
if (queryFallbacks) {
61-
return roleValue
62-
.split(' ')
63-
.filter(Boolean)
64-
.some(text => matcher(text, node, role, matchNormalizer))
62+
const roles = roleValue.split(' ').filter(Boolean)
63+
return getRolesAndSuperClassByRoles(roles).some(text =>
64+
matcher(text, node, role, matchNormalizer),
65+
)
6566
}
6667
// if a custom normalizer is passed then let normalizer handle the role value
6768
if (normalizer) {
68-
return matcher(roleValue, node, role, matchNormalizer)
69+
return getRolesAndSuperClassByRoles(roleValue).some(text =>
70+
matcher(text, node, role, matchNormalizer),
71+
)
6972
}
7073
// other wise only send the first word to match
71-
const [firstWord] = roleValue.split(' ')
72-
return matcher(firstWord, node, role, matchNormalizer)
74+
const roles = getRolesAndSuperClassByRoles(roleValue.split(' ')[0])
75+
return roles.some(text => matcher(text, node, role, matchNormalizer))
7376
}
7477

75-
const implicitRoles = getImplicitAriaRoles(node)
76-
78+
let implicitRoles = getImplicitAriaRoles(node)
79+
implicitRoles = getRolesAndSuperClassByRoles(implicitRoles)
7780
return implicitRoles.some(implicitRole =>
7881
matcher(implicitRole, node, role, matchNormalizer),
7982
)

0 commit comments

Comments
 (0)