From c530eaa6ea885d16ec047e19729a3b3d33252229 Mon Sep 17 00:00:00 2001 From: Bianca Del Carretto Date: Fri, 5 Jun 2020 15:25:35 +0200 Subject: [PATCH 1/3] fix: getByLabelText ignores input labels (#545) --- src/__tests__/element-queries.js | 9 +++++++++ src/queries/label-text.js | 13 ++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/__tests__/element-queries.js b/src/__tests__/element-queries.js index 05aade0c..d0dbfe7e 100644 --- a/src/__tests__/element-queries.js +++ b/src/__tests__/element-queries.js @@ -168,6 +168,12 @@ test('can get form controls by label text', () => { +
+ + + + +
`) expect(getByLabelText('1st').id).toBe('first-id') @@ -176,6 +182,9 @@ test('can get form controls by label text', () => { expect(getByLabelText('4th').id).toBe('fourth.id') expect(getByLabelText('5th one').id).toBe('fifth-id') expect(getByLabelText('5th two').id).toBe('fifth-id') + expect(getByLabelText('6th one').id).toBe('sixth-id') + expect(getByLabelText('6th two').id).toBe('sixth-id') + expect(getByLabelText('6th three').id).toBe('sixth-id') }) test('can get elements labelled with aria-labelledby attribute', () => { diff --git a/src/queries/label-text.js b/src/queries/label-text.js index 9e900025..5200eab5 100644 --- a/src/queries/label-text.js +++ b/src/queries/label-text.js @@ -18,22 +18,25 @@ function queryAllLabelsByText( ) { const matcher = exact ? matches : fuzzyMatches const matchNormalizer = makeNormalizer({collapseWhitespace, trim, normalizer}) - return Array.from(container.querySelectorAll('label')).filter(label => { - let textToMatch = label.textContent + return Array.from(container.querySelectorAll('label,input')).filter(node => { + let textToMatch = + node.tagName.toLowerCase() === 'label' + ? node.textContent + : node.value || null // The children of a textarea are part of `textContent` as well. We // need to remove them from the string so we can match it afterwards. - Array.from(label.querySelectorAll('textarea')).forEach(textarea => { + Array.from(node.querySelectorAll('textarea')).forEach(textarea => { textToMatch = textToMatch.replace(textarea.value, '') }) // The children of a select are also part of `textContent`, so we // need also to remove their text. - Array.from(label.querySelectorAll('select')).forEach(select => { + Array.from(node.querySelectorAll('select')).forEach(select => { textToMatch = textToMatch.replace(select.textContent, '') }) - return matcher(textToMatch, label, text, matchNormalizer) + return matcher(textToMatch, node, text, matchNormalizer) }) } From 881820b515bd2262e22034f3ac2120dfd5bb2e7d Mon Sep 17 00:00:00 2001 From: Bianca Del Carretto Date: Sat, 6 Jun 2020 22:29:56 +0200 Subject: [PATCH 2/3] fix: getByLabelText does not get multiple concatenated labels(#545) --- src/__tests__/element-queries.js | 3 +++ src/matches.js | 6 ++++-- src/queries/label-text.js | 25 ++++++++++++++++++++++--- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/__tests__/element-queries.js b/src/__tests__/element-queries.js index d0dbfe7e..f5b36b2d 100644 --- a/src/__tests__/element-queries.js +++ b/src/__tests__/element-queries.js @@ -185,6 +185,9 @@ test('can get form controls by label text', () => { expect(getByLabelText('6th one').id).toBe('sixth-id') expect(getByLabelText('6th two').id).toBe('sixth-id') expect(getByLabelText('6th three').id).toBe('sixth-id') + expect(getByLabelText('6th one 6th two 6th three', {concat: true}).id).toBe( + 'sixth-id', + ) }) test('can get elements labelled with aria-labelledby attribute', () => { diff --git a/src/matches.js b/src/matches.js index 3241e680..77abfb4e 100644 --- a/src/matches.js +++ b/src/matches.js @@ -13,14 +13,16 @@ function fuzzyMatches(textToMatch, node, matcher, normalizer) { } } -function matches(textToMatch, node, matcher, normalizer) { +function matches(textToMatch, node, matcher, normalizer, concat = false) { if (typeof textToMatch !== 'string') { return false } const normalizedText = normalizer(textToMatch) if (typeof matcher === 'string') { - return normalizedText === matcher + return concat + ? matcher.toLowerCase().includes(normalizedText.toLowerCase()) + : normalizedText === matcher } else if (typeof matcher === 'function') { return matcher(normalizedText, node) } else { diff --git a/src/queries/label-text.js b/src/queries/label-text.js index 5200eab5..3eabb15b 100644 --- a/src/queries/label-text.js +++ b/src/queries/label-text.js @@ -14,7 +14,7 @@ import {queryAllByText} from './text' function queryAllLabelsByText( container, text, - {exact = true, trim, collapseWhitespace, normalizer} = {}, + {exact = true, trim, collapseWhitespace, normalizer, concat = false} = {}, ) { const matcher = exact ? matches : fuzzyMatches const matchNormalizer = makeNormalizer({collapseWhitespace, trim, normalizer}) @@ -36,20 +36,39 @@ function queryAllLabelsByText( textToMatch = textToMatch.replace(select.textContent, '') }) - return matcher(textToMatch, node, text, matchNormalizer) + return matcher(textToMatch, node, text, matchNormalizer, concat) }) } function queryAllByLabelText( container, text, - {selector = '*', exact = true, collapseWhitespace, trim, normalizer} = {}, + { + selector = '*', + exact = true, + collapseWhitespace, + trim, + normalizer, + concat = false, + } = {}, ) { const matchNormalizer = makeNormalizer({collapseWhitespace, trim, normalizer}) const labels = queryAllLabelsByText(container, text, { exact, normalizer: matchNormalizer, + concat, }) + if (concat) { + const labelsValues = labels.map(label => label.textContent || label.value) + if ( + labelsValues.reduce( + (agg, label) => agg.replace(`${label} `, ''), + `${text} `, + ) !== '' + ) { + return [] + } + } const labelledElements = labels .reduce((matchedElements, label) => { const elementsForLabel = [] From 5b7c97ce597b653c1ac8b77b7fbff79c808bc387 Mon Sep 17 00:00:00 2001 From: Bianca Del Carretto Date: Sat, 6 Jun 2020 22:59:45 +0200 Subject: [PATCH 3/3] fix: getByLabelText add concat type to matches(#545) --- types/matches.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/matches.d.ts b/types/matches.d.ts index 6454c86a..43b1e201 100644 --- a/types/matches.d.ts +++ b/types/matches.d.ts @@ -12,6 +12,7 @@ export interface MatcherOptions { normalizer?: NormalizerFn /** suppress suggestions for a specific query */ suggest?: boolean + concat?: boolean } export type Match = (