Skip to content

Commit e2f0c86

Browse files
Merge branch 'master' into pr/add-config-fields
2 parents 991262e + 2c57f06 commit e2f0c86

File tree

4 files changed

+155
-7
lines changed

4 files changed

+155
-7
lines changed

.all-contributorsrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,16 @@
11451145
"code",
11461146
"test"
11471147
]
1148+
},
1149+
{
1150+
"login": "ipap360",
1151+
"name": "Ioannis Papadopoulos",
1152+
"avatar_url": "https://avatars2.githubusercontent.com/u/11017666?v=4",
1153+
"profile": "https://github.com/ipap360",
1154+
"contributions": [
1155+
"code",
1156+
"test"
1157+
]
11481158
}
11491159
],
11501160
"repoHost": "https://github.com"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ Thanks goes to these people ([emoji key][emojis]):
281281
<td align="center"><a href="https://www.linkedin.com/in/deniz-susman-92b40a145/"><img src="https://avatars1.githubusercontent.com/u/39295979?v=4" width="100px;" alt=""/><br /><sub><b>Deniz Susman</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=DenrizSusam" title="Code">💻</a></td>
282282
<td align="center"><a href="https://github.com/delca85"><img src="https://avatars1.githubusercontent.com/u/4076043?v=4" width="100px;" alt=""/><br /><sub><b>Bianca Del Carretto</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=delca85" title="Tests">⚠️</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=delca85" title="Code">💻</a></td>
283283
<td align="center"><a href="https://www.linkedin.com/in/joshlalonde3/"><img src="https://avatars3.githubusercontent.com/u/9097492?v=4" width="100px;" alt=""/><br /><sub><b>Josh Lalonde</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=ryuuji3" title="Code">💻</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=ryuuji3" title="Tests">⚠️</a></td>
284+
<td align="center"><a href="https://github.com/ipap360"><img src="https://avatars2.githubusercontent.com/u/11017666?v=4" width="100px;" alt=""/><br /><sub><b>Ioannis Papadopoulos</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=ipap360" title="Code">💻</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=ipap360" title="Tests">⚠️</a></td>
284285
</tr>
285286
</table>
286287

src/__tests__/element-queries.js

Lines changed: 113 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,17 +352,19 @@ test('label with no form control', () => {
352352
`)
353353
})
354354

355-
test('label with no form control and fuzzy matcher', () => {
355+
test('label with "for" attribute but no form control and fuzzy matcher', () => {
356356
const {getByLabelText, queryByLabelText} = render(
357-
`<label>All alone label</label>`,
357+
`<label for="foo">All alone label</label>`,
358358
)
359359
expect(queryByLabelText('alone', {exact: false})).toBeNull()
360360
expect(() => getByLabelText('alone', {exact: false}))
361361
.toThrowErrorMatchingInlineSnapshot(`
362362
"Found a label with the text of: alone, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.
363363
364364
<div>
365-
<label>
365+
<label
366+
for="foo"
367+
>
366368
All alone label
367369
</label>
368370
</div>"
@@ -407,6 +409,114 @@ test('label with children with no form control', () => {
407409
`)
408410
})
409411

412+
test('label with non-labellable element', () => {
413+
const {getByLabelText, queryByLabelText} = render(`
414+
<div>
415+
<label for="div1">Label 1</label>
416+
<div id="div1">
417+
Hello
418+
</div>
419+
</div>
420+
`)
421+
422+
expect(queryByLabelText(/Label/)).toBeNull()
423+
expect(() => getByLabelText(/Label/)).toThrowErrorMatchingInlineSnapshot(`
424+
"Found a label with the text of: /Label/, however the element associated with this label (<div />) is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a <div />, you can use aria-label or aria-labelledby instead.
425+
426+
<div>
427+
428+
429+
<div>
430+
431+
432+
<label
433+
for="div1"
434+
>
435+
Label 1
436+
</label>
437+
438+
439+
<div
440+
id="div1"
441+
>
442+
443+
Hello
444+
445+
</div>
446+
447+
448+
</div>
449+
450+
451+
</div>"
452+
`)
453+
})
454+
455+
test('multiple labels with non-labellable elements', () => {
456+
const {getAllByLabelText, queryAllByLabelText} = render(`
457+
<div>
458+
<label for="span1">Label 1</label>
459+
<span id="span1">
460+
Hello
461+
</span>
462+
<label for="p1">Label 2</label>
463+
<p id="p1">
464+
World
465+
</p>
466+
</div>
467+
`)
468+
469+
expect(queryAllByLabelText(/Label/)).toEqual([])
470+
expect(() => getAllByLabelText(/Label/)).toThrowErrorMatchingInlineSnapshot(`
471+
"Found a label with the text of: /Label/, however the element associated with this label (<span />) is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a <span />, you can use aria-label or aria-labelledby instead.
472+
473+
Found a label with the text of: /Label/, however the element associated with this label (<p />) is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a <p />, you can use aria-label or aria-labelledby instead.
474+
475+
<div>
476+
477+
478+
<div>
479+
480+
481+
<label
482+
for="span1"
483+
>
484+
Label 1
485+
</label>
486+
487+
488+
<span
489+
id="span1"
490+
>
491+
492+
Hello
493+
494+
</span>
495+
496+
497+
<label
498+
for="p1"
499+
>
500+
Label 2
501+
</label>
502+
503+
504+
<p
505+
id="p1"
506+
>
507+
508+
World
509+
510+
</p>
511+
512+
513+
</div>
514+
515+
516+
</div>"
517+
`)
518+
})
519+
410520
test('totally empty label', () => {
411521
const {getByLabelText, queryByLabelText} = render(`<label />`)
412522
expect(queryByLabelText('')).toBeNull()

src/queries/label-text.js

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,27 @@ const getAllByLabelText = (container, text, ...rest) => {
149149
if (!els.length) {
150150
const labels = queryAllLabelsByText(container, text, ...rest)
151151
if (labels.length) {
152-
throw getConfig().getElementError(
153-
`Found a label with the text of: ${text}, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.`,
154-
container,
155-
)
152+
const tagNames = labels
153+
.map(label =>
154+
getTagNameOfElementAssociatedWithLabelViaFor(container, label),
155+
)
156+
.filter(tagName => !!tagName)
157+
if (tagNames.length) {
158+
throw getConfig().getElementError(
159+
tagNames
160+
.map(
161+
tagName =>
162+
`Found a label with the text of: ${text}, however the element associated with this label (<${tagName} />) is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a <${tagName} />, you can use aria-label or aria-labelledby instead.`,
163+
)
164+
.join('\n\n'),
165+
container,
166+
)
167+
} else {
168+
throw getConfig().getElementError(
169+
`Found a label with the text of: ${text}, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.`,
170+
container,
171+
)
172+
}
156173
} else {
157174
throw getConfig().getElementError(
158175
`Unable to find a label with the text of: ${text}`,
@@ -163,6 +180,16 @@ const getAllByLabelText = (container, text, ...rest) => {
163180
return els
164181
}
165182

183+
function getTagNameOfElementAssociatedWithLabelViaFor(container, label) {
184+
const htmlFor = label.getAttribute('for')
185+
if (!htmlFor) {
186+
return null
187+
}
188+
189+
const element = container.querySelector(`[id="${htmlFor}"]`)
190+
return element ? element.tagName.toLowerCase() : null
191+
}
192+
166193
// the reason mentioned above is the same reason we're not using buildQueries
167194
const getMultipleError = (c, text) =>
168195
`Found multiple elements with the text of: ${text}`

0 commit comments

Comments
 (0)