From 35a4feb71bbc12ada360940564ea432cce727cb3 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Mon, 1 Jul 2019 14:17:07 +0000 Subject: [PATCH 1/2] feat: Add ByTextContent query --- src/__tests__/text-matchers.js | 14 ++++++++++--- src/queries/index.js | 1 + src/queries/text-content.js | 29 ++++++++++++++++++++++++++ typings/queries.d.ts | 38 ++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 src/queries/text-content.js diff --git a/src/__tests__/text-matchers.js b/src/__tests__/text-matchers.js index ae5a08ab..7310f0d5 100644 --- a/src/__tests__/text-matchers.js +++ b/src/__tests__/text-matchers.js @@ -28,7 +28,7 @@ cases( queryAllByAltText: { dom: ` Finding Nemo poster`, query: `Finding Nemo poster`, @@ -87,7 +87,7 @@ cases( dom: ` 
-            Finding Nemo poster `, query: /^Finding Nemo poster$/, @@ -192,7 +192,7 @@ cases( queryAllByAltText: { dom: ` Finding Nemo poster`, query: `Finding Nemo poster`, @@ -321,3 +321,11 @@ test('we support an older API with trim and collapseWhitespace instead of a norm expect(queryAllByText('x y', {collapseWhitespace: false})).toHaveLength(0) expect(queryAllByText('x y', {collapseWhitespace: false})).toHaveLength(1) }) + +test('ByTextContent is a simple selector for HTMLElement.textContent', () => { + const {queryAllByTextContent} = render( + '', + ) + expect(queryAllByTextContent('Click me', 'button')).toHaveLength(0) + expect(queryAllByTextContent(' Click me', 'button')).toHaveLength(1) +}) diff --git a/src/queries/index.js b/src/queries/index.js index 56b283fa..65061308 100644 --- a/src/queries/index.js +++ b/src/queries/index.js @@ -6,3 +6,4 @@ export * from './alt-text' export * from './title' export * from './role' export * from './test-id' +export * from './text-content' diff --git a/src/queries/text-content.js b/src/queries/text-content.js new file mode 100644 index 00000000..db74cf8b --- /dev/null +++ b/src/queries/text-content.js @@ -0,0 +1,29 @@ +import {buildQueries, matches} from './all-utils' + +function queryAllByTextContent(container, text, selector = '*') { + return Array.from(container.querySelectorAll(selector)).filter(node => + matches(node.textContent, node, text, s => s), + ) +} + +const getMultipleError = (c, text) => + `Found multiple elements with the text content: ${text}` +const getMissingError = (c, text) => + `Unable to find an element with the text content: ${text}. This could be because your text input didn't consider whitespace.` + +const [ + queryByTextContent, + getAllByTextContent, + getByTextContent, + findAllByTextContent, + findByTextContent, +] = buildQueries(queryAllByTextContent, getMultipleError, getMissingError) + +export { + queryByTextContent, + queryAllByTextContent, + getByTextContent, + getAllByTextContent, + findAllByTextContent, + findByTextContent, +} diff --git a/typings/queries.d.ts b/typings/queries.d.ts index 5a9ba329..0183e44c 100644 --- a/typings/queries.d.ts +++ b/typings/queries.d.ts @@ -66,6 +66,38 @@ export type FindByText = ( waitForElementOptions?: WaitForElementOptions, ) => Promise +export type QueryByTextContent = ( + container: HTMLElement, + id: Matcher, + selector?: string, +) => HTMLElement | null + +export type AllByTextContent = ( + container: HTMLElement, + id: Matcher, + selector?: string, +) => HTMLElement[] + +export type FindAllByTextContent = ( + container: HTMLElement, + id: Matcher, + selector?: string, + waitForElementOptions?: WaitForElementOptions, +) => Promise + +export type GetByTextContent = ( + container: HTMLElement, + id: Matcher, + selector?: string, +) => HTMLElement + +export type FindByTextContent = ( + container: HTMLElement, + id: Matcher, + selector?: string, + waitForElementOptions?: WaitForElementOptions, +) => Promise + export const getByLabelText: GetByText export const getAllByLabelText: AllByText export const queryByLabelText: QueryByText @@ -84,6 +116,12 @@ export const queryByText: QueryByText export const queryAllByText: AllByText export const findByText: FindByText export const findAllByText: FindAllByText +export const getByTextContent: GetByTextContent +export const getAllByTextContent: AllByTextContent +export const queryByTextContent: QueryByTextContent +export const queryAllByTextContent: AllByTextContent +export const findByTextContent: FindByTextContent +export const findAllByTextContent: FindAllByTextContent export const getByAltText: GetByBoundAttribute export const getAllByAltText: AllByBoundAttribute export const queryByAltText: QueryByBoundAttribute From 9b76f71706d7529cf092f4a43f396deced05bccd Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Mon, 1 Jul 2019 14:42:31 +0000 Subject: [PATCH 2/2] Test default case --- src/__tests__/text-matchers.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/__tests__/text-matchers.js b/src/__tests__/text-matchers.js index 7310f0d5..d8218a34 100644 --- a/src/__tests__/text-matchers.js +++ b/src/__tests__/text-matchers.js @@ -329,3 +329,10 @@ test('ByTextContent is a simple selector for HTMLElement.textContent', () => { expect(queryAllByTextContent('Click me', 'button')).toHaveLength(0) expect(queryAllByTextContent(' Click me', 'button')).toHaveLength(1) }) + +test('ByTextContent tests all elements by default', () => { + const {container,queryAllByTextContent} = render( + 'jekyll
jekyll
', + ) + expect(queryAllByTextContent('jekyll')).toHaveLength(2) +})