From 6c34f0ff4b1c8eee334cda0a9665c27b7747a767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Sun, 2 Jun 2019 10:32:52 +0200 Subject: [PATCH 1/5] feat: add getAllByTestId and queryAllByTestId queries --- src/helpers/getByAPI.js | 13 +++++++++++++ src/helpers/queryByAPI.js | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/helpers/getByAPI.js b/src/helpers/getByAPI.js index c0a219c85..9f6b9e7fa 100644 --- a/src/helpers/getByAPI.js +++ b/src/helpers/getByAPI.js @@ -212,6 +212,18 @@ export const getAllByProps = (instance: ReactTestInstance) => return results; }; +export const getAllByTestId = (instance: ReactTestInstance) => + function getAllByTestIdFn(testID: string) { + const results = instance.findAllByProps({ testID }); + if (results.length === 0) { + throw new ErrorWithStack( + `No instances found with testID: ${String(testID)}`, + getAllByTestIdFn + ); + } + return results; + }; + export const getByAPI = (instance: ReactTestInstance) => ({ getByTestId: getByTestId(instance), getByName: getByName(instance), @@ -220,6 +232,7 @@ export const getByAPI = (instance: ReactTestInstance) => ({ getByPlaceholder: getByPlaceholder(instance), getByDisplayValue: getByDisplayValue(instance), getByProps: getByProps(instance), + getAllByTestId: getAllByTestId(instance), getAllByName: getAllByName(instance), getAllByType: getAllByType(instance), getAllByText: getAllByText(instance), diff --git a/src/helpers/queryByAPI.js b/src/helpers/queryByAPI.js index 95c6c5c06..33c146add 100644 --- a/src/helpers/queryByAPI.js +++ b/src/helpers/queryByAPI.js @@ -8,6 +8,7 @@ import { getByPlaceholder, getByDisplayValue, getByProps, + getAllByTestId, getAllByName, getAllByType, getAllByText, @@ -142,6 +143,16 @@ export const queryAllByProps = (instance: ReactTestInstance) => (props: { } }; +export const queryAllByTestId = (instance: ReactTestInstance) => ( + testID: string +) => { + try { + return getAllByTestId(instance)(testID); + } catch (error) { + return []; + } +}; + export const queryByAPI = (instance: ReactTestInstance) => ({ queryByTestId: queryByTestId(instance), queryByName: queryByName(instance), @@ -150,6 +161,7 @@ export const queryByAPI = (instance: ReactTestInstance) => ({ queryByPlaceholder: queryByPlaceholder(instance), queryByDisplayValue: queryByDisplayValue(instance), queryByProps: queryByProps(instance), + queryAllByTestId: queryAllByTestId(instance), queryAllByName: queryAllByName(instance), queryAllByType: queryAllByType(instance), queryAllByText: queryAllByText(instance), From 9fa438602cd8cb1e552b7143a724869c19dc0a81 Mon Sep 17 00:00:00 2001 From: Scotty Waggoner Date: Tue, 2 Jul 2019 22:28:38 -0700 Subject: [PATCH 2/5] Add test for getAllByTestId and queryAllByTestId - Filter out intermediate components in getAllByTestId. testIDs may be passed down to child components and appearing multiple times in the render tree. Some React Native components render multiple anyways. is an example. --- .../__snapshots__/render.test.js.snap | 50 +++++++++++++++++++ src/__tests__/render.test.js | 23 ++++++++- src/helpers/getByAPI.js | 5 +- 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/__tests__/__snapshots__/render.test.js.snap b/src/__tests__/__snapshots__/render.test.js.snap index 29c1bfa1f..9839db4dc 100644 --- a/src/__tests__/__snapshots__/render.test.js.snap +++ b/src/__tests__/__snapshots__/render.test.js.snap @@ -45,6 +45,16 @@ exports[`debug 1`] = ` Change freshness! + + First Text + + + Second Text + " `; @@ -93,6 +103,16 @@ exports[`debug changing component: bananaFresh button message should now be "fre Change freshness! + + First Text + + + Second Text + " `; @@ -128,6 +148,16 @@ exports[`debug: shallow 1`] = ` > Change freshness! + + First Text + + + Second Text + " `; @@ -165,6 +195,16 @@ exports[`debug: shallow with message 1`] = ` > Change freshness! + + First Text + + + Second Text + " `; @@ -215,6 +255,16 @@ exports[`debug: with message 1`] = ` Change freshness! + + First Text + + + Second Text + " `; diff --git a/src/__tests__/render.test.js b/src/__tests__/render.test.js index 8879b90e1..372e19fdb 100644 --- a/src/__tests__/render.test.js +++ b/src/__tests__/render.test.js @@ -71,6 +71,8 @@ class Banana extends React.Component<*, *> { + First Text + Second Text ); } @@ -87,6 +89,25 @@ test('getByTestId, queryByTestId', () => { expect(queryByTestId('InExistent')).toBeNull(); }); +test('getAllByTestId, queryAllByTestId', () => { + const { getAllByTestId, queryAllByTestId } = render(); + const textElements = getAllByTestId('duplicateText'); + + expect(textElements.length).toBe(2); + expect(textElements[0].props.children).toBe('First Text'); + expect(textElements[1].props.children).toBe('Second Text'); + expect(() => getAllByTestId('nonExistentTestId')).toThrow( + 'No instances found' + ); + + const queriedTextElements = queryAllByTestId('duplicateText'); + + expect(queriedTextElements.length).toBe(2); + expect(queriedTextElements[0]).toBe(textElements[0]); + expect(queriedTextElements[1]).toBe(textElements[1]); + expect(queryAllByTestId('nonExistentTestId')).toHaveLength(0); +}); + test('getByName, queryByName', () => { const { getByTestId, getByName, queryByName } = render(); const bananaFresh = getByTestId('bananaFresh'); @@ -101,7 +122,7 @@ test('getByName, queryByName', () => { expect(bananaFresh.props.children).toBe('not fresh'); expect(() => getByName('InExistent')).toThrow('No instances found'); - expect(() => getByName(Text)).toThrow('Expected 1 but found 3'); + expect(() => getByName(Text)).toThrow('Expected 1 but found 5'); expect(queryByName('Button')).toBe(button); expect(queryByName('InExistent')).toBeNull(); diff --git a/src/helpers/getByAPI.js b/src/helpers/getByAPI.js index 9f6b9e7fa..224fa1619 100644 --- a/src/helpers/getByAPI.js +++ b/src/helpers/getByAPI.js @@ -214,7 +214,10 @@ export const getAllByProps = (instance: ReactTestInstance) => export const getAllByTestId = (instance: ReactTestInstance) => function getAllByTestIdFn(testID: string) { - const results = instance.findAllByProps({ testID }); + const results = instance + .findAllByProps({ testID }) + .filter(element => typeof element.type === 'string'); + if (results.length === 0) { throw new ErrorWithStack( `No instances found with testID: ${String(testID)}`, From ed54913115569b905a8969e374c09b26eac82cf0 Mon Sep 17 00:00:00 2001 From: Scotty Waggoner Date: Tue, 2 Jul 2019 22:53:14 -0700 Subject: [PATCH 3/5] Update TypeScript typings --- typings/index.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/typings/index.d.ts b/typings/index.d.ts index 838460332..d78bd8849 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -9,6 +9,7 @@ export interface GetByAPI { getByDisplayValue: (value: string | RegExp) => ReactTestInstance; getByProps: (props: Record) => ReactTestInstance; getByTestId: (testID: string) => ReactTestInstance; + getAllByTestId: (testID: string) => Array; getAllByName: (name: React.ReactType | string) => Array; getAllByType:

(type: React.ComponentType

) => Array; getAllByText: (text: string | RegExp) => Array; @@ -29,6 +30,7 @@ export interface QueryByAPI { queryByDisplayValue: (value: string | RegExp) => ReactTestInstance | null; queryByProps: (props: Record) => ReactTestInstance | null; queryByTestId: (testID: string) => ReactTestInstance | null; + queryAllByTestId: (testID: string) => Array | null; queryAllByName: ( name: React.ReactType | string ) => Array | []; From c04bddca7198d0918fc4ec5fb10890db5df72ad9 Mon Sep 17 00:00:00 2001 From: Scotty Waggoner Date: Tue, 2 Jul 2019 23:00:43 -0700 Subject: [PATCH 4/5] Fix flow types --- src/helpers/getByAPI.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/getByAPI.js b/src/helpers/getByAPI.js index 224fa1619..0bf99d16f 100644 --- a/src/helpers/getByAPI.js +++ b/src/helpers/getByAPI.js @@ -213,7 +213,7 @@ export const getAllByProps = (instance: ReactTestInstance) => }; export const getAllByTestId = (instance: ReactTestInstance) => - function getAllByTestIdFn(testID: string) { + function getAllByTestIdFn(testID: string): ReactTestInstance[] { const results = instance .findAllByProps({ testID }) .filter(element => typeof element.type === 'string'); From 6f9fcc9971b753a76e754643eb6201acf8e7f607 Mon Sep 17 00:00:00 2001 From: Scotty Waggoner Date: Wed, 3 Jul 2019 00:49:06 -0700 Subject: [PATCH 5/5] Update TS typings test --- typings/__tests__/index.test.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/typings/__tests__/index.test.tsx b/typings/__tests__/index.test.tsx index c06112a86..2ea7d1ec1 100644 --- a/typings/__tests__/index.test.tsx +++ b/typings/__tests__/index.test.tsx @@ -54,6 +54,7 @@ const getByDisplayValueRegExp: ReactTestInstance = tree.getByDisplayValue( ); const getByProps: ReactTestInstance = tree.getByProps({ value: 2 }); const getByTestId: ReactTestInstance = tree.getByTestId('test-id'); +const getAllByTestId: ReactTestInstance[] = tree.getAllByTestId('test-id'); const getAllByNameString: Array = tree.getAllByName('View'); const getAllByNameConstructor: Array = tree.getAllByName( View @@ -93,6 +94,9 @@ const queryByDisplayValueRegExp: ReactTestInstance | null = tree.queryByDisplayV ); const queryByProps: ReactTestInstance | null = tree.queryByProps({ value: 2 }); const queryByTestId: ReactTestInstance | null = tree.queryByTestId('test-id'); +const queryAllByTestId: ReactTestInstance[] | null = tree.queryAllByTestId( + 'test-id' +); const queryAllByNameString: Array = tree.queryAllByName( 'View' );