Skip to content

Commit f83f8e9

Browse files
authored
fix(ByLabelText): support IE and other legacy browsers (#726)
* fix(ByLabelText): support IE Polyfill HTMLInputElement.labels to support IE and other legacy browsers. Closes #723. * fix: ensure mocks are restored * test: remove unnecessary test cases Co-authored-by: Maxwell Newlands <[email protected]>
1 parent 54aebf7 commit f83f8e9

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

src/__tests__/element-queries.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,3 +1182,19 @@ test('return a proper error message when no label is found and there is an aria-
11821182
</div>"
11831183
`)
11841184
})
1185+
1186+
// https://github.com/testing-library/dom-testing-library/issues/723
1187+
it('gets form controls by label text on IE and other legacy browsers', () => {
1188+
// Simulate lack of support for HTMLInputElement.prototype.labels
1189+
jest
1190+
.spyOn(HTMLInputElement.prototype, 'labels', 'get')
1191+
.mockReturnValue(undefined)
1192+
1193+
const {getByLabelText} = renderIntoDocument(`
1194+
<label>
1195+
Label text
1196+
<input id="input-id" />
1197+
</label>
1198+
`)
1199+
expect(getByLabelText('Label text').id).toBe('input-id')
1200+
})

src/queries/label-text.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ function queryAllByLabelText(
7272
const matcher = exact ? matches : fuzzyMatches
7373
const matchNormalizer = makeNormalizer({collapseWhitespace, trim, normalizer})
7474
const matchingLabelledElements = Array.from(container.querySelectorAll('*'))
75-
.filter(
76-
element => element.labels || element.hasAttribute('aria-labelledby'),
77-
)
75+
.filter(element => {
76+
return getLabels(element) || element.hasAttribute('aria-labelledby')
77+
})
7878
.reduce((labelledElements, labelledElement) => {
7979
const labelsId = labelledElement.getAttribute('aria-labelledby')
8080
? labelledElement.getAttribute('aria-labelledby').split(' ')
@@ -86,7 +86,7 @@ function queryAllByLabelText(
8686
)
8787
return labellingElement ? getLabelContent(labellingElement) : ''
8888
})
89-
: Array.from(labelledElement.labels).map(label => {
89+
: Array.from(getLabels(labelledElement)).map(label => {
9090
const textToMatch = getLabelContent(label)
9191
const formControlSelector =
9292
'button, input, meter, output, progress, select, textarea'
@@ -235,3 +235,20 @@ export {
235235
findAllByLabelText,
236236
findByLabelText,
237237
}
238+
239+
// Based on https://github.com/eps1lon/dom-accessibility-api/pull/352
240+
function getLabels(element) {
241+
if (element.labels !== undefined) return element.labels
242+
243+
if (!isLabelable(element)) return null
244+
245+
const labels = element.ownerDocument.querySelectorAll('label')
246+
return Array.from(labels).filter(label => label.control === element)
247+
}
248+
249+
function isLabelable(element) {
250+
return (
251+
element.tagName.match(/BUTTON|METER|OUTPUT|PROGRESS|SELECT|TEXTAREA/) ||
252+
(element.tagName === 'INPUT' && element.getAttribute('type') !== 'hidden')
253+
)
254+
}

tests/setup-env.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,5 @@ beforeAll(() => {
3737
})
3838

3939
afterAll(() => {
40-
console.warn.mockRestore()
40+
jest.restoreAllMocks()
4141
})

0 commit comments

Comments
 (0)