Skip to content

Commit 437ea5c

Browse files
committed
feat(byRole): Implement TextMatch for name option
1 parent 810cd60 commit 437ea5c

File tree

2 files changed

+89
-7
lines changed

2 files changed

+89
-7
lines changed

src/__tests__/role.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,78 @@ test('can be filtered by accessible name', () => {
224224
).not.toBeNull()
225225
})
226226

227+
test('accessible name filter implements TextMatch', () => {
228+
const {getByRole} = render(
229+
`<h1>Sign <em>up</em></h1><h2>Details</h2><h2>Your Signature</h2>`,
230+
)
231+
232+
// subset via regex
233+
expect(getByRole('heading', {name: /gn u/})).not.toBeNull()
234+
// regex
235+
expect(getByRole('heading', {name: /^sign/i})).not.toBeNull()
236+
// function
237+
expect(
238+
getByRole('heading', {
239+
name: (name, element) => {
240+
return element.nodeName === 'H2' && name === 'Your Signature'
241+
},
242+
}),
243+
).not.toBeNull()
244+
})
245+
227246
test('includes accesible names in error message', () => {
228247
const {getByRole} = render(`<h1>Sign <em>up</em></h1>`)
229248

230249
expect(() => getByRole('heading', {name: 'Sign Up'}))
231250
.toThrowErrorMatchingInlineSnapshot(`
232251
"Unable to find an accessible element with the role "heading" and name "Sign Up"
233252
253+
Here are the accessible roles:
254+
255+
heading:
256+
257+
Name "Sign up":
258+
<h1 />
259+
260+
--------------------------------------------------
261+
262+
<div>
263+
<h1>
264+
Sign
265+
<em>
266+
up
267+
</em>
268+
</h1>
269+
</div>"
270+
`)
271+
272+
expect(() => getByRole('heading', {name: /Login/}))
273+
.toThrowErrorMatchingInlineSnapshot(`
274+
"Unable to find an accessible element with the role "heading" and name \`/Login/\`
275+
276+
Here are the accessible roles:
277+
278+
heading:
279+
280+
Name "Sign up":
281+
<h1 />
282+
283+
--------------------------------------------------
284+
285+
<div>
286+
<h1>
287+
Sign
288+
<em>
289+
up
290+
</em>
291+
</h1>
292+
</div>"
293+
`)
294+
295+
expect(() => getByRole('heading', {name: () => false}))
296+
.toThrowErrorMatchingInlineSnapshot(`
297+
"Unable to find an accessible element with the role "heading" and name \`() => false\`
298+
234299
Here are the accessible roles:
235300
236301
heading:

src/queries/role.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,19 @@ function queryAllByRole(
7373
: true
7474
})
7575
.filter(element => {
76-
return typeof name === 'string'
77-
? computeAccessibleName(element) === name
78-
: true
76+
if (name === undefined) {
77+
// Don't care
78+
return true
79+
}
80+
81+
const accessibleName = computeAccessibleName(element)
82+
if (typeof name === 'string') {
83+
return name === accessibleName
84+
}
85+
if (typeof name === 'function') {
86+
return name(accessibleName, element)
87+
}
88+
return name.test(accessibleName)
7989
})
8090
}
8191

@@ -89,7 +99,7 @@ const getMissingError = (
8999
) => {
90100
const roles = prettyRoles(container, {
91101
hidden,
92-
includeName: typeof name === 'string',
102+
includeName: name !== undefined,
93103
})
94104
let roleMessage
95105

@@ -110,12 +120,19 @@ Here are the ${hidden === false ? 'accessible' : 'available'} roles:
110120
`.trim()
111121
}
112122

123+
let nameHint = ''
124+
if (name === undefined) {
125+
nameHint = ''
126+
} else if (typeof name === 'string') {
127+
nameHint = ` and name "${name}"`
128+
} else {
129+
nameHint = ` and name \`${name}\``
130+
}
131+
113132
return `
114133
Unable to find an ${
115134
hidden === false ? 'accessible ' : ''
116-
}element with the role "${role}"${
117-
typeof name === 'string' ? ` and name "${name}"` : ''
118-
}
135+
}element with the role "${role}"${nameHint}
119136
120137
${roleMessage}`.trim()
121138
}

0 commit comments

Comments
 (0)