From 4b8403e408c7a758aa5be23976544c299f85c7d0 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 14 May 2022 16:54:43 +0200 Subject: [PATCH 01/38] refactor: make Options generic type optionnal in queries --- src/queries/makeQueries.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/queries/makeQueries.ts b/src/queries/makeQueries.ts index b54da4207..0122259ab 100644 --- a/src/queries/makeQueries.ts +++ b/src/queries/makeQueries.ts @@ -3,33 +3,33 @@ import { ErrorWithStack } from '../helpers/errors'; import waitFor from '../waitFor'; import type { WaitForOptions } from '../waitFor'; -export type GetByQuery = ( +export type GetByQuery = ( predicate: Predicate, options?: Options ) => ReactTestInstance; -export type GetAllByQuery = ( +export type GetAllByQuery = ( predicate: Predicate, options?: Options ) => ReactTestInstance[]; -export type QueryByQuery = ( +export type QueryByQuery = ( predicate: Predicate, options?: Options ) => ReactTestInstance | null; -export type QueryAllByQuery = ( +export type QueryAllByQuery = ( predicate: Predicate, options?: Options ) => ReactTestInstance[]; -export type FindByQuery = ( +export type FindByQuery = ( predicate: Predicate, options?: Options & WaitForOptions, waitForOptions?: WaitForOptions ) => Promise; -export type FindAllByQuery = ( +export type FindAllByQuery = ( predicate: Predicate, options?: Options & WaitForOptions, waitForOptions?: WaitForOptions From 5896dfe0d57f2f635c58436834b7b33b000381d4 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Tue, 10 May 2022 09:01:17 +0200 Subject: [PATCH 02/38] refactor: extract byLabelText queries and its tests --- src/queries/__tests__/a11yAPI.test.tsx | 49 ---------- src/queries/__tests__/labelText.test.tsx | 110 +++++++++++++++++++++++ src/queries/a11yAPI.ts | 26 ------ src/queries/labelText.ts | 68 ++++++++++++++ src/within.ts | 2 + 5 files changed, 180 insertions(+), 75 deletions(-) create mode 100644 src/queries/__tests__/labelText.test.tsx create mode 100644 src/queries/labelText.ts diff --git a/src/queries/__tests__/a11yAPI.test.tsx b/src/queries/__tests__/a11yAPI.test.tsx index b195b13ad..f61780ff3 100644 --- a/src/queries/__tests__/a11yAPI.test.tsx +++ b/src/queries/__tests__/a11yAPI.test.tsx @@ -69,55 +69,6 @@ function Section() { ); } -test('getByLabelText, queryByLabelText, findByLabelText', async () => { - const { getByLabelText, queryByLabelText, findByLabelText } = render( -
- ); - - expect(getByLabelText(BUTTON_LABEL).props.accessibilityLabel).toEqual( - BUTTON_LABEL - ); - const button = queryByLabelText(/button/g); - expect(button?.props.accessibilityLabel).toEqual(BUTTON_LABEL); - - expect(() => getByLabelText(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityLabel') - ); - expect(queryByLabelText(NO_MATCHES_TEXT)).toBeNull(); - - expect(() => getByLabelText(TEXT_LABEL)).toThrow(FOUND_TWO_INSTANCES); - expect(() => queryByLabelText(TEXT_LABEL)).toThrow(FOUND_TWO_INSTANCES); - - const asyncButton = await findByLabelText(BUTTON_LABEL); - expect(asyncButton.props.accessibilityLabel).toEqual(BUTTON_LABEL); - await expect( - findByLabelText(NO_MATCHES_TEXT, waitForOptions) - ).rejects.toThrow(getNoInstancesFoundMessage('accessibilityLabel')); - - await expect(findByLabelText(TEXT_LABEL, waitForOptions)).rejects.toThrow( - FOUND_TWO_INSTANCES - ); -}); - -test('getAllByLabelText, queryAllByLabelText, findAllByLabelText', async () => { - const { getAllByLabelText, queryAllByLabelText, findAllByLabelText } = render( -
- ); - - expect(getAllByLabelText(TEXT_LABEL)).toHaveLength(2); - expect(queryAllByLabelText(/cool/g)).toHaveLength(3); - - expect(() => getAllByLabelText(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityLabel') - ); - expect(queryAllByLabelText(NO_MATCHES_TEXT)).toEqual([]); - - await expect(findAllByLabelText(TEXT_LABEL)).resolves.toHaveLength(2); - await expect(findAllByLabelText(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityLabel') - ); -}); - test('getByA11yHint, queryByA11yHint, findByA11yHint', async () => { const { getByA11yHint, queryByA11yHint, findByA11yHint } = render(
diff --git a/src/queries/__tests__/labelText.test.tsx b/src/queries/__tests__/labelText.test.tsx new file mode 100644 index 000000000..75b638c41 --- /dev/null +++ b/src/queries/__tests__/labelText.test.tsx @@ -0,0 +1,110 @@ +import * as React from 'react'; +import { TouchableOpacity, Text } from 'react-native'; +import { render } from '../..'; + +const BUTTON_LABEL = 'cool button'; +const BUTTON_HINT = 'click this button'; +const TEXT_LABEL = 'cool text'; +const TEXT_HINT = 'static text'; +// Little hack to make all the methods happy with type +const NO_MATCHES_TEXT: any = 'not-existent-element'; + +const getMultipleInstancesFoundMessage = ( + name: string, + value: string = NO_MATCHES_TEXT +) => { + return `Found multiple elements with ${name}: ${value}`; +}; + +const getNoInstancesFoundMessage = ( + name: string, + value: string = NO_MATCHES_TEXT +) => { + return `Unable to find an element with ${name}: ${value}`; +}; + +const Typography = ({ children, ...rest }: any) => { + return {children}; +}; + +class Button extends React.Component { + render() { + return ( + + + {this.props.children} + + + ); + } +} + +function Section() { + return ( + <> + + Title + + + + ); +} + +test('getByLabelText, queryByLabelText, findByLabelText', async () => { + const { getByLabelText, queryByLabelText, findByLabelText } = render( +
+ ); + + expect(getByLabelText(BUTTON_LABEL).props.accessibilityLabel).toEqual( + BUTTON_LABEL + ); + const button = queryByLabelText(/button/g); + expect(button?.props.accessibilityLabel).toEqual(BUTTON_LABEL); + + expect(() => getByLabelText(NO_MATCHES_TEXT)).toThrow( + getNoInstancesFoundMessage('accessibilityLabel') + ); + expect(queryByLabelText(NO_MATCHES_TEXT)).toBeNull(); + + expect(() => getByLabelText(TEXT_LABEL)).toThrow( + getMultipleInstancesFoundMessage('accessibilityLabel', TEXT_LABEL) + ); + expect(() => queryByLabelText(TEXT_LABEL)).toThrow( + getMultipleInstancesFoundMessage('accessibilityLabel', TEXT_LABEL) + ); + + const asyncButton = await findByLabelText(BUTTON_LABEL); + expect(asyncButton.props.accessibilityLabel).toEqual(BUTTON_LABEL); + await expect(findByLabelText(NO_MATCHES_TEXT)).rejects.toThrow( + getNoInstancesFoundMessage('accessibilityLabel') + ); + + await expect(findByLabelText(TEXT_LABEL)).rejects.toThrow( + getMultipleInstancesFoundMessage('accessibilityLabel', TEXT_LABEL) + ); +}); + +test('getAllByLabelText, queryAllByLabelText, findAllByLabelText', async () => { + const { getAllByLabelText, queryAllByLabelText, findAllByLabelText } = render( +
+ ); + + expect(getAllByLabelText(TEXT_LABEL)).toHaveLength(2); + expect(queryAllByLabelText(/cool/g)).toHaveLength(3); + + expect(() => getAllByLabelText(NO_MATCHES_TEXT)).toThrow( + getNoInstancesFoundMessage('accessibilityLabel') + ); + expect(queryAllByLabelText(NO_MATCHES_TEXT)).toEqual([]); + + await expect(findAllByLabelText(TEXT_LABEL)).resolves.toHaveLength(2); + await expect(findAllByLabelText(NO_MATCHES_TEXT)).rejects.toThrow( + getNoInstancesFoundMessage('accessibilityLabel') + ); +}); diff --git a/src/queries/a11yAPI.ts b/src/queries/a11yAPI.ts index 4b9f42e53..9eed14511 100644 --- a/src/queries/a11yAPI.ts +++ b/src/queries/a11yAPI.ts @@ -20,20 +20,6 @@ type FindReturn = Promise; type FindAllReturn = Promise; export type A11yAPI = { - // Label - getByLabelText: (label: TextMatch) => GetReturn; - getAllByLabelText: (label: TextMatch) => GetAllReturn; - queryByLabelText: (label: TextMatch) => QueryReturn; - queryAllByLabelText: (label: TextMatch) => QueryAllReturn; - findByLabelText: ( - label: TextMatch, - waitForOptions?: WaitForOptions - ) => FindReturn; - findAllByLabelText: ( - label: TextMatch, - waitForOptions?: WaitForOptions - ) => FindAllReturn; - // Hint getByA11yHint: (a11yHint: TextMatch) => GetReturn; getByHintText: (a11yHint: TextMatch) => GetReturn; @@ -170,18 +156,6 @@ export function matchObject>( export const a11yAPI = (instance: ReactTestInstance): A11yAPI => ({ - ...makeA11yQuery( - 'accessibilityLabel', - { - getBy: ['getByLabelText'], - getAllBy: ['getAllByLabelText'], - queryBy: ['queryByLabelText'], - queryAllBy: ['queryAllByLabelText'], - findBy: ['findByLabelText'], - findAllBy: ['findAllByLabelText'], - }, - matchStringValue - )(instance), ...makeA11yQuery( 'accessibilityHint', { diff --git a/src/queries/labelText.ts b/src/queries/labelText.ts new file mode 100644 index 000000000..454b67c74 --- /dev/null +++ b/src/queries/labelText.ts @@ -0,0 +1,68 @@ +import type { ReactTestInstance } from 'react-test-renderer'; +import { TextMatch } from '../matches'; +import { makeQueries } from './makeQueries'; +import type { + FindAllByQuery, + FindByQuery, + GetAllByQuery, + GetByQuery, + QueryAllByQuery, + QueryByQuery, +} from './makeQueries'; + +export function matchStringValue( + prop: string | undefined, + matcher: TextMatch +): boolean { + if (!prop) { + return false; + } + + if (typeof matcher === 'string') { + return prop === matcher; + } + + return Boolean(prop.match(matcher)); +} + +const queryAllByLabelText = ( + instance: ReactTestInstance +): ((displayValue: TextMatch) => Array) => + function queryAllByDisplayValueFn(displayValue) { + return instance.findAll( + (node) => + typeof node.type === 'string' && + matchStringValue(node.props.accessibilityLabel, displayValue) + ); + }; + +const getMultipleError = (labelText: TextMatch) => + `Found multiple elements with accessibilityLabel: ${String(labelText)} `; +const getMissingError = (labelText: TextMatch) => + `Unable to find an element with accessibilityLabel: ${String(labelText)}`; + +const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( + queryAllByLabelText, + getMissingError, + getMultipleError +); + +export type ByLabelTextQueries = { + getByLabelText: GetByQuery; + getAllByLabelText: GetAllByQuery; + queryByLabelText: QueryByQuery; + queryAllByLabelText: QueryAllByQuery; + findByLabelText: FindByQuery; + findAllByLabelText: FindAllByQuery; +}; + +export const bindByLabelTextQueries = ( + instance: ReactTestInstance +): ByLabelTextQueries => ({ + getByLabelText: getBy(instance), + getAllByLabelText: getAllBy(instance), + queryByLabelText: queryBy(instance), + queryAllByLabelText: queryAllBy(instance), + findByLabelText: findBy(instance), + findAllByLabelText: findAllBy(instance), +}); diff --git a/src/within.ts b/src/within.ts index 9a6bdc8fe..e40c45ddb 100644 --- a/src/within.ts +++ b/src/within.ts @@ -6,6 +6,7 @@ import { bindByDisplayValueQueries } from './queries/displayValue'; import { bindByPlaceholderTextQueries } from './queries/placeholderText'; import { bindUnsafeByTypeQueries } from './queries/unsafeType'; import { bindUnsafeByPropsQueries } from './queries/unsafeProps'; +import { bindByLabelTextQueries } from './queries/labelText'; export function within(instance: ReactTestInstance) { return { @@ -15,6 +16,7 @@ export function within(instance: ReactTestInstance) { ...bindByPlaceholderTextQueries(instance), ...bindUnsafeByTypeQueries(instance), ...bindUnsafeByPropsQueries(instance), + ...bindByLabelTextQueries(instance), ...a11yAPI(instance), }; } From cc7811760959d9374a477da9a2093007200d7a37 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Tue, 10 May 2022 22:11:39 +0200 Subject: [PATCH 03/38] refactor: extract byA11yHint queries and its tests --- src/queries/__tests__/a11yAPI.test.tsx | 73 ----------------- src/queries/__tests__/a11yHint.test.tsx | 100 ++++++++++++++++++++++++ src/queries/a11yAPI.ts | 54 ------------- src/queries/a11yHint.ts | 68 ++++++++++++++++ src/within.ts | 2 + 5 files changed, 170 insertions(+), 127 deletions(-) create mode 100644 src/queries/__tests__/a11yHint.test.tsx create mode 100644 src/queries/a11yHint.ts diff --git a/src/queries/__tests__/a11yAPI.test.tsx b/src/queries/__tests__/a11yAPI.test.tsx index f61780ff3..6a9ab9e16 100644 --- a/src/queries/__tests__/a11yAPI.test.tsx +++ b/src/queries/__tests__/a11yAPI.test.tsx @@ -69,54 +69,6 @@ function Section() { ); } -test('getByA11yHint, queryByA11yHint, findByA11yHint', async () => { - const { getByA11yHint, queryByA11yHint, findByA11yHint } = render( -
- ); - - expect(getByA11yHint(BUTTON_HINT).props.accessibilityHint).toEqual( - BUTTON_HINT - ); - const button = queryByA11yHint(/button/g); - expect(button?.props.accessibilityHint).toEqual(BUTTON_HINT); - - expect(() => getByA11yHint(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityHint') - ); - expect(queryByA11yHint(NO_MATCHES_TEXT)).toBeNull(); - - expect(() => getByA11yHint(TEXT_HINT)).toThrow(FOUND_TWO_INSTANCES); - expect(() => queryByA11yHint(TEXT_HINT)).toThrow(FOUND_TWO_INSTANCES); - - const asyncButton = await findByA11yHint(BUTTON_HINT); - expect(asyncButton.props.accessibilityHint).toEqual(BUTTON_HINT); - await expect(findByA11yHint(NO_MATCHES_TEXT, waitForOptions)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityHint') - ); - await expect(findByA11yHint(TEXT_HINT, waitForOptions)).rejects.toThrow( - FOUND_TWO_INSTANCES - ); -}); - -test('getAllByA11yHint, queryAllByA11yHint, findAllByA11yHint', async () => { - const { getAllByA11yHint, queryAllByA11yHint, findAllByA11yHint } = render( -
- ); - - expect(getAllByA11yHint(TEXT_HINT)).toHaveLength(2); - expect(queryAllByA11yHint(/static/g)).toHaveLength(2); - - expect(() => getAllByA11yHint(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityHint') - ); - expect(queryAllByA11yHint(NO_MATCHES_TEXT)).toEqual([]); - - await expect(findAllByA11yHint(TEXT_HINT)).resolves.toHaveLength(2); - await expect(findAllByA11yHint(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityHint') - ); -}); - test('getByRole, queryByRole, findByRole', async () => { const { getByRole, queryByRole, findByRole } = render(
); @@ -342,28 +294,3 @@ test('getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue', async () => { ); await expect(findAllByA11yValue({ max: 60 })).resolves.toHaveLength(2); }); - -test('a11y hint queries have aliases', () => { - const { - getByA11yHint, - getByHintText, - queryByA11yHint, - queryByHintText, - findByA11yHint, - findByHintText, - getAllByA11yHint, - getAllByHintText, - queryAllByA11yHint, - queryAllByHintText, - findAllByA11yHint, - findAllByHintText, - } = render(
); - - // Assert that query aliases are referencing the same function - expect(getByA11yHint).toBe(getByHintText); - expect(queryByA11yHint).toBe(queryByHintText); - expect(findByA11yHint).toBe(findByHintText); - expect(getAllByA11yHint).toBe(getAllByHintText); - expect(queryAllByA11yHint).toBe(queryAllByHintText); - expect(findAllByA11yHint).toBe(findAllByHintText); -}); diff --git a/src/queries/__tests__/a11yHint.test.tsx b/src/queries/__tests__/a11yHint.test.tsx new file mode 100644 index 000000000..05b2bface --- /dev/null +++ b/src/queries/__tests__/a11yHint.test.tsx @@ -0,0 +1,100 @@ +import * as React from 'react'; +import { TouchableOpacity, Text } from 'react-native'; +import { render } from '../..'; + +const BUTTON_HINT = 'click this button'; +const TEXT_HINT = 'static text'; +// Little hack to make all the methods happy with type +const NO_MATCHES_TEXT: any = 'not-existent-element'; + +const getMultipleInstancesFoundMessage = ( + name: string, + value: string = NO_MATCHES_TEXT +) => { + return `Found multiple elements with ${name}: ${value}`; +}; + +const getNoInstancesFoundMessage = ( + name: string, + value: string = NO_MATCHES_TEXT +) => { + return `Unable to find an element with ${name}: ${value}`; +}; + +const Typography = ({ children, ...rest }: any) => { + return {children}; +}; + +class Button extends React.Component { + render() { + return ( + + + {this.props.children} + + + ); + } +} + +function Section() { + return ( + <> + Title + + + ); +} + +test('getByA11yHint, queryByA11yHint, findByA11yHint', async () => { + const { getByA11yHint, queryByA11yHint, findByA11yHint } = render( +
+ ); + + expect(getByA11yHint(BUTTON_HINT).props.accessibilityHint).toEqual( + BUTTON_HINT + ); + const button = queryByA11yHint(BUTTON_HINT); + expect(button?.props.accessibilityHint).toEqual(BUTTON_HINT); + + expect(() => getByA11yHint(NO_MATCHES_TEXT)).toThrow( + getNoInstancesFoundMessage('accessibilityHint') + ); + expect(queryByA11yHint(NO_MATCHES_TEXT)).toBeNull(); + + expect(() => getByA11yHint(TEXT_HINT)).toThrow( + getMultipleInstancesFoundMessage('accessibilityHint', TEXT_HINT) + ); + expect(() => queryByA11yHint(TEXT_HINT)).toThrow( + getMultipleInstancesFoundMessage('accessibilityHint', TEXT_HINT) + ); + + const asyncButton = await findByA11yHint(BUTTON_HINT); + expect(asyncButton.props.accessibilityHint).toEqual(BUTTON_HINT); + await expect(findByA11yHint(NO_MATCHES_TEXT)).rejects.toThrow( + getNoInstancesFoundMessage('accessibilityHint') + ); + + await expect(findByA11yHint(TEXT_HINT)).rejects.toThrow( + getMultipleInstancesFoundMessage('accessibilityHint', TEXT_HINT) + ); +}); + +test('getAllByA11yHint, queryAllByA11yHint, findAllByA11yHint', async () => { + const { getAllByA11yHint, queryAllByA11yHint, findAllByA11yHint } = render( +
+ ); + + expect(getAllByA11yHint(TEXT_HINT)).toHaveLength(2); + expect(queryAllByA11yHint(TEXT_HINT)).toHaveLength(2); + + expect(() => getAllByA11yHint(NO_MATCHES_TEXT)).toThrow( + getNoInstancesFoundMessage('accessibilityHint') + ); + expect(queryAllByA11yHint(NO_MATCHES_TEXT)).toEqual([]); + + await expect(findAllByA11yHint(TEXT_HINT)).resolves.toHaveLength(2); + await expect(findAllByA11yHint(NO_MATCHES_TEXT)).rejects.toThrow( + getNoInstancesFoundMessage('accessibilityHint') + ); +}); diff --git a/src/queries/a11yAPI.ts b/src/queries/a11yAPI.ts index 9eed14511..24e7115c3 100644 --- a/src/queries/a11yAPI.ts +++ b/src/queries/a11yAPI.ts @@ -20,32 +20,6 @@ type FindReturn = Promise; type FindAllReturn = Promise; export type A11yAPI = { - // Hint - getByA11yHint: (a11yHint: TextMatch) => GetReturn; - getByHintText: (a11yHint: TextMatch) => GetReturn; - getAllByA11yHint: (a11yHint: TextMatch) => GetAllReturn; - getAllByHintText: (a11yHint: TextMatch) => GetAllReturn; - queryByA11yHint: (a11yHint: TextMatch) => QueryReturn; - queryByHintText: (a11yHint: TextMatch) => QueryReturn; - queryAllByA11yHint: (a11yHint: TextMatch) => QueryAllReturn; - queryAllByHintText: (a11yHint: TextMatch) => QueryAllReturn; - findByA11yHint: ( - a11yHint: TextMatch, - waitForOptions?: WaitForOptions - ) => FindReturn; - findByHintText: ( - a11yHint: TextMatch, - waitForOptions?: WaitForOptions - ) => FindReturn; - findAllByA11yHint: ( - a11yHint: TextMatch, - waitForOptions?: WaitForOptions - ) => FindAllReturn; - findAllByHintText: ( - a11yHint: TextMatch, - waitForOptions?: WaitForOptions - ) => FindAllReturn; - // Role getByRole: (role: AccessibilityRole | RegExp) => GetReturn; getAllByRole: (role: AccessibilityRole | RegExp) => GetAllReturn; @@ -156,34 +130,6 @@ export function matchObject>( export const a11yAPI = (instance: ReactTestInstance): A11yAPI => ({ - ...makeA11yQuery( - 'accessibilityHint', - { - getBy: ['getByA11yHint', 'getByAccessibilityHint', 'getByHintText'], - getAllBy: [ - 'getAllByA11yHint', - 'getAllByAccessibilityHint', - 'getAllByHintText', - ], - queryBy: [ - 'queryByA11yHint', - 'queryByAccessibilityHint', - 'queryByHintText', - ], - queryAllBy: [ - 'queryAllByA11yHint', - 'queryAllByAccessibilityHint', - 'queryAllByHintText', - ], - findBy: ['findByA11yHint', 'findByAccessibilityHint', 'findByHintText'], - findAllBy: [ - 'findAllByA11yHint', - 'findAllByAccessibilityHint', - 'findAllByHintText', - ], - }, - matchStringValue - )(instance), ...makeA11yQuery( 'accessibilityRole', { diff --git a/src/queries/a11yHint.ts b/src/queries/a11yHint.ts new file mode 100644 index 000000000..224bcd469 --- /dev/null +++ b/src/queries/a11yHint.ts @@ -0,0 +1,68 @@ +import type { ReactTestInstance } from 'react-test-renderer'; +import { TextMatch } from '../matches'; +import { makeQueries } from './makeQueries'; +import type { + FindAllByQuery, + FindByQuery, + GetAllByQuery, + GetByQuery, + QueryAllByQuery, + QueryByQuery, +} from './makeQueries'; + +export function matchStringValue( + prop: string | undefined, + matcher: TextMatch +): boolean { + if (!prop) { + return false; + } + + if (typeof matcher === 'string') { + return prop === matcher; + } + + return Boolean(prop.match(matcher)); +} + +const queryAllByA11yHint = ( + instance: ReactTestInstance +): ((displayValue: TextMatch) => Array) => + function queryAllByDisplayValueFn(displayValue) { + return instance.findAll( + (node) => + typeof node.type === 'string' && + matchStringValue(node.props.accessibilityHint, displayValue) + ); + }; + +const getMultipleError = (a11yHint: TextMatch) => + `Found multiple elements with accessibilityHint: ${String(a11yHint)} `; +const getMissingError = (a11yHint: TextMatch) => + `Unable to find an element with accessibilityHint: ${String(a11yHint)}`; + +const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( + queryAllByA11yHint, + getMissingError, + getMultipleError +); + +export type ByA11yHintQueries = { + getByA11yHint: GetByQuery; + getAllByA11yHint: GetAllByQuery; + queryByA11yHint: QueryByQuery; + queryAllByA11yHint: QueryAllByQuery; + findByA11yHint: FindByQuery; + findAllByA11yHint: FindAllByQuery; +}; + +export const bindByA11yHintQueries = ( + instance: ReactTestInstance +): ByA11yHintQueries => ({ + getByA11yHint: getBy(instance), + getAllByA11yHint: getAllBy(instance), + queryByA11yHint: queryBy(instance), + queryAllByA11yHint: queryAllBy(instance), + findByA11yHint: findBy(instance), + findAllByA11yHint: findAllBy(instance), +}); diff --git a/src/within.ts b/src/within.ts index e40c45ddb..0b23726a4 100644 --- a/src/within.ts +++ b/src/within.ts @@ -7,6 +7,7 @@ import { bindByPlaceholderTextQueries } from './queries/placeholderText'; import { bindUnsafeByTypeQueries } from './queries/unsafeType'; import { bindUnsafeByPropsQueries } from './queries/unsafeProps'; import { bindByLabelTextQueries } from './queries/labelText'; +import { bindByA11yHintQueries } from './queries/a11yHint'; export function within(instance: ReactTestInstance) { return { @@ -17,6 +18,7 @@ export function within(instance: ReactTestInstance) { ...bindUnsafeByTypeQueries(instance), ...bindUnsafeByPropsQueries(instance), ...bindByLabelTextQueries(instance), + ...bindByA11yHintQueries(instance), ...a11yAPI(instance), }; } From 0bba3642be5fd7f46e132275382ed4bc20a10b2a Mon Sep 17 00:00:00 2001 From: MattAgn Date: Tue, 10 May 2022 22:35:32 +0200 Subject: [PATCH 04/38] refactor: extract byRole queries and its tests --- src/queries/__tests__/a11yAPI.test.tsx | 40 ----------- src/queries/__tests__/role.test.tsx | 91 ++++++++++++++++++++++++++ src/queries/a11yAPI.ts | 28 +------- src/queries/role.ts | 68 +++++++++++++++++++ src/within.ts | 2 + 5 files changed, 162 insertions(+), 67 deletions(-) create mode 100644 src/queries/__tests__/role.test.tsx create mode 100644 src/queries/role.ts diff --git a/src/queries/__tests__/a11yAPI.test.tsx b/src/queries/__tests__/a11yAPI.test.tsx index 6a9ab9e16..71bec80d8 100644 --- a/src/queries/__tests__/a11yAPI.test.tsx +++ b/src/queries/__tests__/a11yAPI.test.tsx @@ -69,46 +69,6 @@ function Section() { ); } -test('getByRole, queryByRole, findByRole', async () => { - const { getByRole, queryByRole, findByRole } = render(
); - - expect(getByRole('button').props.accessibilityRole).toEqual('button'); - const button = queryByRole(/button/g); - expect(button?.props.accessibilityRole).toEqual('button'); - - expect(() => getByRole(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityRole') - ); - expect(queryByRole(NO_MATCHES_TEXT)).toBeNull(); - - expect(() => getByRole('link')).toThrow(FOUND_TWO_INSTANCES); - expect(() => queryByRole('link')).toThrow(FOUND_TWO_INSTANCES); - - const asyncButton = await findByRole('button'); - expect(asyncButton.props.accessibilityRole).toEqual('button'); - await expect(findByRole(NO_MATCHES_TEXT, waitForOptions)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityRole') - ); - await expect(findByRole('link')).rejects.toThrow(FOUND_TWO_INSTANCES); -}); - -test('getAllByRole, queryAllByRole, findAllByRole', async () => { - const { getAllByRole, queryAllByRole, findAllByRole } = render(
); - - expect(getAllByRole('link')).toHaveLength(2); - expect(queryAllByRole(/ink/g)).toHaveLength(2); - - expect(() => getAllByRole(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityRole') - ); - expect(queryAllByRole(NO_MATCHES_TEXT)).toEqual([]); - - await expect(findAllByRole('link')).resolves.toHaveLength(2); - await expect(findAllByRole(NO_MATCHES_TEXT, waitForOptions)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityRole') - ); -}); - // TODO: accessibilityStates was removed from RN 0.62 test.skip('getByA11yStates, queryByA11yStates', () => { const { getByA11yStates, queryByA11yStates } = render(
); diff --git a/src/queries/__tests__/role.test.tsx b/src/queries/__tests__/role.test.tsx new file mode 100644 index 000000000..3292ae03c --- /dev/null +++ b/src/queries/__tests__/role.test.tsx @@ -0,0 +1,91 @@ +import * as React from 'react'; +import { TouchableOpacity, Text } from 'react-native'; +import { render } from '../..'; + +const TEXT_LABEL = 'cool text'; + +// Little hack to make all the methods happy with type +const NO_MATCHES_TEXT: any = 'not-existent-element'; + +const getMultipleInstancesFoundMessage = ( + name: string, + value: string = NO_MATCHES_TEXT +) => { + return `Found multiple elements with ${name}: ${value}`; +}; + +const getNoInstancesFoundMessage = ( + name: string, + value: string = NO_MATCHES_TEXT +) => { + return `Unable to find an element with ${name}: ${value}`; +}; + +const Typography = ({ children, ...rest }: any) => { + return {children}; +}; + +class Button extends React.Component { + render() { + return ( + + {this.props.children} + + ); + } +} + +function Section() { + return ( + <> + Title + + + ); +} + +test('getByRole, queryByRole, findByRole', async () => { + const { getByRole, queryByRole, findByRole } = render(
); + + expect(getByRole('button').props.accessibilityRole).toEqual('button'); + const button = queryByRole(/button/g); + expect(button?.props.accessibilityRole).toEqual('button'); + + expect(() => getByRole(NO_MATCHES_TEXT)).toThrow( + getNoInstancesFoundMessage('accessibilityRole') + ); + expect(queryByRole(NO_MATCHES_TEXT)).toBeNull(); + + expect(() => getByRole('link')).toThrow( + getMultipleInstancesFoundMessage('accessibilityRole', 'link') + ); + expect(() => queryByRole('link')).toThrow( + getMultipleInstancesFoundMessage('accessibilityRole', 'link') + ); + + const asyncButton = await findByRole('button'); + expect(asyncButton.props.accessibilityRole).toEqual('button'); + await expect(findByRole(NO_MATCHES_TEXT)).rejects.toThrow( + getNoInstancesFoundMessage('accessibilityRole') + ); + await expect(findByRole('link')).rejects.toThrow( + getMultipleInstancesFoundMessage('accessibilityRole', 'link') + ); +}); + +test('getAllByRole, queryAllByRole, findAllByRole', async () => { + const { getAllByRole, queryAllByRole, findAllByRole } = render(
); + + expect(getAllByRole('link')).toHaveLength(2); + expect(queryAllByRole(/ink/g)).toHaveLength(2); + + expect(() => getAllByRole(NO_MATCHES_TEXT)).toThrow( + getNoInstancesFoundMessage('accessibilityRole') + ); + expect(queryAllByRole(NO_MATCHES_TEXT)).toEqual([]); + + await expect(findAllByRole('link')).resolves.toHaveLength(2); + await expect(findAllByRole(NO_MATCHES_TEXT)).rejects.toThrow( + getNoInstancesFoundMessage('accessibilityRole') + ); +}); diff --git a/src/queries/a11yAPI.ts b/src/queries/a11yAPI.ts index 24e7115c3..0f43ea5fb 100644 --- a/src/queries/a11yAPI.ts +++ b/src/queries/a11yAPI.ts @@ -1,5 +1,5 @@ import type { ReactTestInstance } from 'react-test-renderer'; -import type { AccessibilityRole, AccessibilityState } from 'react-native'; +import type { AccessibilityState } from 'react-native'; import type { WaitForOptions } from '../waitFor'; import type { TextMatch } from '../matches'; import makeA11yQuery from './makeA11yQuery'; @@ -20,20 +20,6 @@ type FindReturn = Promise; type FindAllReturn = Promise; export type A11yAPI = { - // Role - getByRole: (role: AccessibilityRole | RegExp) => GetReturn; - getAllByRole: (role: AccessibilityRole | RegExp) => GetAllReturn; - queryByRole: (role: AccessibilityRole | RegExp) => QueryReturn; - queryAllByRole: (role: AccessibilityRole | RegExp) => QueryAllReturn; - findByRole: ( - role: AccessibilityRole, - waitForOptions?: WaitForOptions - ) => FindReturn; - findAllByRole: ( - role: AccessibilityRole, - waitForOptions?: WaitForOptions - ) => FindAllReturn; - // States getByA11yStates: ( accessibilityStateKey: AccessibilityStateKey | Array @@ -130,18 +116,6 @@ export function matchObject>( export const a11yAPI = (instance: ReactTestInstance): A11yAPI => ({ - ...makeA11yQuery( - 'accessibilityRole', - { - getBy: ['getByRole'], - getAllBy: ['getAllByRole'], - queryBy: ['queryByRole'], - queryAllBy: ['queryAllByRole'], - findBy: ['findByRole'], - findAllBy: ['findAllByRole'], - }, - matchStringValue - )(instance), ...makeA11yQuery( 'accessibilityStates', { diff --git a/src/queries/role.ts b/src/queries/role.ts new file mode 100644 index 000000000..84920021f --- /dev/null +++ b/src/queries/role.ts @@ -0,0 +1,68 @@ +import type { ReactTestInstance } from 'react-test-renderer'; +import { TextMatch } from '../matches'; +import { makeQueries } from './makeQueries'; +import type { + FindAllByQuery, + FindByQuery, + GetAllByQuery, + GetByQuery, + QueryAllByQuery, + QueryByQuery, +} from './makeQueries'; + +export function matchStringValue( + prop: string | undefined, + matcher: TextMatch +): boolean { + if (!prop) { + return false; + } + + if (typeof matcher === 'string') { + return prop === matcher; + } + + return Boolean(prop.match(matcher)); +} + +const queryAllByRole = ( + instance: ReactTestInstance +): ((displayValue: TextMatch) => Array) => + function queryAllByDisplayValueFn(displayValue) { + return instance.findAll( + (node) => + typeof node.type === 'string' && + matchStringValue(node.props.accessibilityRole, displayValue) + ); + }; + +const getMultipleError = (role: TextMatch) => + `Found multiple elements with accessibilityRole: ${String(role)} `; +const getMissingError = (role: TextMatch) => + `Unable to find an element with accessibilityRole: ${String(role)}`; + +const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( + queryAllByRole, + getMissingError, + getMultipleError +); + +export type ByRoleQueries = { + getByRole: GetByQuery; + getAllByRole: GetAllByQuery; + queryByRole: QueryByQuery; + queryAllByRole: QueryAllByQuery; + findByRole: FindByQuery; + findAllByRole: FindAllByQuery; +}; + +export const bindByRoleQueries = ( + instance: ReactTestInstance +): ByRoleQueries => ({ + getByRole: getBy(instance), + getAllByRole: getAllBy(instance), + queryByRole: queryBy(instance), + queryAllByRole: queryAllBy(instance), + findByRole: findBy(instance), + findAllByRole: findAllBy(instance), +}); diff --git a/src/within.ts b/src/within.ts index 0b23726a4..470191f16 100644 --- a/src/within.ts +++ b/src/within.ts @@ -8,6 +8,7 @@ import { bindUnsafeByTypeQueries } from './queries/unsafeType'; import { bindUnsafeByPropsQueries } from './queries/unsafeProps'; import { bindByLabelTextQueries } from './queries/labelText'; import { bindByA11yHintQueries } from './queries/a11yHint'; +import { bindByRoleQueries } from './queries/role'; export function within(instance: ReactTestInstance) { return { @@ -18,6 +19,7 @@ export function within(instance: ReactTestInstance) { ...bindUnsafeByTypeQueries(instance), ...bindUnsafeByPropsQueries(instance), ...bindByLabelTextQueries(instance), + ...bindByRoleQueries(instance), ...bindByA11yHintQueries(instance), ...a11yAPI(instance), }; From 19fd1584a0410158b23c5cdcef4971f9e83fce8d Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 14 May 2022 17:06:23 +0200 Subject: [PATCH 05/38] refactor: extract byA11yState queries and its tests --- src/queries/__tests__/a11yAPI.test.tsx | 86 ------------------- src/queries/__tests__/a11yState.test.tsx | 104 +++++++++++++++++++++++ src/queries/a11yAPI.ts | 28 ------ src/queries/a11yState.ts | 68 +++++++++++++++ src/within.ts | 2 + 5 files changed, 174 insertions(+), 114 deletions(-) create mode 100644 src/queries/__tests__/a11yState.test.tsx create mode 100644 src/queries/a11yState.ts diff --git a/src/queries/__tests__/a11yAPI.test.tsx b/src/queries/__tests__/a11yAPI.test.tsx index 71bec80d8..3d5ed49c0 100644 --- a/src/queries/__tests__/a11yAPI.test.tsx +++ b/src/queries/__tests__/a11yAPI.test.tsx @@ -111,92 +111,6 @@ test.skip('getAllByA11yStates, queryAllByA11yStates', () => { expect(queryAllByA11yStates(NO_MATCHES_TEXT)).toEqual([]); }); -test('getByA11yState, queryByA11yState, findByA11yState', async () => { - const { getByA11yState, queryByA11yState, findByA11yState } = render( -
- ); - - expect(getByA11yState({ selected: true }).props.accessibilityState).toEqual({ - selected: true, - expanded: false, - }); - expect( - queryByA11yState({ selected: true })?.props.accessibilityState - ).toEqual({ - selected: true, - expanded: false, - }); - - expect(() => getByA11yState({ disabled: true })).toThrow( - getNoInstancesFoundMessage( - 'accessibilityState', - '{"disabled": true}', - false - ) - ); - expect(queryByA11yState({ disabled: true })).toEqual(null); - - expect(() => getByA11yState({ expanded: false })).toThrow( - FOUND_TWO_INSTANCES - ); - expect(() => queryByA11yState({ expanded: false })).toThrow( - FOUND_TWO_INSTANCES - ); - - const asyncButton = await findByA11yState({ selected: true }); - expect(asyncButton.props.accessibilityState).toEqual({ - selected: true, - expanded: false, - }); - await expect( - findByA11yState({ disabled: true }, waitForOptions) - ).rejects.toThrow( - getNoInstancesFoundMessage( - 'accessibilityState', - '{"disabled": true}', - false - ) - ); - await expect( - findByA11yState({ expanded: false }, waitForOptions) - ).rejects.toThrow(FOUND_TWO_INSTANCES); -}); - -test('getAllByA11yState, queryAllByA11yState, findAllByA11yState', async () => { - const { getAllByA11yState, queryAllByA11yState, findAllByA11yState } = render( -
- ); - - expect(getAllByA11yState({ selected: true })).toHaveLength(1); - expect(queryAllByA11yState({ selected: true })).toHaveLength(1); - - expect(() => getAllByA11yState({ disabled: true })).toThrow( - getNoInstancesFoundMessage( - 'accessibilityState', - '{"disabled": true}', - false - ) - ); - expect(queryAllByA11yState({ disabled: true })).toEqual([]); - - expect(getAllByA11yState({ expanded: false })).toHaveLength(2); - expect(queryAllByA11yState({ expanded: false })).toHaveLength(2); - - await expect(findAllByA11yState({ selected: true })).resolves.toHaveLength(1); - await expect( - findAllByA11yState({ disabled: true }, waitForOptions) - ).rejects.toThrow( - getNoInstancesFoundMessage( - 'accessibilityState', - '{"disabled": true}', - false - ) - ); - await expect(findAllByA11yState({ expanded: false })).resolves.toHaveLength( - 2 - ); -}); - test('getByA11yValue, queryByA11yValue, findByA11yValue', async () => { const { getByA11yValue, queryByA11yValue, findByA11yValue } = render(
diff --git a/src/queries/__tests__/a11yState.test.tsx b/src/queries/__tests__/a11yState.test.tsx new file mode 100644 index 000000000..da76ea2a8 --- /dev/null +++ b/src/queries/__tests__/a11yState.test.tsx @@ -0,0 +1,104 @@ +import * as React from 'react'; +import { TouchableOpacity, Text } from 'react-native'; +import { render } from '../..'; + +const TEXT_LABEL = 'cool text'; + +const getMultipleInstancesFoundMessage = (name: string, value: string) => { + return `Found multiple elements with ${name}: ${value}`; +}; + +const getNoInstancesFoundMessage = (name: string, value: string) => { + return `Unable to find an element with ${name}: ${value}`; +}; + +const Typography = ({ children, ...rest }: any) => { + return {children}; +}; + +class Button extends React.Component { + render() { + return ( + + + {this.props.children} + + + ); + } +} + +function Section() { + return ( + <> + Title + + + ); +} + +test('getByA11yState, queryByA11yState, findByA11yState', async () => { + const { getByA11yState, queryByA11yState, findByA11yState } = render( +
+ ); + + expect(getByA11yState({ selected: true }).props.accessibilityState).toEqual({ + selected: true, + expanded: false, + }); + expect( + queryByA11yState({ selected: true })?.props.accessibilityState + ).toEqual({ + selected: true, + expanded: false, + }); + + expect(() => getByA11yState({ disabled: true })).toThrow( + getNoInstancesFoundMessage('accessibilityState', '{"disabled":true}') + ); + expect(queryByA11yState({ disabled: true })).toEqual(null); + + expect(() => getByA11yState({ expanded: false })).toThrow( + getMultipleInstancesFoundMessage('accessibilityState', '{"expanded":false}') + ); + expect(() => queryByA11yState({ expanded: false })).toThrow( + getMultipleInstancesFoundMessage('accessibilityState', '{"expanded":false}') + ); + + const asyncButton = await findByA11yState({ selected: true }); + expect(asyncButton.props.accessibilityState).toEqual({ + selected: true, + expanded: false, + }); + await expect(findByA11yState({ disabled: true })).rejects.toThrow( + getNoInstancesFoundMessage('accessibilityState', '{"disabled":true}') + ); + await expect(findByA11yState({ expanded: false })).rejects.toThrow( + getMultipleInstancesFoundMessage('accessibilityState', '{"expanded":false}') + ); +}); + +test('getAllByA11yState, queryAllByA11yState, findAllByA11yState', async () => { + const { getAllByA11yState, queryAllByA11yState, findAllByA11yState } = render( +
+ ); + + expect(getAllByA11yState({ selected: true })).toHaveLength(1); + expect(queryAllByA11yState({ selected: true })).toHaveLength(1); + + expect(() => getAllByA11yState({ disabled: true })).toThrow( + getNoInstancesFoundMessage('accessibilityState', '{"disabled":true}') + ); + expect(queryAllByA11yState({ disabled: true })).toEqual([]); + + expect(getAllByA11yState({ expanded: false })).toHaveLength(2); + expect(queryAllByA11yState({ expanded: false })).toHaveLength(2); + + await expect(findAllByA11yState({ selected: true })).resolves.toHaveLength(1); + await expect(findAllByA11yState({ disabled: true })).rejects.toThrow( + getNoInstancesFoundMessage('accessibilityState', '{"disabled":true}') + ); + await expect(findAllByA11yState({ expanded: false })).resolves.toHaveLength( + 2 + ); +}); diff --git a/src/queries/a11yAPI.ts b/src/queries/a11yAPI.ts index 0f43ea5fb..cb36ded23 100644 --- a/src/queries/a11yAPI.ts +++ b/src/queries/a11yAPI.ts @@ -42,22 +42,6 @@ export type A11yAPI = { waitForOptions?: WaitForOptions ) => FindAllReturn; - // State - getByA11yState: (accessibilityState: AccessibilityState) => GetReturn; - getAllByA11yState: (accessibilityState: AccessibilityState) => GetAllReturn; - queryByA11yState: (accessibilityState: AccessibilityState) => QueryReturn; - queryAllByA11yState: ( - accessibilityState: AccessibilityState - ) => QueryAllReturn; - findByA11yState: ( - accessibilityState: AccessibilityState, - waitForOptions?: WaitForOptions - ) => FindReturn; - findAllByA11yState: ( - accessibilityState: AccessibilityState, - waitForOptions?: WaitForOptions - ) => FindAllReturn; - // Value getByA11yValue: (a11yValue: A11yValue) => GetReturn; getAllByA11yValue: (a11yValue: A11yValue) => GetAllReturn; @@ -128,18 +112,6 @@ export const a11yAPI = (instance: ReactTestInstance): A11yAPI => }, matchArrayValue )(instance), - ...makeA11yQuery( - 'accessibilityState', - { - getBy: ['getByA11yState', 'getByAccessibilityState'], - getAllBy: ['getAllByA11yState', 'getAllByAccessibilityState'], - queryBy: ['queryByA11yState', 'queryByAccessibilityState'], - queryAllBy: ['queryAllByA11yState', 'queryAllByAccessibilityState'], - findBy: ['findByA11yState', 'findByAccessibilityState'], - findAllBy: ['findAllByA11yState', 'findAllByAccessibilityState'], - }, - matchObject - )(instance), ...makeA11yQuery( 'accessibilityValue', { diff --git a/src/queries/a11yState.ts b/src/queries/a11yState.ts new file mode 100644 index 000000000..b11ae6d58 --- /dev/null +++ b/src/queries/a11yState.ts @@ -0,0 +1,68 @@ +import type { ReactTestInstance } from 'react-test-renderer'; +import { AccessibilityState } from 'react-native'; +import { makeQueries } from './makeQueries'; +import type { + FindAllByQuery, + FindByQuery, + GetAllByQuery, + GetByQuery, + QueryAllByQuery, + QueryByQuery, +} from './makeQueries'; + +export function matchObject>( + prop: T | undefined, + matcher: T +): boolean { + return prop + ? Object.keys(matcher).length !== 0 && + Object.keys(prop).length !== 0 && + !Object.keys(matcher).some((key) => prop[key] !== matcher[key]) + : false; +} + +const queryAllByA11yState = ( + instance: ReactTestInstance +): ((accessibilityStateKey: AccessibilityState) => Array) => + function queryAllByDisplayValueFn(accessibilityStateKey) { + return instance.findAll( + (node) => + typeof node.type === 'string' && + matchObject(node.props.accessibilityState, accessibilityStateKey) + ); + }; + +const getMultipleError = (a11yState: AccessibilityState) => + `Found multiple elements with accessibilityState: ${JSON.stringify( + a11yState + )}`; +const getMissingError = (a11yState: AccessibilityState) => + `Unable to find an element with accessibilityState: ${JSON.stringify( + a11yState + )}`; + +const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( + queryAllByA11yState, + getMissingError, + getMultipleError +); + +export type ByA11yStateQueries = { + getByA11yState: GetByQuery; + getAllByA11yState: GetAllByQuery; + queryByA11yState: QueryByQuery; + queryAllByA11yState: QueryAllByQuery; + findByA11yState: FindByQuery; + findAllByA11yState: FindAllByQuery; +}; + +export const bindByA11yStateQueries = ( + instance: ReactTestInstance +): ByA11yStateQueries => ({ + getByA11yState: getBy(instance), + getAllByA11yState: getAllBy(instance), + queryByA11yState: queryBy(instance), + queryAllByA11yState: queryAllBy(instance), + findByA11yState: findBy(instance), + findAllByA11yState: findAllBy(instance), +}); diff --git a/src/within.ts b/src/within.ts index 470191f16..1360f8bfe 100644 --- a/src/within.ts +++ b/src/within.ts @@ -9,6 +9,7 @@ import { bindUnsafeByPropsQueries } from './queries/unsafeProps'; import { bindByLabelTextQueries } from './queries/labelText'; import { bindByA11yHintQueries } from './queries/a11yHint'; import { bindByRoleQueries } from './queries/role'; +import { bindByA11yStateQueries } from './queries/a11yState'; export function within(instance: ReactTestInstance) { return { @@ -21,6 +22,7 @@ export function within(instance: ReactTestInstance) { ...bindByLabelTextQueries(instance), ...bindByRoleQueries(instance), ...bindByA11yHintQueries(instance), + ...bindByA11yStateQueries(instance), ...a11yAPI(instance), }; } From 51e2f853916b8858b5d7e09540889f9b29ef5f14 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 14 May 2022 17:20:54 +0200 Subject: [PATCH 06/38] refactor: extract byA11yValue queries and its tests --- src/queries/__tests__/a11yAPI.test.tsx | 60 -------------- src/queries/__tests__/a11yValue.test.tsx | 100 +++++++++++++++++++++++ src/queries/a11yAPI.ts | 32 -------- src/queries/a11yValue.ts | 74 +++++++++++++++++ src/within.ts | 2 + 5 files changed, 176 insertions(+), 92 deletions(-) create mode 100644 src/queries/__tests__/a11yValue.test.tsx create mode 100644 src/queries/a11yValue.ts diff --git a/src/queries/__tests__/a11yAPI.test.tsx b/src/queries/__tests__/a11yAPI.test.tsx index 3d5ed49c0..2edaf8b1d 100644 --- a/src/queries/__tests__/a11yAPI.test.tsx +++ b/src/queries/__tests__/a11yAPI.test.tsx @@ -23,8 +23,6 @@ const Typography = ({ children, ...rest }: any) => { return {children}; }; -const waitForOptions = { timeout: 10 }; - class Button extends React.Component { render() { return ( @@ -110,61 +108,3 @@ test.skip('getAllByA11yStates, queryAllByA11yStates', () => { ); expect(queryAllByA11yStates(NO_MATCHES_TEXT)).toEqual([]); }); - -test('getByA11yValue, queryByA11yValue, findByA11yValue', async () => { - const { getByA11yValue, queryByA11yValue, findByA11yValue } = render( -
- ); - - expect(getByA11yValue({ min: 40 }).props.accessibilityValue).toEqual({ - min: 40, - max: 60, - }); - expect(queryByA11yValue({ min: 40 })?.props.accessibilityValue).toEqual({ - min: 40, - max: 60, - }); - - expect(() => getByA11yValue({ min: 50 })).toThrow( - getNoInstancesFoundMessage('accessibilityValue', '{"min": 50}', false) - ); - expect(queryByA11yValue({ min: 50 })).toEqual(null); - - expect(() => getByA11yValue({ max: 60 })).toThrow(FOUND_TWO_INSTANCES); - expect(() => queryByA11yValue({ max: 60 })).toThrow(FOUND_TWO_INSTANCES); - - const asyncElement = await findByA11yValue({ min: 40 }); - expect(asyncElement.props.accessibilityValue).toEqual({ - min: 40, - max: 60, - }); - await expect(findByA11yValue({ min: 50 }, waitForOptions)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityValue', '{"min": 50}', false) - ); - await expect(findByA11yValue({ max: 60 }, waitForOptions)).rejects.toThrow( - FOUND_TWO_INSTANCES - ); -}); - -test('getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue', async () => { - const { getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue } = render( -
- ); - - expect(getAllByA11yValue({ min: 40 })).toHaveLength(1); - expect(queryAllByA11yValue({ min: 40 })).toHaveLength(1); - - expect(() => getAllByA11yValue({ min: 50 })).toThrow( - getNoInstancesFoundMessage('accessibilityValue', '{"min": 50}', false) - ); - expect(queryAllByA11yValue({ min: 50 })).toEqual([]); - - expect(queryAllByA11yValue({ max: 60 })).toHaveLength(2); - expect(getAllByA11yValue({ max: 60 })).toHaveLength(2); - - await expect(findAllByA11yValue({ min: 40 })).resolves.toHaveLength(1); - await expect(findAllByA11yValue({ min: 50 }, waitForOptions)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityValue', '{"min": 50}', false) - ); - await expect(findAllByA11yValue({ max: 60 })).resolves.toHaveLength(2); -}); diff --git a/src/queries/__tests__/a11yValue.test.tsx b/src/queries/__tests__/a11yValue.test.tsx new file mode 100644 index 000000000..f36f63b3d --- /dev/null +++ b/src/queries/__tests__/a11yValue.test.tsx @@ -0,0 +1,100 @@ +import * as React from 'react'; +import { TouchableOpacity, Text } from 'react-native'; +import { render } from '../..'; + +const TEXT_LABEL = 'cool text'; + +const getMultipleInstancesFoundMessage = (name: string, value: string) => { + return `Found multiple elements with ${name}: ${value}`; +}; + +const getNoInstancesFoundMessage = (name: string, value: string) => { + return `Unable to find an element with ${name}: ${value}`; +}; + +const Typography = ({ children, ...rest }: any) => { + return {children}; +}; + +class Button extends React.Component { + render() { + return ( + + + {this.props.children} + + + ); + } +} + +function Section() { + return ( + <> + Title + + + ); +} + +test('getByA11yValue, queryByA11yValue, findByA11yValue', async () => { + const { getByA11yValue, queryByA11yValue, findByA11yValue } = render( +
+ ); + + expect(getByA11yValue({ min: 40 }).props.accessibilityValue).toEqual({ + min: 40, + max: 60, + }); + expect(queryByA11yValue({ min: 40 })?.props.accessibilityValue).toEqual({ + min: 40, + max: 60, + }); + + expect(() => getByA11yValue({ min: 50 })).toThrow( + getNoInstancesFoundMessage('accessibilityValue', '{"min":50}') + ); + expect(queryByA11yValue({ min: 50 })).toEqual(null); + + expect(() => getByA11yValue({ max: 60 })).toThrow( + getMultipleInstancesFoundMessage('accessibilityValue', '{"max":60}') + ); + expect(() => queryByA11yValue({ max: 60 })).toThrow( + getMultipleInstancesFoundMessage('accessibilityValue', '{"max":60}') + ); + + const asyncElement = await findByA11yValue({ min: 40 }); + expect(asyncElement.props.accessibilityValue).toEqual({ + min: 40, + max: 60, + }); + await expect(findByA11yValue({ min: 50 })).rejects.toThrow( + getNoInstancesFoundMessage('accessibilityValue', '{"min":50}') + ); + await expect(findByA11yValue({ max: 60 })).rejects.toThrow( + getMultipleInstancesFoundMessage('accessibilityValue', '{"max":60}') + ); +}); + +test('getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue', async () => { + const { getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue } = render( +
+ ); + + expect(getAllByA11yValue({ min: 40 })).toHaveLength(1); + expect(queryAllByA11yValue({ min: 40 })).toHaveLength(1); + + expect(() => getAllByA11yValue({ min: 50 })).toThrow( + getNoInstancesFoundMessage('accessibilityValue', '{"min":50}') + ); + expect(queryAllByA11yValue({ min: 50 })).toEqual([]); + + expect(queryAllByA11yValue({ max: 60 })).toHaveLength(2); + expect(getAllByA11yValue({ max: 60 })).toHaveLength(2); + + await expect(findAllByA11yValue({ min: 40 })).resolves.toHaveLength(1); + await expect(findAllByA11yValue({ min: 50 })).rejects.toThrow( + getNoInstancesFoundMessage('accessibilityValue', '{"min":50}') + ); + await expect(findAllByA11yValue({ max: 60 })).resolves.toHaveLength(2); +}); diff --git a/src/queries/a11yAPI.ts b/src/queries/a11yAPI.ts index cb36ded23..edb53e1a1 100644 --- a/src/queries/a11yAPI.ts +++ b/src/queries/a11yAPI.ts @@ -5,12 +5,6 @@ import type { TextMatch } from '../matches'; import makeA11yQuery from './makeA11yQuery'; type AccessibilityStateKey = keyof AccessibilityState; -type A11yValue = { - min?: number; - max?: number; - now?: number; - text?: string; -}; type GetReturn = ReactTestInstance; type GetAllReturn = Array; @@ -41,20 +35,6 @@ export type A11yAPI = { accessibilityStateKey: AccessibilityStateKey, waitForOptions?: WaitForOptions ) => FindAllReturn; - - // Value - getByA11yValue: (a11yValue: A11yValue) => GetReturn; - getAllByA11yValue: (a11yValue: A11yValue) => GetAllReturn; - queryByA11yValue: (a11yValue: A11yValue) => QueryReturn; - queryAllByA11yValue: (a11yValue: A11yValue) => QueryAllReturn; - findByA11yValue: ( - a11yValue: A11yValue, - waitForOptions?: WaitForOptions - ) => FindReturn; - findAllByA11yValue: ( - a11yValue: A11yValue, - waitForOptions?: WaitForOptions - ) => FindAllReturn; }; export function matchStringValue( @@ -112,16 +92,4 @@ export const a11yAPI = (instance: ReactTestInstance): A11yAPI => }, matchArrayValue )(instance), - ...makeA11yQuery( - 'accessibilityValue', - { - getBy: ['getByA11yValue', 'getByAccessibilityValue'], - getAllBy: ['getAllByA11yValue', 'getAllByAccessibilityValue'], - queryBy: ['queryByA11yValue', 'queryByAccessibilityValue'], - queryAllBy: ['queryAllByA11yValue', 'queryAllByAccessibilityValue'], - findBy: ['findByA11yValue', 'findByAccessibilityValue'], - findAllBy: ['findAllByA11yValue', 'findAllByAccessibilityValue'], - }, - matchObject - )(instance), } as any); diff --git a/src/queries/a11yValue.ts b/src/queries/a11yValue.ts new file mode 100644 index 000000000..be16301ed --- /dev/null +++ b/src/queries/a11yValue.ts @@ -0,0 +1,74 @@ +import type { ReactTestInstance } from 'react-test-renderer'; +import { makeQueries } from './makeQueries'; +import type { + FindAllByQuery, + FindByQuery, + GetAllByQuery, + GetByQuery, + QueryAllByQuery, + QueryByQuery, +} from './makeQueries'; + +type A11yValue = { + min?: number; + max?: number; + now?: number; + text?: string; +}; + +export function matchObject>( + prop: T | undefined, + matcher: T +): boolean { + return prop + ? Object.keys(matcher).length !== 0 && + Object.keys(prop).length !== 0 && + !Object.keys(matcher).some((key) => prop[key] !== matcher[key]) + : false; +} + +const queryAllByA11yValue = ( + instance: ReactTestInstance +): ((displayValue: A11yValue) => Array) => + function queryAllByDisplayValueFn(displayValue) { + return instance.findAll( + (node) => + typeof node.type === 'string' && + matchObject(node.props.accessibilityValue, displayValue) + ); + }; + +const getMultipleError = (a11yValue: A11yValue) => + `Found multiple elements with accessibilityValue: ${JSON.stringify( + a11yValue + )} `; +const getMissingError = (a11yValue: A11yValue) => + `Unable to find an element with accessibilityValue: ${JSON.stringify( + a11yValue + )}`; + +const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( + queryAllByA11yValue, + getMissingError, + getMultipleError +); + +export type ByA11yValueQueries = { + getByA11yValue: GetByQuery; + getAllByA11yValue: GetAllByQuery; + queryByA11yValue: QueryByQuery; + queryAllByA11yValue: QueryAllByQuery; + findByA11yValue: FindByQuery; + findAllByA11yValue: FindAllByQuery; +}; + +export const bindByA11yValueQueries = ( + instance: ReactTestInstance +): ByA11yValueQueries => ({ + getByA11yValue: getBy(instance), + getAllByA11yValue: getAllBy(instance), + queryByA11yValue: queryBy(instance), + queryAllByA11yValue: queryAllBy(instance), + findByA11yValue: findBy(instance), + findAllByA11yValue: findAllBy(instance), +}); diff --git a/src/within.ts b/src/within.ts index 1360f8bfe..a645fe242 100644 --- a/src/within.ts +++ b/src/within.ts @@ -10,6 +10,7 @@ import { bindByLabelTextQueries } from './queries/labelText'; import { bindByA11yHintQueries } from './queries/a11yHint'; import { bindByRoleQueries } from './queries/role'; import { bindByA11yStateQueries } from './queries/a11yState'; +import { bindByA11yValueQueries } from './queries/a11yValue'; export function within(instance: ReactTestInstance) { return { @@ -23,6 +24,7 @@ export function within(instance: ReactTestInstance) { ...bindByRoleQueries(instance), ...bindByA11yHintQueries(instance), ...bindByA11yStateQueries(instance), + ...bindByA11yValueQueries(instance), ...a11yAPI(instance), }; } From 96512c4c1cd3455b13882070a74f5e07eab52e48 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 14 May 2022 17:33:22 +0200 Subject: [PATCH 07/38] refactor: extract byA11yStates queries and its tests --- .../{a11yAPI.test.tsx => a11yStates.test.tsx} | 42 ++++---- src/queries/a11yAPI.ts | 95 ------------------- src/queries/a11yStates.ts | 79 +++++++++++++++ src/within.ts | 4 +- 4 files changed, 97 insertions(+), 123 deletions(-) rename src/queries/__tests__/{a11yAPI.test.tsx => a11yStates.test.tsx} (67%) delete mode 100644 src/queries/a11yAPI.ts create mode 100644 src/queries/a11yStates.ts diff --git a/src/queries/__tests__/a11yAPI.test.tsx b/src/queries/__tests__/a11yStates.test.tsx similarity index 67% rename from src/queries/__tests__/a11yAPI.test.tsx rename to src/queries/__tests__/a11yStates.test.tsx index 2edaf8b1d..606e83ec7 100644 --- a/src/queries/__tests__/a11yAPI.test.tsx +++ b/src/queries/__tests__/a11yStates.test.tsx @@ -2,21 +2,22 @@ import * as React from 'react'; import { TouchableOpacity, Text } from 'react-native'; import { render } from '../..'; -const BUTTON_LABEL = 'cool button'; -const BUTTON_HINT = 'click this button'; const TEXT_LABEL = 'cool text'; -const TEXT_HINT = 'static text'; // Little hack to make all the methods happy with type const NO_MATCHES_TEXT: any = 'not-existent-element'; -const FOUND_TWO_INSTANCES = 'Expected 1 but found 2 instances'; + +const getMultipleInstancesFoundMessage = ( + name: string, + value: string = NO_MATCHES_TEXT +) => { + return `Found multiple elements with ${name}: ${value}`; +}; const getNoInstancesFoundMessage = ( name: string, - value: string = NO_MATCHES_TEXT, - includeQuotes: boolean = true + value: string = NO_MATCHES_TEXT ) => { - const quote = includeQuotes ? '"' : ''; - return `No instances found with ${name} ${quote}${value}${quote}`; + return `Unable to find an element with ${name}: ${value}`; }; const Typography = ({ children, ...rest }: any) => { @@ -27,20 +28,10 @@ class Button extends React.Component { render() { return ( - + {this.props.children} @@ -52,13 +43,8 @@ function Section() { return ( <> Title @@ -92,8 +78,12 @@ test.skip('getByA11yStates, queryByA11yStates', () => { expect(queryByA11yStates(NO_MATCHES_TEXT)).toBeNull(); expect(queryByA11yStates([])).toBeNull(); - expect(() => getByA11yStates('selected')).toThrow(FOUND_TWO_INSTANCES); - expect(() => queryByA11yStates('selected')).toThrow(FOUND_TWO_INSTANCES); + expect(() => getByA11yStates('selected')).toThrow( + getMultipleInstancesFoundMessage('accessibilityStates', '["selected"]') + ); + expect(() => queryByA11yStates('selected')).toThrow( + getMultipleInstancesFoundMessage('accessibilityStates', '["selected"]') + ); }); // TODO: accessibilityStates was removed from RN 0.62 diff --git a/src/queries/a11yAPI.ts b/src/queries/a11yAPI.ts deleted file mode 100644 index edb53e1a1..000000000 --- a/src/queries/a11yAPI.ts +++ /dev/null @@ -1,95 +0,0 @@ -import type { ReactTestInstance } from 'react-test-renderer'; -import type { AccessibilityState } from 'react-native'; -import type { WaitForOptions } from '../waitFor'; -import type { TextMatch } from '../matches'; -import makeA11yQuery from './makeA11yQuery'; - -type AccessibilityStateKey = keyof AccessibilityState; - -type GetReturn = ReactTestInstance; -type GetAllReturn = Array; -type QueryReturn = ReactTestInstance | null; -type QueryAllReturn = Array; -type FindReturn = Promise; -type FindAllReturn = Promise; - -export type A11yAPI = { - // States - getByA11yStates: ( - accessibilityStateKey: AccessibilityStateKey | Array - ) => GetReturn; - getAllByA11yStates: ( - accessibilityStateKey: AccessibilityStateKey | Array - ) => GetAllReturn; - queryByA11yStates: ( - accessibilityStateKey: AccessibilityStateKey | Array - ) => QueryReturn; - queryAllByA11yStates: ( - accessibilityStateKey: AccessibilityStateKey | Array - ) => QueryAllReturn; - findByA11yStates: ( - accessibilityStateKey: AccessibilityStateKey, - waitForOptions?: WaitForOptions - ) => FindReturn; - findAllByA11yStates: ( - accessibilityStateKey: AccessibilityStateKey, - waitForOptions?: WaitForOptions - ) => FindAllReturn; -}; - -export function matchStringValue( - prop: string | undefined, - matcher: TextMatch -): boolean { - if (!prop) { - return false; - } - - if (typeof matcher === 'string') { - return prop === matcher; - } - - return Boolean(prop.match(matcher)); -} - -export function matchArrayValue( - prop: Array | undefined, - matcher: string | Array -): boolean { - if (!prop || matcher.length === 0) { - return false; - } - - if (typeof matcher === 'string') { - return prop.includes(matcher); - } - - return !matcher.some((e) => !prop.includes(e)); -} - -export function matchObject>( - prop: T | undefined, - matcher: T -): boolean { - return prop - ? Object.keys(matcher).length !== 0 && - Object.keys(prop).length !== 0 && - !Object.keys(matcher).some((key) => prop[key] !== matcher[key]) - : false; -} - -export const a11yAPI = (instance: ReactTestInstance): A11yAPI => - ({ - ...makeA11yQuery( - 'accessibilityStates', - { - getBy: ['getByA11yStates', 'getByAccessibilityStates'], - getAllBy: ['getAllByA11yStates', 'getAllByAccessibilityStates'], - queryBy: ['queryByA11yStates', 'queryByAccessibilityStates'], - queryAllBy: ['queryAllByA11yStates', 'queryAllByAccessibilityStates'], - findBy: ['findByA11yStates', 'findByAccessibilityStates'], - findAllBy: ['findAllByA11yStates', 'findAllByAccessibilityStates'], - }, - matchArrayValue - )(instance), - } as any); diff --git a/src/queries/a11yStates.ts b/src/queries/a11yStates.ts new file mode 100644 index 000000000..e11f3784b --- /dev/null +++ b/src/queries/a11yStates.ts @@ -0,0 +1,79 @@ +import type { ReactTestInstance } from 'react-test-renderer'; +import { AccessibilityState } from 'react-native'; +import { makeQueries } from './makeQueries'; +import type { + FindAllByQuery, + FindByQuery, + GetAllByQuery, + GetByQuery, + QueryAllByQuery, + QueryByQuery, +} from './makeQueries'; + +type AccessibilityStateKey = keyof AccessibilityState; +type AccessibilityStateKeyQueryParam = + | AccessibilityStateKey + | Array; + +export function matchArrayValue( + prop: Array | undefined, + matcher: string | Array +): boolean { + if (!prop || matcher.length === 0) { + return false; + } + + if (typeof matcher === 'string') { + return prop.includes(matcher); + } + + return !matcher.some((e) => !prop.includes(e)); +} + +const queryAllByA11yStates = ( + instance: ReactTestInstance +): (( + accessibilityStateKey: AccessibilityStateKeyQueryParam +) => Array) => + function queryAllByDisplayValueFn(accessibilityStateKey) { + return instance.findAll( + (node) => + typeof node.type === 'string' && + matchArrayValue(node.props.accessibilityState, accessibilityStateKey) + ); + }; + +const getMultipleError = (a11yStates: AccessibilityStateKeyQueryParam) => + `Found multiple elements with accessibilityState: ${JSON.stringify( + a11yStates + )}`; +const getMissingError = (a11yStates: AccessibilityStateKeyQueryParam) => + `Unable to find an element with accessibilityState: ${JSON.stringify( + a11yStates + )}`; + +const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( + queryAllByA11yStates, + getMissingError, + getMultipleError +); + +export type ByA11yStatesQueries = { + getByA11yStates: GetByQuery; + getAllByA11yStates: GetAllByQuery; + queryByA11yStates: QueryByQuery; + queryAllByA11yStates: QueryAllByQuery; + findByA11yStates: FindByQuery; + findAllByA11yStates: FindAllByQuery; +}; + +export const bindByA11yStatesQueries = ( + instance: ReactTestInstance +): ByA11yStatesQueries => ({ + getByA11yStates: getBy(instance), + getAllByA11yStates: getAllBy(instance), + queryByA11yStates: queryBy(instance), + queryAllByA11yStates: queryAllBy(instance), + findByA11yStates: findBy(instance), + findAllByA11yStates: findAllBy(instance), +}); diff --git a/src/within.ts b/src/within.ts index a645fe242..b8cd2dcb5 100644 --- a/src/within.ts +++ b/src/within.ts @@ -1,5 +1,4 @@ import type { ReactTestInstance } from 'react-test-renderer'; -import { a11yAPI } from './queries/a11yAPI'; import { bindByTextQueries } from './queries/text'; import { bindByTestIdQueries } from './queries/testId'; import { bindByDisplayValueQueries } from './queries/displayValue'; @@ -11,6 +10,7 @@ import { bindByA11yHintQueries } from './queries/a11yHint'; import { bindByRoleQueries } from './queries/role'; import { bindByA11yStateQueries } from './queries/a11yState'; import { bindByA11yValueQueries } from './queries/a11yValue'; +import { bindByA11yStatesQueries } from './queries/a11yStates'; export function within(instance: ReactTestInstance) { return { @@ -25,7 +25,7 @@ export function within(instance: ReactTestInstance) { ...bindByA11yHintQueries(instance), ...bindByA11yStateQueries(instance), ...bindByA11yValueQueries(instance), - ...a11yAPI(instance), + ...bindByA11yStatesQueries(instance), }; } From 847ca209e61e2ef5e065b0ff6f94d97b8e842e26 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 14 May 2022 17:44:30 +0200 Subject: [PATCH 08/38] refactor: harmonize component declaration in queries testsx --- src/queries/__tests__/a11yHint.test.tsx | 32 ++++++--------- src/queries/__tests__/a11yState.test.tsx | 34 +++++++--------- src/queries/__tests__/a11yStates.test.tsx | 46 +++++++++------------- src/queries/__tests__/a11yValue.test.tsx | 34 +++++++--------- src/queries/__tests__/labelText.test.tsx | 47 +++++++++-------------- src/queries/__tests__/role.test.tsx | 30 ++++++--------- 6 files changed, 90 insertions(+), 133 deletions(-) diff --git a/src/queries/__tests__/a11yHint.test.tsx b/src/queries/__tests__/a11yHint.test.tsx index 05b2bface..362f0d266 100644 --- a/src/queries/__tests__/a11yHint.test.tsx +++ b/src/queries/__tests__/a11yHint.test.tsx @@ -25,26 +25,18 @@ const Typography = ({ children, ...rest }: any) => { return {children}; }; -class Button extends React.Component { - render() { - return ( - - - {this.props.children} - - - ); - } -} - -function Section() { - return ( - <> - Title - - - ); -} +const Button = ({ children }: { children: React.ReactNode }) => ( + + {children} + +); + +const Section = () => ( + <> + Title + + +); test('getByA11yHint, queryByA11yHint, findByA11yHint', async () => { const { getByA11yHint, queryByA11yHint, findByA11yHint } = render( diff --git a/src/queries/__tests__/a11yState.test.tsx b/src/queries/__tests__/a11yState.test.tsx index da76ea2a8..d6003b176 100644 --- a/src/queries/__tests__/a11yState.test.tsx +++ b/src/queries/__tests__/a11yState.test.tsx @@ -16,26 +16,20 @@ const Typography = ({ children, ...rest }: any) => { return {children}; }; -class Button extends React.Component { - render() { - return ( - - - {this.props.children} - - - ); - } -} - -function Section() { - return ( - <> - Title - - - ); -} +const Button = ({ children }: { children: React.ReactNode }) => ( + + + {children} + + +); + +const Section = () => ( + <> + Title + + +); test('getByA11yState, queryByA11yState, findByA11yState', async () => { const { getByA11yState, queryByA11yState, findByA11yState } = render( diff --git a/src/queries/__tests__/a11yStates.test.tsx b/src/queries/__tests__/a11yStates.test.tsx index 606e83ec7..936211b43 100644 --- a/src/queries/__tests__/a11yStates.test.tsx +++ b/src/queries/__tests__/a11yStates.test.tsx @@ -24,34 +24,26 @@ const Typography = ({ children, ...rest }: any) => { return {children}; }; -class Button extends React.Component { - render() { - return ( - - - {this.props.children} - - - ); - } -} +const Button = ({ children }: { children: React.ReactNode }) => ( + + {children} + +); -function Section() { - return ( - <> - - Title - - - - ); -} +const Section = () => ( + <> + + Title + + + +); // TODO: accessibilityStates was removed from RN 0.62 test.skip('getByA11yStates, queryByA11yStates', () => { diff --git a/src/queries/__tests__/a11yValue.test.tsx b/src/queries/__tests__/a11yValue.test.tsx index f36f63b3d..8709ae8fe 100644 --- a/src/queries/__tests__/a11yValue.test.tsx +++ b/src/queries/__tests__/a11yValue.test.tsx @@ -16,26 +16,20 @@ const Typography = ({ children, ...rest }: any) => { return {children}; }; -class Button extends React.Component { - render() { - return ( - - - {this.props.children} - - - ); - } -} - -function Section() { - return ( - <> - Title - - - ); -} +const Button = ({ children }: { children: React.ReactNode }) => ( + + + {children} + + +); + +const Section = () => ( + <> + Title + + +); test('getByA11yValue, queryByA11yValue, findByA11yValue', async () => { const { getByA11yValue, queryByA11yValue, findByA11yValue } = render( diff --git a/src/queries/__tests__/labelText.test.tsx b/src/queries/__tests__/labelText.test.tsx index 75b638c41..e00fb8fe7 100644 --- a/src/queries/__tests__/labelText.test.tsx +++ b/src/queries/__tests__/labelText.test.tsx @@ -27,34 +27,25 @@ const Typography = ({ children, ...rest }: any) => { return {children}; }; -class Button extends React.Component { - render() { - return ( - - - {this.props.children} - - - ); - } -} - -function Section() { - return ( - <> - - Title - - - - ); -} +const Button = ({ children }: { children: React.ReactNode }) => ( + + + {children} + + +); + +const Section = () => ( + <> + + Title + + + +); test('getByLabelText, queryByLabelText, findByLabelText', async () => { const { getByLabelText, queryByLabelText, findByLabelText } = render( diff --git a/src/queries/__tests__/role.test.tsx b/src/queries/__tests__/role.test.tsx index 3292ae03c..76b7b88e6 100644 --- a/src/queries/__tests__/role.test.tsx +++ b/src/queries/__tests__/role.test.tsx @@ -25,24 +25,18 @@ const Typography = ({ children, ...rest }: any) => { return {children}; }; -class Button extends React.Component { - render() { - return ( - - {this.props.children} - - ); - } -} - -function Section() { - return ( - <> - Title - - - ); -} +const Button = ({ children }: { children: React.ReactNode }) => ( + + {children} + +); + +const Section = () => ( + <> + Title + + +); test('getByRole, queryByRole, findByRole', async () => { const { getByRole, queryByRole, findByRole } = render(
); From b4f4b84cfeb1dbd58588cb1a9eeaceee667073d1 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 14 May 2022 19:29:00 +0200 Subject: [PATCH 09/38] refactor: simplify error helpers in queries tests --- src/queries/__tests__/a11yHint.test.tsx | 28 +++++++++-------------- src/queries/__tests__/a11yState.test.tsx | 22 +++++++++--------- src/queries/__tests__/a11yStates.test.tsx | 20 ++++++---------- src/queries/__tests__/a11yValue.test.tsx | 22 +++++++++--------- src/queries/__tests__/labelText.test.tsx | 28 +++++++++-------------- src/queries/__tests__/role.test.tsx | 28 +++++++++-------------- 6 files changed, 62 insertions(+), 86 deletions(-) diff --git a/src/queries/__tests__/a11yHint.test.tsx b/src/queries/__tests__/a11yHint.test.tsx index 362f0d266..04a9f241e 100644 --- a/src/queries/__tests__/a11yHint.test.tsx +++ b/src/queries/__tests__/a11yHint.test.tsx @@ -7,18 +7,12 @@ const TEXT_HINT = 'static text'; // Little hack to make all the methods happy with type const NO_MATCHES_TEXT: any = 'not-existent-element'; -const getMultipleInstancesFoundMessage = ( - name: string, - value: string = NO_MATCHES_TEXT -) => { - return `Found multiple elements with ${name}: ${value}`; +const getMultipleInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { + return `Found multiple elements with accessibilityHint: ${value}`; }; -const getNoInstancesFoundMessage = ( - name: string, - value: string = NO_MATCHES_TEXT -) => { - return `Unable to find an element with ${name}: ${value}`; +const getNoInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { + return `Unable to find an element with accessibilityHint: ${value}`; }; const Typography = ({ children, ...rest }: any) => { @@ -50,25 +44,25 @@ test('getByA11yHint, queryByA11yHint, findByA11yHint', async () => { expect(button?.props.accessibilityHint).toEqual(BUTTON_HINT); expect(() => getByA11yHint(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityHint') + getNoInstancesFoundMessage() ); expect(queryByA11yHint(NO_MATCHES_TEXT)).toBeNull(); expect(() => getByA11yHint(TEXT_HINT)).toThrow( - getMultipleInstancesFoundMessage('accessibilityHint', TEXT_HINT) + getMultipleInstancesFoundMessage(TEXT_HINT) ); expect(() => queryByA11yHint(TEXT_HINT)).toThrow( - getMultipleInstancesFoundMessage('accessibilityHint', TEXT_HINT) + getMultipleInstancesFoundMessage(TEXT_HINT) ); const asyncButton = await findByA11yHint(BUTTON_HINT); expect(asyncButton.props.accessibilityHint).toEqual(BUTTON_HINT); await expect(findByA11yHint(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityHint') + getNoInstancesFoundMessage() ); await expect(findByA11yHint(TEXT_HINT)).rejects.toThrow( - getMultipleInstancesFoundMessage('accessibilityHint', TEXT_HINT) + getMultipleInstancesFoundMessage(TEXT_HINT) ); }); @@ -81,12 +75,12 @@ test('getAllByA11yHint, queryAllByA11yHint, findAllByA11yHint', async () => { expect(queryAllByA11yHint(TEXT_HINT)).toHaveLength(2); expect(() => getAllByA11yHint(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityHint') + getNoInstancesFoundMessage() ); expect(queryAllByA11yHint(NO_MATCHES_TEXT)).toEqual([]); await expect(findAllByA11yHint(TEXT_HINT)).resolves.toHaveLength(2); await expect(findAllByA11yHint(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityHint') + getNoInstancesFoundMessage() ); }); diff --git a/src/queries/__tests__/a11yState.test.tsx b/src/queries/__tests__/a11yState.test.tsx index d6003b176..c15c078b4 100644 --- a/src/queries/__tests__/a11yState.test.tsx +++ b/src/queries/__tests__/a11yState.test.tsx @@ -4,12 +4,12 @@ import { render } from '../..'; const TEXT_LABEL = 'cool text'; -const getMultipleInstancesFoundMessage = (name: string, value: string) => { - return `Found multiple elements with ${name}: ${value}`; +const getMultipleInstancesFoundMessage = (value: string) => { + return `Found multiple elements with accessibilityState: ${value}`; }; -const getNoInstancesFoundMessage = (name: string, value: string) => { - return `Unable to find an element with ${name}: ${value}`; +const getNoInstancesFoundMessage = (value: string) => { + return `Unable to find an element with accessibilityState: ${value}`; }; const Typography = ({ children, ...rest }: any) => { @@ -48,15 +48,15 @@ test('getByA11yState, queryByA11yState, findByA11yState', async () => { }); expect(() => getByA11yState({ disabled: true })).toThrow( - getNoInstancesFoundMessage('accessibilityState', '{"disabled":true}') + getNoInstancesFoundMessage('{"disabled":true}') ); expect(queryByA11yState({ disabled: true })).toEqual(null); expect(() => getByA11yState({ expanded: false })).toThrow( - getMultipleInstancesFoundMessage('accessibilityState', '{"expanded":false}') + getMultipleInstancesFoundMessage('{"expanded":false}') ); expect(() => queryByA11yState({ expanded: false })).toThrow( - getMultipleInstancesFoundMessage('accessibilityState', '{"expanded":false}') + getMultipleInstancesFoundMessage('{"expanded":false}') ); const asyncButton = await findByA11yState({ selected: true }); @@ -65,10 +65,10 @@ test('getByA11yState, queryByA11yState, findByA11yState', async () => { expanded: false, }); await expect(findByA11yState({ disabled: true })).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityState', '{"disabled":true}') + getNoInstancesFoundMessage('{"disabled":true}') ); await expect(findByA11yState({ expanded: false })).rejects.toThrow( - getMultipleInstancesFoundMessage('accessibilityState', '{"expanded":false}') + getMultipleInstancesFoundMessage('{"expanded":false}') ); }); @@ -81,7 +81,7 @@ test('getAllByA11yState, queryAllByA11yState, findAllByA11yState', async () => { expect(queryAllByA11yState({ selected: true })).toHaveLength(1); expect(() => getAllByA11yState({ disabled: true })).toThrow( - getNoInstancesFoundMessage('accessibilityState', '{"disabled":true}') + getNoInstancesFoundMessage('{"disabled":true}') ); expect(queryAllByA11yState({ disabled: true })).toEqual([]); @@ -90,7 +90,7 @@ test('getAllByA11yState, queryAllByA11yState, findAllByA11yState', async () => { await expect(findAllByA11yState({ selected: true })).resolves.toHaveLength(1); await expect(findAllByA11yState({ disabled: true })).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityState', '{"disabled":true}') + getNoInstancesFoundMessage('{"disabled":true}') ); await expect(findAllByA11yState({ expanded: false })).resolves.toHaveLength( 2 diff --git a/src/queries/__tests__/a11yStates.test.tsx b/src/queries/__tests__/a11yStates.test.tsx index 936211b43..df25bca6e 100644 --- a/src/queries/__tests__/a11yStates.test.tsx +++ b/src/queries/__tests__/a11yStates.test.tsx @@ -6,18 +6,12 @@ const TEXT_LABEL = 'cool text'; // Little hack to make all the methods happy with type const NO_MATCHES_TEXT: any = 'not-existent-element'; -const getMultipleInstancesFoundMessage = ( - name: string, - value: string = NO_MATCHES_TEXT -) => { - return `Found multiple elements with ${name}: ${value}`; +const getMultipleInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { + return `Found multiple elements with accessibilityStates: ${value}`; }; -const getNoInstancesFoundMessage = ( - name: string, - value: string = NO_MATCHES_TEXT -) => { - return `Unable to find an element with ${name}: ${value}`; +const getNoInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { + return `Unable to find an element with accessibilityStates: ${value}`; }; const Typography = ({ children, ...rest }: any) => { @@ -71,10 +65,10 @@ test.skip('getByA11yStates, queryByA11yStates', () => { expect(queryByA11yStates([])).toBeNull(); expect(() => getByA11yStates('selected')).toThrow( - getMultipleInstancesFoundMessage('accessibilityStates', '["selected"]') + getMultipleInstancesFoundMessage('["selected"]') ); expect(() => queryByA11yStates('selected')).toThrow( - getMultipleInstancesFoundMessage('accessibilityStates', '["selected"]') + getMultipleInstancesFoundMessage('["selected"]') ); }); @@ -86,7 +80,7 @@ test.skip('getAllByA11yStates, queryAllByA11yStates', () => { expect(queryAllByA11yStates(['selected'])).toHaveLength(3); expect(() => getAllByA11yStates([])).toThrow( - getNoInstancesFoundMessage('accessibilityStates') + getNoInstancesFoundMessage('[]') ); expect(queryAllByA11yStates(NO_MATCHES_TEXT)).toEqual([]); }); diff --git a/src/queries/__tests__/a11yValue.test.tsx b/src/queries/__tests__/a11yValue.test.tsx index 8709ae8fe..ddb4201a4 100644 --- a/src/queries/__tests__/a11yValue.test.tsx +++ b/src/queries/__tests__/a11yValue.test.tsx @@ -4,12 +4,12 @@ import { render } from '../..'; const TEXT_LABEL = 'cool text'; -const getMultipleInstancesFoundMessage = (name: string, value: string) => { - return `Found multiple elements with ${name}: ${value}`; +const getMultipleInstancesFoundMessage = (value: string) => { + return `Found multiple elements with accessibilityValue: ${value}`; }; -const getNoInstancesFoundMessage = (name: string, value: string) => { - return `Unable to find an element with ${name}: ${value}`; +const getNoInstancesFoundMessage = (value: string) => { + return `Unable to find an element with accessibilityValue: ${value}`; }; const Typography = ({ children, ...rest }: any) => { @@ -46,15 +46,15 @@ test('getByA11yValue, queryByA11yValue, findByA11yValue', async () => { }); expect(() => getByA11yValue({ min: 50 })).toThrow( - getNoInstancesFoundMessage('accessibilityValue', '{"min":50}') + getNoInstancesFoundMessage('{"min":50}') ); expect(queryByA11yValue({ min: 50 })).toEqual(null); expect(() => getByA11yValue({ max: 60 })).toThrow( - getMultipleInstancesFoundMessage('accessibilityValue', '{"max":60}') + getMultipleInstancesFoundMessage('{"max":60}') ); expect(() => queryByA11yValue({ max: 60 })).toThrow( - getMultipleInstancesFoundMessage('accessibilityValue', '{"max":60}') + getMultipleInstancesFoundMessage('{"max":60}') ); const asyncElement = await findByA11yValue({ min: 40 }); @@ -63,10 +63,10 @@ test('getByA11yValue, queryByA11yValue, findByA11yValue', async () => { max: 60, }); await expect(findByA11yValue({ min: 50 })).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityValue', '{"min":50}') + getNoInstancesFoundMessage('{"min":50}') ); await expect(findByA11yValue({ max: 60 })).rejects.toThrow( - getMultipleInstancesFoundMessage('accessibilityValue', '{"max":60}') + getMultipleInstancesFoundMessage('{"max":60}') ); }); @@ -79,7 +79,7 @@ test('getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue', async () => { expect(queryAllByA11yValue({ min: 40 })).toHaveLength(1); expect(() => getAllByA11yValue({ min: 50 })).toThrow( - getNoInstancesFoundMessage('accessibilityValue', '{"min":50}') + getNoInstancesFoundMessage('{"min":50}') ); expect(queryAllByA11yValue({ min: 50 })).toEqual([]); @@ -88,7 +88,7 @@ test('getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue', async () => { await expect(findAllByA11yValue({ min: 40 })).resolves.toHaveLength(1); await expect(findAllByA11yValue({ min: 50 })).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityValue', '{"min":50}') + getNoInstancesFoundMessage('{"min":50}') ); await expect(findAllByA11yValue({ max: 60 })).resolves.toHaveLength(2); }); diff --git a/src/queries/__tests__/labelText.test.tsx b/src/queries/__tests__/labelText.test.tsx index e00fb8fe7..ea306807d 100644 --- a/src/queries/__tests__/labelText.test.tsx +++ b/src/queries/__tests__/labelText.test.tsx @@ -9,18 +9,12 @@ const TEXT_HINT = 'static text'; // Little hack to make all the methods happy with type const NO_MATCHES_TEXT: any = 'not-existent-element'; -const getMultipleInstancesFoundMessage = ( - name: string, - value: string = NO_MATCHES_TEXT -) => { - return `Found multiple elements with ${name}: ${value}`; +const getMultipleInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { + return `Found multiple elements with accessibilityLabel: ${value}`; }; -const getNoInstancesFoundMessage = ( - name: string, - value: string = NO_MATCHES_TEXT -) => { - return `Unable to find an element with ${name}: ${value}`; +const getNoInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { + return `Unable to find an element with accessibilityLabel: ${value}`; }; const Typography = ({ children, ...rest }: any) => { @@ -59,25 +53,25 @@ test('getByLabelText, queryByLabelText, findByLabelText', async () => { expect(button?.props.accessibilityLabel).toEqual(BUTTON_LABEL); expect(() => getByLabelText(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityLabel') + getNoInstancesFoundMessage() ); expect(queryByLabelText(NO_MATCHES_TEXT)).toBeNull(); expect(() => getByLabelText(TEXT_LABEL)).toThrow( - getMultipleInstancesFoundMessage('accessibilityLabel', TEXT_LABEL) + getMultipleInstancesFoundMessage(TEXT_LABEL) ); expect(() => queryByLabelText(TEXT_LABEL)).toThrow( - getMultipleInstancesFoundMessage('accessibilityLabel', TEXT_LABEL) + getMultipleInstancesFoundMessage(TEXT_LABEL) ); const asyncButton = await findByLabelText(BUTTON_LABEL); expect(asyncButton.props.accessibilityLabel).toEqual(BUTTON_LABEL); await expect(findByLabelText(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityLabel') + getNoInstancesFoundMessage() ); await expect(findByLabelText(TEXT_LABEL)).rejects.toThrow( - getMultipleInstancesFoundMessage('accessibilityLabel', TEXT_LABEL) + getMultipleInstancesFoundMessage(TEXT_LABEL) ); }); @@ -90,12 +84,12 @@ test('getAllByLabelText, queryAllByLabelText, findAllByLabelText', async () => { expect(queryAllByLabelText(/cool/g)).toHaveLength(3); expect(() => getAllByLabelText(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityLabel') + getNoInstancesFoundMessage() ); expect(queryAllByLabelText(NO_MATCHES_TEXT)).toEqual([]); await expect(findAllByLabelText(TEXT_LABEL)).resolves.toHaveLength(2); await expect(findAllByLabelText(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityLabel') + getNoInstancesFoundMessage() ); }); diff --git a/src/queries/__tests__/role.test.tsx b/src/queries/__tests__/role.test.tsx index 76b7b88e6..303472a6e 100644 --- a/src/queries/__tests__/role.test.tsx +++ b/src/queries/__tests__/role.test.tsx @@ -7,18 +7,12 @@ const TEXT_LABEL = 'cool text'; // Little hack to make all the methods happy with type const NO_MATCHES_TEXT: any = 'not-existent-element'; -const getMultipleInstancesFoundMessage = ( - name: string, - value: string = NO_MATCHES_TEXT -) => { - return `Found multiple elements with ${name}: ${value}`; +const getMultipleInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { + return `Found multiple elements with accessibilityRole: ${value}`; }; -const getNoInstancesFoundMessage = ( - name: string, - value: string = NO_MATCHES_TEXT -) => { - return `Unable to find an element with ${name}: ${value}`; +const getNoInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { + return `Unable to find an element with accessibilityRole: ${value}`; }; const Typography = ({ children, ...rest }: any) => { @@ -46,24 +40,24 @@ test('getByRole, queryByRole, findByRole', async () => { expect(button?.props.accessibilityRole).toEqual('button'); expect(() => getByRole(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityRole') + getNoInstancesFoundMessage() ); expect(queryByRole(NO_MATCHES_TEXT)).toBeNull(); expect(() => getByRole('link')).toThrow( - getMultipleInstancesFoundMessage('accessibilityRole', 'link') + getMultipleInstancesFoundMessage('link') ); expect(() => queryByRole('link')).toThrow( - getMultipleInstancesFoundMessage('accessibilityRole', 'link') + getMultipleInstancesFoundMessage('link') ); const asyncButton = await findByRole('button'); expect(asyncButton.props.accessibilityRole).toEqual('button'); await expect(findByRole(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityRole') + getNoInstancesFoundMessage() ); await expect(findByRole('link')).rejects.toThrow( - getMultipleInstancesFoundMessage('accessibilityRole', 'link') + getMultipleInstancesFoundMessage('link') ); }); @@ -74,12 +68,12 @@ test('getAllByRole, queryAllByRole, findAllByRole', async () => { expect(queryAllByRole(/ink/g)).toHaveLength(2); expect(() => getAllByRole(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage('accessibilityRole') + getNoInstancesFoundMessage() ); expect(queryAllByRole(NO_MATCHES_TEXT)).toEqual([]); await expect(findAllByRole('link')).resolves.toHaveLength(2); await expect(findAllByRole(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage('accessibilityRole') + getNoInstancesFoundMessage() ); }); From c3a7416fdb3eed564ff22647bd000dc0ca5ac497 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 14 May 2022 19:31:36 +0200 Subject: [PATCH 10/38] refactor: make error helpers more explicit --- src/queries/__tests__/a11yHint.test.tsx | 12 ++++++------ src/queries/__tests__/a11yStates.test.tsx | 4 ++-- src/queries/__tests__/labelText.test.tsx | 12 ++++++------ src/queries/__tests__/role.test.tsx | 12 ++++++------ 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/queries/__tests__/a11yHint.test.tsx b/src/queries/__tests__/a11yHint.test.tsx index 04a9f241e..6e5ddb5e7 100644 --- a/src/queries/__tests__/a11yHint.test.tsx +++ b/src/queries/__tests__/a11yHint.test.tsx @@ -7,11 +7,11 @@ const TEXT_HINT = 'static text'; // Little hack to make all the methods happy with type const NO_MATCHES_TEXT: any = 'not-existent-element'; -const getMultipleInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { +const getMultipleInstancesFoundMessage = (value: string) => { return `Found multiple elements with accessibilityHint: ${value}`; }; -const getNoInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { +const getNoInstancesFoundMessage = (value: string) => { return `Unable to find an element with accessibilityHint: ${value}`; }; @@ -44,7 +44,7 @@ test('getByA11yHint, queryByA11yHint, findByA11yHint', async () => { expect(button?.props.accessibilityHint).toEqual(BUTTON_HINT); expect(() => getByA11yHint(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); expect(queryByA11yHint(NO_MATCHES_TEXT)).toBeNull(); @@ -58,7 +58,7 @@ test('getByA11yHint, queryByA11yHint, findByA11yHint', async () => { const asyncButton = await findByA11yHint(BUTTON_HINT); expect(asyncButton.props.accessibilityHint).toEqual(BUTTON_HINT); await expect(findByA11yHint(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); await expect(findByA11yHint(TEXT_HINT)).rejects.toThrow( @@ -75,12 +75,12 @@ test('getAllByA11yHint, queryAllByA11yHint, findAllByA11yHint', async () => { expect(queryAllByA11yHint(TEXT_HINT)).toHaveLength(2); expect(() => getAllByA11yHint(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); expect(queryAllByA11yHint(NO_MATCHES_TEXT)).toEqual([]); await expect(findAllByA11yHint(TEXT_HINT)).resolves.toHaveLength(2); await expect(findAllByA11yHint(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); }); diff --git a/src/queries/__tests__/a11yStates.test.tsx b/src/queries/__tests__/a11yStates.test.tsx index df25bca6e..7a01b0725 100644 --- a/src/queries/__tests__/a11yStates.test.tsx +++ b/src/queries/__tests__/a11yStates.test.tsx @@ -6,11 +6,11 @@ const TEXT_LABEL = 'cool text'; // Little hack to make all the methods happy with type const NO_MATCHES_TEXT: any = 'not-existent-element'; -const getMultipleInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { +const getMultipleInstancesFoundMessage = (value: string) => { return `Found multiple elements with accessibilityStates: ${value}`; }; -const getNoInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { +const getNoInstancesFoundMessage = (value: string) => { return `Unable to find an element with accessibilityStates: ${value}`; }; diff --git a/src/queries/__tests__/labelText.test.tsx b/src/queries/__tests__/labelText.test.tsx index ea306807d..8b9dc54e1 100644 --- a/src/queries/__tests__/labelText.test.tsx +++ b/src/queries/__tests__/labelText.test.tsx @@ -9,11 +9,11 @@ const TEXT_HINT = 'static text'; // Little hack to make all the methods happy with type const NO_MATCHES_TEXT: any = 'not-existent-element'; -const getMultipleInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { +const getMultipleInstancesFoundMessage = (value: string) => { return `Found multiple elements with accessibilityLabel: ${value}`; }; -const getNoInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { +const getNoInstancesFoundMessage = (value: string) => { return `Unable to find an element with accessibilityLabel: ${value}`; }; @@ -53,7 +53,7 @@ test('getByLabelText, queryByLabelText, findByLabelText', async () => { expect(button?.props.accessibilityLabel).toEqual(BUTTON_LABEL); expect(() => getByLabelText(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); expect(queryByLabelText(NO_MATCHES_TEXT)).toBeNull(); @@ -67,7 +67,7 @@ test('getByLabelText, queryByLabelText, findByLabelText', async () => { const asyncButton = await findByLabelText(BUTTON_LABEL); expect(asyncButton.props.accessibilityLabel).toEqual(BUTTON_LABEL); await expect(findByLabelText(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); await expect(findByLabelText(TEXT_LABEL)).rejects.toThrow( @@ -84,12 +84,12 @@ test('getAllByLabelText, queryAllByLabelText, findAllByLabelText', async () => { expect(queryAllByLabelText(/cool/g)).toHaveLength(3); expect(() => getAllByLabelText(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); expect(queryAllByLabelText(NO_MATCHES_TEXT)).toEqual([]); await expect(findAllByLabelText(TEXT_LABEL)).resolves.toHaveLength(2); await expect(findAllByLabelText(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); }); diff --git a/src/queries/__tests__/role.test.tsx b/src/queries/__tests__/role.test.tsx index 303472a6e..de5ebfd7f 100644 --- a/src/queries/__tests__/role.test.tsx +++ b/src/queries/__tests__/role.test.tsx @@ -7,11 +7,11 @@ const TEXT_LABEL = 'cool text'; // Little hack to make all the methods happy with type const NO_MATCHES_TEXT: any = 'not-existent-element'; -const getMultipleInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { +const getMultipleInstancesFoundMessage = (value: string) => { return `Found multiple elements with accessibilityRole: ${value}`; }; -const getNoInstancesFoundMessage = (value: string = NO_MATCHES_TEXT) => { +const getNoInstancesFoundMessage = (value: string) => { return `Unable to find an element with accessibilityRole: ${value}`; }; @@ -40,7 +40,7 @@ test('getByRole, queryByRole, findByRole', async () => { expect(button?.props.accessibilityRole).toEqual('button'); expect(() => getByRole(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); expect(queryByRole(NO_MATCHES_TEXT)).toBeNull(); @@ -54,7 +54,7 @@ test('getByRole, queryByRole, findByRole', async () => { const asyncButton = await findByRole('button'); expect(asyncButton.props.accessibilityRole).toEqual('button'); await expect(findByRole(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); await expect(findByRole('link')).rejects.toThrow( getMultipleInstancesFoundMessage('link') @@ -68,12 +68,12 @@ test('getAllByRole, queryAllByRole, findAllByRole', async () => { expect(queryAllByRole(/ink/g)).toHaveLength(2); expect(() => getAllByRole(NO_MATCHES_TEXT)).toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); expect(queryAllByRole(NO_MATCHES_TEXT)).toEqual([]); await expect(findAllByRole('link')).resolves.toHaveLength(2); await expect(findAllByRole(NO_MATCHES_TEXT)).rejects.toThrow( - getNoInstancesFoundMessage() + getNoInstancesFoundMessage(NO_MATCHES_TEXT) ); }); From e4b5c5550ee8a61ab3ae7fde38247e032cdc9a6d Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 14 May 2022 19:34:25 +0200 Subject: [PATCH 11/38] chore: remove now unused makeA11yQueries --- src/queries/makeA11yQuery.ts | 96 ------------------------------------ 1 file changed, 96 deletions(-) delete mode 100644 src/queries/makeA11yQuery.ts diff --git a/src/queries/makeA11yQuery.ts b/src/queries/makeA11yQuery.ts deleted file mode 100644 index 889f00be8..000000000 --- a/src/queries/makeA11yQuery.ts +++ /dev/null @@ -1,96 +0,0 @@ -import type { ReactTestInstance } from 'react-test-renderer'; -import waitFor from '../waitFor'; -import type { WaitForOptions } from '../waitFor'; -import { - ErrorWithStack, - prepareErrorMessage, - createQueryByError, -} from '../helpers/errors'; - -function isNodeValid(node: ReactTestInstance) { - return typeof node.type === 'string'; -} - -function makeAliases(aliases: Array, query: Function) { - return aliases - .map((alias) => ({ [alias]: query })) - .reduce((acc, query) => ({ ...acc, ...query }), {}); -} - -type QueryNames = { - getBy: Array; - getAllBy: Array; - queryBy: Array; - queryAllBy: Array; - findBy: Array; - findAllBy: Array; -}; - -const makeA11yQuery =

( - name: string, - queryNames: QueryNames, - matcherFn: (prop: P, value: M) => boolean -) => (instance: ReactTestInstance) => { - const getBy = (matcher: M) => { - try { - return instance.find( - (node) => isNodeValid(node) && matcherFn(node.props[name], matcher) - ); - } catch (error) { - throw new ErrorWithStack( - prepareErrorMessage(error, name, matcher), - getBy - ); - } - }; - - const getAllBy = (matcher: M) => { - const results = instance.findAll( - (node) => isNodeValid(node) && matcherFn(node.props[name], matcher) - ); - - if (results.length === 0) { - throw new ErrorWithStack( - prepareErrorMessage(new Error('No instances found'), name, matcher), - getAllBy - ); - } - - return results; - }; - - const queryBy = (matcher: M) => { - try { - return getBy(matcher); - } catch (error) { - return createQueryByError(error, queryBy); - } - }; - - const queryAllBy = (matcher: M) => { - try { - return getAllBy(matcher); - } catch (error) { - return []; - } - }; - - const findBy = (matcher: M, waitForOptions?: WaitForOptions) => { - return waitFor(() => getBy(matcher), waitForOptions); - }; - - const findAllBy = (matcher: M, waitForOptions?: WaitForOptions) => { - return waitFor(() => getAllBy(matcher), waitForOptions); - }; - - return { - ...makeAliases(queryNames.getBy, getBy), - ...makeAliases(queryNames.getAllBy, getAllBy), - ...makeAliases(queryNames.queryBy, queryBy), - ...makeAliases(queryNames.queryAllBy, queryAllBy), - ...makeAliases(queryNames.findBy, findBy), - ...makeAliases(queryNames.findAllBy, findAllBy), - }; -}; - -export default makeA11yQuery; From 6d35b7f9c1e3c464854cf6738fb2611474db98d0 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:09:37 +0200 Subject: [PATCH 12/38] refactor: rename AccessibilityStateKeyQueryParam to AccessibilityStateKeys --- src/queries/a11yStates.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/queries/a11yStates.ts b/src/queries/a11yStates.ts index e11f3784b..fd1b00488 100644 --- a/src/queries/a11yStates.ts +++ b/src/queries/a11yStates.ts @@ -11,7 +11,7 @@ import type { } from './makeQueries'; type AccessibilityStateKey = keyof AccessibilityState; -type AccessibilityStateKeyQueryParam = +type AccessibilityStateKeys = | AccessibilityStateKey | Array; @@ -33,7 +33,7 @@ export function matchArrayValue( const queryAllByA11yStates = ( instance: ReactTestInstance ): (( - accessibilityStateKey: AccessibilityStateKeyQueryParam + accessibilityStateKey: AccessibilityStateKeys ) => Array) => function queryAllByDisplayValueFn(accessibilityStateKey) { return instance.findAll( @@ -43,11 +43,11 @@ const queryAllByA11yStates = ( ); }; -const getMultipleError = (a11yStates: AccessibilityStateKeyQueryParam) => +const getMultipleError = (a11yStates: AccessibilityStateKeys) => `Found multiple elements with accessibilityState: ${JSON.stringify( a11yStates )}`; -const getMissingError = (a11yStates: AccessibilityStateKeyQueryParam) => +const getMissingError = (a11yStates: AccessibilityStateKeys) => `Unable to find an element with accessibilityState: ${JSON.stringify( a11yStates )}`; @@ -59,12 +59,12 @@ const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( ); export type ByA11yStatesQueries = { - getByA11yStates: GetByQuery; - getAllByA11yStates: GetAllByQuery; - queryByA11yStates: QueryByQuery; - queryAllByA11yStates: QueryAllByQuery; - findByA11yStates: FindByQuery; - findAllByA11yStates: FindAllByQuery; + getByA11yStates: GetByQuery; + getAllByA11yStates: GetAllByQuery; + queryByA11yStates: QueryByQuery; + queryAllByA11yStates: QueryAllByQuery; + findByA11yStates: FindByQuery; + findAllByA11yStates: FindAllByQuery; }; export const bindByA11yStatesQueries = ( From 8fd103ab4ba2ab0ca13898ebb65efd5ea4fcb400 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:14:04 +0200 Subject: [PATCH 13/38] refactor: rename param in a11yStates --- src/queries/a11yStates.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/queries/a11yStates.ts b/src/queries/a11yStates.ts index fd1b00488..fa4324003 100644 --- a/src/queries/a11yStates.ts +++ b/src/queries/a11yStates.ts @@ -33,13 +33,13 @@ export function matchArrayValue( const queryAllByA11yStates = ( instance: ReactTestInstance ): (( - accessibilityStateKey: AccessibilityStateKeys + accessibilityStates: AccessibilityStateKeys ) => Array) => - function queryAllByDisplayValueFn(accessibilityStateKey) { + function queryAllByDisplayValueFn(accessibilityStates) { return instance.findAll( (node) => typeof node.type === 'string' && - matchArrayValue(node.props.accessibilityState, accessibilityStateKey) + matchArrayValue(node.props.accessibilityState, accessibilityStates) ); }; From 107aa7b233d77ba5dc7598035315604261f64b3b Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:24:20 +0200 Subject: [PATCH 14/38] refactor: simplify matchObject --- src/queries/a11yValue.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/queries/a11yValue.ts b/src/queries/a11yValue.ts index be16301ed..47c2dfecd 100644 --- a/src/queries/a11yValue.ts +++ b/src/queries/a11yValue.ts @@ -23,7 +23,7 @@ export function matchObject>( return prop ? Object.keys(matcher).length !== 0 && Object.keys(prop).length !== 0 && - !Object.keys(matcher).some((key) => prop[key] !== matcher[key]) + Object.keys(matcher).every((key) => prop[key] === matcher[key]) : false; } From 3d90a8fe38e32713f81fd976f5b22f85dfa4b1c5 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:35:27 +0200 Subject: [PATCH 15/38] refactor: fix namings in labelText --- src/queries/labelText.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/queries/labelText.ts b/src/queries/labelText.ts index 454b67c74..fb569b459 100644 --- a/src/queries/labelText.ts +++ b/src/queries/labelText.ts @@ -27,12 +27,12 @@ export function matchStringValue( const queryAllByLabelText = ( instance: ReactTestInstance -): ((displayValue: TextMatch) => Array) => - function queryAllByDisplayValueFn(displayValue) { +): ((text: TextMatch) => Array) => + function queryAllByLabelTextFn(text) { return instance.findAll( (node) => typeof node.type === 'string' && - matchStringValue(node.props.accessibilityLabel, displayValue) + matchStringValue(node.props.accessibilityLabel, text) ); }; From 91b27ef420fa167a75896895751ad0a5dd3d45c6 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:36:54 +0200 Subject: [PATCH 16/38] refactor: fix namings in a11yHint --- src/queries/a11yHint.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/queries/a11yHint.ts b/src/queries/a11yHint.ts index 224bcd469..8e23ca93b 100644 --- a/src/queries/a11yHint.ts +++ b/src/queries/a11yHint.ts @@ -27,19 +27,19 @@ export function matchStringValue( const queryAllByA11yHint = ( instance: ReactTestInstance -): ((displayValue: TextMatch) => Array) => - function queryAllByDisplayValueFn(displayValue) { +): ((hint: TextMatch) => Array) => + function queryAllByA11yHintFn(hint) { return instance.findAll( (node) => typeof node.type === 'string' && - matchStringValue(node.props.accessibilityHint, displayValue) + matchStringValue(node.props.accessibilityHint, hint) ); }; -const getMultipleError = (a11yHint: TextMatch) => - `Found multiple elements with accessibilityHint: ${String(a11yHint)} `; -const getMissingError = (a11yHint: TextMatch) => - `Unable to find an element with accessibilityHint: ${String(a11yHint)}`; +const getMultipleError = (hint: TextMatch) => + `Found multiple elements with accessibilityHint: ${String(hint)} `; +const getMissingError = (hint: TextMatch) => + `Unable to find an element with accessibilityHint: ${String(hint)}`; const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( queryAllByA11yHint, From d88c7b586a66519089a1c4cc3cef71c65259cfb5 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:38:29 +0200 Subject: [PATCH 17/38] refactor: fix queryAll namings' --- src/queries/a11yState.ts | 2 +- src/queries/a11yStates.ts | 2 +- src/queries/a11yValue.ts | 2 +- src/queries/role.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/queries/a11yState.ts b/src/queries/a11yState.ts index b11ae6d58..af0d11228 100644 --- a/src/queries/a11yState.ts +++ b/src/queries/a11yState.ts @@ -24,7 +24,7 @@ export function matchObject>( const queryAllByA11yState = ( instance: ReactTestInstance ): ((accessibilityStateKey: AccessibilityState) => Array) => - function queryAllByDisplayValueFn(accessibilityStateKey) { + function queryAllByA11yStateFn(accessibilityStateKey) { return instance.findAll( (node) => typeof node.type === 'string' && diff --git a/src/queries/a11yStates.ts b/src/queries/a11yStates.ts index fa4324003..133c9a255 100644 --- a/src/queries/a11yStates.ts +++ b/src/queries/a11yStates.ts @@ -35,7 +35,7 @@ const queryAllByA11yStates = ( ): (( accessibilityStates: AccessibilityStateKeys ) => Array) => - function queryAllByDisplayValueFn(accessibilityStates) { + function queryAllByA11yStatesFn(accessibilityStates) { return instance.findAll( (node) => typeof node.type === 'string' && diff --git a/src/queries/a11yValue.ts b/src/queries/a11yValue.ts index 47c2dfecd..feaf1acaa 100644 --- a/src/queries/a11yValue.ts +++ b/src/queries/a11yValue.ts @@ -30,7 +30,7 @@ export function matchObject>( const queryAllByA11yValue = ( instance: ReactTestInstance ): ((displayValue: A11yValue) => Array) => - function queryAllByDisplayValueFn(displayValue) { + function queryAllByA11yValueFn(displayValue) { return instance.findAll( (node) => typeof node.type === 'string' && diff --git a/src/queries/role.ts b/src/queries/role.ts index 84920021f..6469e905a 100644 --- a/src/queries/role.ts +++ b/src/queries/role.ts @@ -28,7 +28,7 @@ export function matchStringValue( const queryAllByRole = ( instance: ReactTestInstance ): ((displayValue: TextMatch) => Array) => - function queryAllByDisplayValueFn(displayValue) { + function queryAllByRoleFn(displayValue) { return instance.findAll( (node) => typeof node.type === 'string' && From ebc79182d093d740a7619a37575e728af514b22b Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:41:46 +0200 Subject: [PATCH 18/38] refactor: fix some namings in a11yState --- src/queries/a11yState.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/queries/a11yState.ts b/src/queries/a11yState.ts index af0d11228..9041f8037 100644 --- a/src/queries/a11yState.ts +++ b/src/queries/a11yState.ts @@ -23,23 +23,19 @@ export function matchObject>( const queryAllByA11yState = ( instance: ReactTestInstance -): ((accessibilityStateKey: AccessibilityState) => Array) => - function queryAllByA11yStateFn(accessibilityStateKey) { +): ((state: AccessibilityState) => Array) => + function queryAllByA11yStateFn(state) { return instance.findAll( (node) => typeof node.type === 'string' && - matchObject(node.props.accessibilityState, accessibilityStateKey) + matchObject(node.props.accessibilityState, state) ); }; -const getMultipleError = (a11yState: AccessibilityState) => - `Found multiple elements with accessibilityState: ${JSON.stringify( - a11yState - )}`; -const getMissingError = (a11yState: AccessibilityState) => - `Unable to find an element with accessibilityState: ${JSON.stringify( - a11yState - )}`; +const getMultipleError = (state: AccessibilityState) => + `Found multiple elements with accessibilityState: ${JSON.stringify(state)}`; +const getMissingError = (state: AccessibilityState) => + `Unable to find an element with accessibilityState: ${JSON.stringify(state)}`; const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( queryAllByA11yState, From 827adc276ee4bc4d391e2c1f1ed508fdb31b9f6c Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:44:24 +0200 Subject: [PATCH 19/38] refactor: fix some namings in role --- src/queries/role.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/queries/role.ts b/src/queries/role.ts index 6469e905a..ac670e877 100644 --- a/src/queries/role.ts +++ b/src/queries/role.ts @@ -27,12 +27,12 @@ export function matchStringValue( const queryAllByRole = ( instance: ReactTestInstance -): ((displayValue: TextMatch) => Array) => - function queryAllByRoleFn(displayValue) { +): ((role: TextMatch) => Array) => + function queryAllByRoleFn(role) { return instance.findAll( (node) => typeof node.type === 'string' && - matchStringValue(node.props.accessibilityRole, displayValue) + matchStringValue(node.props.accessibilityRole, role) ); }; From 8f4cd6b4ba0ac97e7ac5ff424208304d856257f1 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:46:17 +0200 Subject: [PATCH 20/38] refactor: fix some namings in a11yValue --- src/queries/a11yValue.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/queries/a11yValue.ts b/src/queries/a11yValue.ts index feaf1acaa..82713d6e9 100644 --- a/src/queries/a11yValue.ts +++ b/src/queries/a11yValue.ts @@ -29,23 +29,19 @@ export function matchObject>( const queryAllByA11yValue = ( instance: ReactTestInstance -): ((displayValue: A11yValue) => Array) => - function queryAllByA11yValueFn(displayValue) { +): ((value: A11yValue) => Array) => + function queryAllByA11yValueFn(value) { return instance.findAll( (node) => typeof node.type === 'string' && - matchObject(node.props.accessibilityValue, displayValue) + matchObject(node.props.accessibilityValue, value) ); }; -const getMultipleError = (a11yValue: A11yValue) => - `Found multiple elements with accessibilityValue: ${JSON.stringify( - a11yValue - )} `; -const getMissingError = (a11yValue: A11yValue) => - `Unable to find an element with accessibilityValue: ${JSON.stringify( - a11yValue - )}`; +const getMultipleError = (value: A11yValue) => + `Found multiple elements with accessibilityValue: ${JSON.stringify(value)} `; +const getMissingError = (value: A11yValue) => + `Unable to find an element with accessibilityValue: ${JSON.stringify(value)}`; const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( queryAllByA11yValue, From 131e473e18090e79fbefc6901cf1a0acb0d34ffa Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:49:09 +0200 Subject: [PATCH 21/38] refactor: extract matchStringValue --- src/helpers/matchers/matchStringValue.ts | 16 ++++++++++++++++ src/queries/a11yHint.ts | 16 +--------------- src/queries/labelText.ts | 16 +--------------- src/queries/role.ts | 16 +--------------- 4 files changed, 19 insertions(+), 45 deletions(-) create mode 100644 src/helpers/matchers/matchStringValue.ts diff --git a/src/helpers/matchers/matchStringValue.ts b/src/helpers/matchers/matchStringValue.ts new file mode 100644 index 000000000..309106500 --- /dev/null +++ b/src/helpers/matchers/matchStringValue.ts @@ -0,0 +1,16 @@ +import { TextMatch } from '../../matches'; + +export function matchStringValue( + prop: string | undefined, + matcher: TextMatch +): boolean { + if (!prop) { + return false; + } + + if (typeof matcher === 'string') { + return prop === matcher; + } + + return Boolean(prop.match(matcher)); +} diff --git a/src/queries/a11yHint.ts b/src/queries/a11yHint.ts index 8e23ca93b..6b4d8f0ff 100644 --- a/src/queries/a11yHint.ts +++ b/src/queries/a11yHint.ts @@ -1,5 +1,6 @@ import type { ReactTestInstance } from 'react-test-renderer'; import { TextMatch } from '../matches'; +import { matchStringValue } from '../helpers/matchers/matchStringValue'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -10,21 +11,6 @@ import type { QueryByQuery, } from './makeQueries'; -export function matchStringValue( - prop: string | undefined, - matcher: TextMatch -): boolean { - if (!prop) { - return false; - } - - if (typeof matcher === 'string') { - return prop === matcher; - } - - return Boolean(prop.match(matcher)); -} - const queryAllByA11yHint = ( instance: ReactTestInstance ): ((hint: TextMatch) => Array) => diff --git a/src/queries/labelText.ts b/src/queries/labelText.ts index fb569b459..f508aa537 100644 --- a/src/queries/labelText.ts +++ b/src/queries/labelText.ts @@ -1,5 +1,6 @@ import type { ReactTestInstance } from 'react-test-renderer'; import { TextMatch } from '../matches'; +import { matchStringValue } from '../helpers/matchers/matchStringValue'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -10,21 +11,6 @@ import type { QueryByQuery, } from './makeQueries'; -export function matchStringValue( - prop: string | undefined, - matcher: TextMatch -): boolean { - if (!prop) { - return false; - } - - if (typeof matcher === 'string') { - return prop === matcher; - } - - return Boolean(prop.match(matcher)); -} - const queryAllByLabelText = ( instance: ReactTestInstance ): ((text: TextMatch) => Array) => diff --git a/src/queries/role.ts b/src/queries/role.ts index ac670e877..ca530fb23 100644 --- a/src/queries/role.ts +++ b/src/queries/role.ts @@ -1,5 +1,6 @@ import type { ReactTestInstance } from 'react-test-renderer'; import { TextMatch } from '../matches'; +import { matchStringValue } from '../helpers/matchers/matchStringValue'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -10,21 +11,6 @@ import type { QueryByQuery, } from './makeQueries'; -export function matchStringValue( - prop: string | undefined, - matcher: TextMatch -): boolean { - if (!prop) { - return false; - } - - if (typeof matcher === 'string') { - return prop === matcher; - } - - return Boolean(prop.match(matcher)); -} - const queryAllByRole = ( instance: ReactTestInstance ): ((role: TextMatch) => Array) => From b5e6d63e23a702cbd8c5af87cb36e75c47c94c0e Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:51:14 +0200 Subject: [PATCH 22/38] refactor: extract matchObject --- src/helpers/matchers/matchObject.ts | 15 +++++++++++++++ src/queries/a11yState.ts | 12 +----------- src/queries/a11yValue.ts | 12 +----------- 3 files changed, 17 insertions(+), 22 deletions(-) create mode 100644 src/helpers/matchers/matchObject.ts diff --git a/src/helpers/matchers/matchObject.ts b/src/helpers/matchers/matchObject.ts new file mode 100644 index 000000000..81f9519c0 --- /dev/null +++ b/src/helpers/matchers/matchObject.ts @@ -0,0 +1,15 @@ +/** + * check that each key value pair of the objects match + * BE CAREFUL it works only for 1 level deep key value pairs + * won't work for nested objects + */ +export function matchObject>( + prop: T | undefined, + matcher: T +): boolean { + return prop + ? Object.keys(matcher).length !== 0 && + Object.keys(prop).length !== 0 && + Object.keys(matcher).every((key) => prop[key] === matcher[key]) + : false; +} diff --git a/src/queries/a11yState.ts b/src/queries/a11yState.ts index 9041f8037..ac89b123e 100644 --- a/src/queries/a11yState.ts +++ b/src/queries/a11yState.ts @@ -1,5 +1,6 @@ import type { ReactTestInstance } from 'react-test-renderer'; import { AccessibilityState } from 'react-native'; +import { matchObject } from '../helpers/matchers/matchObject'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -10,17 +11,6 @@ import type { QueryByQuery, } from './makeQueries'; -export function matchObject>( - prop: T | undefined, - matcher: T -): boolean { - return prop - ? Object.keys(matcher).length !== 0 && - Object.keys(prop).length !== 0 && - !Object.keys(matcher).some((key) => prop[key] !== matcher[key]) - : false; -} - const queryAllByA11yState = ( instance: ReactTestInstance ): ((state: AccessibilityState) => Array) => diff --git a/src/queries/a11yValue.ts b/src/queries/a11yValue.ts index 82713d6e9..701e06a2e 100644 --- a/src/queries/a11yValue.ts +++ b/src/queries/a11yValue.ts @@ -1,4 +1,5 @@ import type { ReactTestInstance } from 'react-test-renderer'; +import { matchObject } from '../helpers/matchers/matchObject'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -16,17 +17,6 @@ type A11yValue = { text?: string; }; -export function matchObject>( - prop: T | undefined, - matcher: T -): boolean { - return prop - ? Object.keys(matcher).length !== 0 && - Object.keys(prop).length !== 0 && - Object.keys(matcher).every((key) => prop[key] === matcher[key]) - : false; -} - const queryAllByA11yValue = ( instance: ReactTestInstance ): ((value: A11yValue) => Array) => From 63c7dbe6a6fc8529b1fed7ab6adcf074b1ce22ce Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 16:55:30 +0200 Subject: [PATCH 23/38] refactor: extract matchArrayValue --- src/helpers/matchers/matchArrayValue.ts | 14 ++++++++++++++ src/queries/a11yStates.ts | 16 +--------------- 2 files changed, 15 insertions(+), 15 deletions(-) create mode 100644 src/helpers/matchers/matchArrayValue.ts diff --git a/src/helpers/matchers/matchArrayValue.ts b/src/helpers/matchers/matchArrayValue.ts new file mode 100644 index 000000000..c43193ab2 --- /dev/null +++ b/src/helpers/matchers/matchArrayValue.ts @@ -0,0 +1,14 @@ +export function matchArrayValue( + prop: Array | undefined, + matcher: string | Array +): boolean { + if (!prop || matcher.length === 0) { + return false; + } + + if (typeof matcher === 'string') { + return prop.includes(matcher); + } + + return !matcher.some((e) => !prop.includes(e)); +} diff --git a/src/queries/a11yStates.ts b/src/queries/a11yStates.ts index 133c9a255..178a15b62 100644 --- a/src/queries/a11yStates.ts +++ b/src/queries/a11yStates.ts @@ -1,5 +1,6 @@ import type { ReactTestInstance } from 'react-test-renderer'; import { AccessibilityState } from 'react-native'; +import { matchArrayValue } from '../helpers/matchers/matchArrayValue'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -15,21 +16,6 @@ type AccessibilityStateKeys = | AccessibilityStateKey | Array; -export function matchArrayValue( - prop: Array | undefined, - matcher: string | Array -): boolean { - if (!prop || matcher.length === 0) { - return false; - } - - if (typeof matcher === 'string') { - return prop.includes(matcher); - } - - return !matcher.some((e) => !prop.includes(e)); -} - const queryAllByA11yStates = ( instance: ReactTestInstance ): (( From 65db09f7bca4588142d0fecc0ce5fb0cd2b7663c Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 17:29:26 +0200 Subject: [PATCH 24/38] test: add tests for the matchers --- .../__tests__/matchArrayValue.test.ts | 34 +++++++++++++++++++ .../matchers/__tests__/matchObject.test.ts | 31 +++++++++++++++++ .../__tests__/matchStringValue.test.ts | 15 ++++++++ 3 files changed, 80 insertions(+) create mode 100644 src/helpers/matchers/__tests__/matchArrayValue.test.ts create mode 100644 src/helpers/matchers/__tests__/matchObject.test.ts create mode 100644 src/helpers/matchers/__tests__/matchStringValue.test.ts diff --git a/src/helpers/matchers/__tests__/matchArrayValue.test.ts b/src/helpers/matchers/__tests__/matchArrayValue.test.ts new file mode 100644 index 000000000..4e7be242c --- /dev/null +++ b/src/helpers/matchers/__tests__/matchArrayValue.test.ts @@ -0,0 +1,34 @@ +import { matchArrayValue } from '../matchArrayValue'; + +test('returns true given 2 identical prop and matcher', () => { + expect(matchArrayValue(['banana'], ['banana'])).toEqual(true); + expect(matchArrayValue(['banana', 'apple'], ['banana', 'apple'])).toEqual( + true + ); +}); + +test('returns true when the prop contains all the values of the matcher', () => { + expect( + matchArrayValue(['banana', 'apple', 'orange'], ['banana', 'orange']) + ).toEqual(true); +}); + +test('returns false when the prop does not contain all the values of the matcher', () => { + expect( + matchArrayValue(['banana', 'apple', 'orange'], ['banana', 'pear']) + ).toEqual(false); +}); + +test('returns false when prop is undefined', () => { + expect(matchArrayValue(undefined, ['banana'])).toEqual(false); +}); + +test('returns false when the matcher is an empty list', () => { + expect(matchArrayValue(['banana'], [])).toEqual(false); +}); + +test('returns false given 2 different prop and matchers', () => { + expect(matchArrayValue(['banana', 'apple'], ['banana', 'orange'])).toEqual( + false + ); +}); diff --git a/src/helpers/matchers/__tests__/matchObject.test.ts b/src/helpers/matchers/__tests__/matchObject.test.ts new file mode 100644 index 000000000..409ed4df1 --- /dev/null +++ b/src/helpers/matchers/__tests__/matchObject.test.ts @@ -0,0 +1,31 @@ +import { matchObject } from '../matchObject'; + +test('returns true given 2 identical objects', () => { + expect(matchObject({ fruit: 'banana' }, { fruit: 'banana' })).toEqual(true); + expect( + matchObject( + { fruit: 'banana', isRipe: true }, + { fruit: 'banana', isRipe: true } + ) + ).toEqual(true); +}); + +test('returns false when one of the param is an empty object', () => { + expect(matchObject({}, { fruit: 'banana' })).toEqual(false); + expect(matchObject({ fruit: 'banana' }, {})).toEqual(false); +}); + +test('returns false given an undefined prop', () => { + expect(matchObject(undefined, { fruit: 'banana' })).toEqual(false); +}); + +test('returns false given 2 different non empty objects', () => { + expect(matchObject({ fruit: 'banana' }, { fruits: 'banana' })).toEqual(false); + expect(matchObject({ fruit: 'banana' }, { fruit: 'orange' })).toEqual(false); + expect( + matchObject( + { fruit: 'banana', isRipe: true }, + { fruit: 'banana', ripe: true } + ) + ).toEqual(false); +}); diff --git a/src/helpers/matchers/__tests__/matchStringValue.test.ts b/src/helpers/matchers/__tests__/matchStringValue.test.ts new file mode 100644 index 000000000..90fb91a97 --- /dev/null +++ b/src/helpers/matchers/__tests__/matchStringValue.test.ts @@ -0,0 +1,15 @@ +import { matchStringValue } from '../matchStringValue'; + +test.each` + prop | matcher | expectedResult + ${'hey'} | ${'hey'} | ${true} + ${'hey'} | ${/hey/} | ${true} + ${'hey'} | ${'heyyyy'} | ${false} + ${'hey'} | ${/heyyy/} | ${false} + ${undefined} | ${'hey'} | ${false} +`( + 'returns $expectedResult given prop $prop and matcher $matcher', + ({ prop, matcher, expectedResult }) => { + expect(matchStringValue(prop, matcher)).toEqual(expectedResult); + } +); From 5c92cb5e9592fb7b2c3ee4e726917011871194c9 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 17:35:58 +0200 Subject: [PATCH 25/38] refactor: simplify matchArrayValue to make it more explicit --- src/helpers/matchers/matchArrayValue.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/matchers/matchArrayValue.ts b/src/helpers/matchers/matchArrayValue.ts index c43193ab2..9782fe4e6 100644 --- a/src/helpers/matchers/matchArrayValue.ts +++ b/src/helpers/matchers/matchArrayValue.ts @@ -10,5 +10,5 @@ export function matchArrayValue( return prop.includes(matcher); } - return !matcher.some((e) => !prop.includes(e)); + return matcher.every((e) => prop.includes(e)); } From d4f523a2b3a40a2bd6400d834fe5ca3ad35863f9 Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sat, 4 Jun 2022 17:41:57 +0200 Subject: [PATCH 26/38] refactor: reorder imports and object keys --- src/within.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/within.ts b/src/within.ts index b8cd2dcb5..f607303e8 100644 --- a/src/within.ts +++ b/src/within.ts @@ -3,14 +3,14 @@ import { bindByTextQueries } from './queries/text'; import { bindByTestIdQueries } from './queries/testId'; import { bindByDisplayValueQueries } from './queries/displayValue'; import { bindByPlaceholderTextQueries } from './queries/placeholderText'; -import { bindUnsafeByTypeQueries } from './queries/unsafeType'; -import { bindUnsafeByPropsQueries } from './queries/unsafeProps'; import { bindByLabelTextQueries } from './queries/labelText'; -import { bindByA11yHintQueries } from './queries/a11yHint'; import { bindByRoleQueries } from './queries/role'; +import { bindByA11yHintQueries } from './queries/a11yHint'; import { bindByA11yStateQueries } from './queries/a11yState'; -import { bindByA11yValueQueries } from './queries/a11yValue'; import { bindByA11yStatesQueries } from './queries/a11yStates'; +import { bindByA11yValueQueries } from './queries/a11yValue'; +import { bindUnsafeByTypeQueries } from './queries/unsafeType'; +import { bindUnsafeByPropsQueries } from './queries/unsafeProps'; export function within(instance: ReactTestInstance) { return { @@ -18,14 +18,14 @@ export function within(instance: ReactTestInstance) { ...bindByTestIdQueries(instance), ...bindByDisplayValueQueries(instance), ...bindByPlaceholderTextQueries(instance), - ...bindUnsafeByTypeQueries(instance), - ...bindUnsafeByPropsQueries(instance), ...bindByLabelTextQueries(instance), ...bindByRoleQueries(instance), ...bindByA11yHintQueries(instance), ...bindByA11yStateQueries(instance), - ...bindByA11yValueQueries(instance), ...bindByA11yStatesQueries(instance), + ...bindByA11yValueQueries(instance), + ...bindUnsafeByTypeQueries(instance), + ...bindUnsafeByPropsQueries(instance), }; } From 6147c655aa79b4f6bf736a0836466d354476c6a4 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 19 Jul 2022 13:46:51 +0200 Subject: [PATCH 27/38] refactor: update types --- src/queries/a11yHint.ts | 54 ----------------------- src/queries/hintText.ts | 95 +++++++++++++++++++++++++++++++++++++++++ src/screen.ts | 18 +++++--- src/within.ts | 4 +- 4 files changed, 109 insertions(+), 62 deletions(-) delete mode 100644 src/queries/a11yHint.ts create mode 100644 src/queries/hintText.ts diff --git a/src/queries/a11yHint.ts b/src/queries/a11yHint.ts deleted file mode 100644 index 6b4d8f0ff..000000000 --- a/src/queries/a11yHint.ts +++ /dev/null @@ -1,54 +0,0 @@ -import type { ReactTestInstance } from 'react-test-renderer'; -import { TextMatch } from '../matches'; -import { matchStringValue } from '../helpers/matchers/matchStringValue'; -import { makeQueries } from './makeQueries'; -import type { - FindAllByQuery, - FindByQuery, - GetAllByQuery, - GetByQuery, - QueryAllByQuery, - QueryByQuery, -} from './makeQueries'; - -const queryAllByA11yHint = ( - instance: ReactTestInstance -): ((hint: TextMatch) => Array) => - function queryAllByA11yHintFn(hint) { - return instance.findAll( - (node) => - typeof node.type === 'string' && - matchStringValue(node.props.accessibilityHint, hint) - ); - }; - -const getMultipleError = (hint: TextMatch) => - `Found multiple elements with accessibilityHint: ${String(hint)} `; -const getMissingError = (hint: TextMatch) => - `Unable to find an element with accessibilityHint: ${String(hint)}`; - -const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( - queryAllByA11yHint, - getMissingError, - getMultipleError -); - -export type ByA11yHintQueries = { - getByA11yHint: GetByQuery; - getAllByA11yHint: GetAllByQuery; - queryByA11yHint: QueryByQuery; - queryAllByA11yHint: QueryAllByQuery; - findByA11yHint: FindByQuery; - findAllByA11yHint: FindAllByQuery; -}; - -export const bindByA11yHintQueries = ( - instance: ReactTestInstance -): ByA11yHintQueries => ({ - getByA11yHint: getBy(instance), - getAllByA11yHint: getAllBy(instance), - queryByA11yHint: queryBy(instance), - queryAllByA11yHint: queryAllBy(instance), - findByA11yHint: findBy(instance), - findAllByA11yHint: findAllBy(instance), -}); diff --git a/src/queries/hintText.ts b/src/queries/hintText.ts new file mode 100644 index 000000000..9610a64c8 --- /dev/null +++ b/src/queries/hintText.ts @@ -0,0 +1,95 @@ +import type { ReactTestInstance } from 'react-test-renderer'; +import { TextMatch } from '../matches'; +import { matchStringValue } from '../helpers/matchers/matchStringValue'; +import { makeQueries } from './makeQueries'; +import type { + FindAllByQuery, + FindByQuery, + GetAllByQuery, + GetByQuery, + QueryAllByQuery, + QueryByQuery, +} from './makeQueries'; + +const queryAllByHintText = ( + instance: ReactTestInstance +): ((hint: TextMatch) => Array) => + function queryAllByA11yHintFn(hint) { + return instance.findAll( + (node) => + typeof node.type === 'string' && + matchStringValue(node.props.accessibilityHint, hint) + ); + }; + +const getMultipleError = (hint: TextMatch) => + `Found multiple elements with accessibilityHint: ${String(hint)} `; +const getMissingError = (hint: TextMatch) => + `Unable to find an element with accessibilityHint: ${String(hint)}`; + +const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( + queryAllByHintText, + getMissingError, + getMultipleError +); + +export type ByHintTextQueries = { + getByHintText: GetByQuery; + getAllByHintText: GetAllByQuery; + queryByHintText: QueryByQuery; + queryAllByHintText: QueryAllByQuery; + findByHintText: FindByQuery; + findAllByHintText: FindAllByQuery; + + // a11yHint aliases + getByA11yHint: GetByQuery; + getAllByA11yHint: GetAllByQuery; + queryByA11yHint: QueryByQuery; + queryAllByA11yHint: QueryAllByQuery; + findByA11yHint: FindByQuery; + findAllByA11yHint: FindAllByQuery; + + // accessibilityHint aliases + getByAccessibilityHint: GetByQuery; + getAllByAccessibilityHint: GetAllByQuery; + queryByAccessibilityHint: QueryByQuery; + queryAllByAccessibilityHint: QueryAllByQuery; + findByAccessibilityHint: FindByQuery; + findAllByAccessibilityHint: FindAllByQuery; +}; + +export const bindByHintTextQueries = ( + instance: ReactTestInstance +): ByHintTextQueries => { + const getByHintText = getBy(instance); + const getAllByHintText = getAllBy(instance); + const queryByHintText = queryBy(instance); + const queryAllByHintText = queryAllBy(instance); + const findByHintText = findBy(instance); + const findAllByHintText = findAllBy(instance); + + return { + getByHintText, + getAllByHintText, + queryByHintText, + queryAllByHintText, + findByHintText, + findAllByHintText, + + // a11yHint aliases + getByA11yHint: getByHintText, + getAllByA11yHint: getAllByHintText, + queryByA11yHint: queryByHintText, + queryAllByA11yHint: queryAllByHintText, + findByA11yHint: findByHintText, + findAllByA11yHint: findAllByHintText, + + // accessibilityHint aliases + getByAccessibilityHint: getByHintText, + getAllByAccessibilityHint: getAllByHintText, + queryByAccessibilityHint: queryByHintText, + queryAllByAccessibilityHint: queryAllByHintText, + findByAccessibilityHint: findByHintText, + findAllByAccessibilityHint: findAllByHintText, + }; +}; diff --git a/src/screen.ts b/src/screen.ts index 6d44957e4..b5a8bcf21 100644 --- a/src/screen.ts +++ b/src/screen.ts @@ -27,18 +27,24 @@ const defaultScreen: RenderResult = { queryAllByLabelText: notImplemented, findByLabelText: notImplemented, findAllByLabelText: notImplemented, - getByA11yHint: notImplemented, getByHintText: notImplemented, - getAllByA11yHint: notImplemented, getAllByHintText: notImplemented, - queryByA11yHint: notImplemented, queryByHintText: notImplemented, - queryAllByA11yHint: notImplemented, queryAllByHintText: notImplemented, - findByA11yHint: notImplemented, findByHintText: notImplemented, - findAllByA11yHint: notImplemented, findAllByHintText: notImplemented, + getByA11yHint: notImplemented, + getAllByA11yHint: notImplemented, + queryByA11yHint: notImplemented, + queryAllByA11yHint: notImplemented, + findByA11yHint: notImplemented, + findAllByA11yHint: notImplemented, + getByAccessibilityHint: notImplemented, + getAllByAccessibilityHint: notImplemented, + queryByAccessibilityHint: notImplemented, + queryAllByAccessibilityHint: notImplemented, + findByAccessibilityHint: notImplemented, + findAllByAccessibilityHint: notImplemented, getByRole: notImplemented, getAllByRole: notImplemented, queryByRole: notImplemented, diff --git a/src/within.ts b/src/within.ts index f607303e8..58d8b8bc3 100644 --- a/src/within.ts +++ b/src/within.ts @@ -5,7 +5,7 @@ import { bindByDisplayValueQueries } from './queries/displayValue'; import { bindByPlaceholderTextQueries } from './queries/placeholderText'; import { bindByLabelTextQueries } from './queries/labelText'; import { bindByRoleQueries } from './queries/role'; -import { bindByA11yHintQueries } from './queries/a11yHint'; +import { bindByHintTextQueries } from './queries/hintText'; import { bindByA11yStateQueries } from './queries/a11yState'; import { bindByA11yStatesQueries } from './queries/a11yStates'; import { bindByA11yValueQueries } from './queries/a11yValue'; @@ -20,7 +20,7 @@ export function within(instance: ReactTestInstance) { ...bindByPlaceholderTextQueries(instance), ...bindByLabelTextQueries(instance), ...bindByRoleQueries(instance), - ...bindByA11yHintQueries(instance), + ...bindByHintTextQueries(instance), ...bindByA11yStateQueries(instance), ...bindByA11yStatesQueries(instance), ...bindByA11yValueQueries(instance), From 313b748b12cb1d281dc95179f42838bac2938698 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 19 Jul 2022 13:53:58 +0200 Subject: [PATCH 28/38] refactor: small tweaks --- src/queries/a11yStates.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/queries/a11yStates.ts b/src/queries/a11yStates.ts index 178a15b62..7e58fb1e9 100644 --- a/src/queries/a11yStates.ts +++ b/src/queries/a11yStates.ts @@ -29,13 +29,11 @@ const queryAllByA11yStates = ( ); }; -const getMultipleError = (a11yStates: AccessibilityStateKeys) => - `Found multiple elements with accessibilityState: ${JSON.stringify( - a11yStates - )}`; -const getMissingError = (a11yStates: AccessibilityStateKeys) => +const getMultipleError = (states: AccessibilityStateKeys) => + `Found multiple elements with accessibilityState: ${JSON.stringify(states)}`; +const getMissingError = (states: AccessibilityStateKeys) => `Unable to find an element with accessibilityState: ${JSON.stringify( - a11yStates + states )}`; const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries( From e96c5756d758d1a4852cbaf82ecbb1ed065c25bd Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 19 Jul 2022 15:06:30 +0200 Subject: [PATCH 29/38] refactor: tweaks --- package.json | 2 +- src/within.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index aff747ce7..37614e0a2 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "timerUtils", "examples/" ], - "testTimeout": 60000, + "testTimeout": 900000, "transformIgnorePatterns": [ "/node_modules/(?!(@react-native|react-native)/).*/" ] diff --git a/src/within.ts b/src/within.ts index 58d8b8bc3..e76122202 100644 --- a/src/within.ts +++ b/src/within.ts @@ -4,8 +4,8 @@ import { bindByTestIdQueries } from './queries/testId'; import { bindByDisplayValueQueries } from './queries/displayValue'; import { bindByPlaceholderTextQueries } from './queries/placeholderText'; import { bindByLabelTextQueries } from './queries/labelText'; -import { bindByRoleQueries } from './queries/role'; import { bindByHintTextQueries } from './queries/hintText'; +import { bindByRoleQueries } from './queries/role'; import { bindByA11yStateQueries } from './queries/a11yState'; import { bindByA11yStatesQueries } from './queries/a11yStates'; import { bindByA11yValueQueries } from './queries/a11yValue'; @@ -19,8 +19,8 @@ export function within(instance: ReactTestInstance) { ...bindByDisplayValueQueries(instance), ...bindByPlaceholderTextQueries(instance), ...bindByLabelTextQueries(instance), - ...bindByRoleQueries(instance), ...bindByHintTextQueries(instance), + ...bindByRoleQueries(instance), ...bindByA11yStateQueries(instance), ...bindByA11yStatesQueries(instance), ...bindByA11yValueQueries(instance), From 6683cfff5a6cf4c5f2052f167d55bbf74c9b2905 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 19 Jul 2022 15:17:34 +0200 Subject: [PATCH 30/38] refactor: clarify matcher naming --- .../__tests__/matchArrayValue.test.ts | 16 ++++++------ .../matchers/__tests__/matchObject.test.ts | 24 +++++++++++------- .../__tests__/matchStringValue.test.ts | 4 +-- src/helpers/matchers/matchArrayProp.ts | 21 ++++++++++++++++ src/helpers/matchers/matchArrayValue.ts | 14 ----------- src/helpers/matchers/matchObject.ts | 15 ----------- src/helpers/matchers/matchObjectProp.ts | 25 +++++++++++++++++++ src/helpers/matchers/matchStringProp.ts | 23 +++++++++++++++++ src/helpers/matchers/matchStringValue.ts | 16 ------------ src/queries/a11yState.ts | 4 +-- src/queries/a11yStates.ts | 4 +-- src/queries/a11yValue.ts | 4 +-- src/queries/hintText.ts | 4 +-- src/queries/labelText.ts | 4 +-- src/queries/role.ts | 4 +-- 15 files changed, 106 insertions(+), 76 deletions(-) create mode 100644 src/helpers/matchers/matchArrayProp.ts delete mode 100644 src/helpers/matchers/matchArrayValue.ts delete mode 100644 src/helpers/matchers/matchObject.ts create mode 100644 src/helpers/matchers/matchObjectProp.ts create mode 100644 src/helpers/matchers/matchStringProp.ts delete mode 100644 src/helpers/matchers/matchStringValue.ts diff --git a/src/helpers/matchers/__tests__/matchArrayValue.test.ts b/src/helpers/matchers/__tests__/matchArrayValue.test.ts index 4e7be242c..c9141916b 100644 --- a/src/helpers/matchers/__tests__/matchArrayValue.test.ts +++ b/src/helpers/matchers/__tests__/matchArrayValue.test.ts @@ -1,34 +1,34 @@ -import { matchArrayValue } from '../matchArrayValue'; +import { matchArrayProp } from '../matchArrayProp'; test('returns true given 2 identical prop and matcher', () => { - expect(matchArrayValue(['banana'], ['banana'])).toEqual(true); - expect(matchArrayValue(['banana', 'apple'], ['banana', 'apple'])).toEqual( + expect(matchArrayProp(['banana'], ['banana'])).toEqual(true); + expect(matchArrayProp(['banana', 'apple'], ['banana', 'apple'])).toEqual( true ); }); test('returns true when the prop contains all the values of the matcher', () => { expect( - matchArrayValue(['banana', 'apple', 'orange'], ['banana', 'orange']) + matchArrayProp(['banana', 'apple', 'orange'], ['banana', 'orange']) ).toEqual(true); }); test('returns false when the prop does not contain all the values of the matcher', () => { expect( - matchArrayValue(['banana', 'apple', 'orange'], ['banana', 'pear']) + matchArrayProp(['banana', 'apple', 'orange'], ['banana', 'pear']) ).toEqual(false); }); test('returns false when prop is undefined', () => { - expect(matchArrayValue(undefined, ['banana'])).toEqual(false); + expect(matchArrayProp(undefined, ['banana'])).toEqual(false); }); test('returns false when the matcher is an empty list', () => { - expect(matchArrayValue(['banana'], [])).toEqual(false); + expect(matchArrayProp(['banana'], [])).toEqual(false); }); test('returns false given 2 different prop and matchers', () => { - expect(matchArrayValue(['banana', 'apple'], ['banana', 'orange'])).toEqual( + expect(matchArrayProp(['banana', 'apple'], ['banana', 'orange'])).toEqual( false ); }); diff --git a/src/helpers/matchers/__tests__/matchObject.test.ts b/src/helpers/matchers/__tests__/matchObject.test.ts index 409ed4df1..a87ed52b0 100644 --- a/src/helpers/matchers/__tests__/matchObject.test.ts +++ b/src/helpers/matchers/__tests__/matchObject.test.ts @@ -1,9 +1,11 @@ -import { matchObject } from '../matchObject'; +import { matchObjectProp } from '../matchObjectProp'; test('returns true given 2 identical objects', () => { - expect(matchObject({ fruit: 'banana' }, { fruit: 'banana' })).toEqual(true); + expect(matchObjectProp({ fruit: 'banana' }, { fruit: 'banana' })).toEqual( + true + ); expect( - matchObject( + matchObjectProp( { fruit: 'banana', isRipe: true }, { fruit: 'banana', isRipe: true } ) @@ -11,19 +13,23 @@ test('returns true given 2 identical objects', () => { }); test('returns false when one of the param is an empty object', () => { - expect(matchObject({}, { fruit: 'banana' })).toEqual(false); - expect(matchObject({ fruit: 'banana' }, {})).toEqual(false); + expect(matchObjectProp({}, { fruit: 'banana' })).toEqual(false); + expect(matchObjectProp({ fruit: 'banana' }, {})).toEqual(false); }); test('returns false given an undefined prop', () => { - expect(matchObject(undefined, { fruit: 'banana' })).toEqual(false); + expect(matchObjectProp(undefined, { fruit: 'banana' })).toEqual(false); }); test('returns false given 2 different non empty objects', () => { - expect(matchObject({ fruit: 'banana' }, { fruits: 'banana' })).toEqual(false); - expect(matchObject({ fruit: 'banana' }, { fruit: 'orange' })).toEqual(false); + expect(matchObjectProp({ fruit: 'banana' }, { fruits: 'banana' })).toEqual( + false + ); + expect(matchObjectProp({ fruit: 'banana' }, { fruit: 'orange' })).toEqual( + false + ); expect( - matchObject( + matchObjectProp( { fruit: 'banana', isRipe: true }, { fruit: 'banana', ripe: true } ) diff --git a/src/helpers/matchers/__tests__/matchStringValue.test.ts b/src/helpers/matchers/__tests__/matchStringValue.test.ts index 90fb91a97..a34b00d00 100644 --- a/src/helpers/matchers/__tests__/matchStringValue.test.ts +++ b/src/helpers/matchers/__tests__/matchStringValue.test.ts @@ -1,4 +1,4 @@ -import { matchStringValue } from '../matchStringValue'; +import { matchStringProp } from '../matchStringProp'; test.each` prop | matcher | expectedResult @@ -10,6 +10,6 @@ test.each` `( 'returns $expectedResult given prop $prop and matcher $matcher', ({ prop, matcher, expectedResult }) => { - expect(matchStringValue(prop, matcher)).toEqual(expectedResult); + expect(matchStringProp(prop, matcher)).toEqual(expectedResult); } ); diff --git a/src/helpers/matchers/matchArrayProp.ts b/src/helpers/matchers/matchArrayProp.ts new file mode 100644 index 000000000..bdd2cbcf8 --- /dev/null +++ b/src/helpers/matchers/matchArrayProp.ts @@ -0,0 +1,21 @@ +/** + * Matches whether given array prop contains the given value, or all given values. + * + * @param prop - The array prop to match. + * @param matcher - The value or values to be included in the array. + * @returns Whether the array prop contains the given value, or all given values. + */ +export function matchArrayProp( + prop: Array | undefined, + matcher: string | Array +): boolean { + if (!prop || matcher.length === 0) { + return false; + } + + if (typeof matcher === 'string') { + return prop.includes(matcher); + } + + return matcher.every((e) => prop.includes(e)); +} diff --git a/src/helpers/matchers/matchArrayValue.ts b/src/helpers/matchers/matchArrayValue.ts deleted file mode 100644 index 9782fe4e6..000000000 --- a/src/helpers/matchers/matchArrayValue.ts +++ /dev/null @@ -1,14 +0,0 @@ -export function matchArrayValue( - prop: Array | undefined, - matcher: string | Array -): boolean { - if (!prop || matcher.length === 0) { - return false; - } - - if (typeof matcher === 'string') { - return prop.includes(matcher); - } - - return matcher.every((e) => prop.includes(e)); -} diff --git a/src/helpers/matchers/matchObject.ts b/src/helpers/matchers/matchObject.ts deleted file mode 100644 index 81f9519c0..000000000 --- a/src/helpers/matchers/matchObject.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * check that each key value pair of the objects match - * BE CAREFUL it works only for 1 level deep key value pairs - * won't work for nested objects - */ -export function matchObject>( - prop: T | undefined, - matcher: T -): boolean { - return prop - ? Object.keys(matcher).length !== 0 && - Object.keys(prop).length !== 0 && - Object.keys(matcher).every((key) => prop[key] === matcher[key]) - : false; -} diff --git a/src/helpers/matchers/matchObjectProp.ts b/src/helpers/matchers/matchObjectProp.ts new file mode 100644 index 000000000..6373c25ed --- /dev/null +++ b/src/helpers/matchers/matchObjectProp.ts @@ -0,0 +1,25 @@ +/** + * check that each key value pair of the objects match + * BE CAREFUL it works only for 1 level deep key value pairs + * won't work for nested objects + */ + +/** + * Matches whether given object prop contains all key/value pairs. + * @param prop - The object prop to match. + * @param matcher - The key/value pairs to be included in the object. + * @returns Whether the object prop contains all key/value pairs. + */ +export function matchObjectProp>( + prop: T | undefined, + matcher: T +): boolean { + if (!prop || Object.keys(matcher).length === 0) { + return false; + } + + return ( + Object.keys(prop).length !== 0 && + Object.keys(matcher).every((key) => prop[key] === matcher[key]) + ); +} diff --git a/src/helpers/matchers/matchStringProp.ts b/src/helpers/matchers/matchStringProp.ts new file mode 100644 index 000000000..4f63de1a6 --- /dev/null +++ b/src/helpers/matchers/matchStringProp.ts @@ -0,0 +1,23 @@ +import { TextMatch } from '../../matches'; + +/** + * Matches the given string property again string or regex matcher. + * + * @param prop - The string prop to match. + * @param matcher - The string or regex to match. + * @returns - Whether the string prop matches the given string or regex. + */ +export function matchStringProp( + prop: string | undefined, + matcher: TextMatch +): boolean { + if (!prop) { + return false; + } + + if (typeof matcher === 'string') { + return prop === matcher; + } + + return prop.match(matcher) != null; +} diff --git a/src/helpers/matchers/matchStringValue.ts b/src/helpers/matchers/matchStringValue.ts deleted file mode 100644 index 309106500..000000000 --- a/src/helpers/matchers/matchStringValue.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TextMatch } from '../../matches'; - -export function matchStringValue( - prop: string | undefined, - matcher: TextMatch -): boolean { - if (!prop) { - return false; - } - - if (typeof matcher === 'string') { - return prop === matcher; - } - - return Boolean(prop.match(matcher)); -} diff --git a/src/queries/a11yState.ts b/src/queries/a11yState.ts index ac89b123e..04da15cb0 100644 --- a/src/queries/a11yState.ts +++ b/src/queries/a11yState.ts @@ -1,6 +1,6 @@ import type { ReactTestInstance } from 'react-test-renderer'; import { AccessibilityState } from 'react-native'; -import { matchObject } from '../helpers/matchers/matchObject'; +import { matchObjectProp } from '../helpers/matchers/matchObjectProp'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -18,7 +18,7 @@ const queryAllByA11yState = ( return instance.findAll( (node) => typeof node.type === 'string' && - matchObject(node.props.accessibilityState, state) + matchObjectProp(node.props.accessibilityState, state) ); }; diff --git a/src/queries/a11yStates.ts b/src/queries/a11yStates.ts index 7e58fb1e9..7c957613c 100644 --- a/src/queries/a11yStates.ts +++ b/src/queries/a11yStates.ts @@ -1,6 +1,6 @@ import type { ReactTestInstance } from 'react-test-renderer'; import { AccessibilityState } from 'react-native'; -import { matchArrayValue } from '../helpers/matchers/matchArrayValue'; +import { matchArrayProp } from '../helpers/matchers/matchArrayProp'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -25,7 +25,7 @@ const queryAllByA11yStates = ( return instance.findAll( (node) => typeof node.type === 'string' && - matchArrayValue(node.props.accessibilityState, accessibilityStates) + matchArrayProp(node.props.accessibilityState, accessibilityStates) ); }; diff --git a/src/queries/a11yValue.ts b/src/queries/a11yValue.ts index 701e06a2e..2b71929e1 100644 --- a/src/queries/a11yValue.ts +++ b/src/queries/a11yValue.ts @@ -1,5 +1,5 @@ import type { ReactTestInstance } from 'react-test-renderer'; -import { matchObject } from '../helpers/matchers/matchObject'; +import { matchObjectProp } from '../helpers/matchers/matchObjectProp'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -24,7 +24,7 @@ const queryAllByA11yValue = ( return instance.findAll( (node) => typeof node.type === 'string' && - matchObject(node.props.accessibilityValue, value) + matchObjectProp(node.props.accessibilityValue, value) ); }; diff --git a/src/queries/hintText.ts b/src/queries/hintText.ts index 9610a64c8..a7a28c1cc 100644 --- a/src/queries/hintText.ts +++ b/src/queries/hintText.ts @@ -1,6 +1,6 @@ import type { ReactTestInstance } from 'react-test-renderer'; import { TextMatch } from '../matches'; -import { matchStringValue } from '../helpers/matchers/matchStringValue'; +import { matchStringProp } from '../helpers/matchers/matchStringProp'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -18,7 +18,7 @@ const queryAllByHintText = ( return instance.findAll( (node) => typeof node.type === 'string' && - matchStringValue(node.props.accessibilityHint, hint) + matchStringProp(node.props.accessibilityHint, hint) ); }; diff --git a/src/queries/labelText.ts b/src/queries/labelText.ts index f508aa537..8142222bb 100644 --- a/src/queries/labelText.ts +++ b/src/queries/labelText.ts @@ -1,6 +1,6 @@ import type { ReactTestInstance } from 'react-test-renderer'; import { TextMatch } from '../matches'; -import { matchStringValue } from '../helpers/matchers/matchStringValue'; +import { matchStringProp } from '../helpers/matchers/matchStringProp'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -18,7 +18,7 @@ const queryAllByLabelText = ( return instance.findAll( (node) => typeof node.type === 'string' && - matchStringValue(node.props.accessibilityLabel, text) + matchStringProp(node.props.accessibilityLabel, text) ); }; diff --git a/src/queries/role.ts b/src/queries/role.ts index ca530fb23..552998b22 100644 --- a/src/queries/role.ts +++ b/src/queries/role.ts @@ -1,6 +1,6 @@ import type { ReactTestInstance } from 'react-test-renderer'; import { TextMatch } from '../matches'; -import { matchStringValue } from '../helpers/matchers/matchStringValue'; +import { matchStringProp } from '../helpers/matchers/matchStringProp'; import { makeQueries } from './makeQueries'; import type { FindAllByQuery, @@ -18,7 +18,7 @@ const queryAllByRole = ( return instance.findAll( (node) => typeof node.type === 'string' && - matchStringValue(node.props.accessibilityRole, role) + matchStringProp(node.props.accessibilityRole, role) ); }; From c2ad8e8b58b6e73c982c7f9e876c816bc1930e68 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 19 Jul 2022 15:45:01 +0200 Subject: [PATCH 31/38] refactor: add missing aliases --- src/queries/a11yState.ts | 39 +++++++++++++++++++++++++++++++-------- src/queries/a11yStates.ts | 39 +++++++++++++++++++++++++++++++-------- src/queries/a11yValue.ts | 39 +++++++++++++++++++++++++++++++-------- src/screen.ts | 18 ++++++++++++++++++ 4 files changed, 111 insertions(+), 24 deletions(-) diff --git a/src/queries/a11yState.ts b/src/queries/a11yState.ts index 04da15cb0..19133fd2c 100644 --- a/src/queries/a11yState.ts +++ b/src/queries/a11yState.ts @@ -40,15 +40,38 @@ export type ByA11yStateQueries = { queryAllByA11yState: QueryAllByQuery; findByA11yState: FindByQuery; findAllByA11yState: FindAllByQuery; + + getByAccessibilityState: GetByQuery; + getAllByAccessibilityState: GetAllByQuery; + queryByAccessibilityState: QueryByQuery; + queryAllByAccessibilityState: QueryAllByQuery; + findByAccessibilityState: FindByQuery; + findAllByAccessibilityState: FindAllByQuery; }; export const bindByA11yStateQueries = ( instance: ReactTestInstance -): ByA11yStateQueries => ({ - getByA11yState: getBy(instance), - getAllByA11yState: getAllBy(instance), - queryByA11yState: queryBy(instance), - queryAllByA11yState: queryAllBy(instance), - findByA11yState: findBy(instance), - findAllByA11yState: findAllBy(instance), -}); +): ByA11yStateQueries => { + const getByA11yState = getBy(instance); + const getAllByA11yState = getAllBy(instance); + const queryByA11yState = queryBy(instance); + const queryAllByA11yState = queryAllBy(instance); + const findByA11yState = findBy(instance); + const findAllByA11yState = findAllBy(instance); + + return { + getByA11yState, + getAllByA11yState, + queryByA11yState, + queryAllByA11yState, + findByA11yState, + findAllByA11yState, + + getByAccessibilityState: getByA11yState, + getAllByAccessibilityState: getAllByA11yState, + queryByAccessibilityState: queryByA11yState, + queryAllByAccessibilityState: queryAllByA11yState, + findByAccessibilityState: findByA11yState, + findAllByAccessibilityState: findAllByA11yState, + }; +}; diff --git a/src/queries/a11yStates.ts b/src/queries/a11yStates.ts index 7c957613c..fbceaa357 100644 --- a/src/queries/a11yStates.ts +++ b/src/queries/a11yStates.ts @@ -49,15 +49,38 @@ export type ByA11yStatesQueries = { queryAllByA11yStates: QueryAllByQuery; findByA11yStates: FindByQuery; findAllByA11yStates: FindAllByQuery; + + getByAccessibilityStates: GetByQuery; + getAllByAccessibilityStates: GetAllByQuery; + queryByAccessibilityStates: QueryByQuery; + queryAllByAccessibilityStates: QueryAllByQuery; + findByAccessibilityStates: FindByQuery; + findAllByAccessibilityStates: FindAllByQuery; }; export const bindByA11yStatesQueries = ( instance: ReactTestInstance -): ByA11yStatesQueries => ({ - getByA11yStates: getBy(instance), - getAllByA11yStates: getAllBy(instance), - queryByA11yStates: queryBy(instance), - queryAllByA11yStates: queryAllBy(instance), - findByA11yStates: findBy(instance), - findAllByA11yStates: findAllBy(instance), -}); +): ByA11yStatesQueries => { + const getByA11yStates = getBy(instance); + const getAllByA11yStates = getAllBy(instance); + const queryByA11yStates = queryBy(instance); + const queryAllByA11yStates = queryAllBy(instance); + const findByA11yStates = findBy(instance); + const findAllByA11yStates = findAllBy(instance); + + return { + getByA11yStates, + getAllByA11yStates, + queryByA11yStates, + queryAllByA11yStates, + findByA11yStates, + findAllByA11yStates, + + getByAccessibilityStates: getByA11yStates, + getAllByAccessibilityStates: getAllByA11yStates, + queryByAccessibilityStates: queryByA11yStates, + queryAllByAccessibilityStates: queryAllByA11yStates, + findByAccessibilityStates: findByA11yStates, + findAllByAccessibilityStates: findAllByA11yStates, + }; +}; diff --git a/src/queries/a11yValue.ts b/src/queries/a11yValue.ts index 2b71929e1..8e68957e3 100644 --- a/src/queries/a11yValue.ts +++ b/src/queries/a11yValue.ts @@ -46,15 +46,38 @@ export type ByA11yValueQueries = { queryAllByA11yValue: QueryAllByQuery; findByA11yValue: FindByQuery; findAllByA11yValue: FindAllByQuery; + + getByAccessibilityValue: GetByQuery; + getAllByAccessibilityValue: GetAllByQuery; + queryByAccessibilityValue: QueryByQuery; + queryAllByAccessibilityValue: QueryAllByQuery; + findByAccessibilityValue: FindByQuery; + findAllByAccessibilityValue: FindAllByQuery; }; export const bindByA11yValueQueries = ( instance: ReactTestInstance -): ByA11yValueQueries => ({ - getByA11yValue: getBy(instance), - getAllByA11yValue: getAllBy(instance), - queryByA11yValue: queryBy(instance), - queryAllByA11yValue: queryAllBy(instance), - findByA11yValue: findBy(instance), - findAllByA11yValue: findAllBy(instance), -}); +): ByA11yValueQueries => { + const getByA11yValue = getBy(instance); + const getAllByA11yValue = getAllBy(instance); + const queryByA11yValue = queryBy(instance); + const queryAllByA11yValue = queryAllBy(instance); + const findByA11yValue = findBy(instance); + const findAllByA11yValue = findAllBy(instance); + + return { + getByA11yValue, + getAllByA11yValue, + queryByA11yValue, + queryAllByA11yValue, + findByA11yValue, + findAllByA11yValue, + + getByAccessibilityValue: getByA11yValue, + getAllByAccessibilityValue: getAllByA11yValue, + queryByAccessibilityValue: queryByA11yValue, + queryAllByAccessibilityValue: queryAllByA11yValue, + findByAccessibilityValue: findByA11yValue, + findAllByAccessibilityValue: findAllByA11yValue, + }; +}; diff --git a/src/screen.ts b/src/screen.ts index b5a8bcf21..5ce85f98d 100644 --- a/src/screen.ts +++ b/src/screen.ts @@ -57,18 +57,36 @@ const defaultScreen: RenderResult = { queryAllByA11yStates: notImplemented, findByA11yStates: notImplemented, findAllByA11yStates: notImplemented, + getByAccessibilityStates: notImplemented, + getAllByAccessibilityStates: notImplemented, + queryByAccessibilityStates: notImplemented, + queryAllByAccessibilityStates: notImplemented, + findByAccessibilityStates: notImplemented, + findAllByAccessibilityStates: notImplemented, getByA11yState: notImplemented, getAllByA11yState: notImplemented, queryByA11yState: notImplemented, queryAllByA11yState: notImplemented, findByA11yState: notImplemented, findAllByA11yState: notImplemented, + getByAccessibilityState: notImplemented, + getAllByAccessibilityState: notImplemented, + queryByAccessibilityState: notImplemented, + queryAllByAccessibilityState: notImplemented, + findByAccessibilityState: notImplemented, + findAllByAccessibilityState: notImplemented, getByA11yValue: notImplemented, getAllByA11yValue: notImplemented, queryByA11yValue: notImplemented, queryAllByA11yValue: notImplemented, findByA11yValue: notImplemented, findAllByA11yValue: notImplemented, + getByAccessibilityValue: notImplemented, + getAllByAccessibilityValue: notImplemented, + queryByAccessibilityValue: notImplemented, + queryAllByAccessibilityValue: notImplemented, + findByAccessibilityValue: notImplemented, + findAllByAccessibilityValue: notImplemented, UNSAFE_getByProps: notImplemented, UNSAFE_getAllByProps: notImplemented, UNSAFE_queryByProps: notImplemented, From a9b1b3ce6df2a57a891fa9b698dce96783f03c6b Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 19 Jul 2022 15:48:00 +0200 Subject: [PATCH 32/38] chore: fix ci timeout --- .circleci/config.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 553eb356a..4a77f3c92 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,7 +54,9 @@ jobs: steps: - attach_workspace: at: ~/react-native-testing-library - - run: yarn test + - run: + command: yarn test + no_output_timeout: 20m - store_artifacts: path: coverage destination: coverage From 6fc907212648e7575e51863ff31f1db0a5ce85ce Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 19 Jul 2022 15:49:57 +0200 Subject: [PATCH 33/38] chore: revert jest timeout increase --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 37614e0a2..3f3ddf7c6 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "timerUtils", "examples/" ], - "testTimeout": 900000, + "testTimeout": 600000, "transformIgnorePatterns": [ "/node_modules/(?!(@react-native|react-native)/).*/" ] From 7466ff9254ee85b31660d65a3eb4992297c9156d Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 20 Jul 2022 09:24:14 +0200 Subject: [PATCH 34/38] chore: revert timeout increase --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3f3ddf7c6..aff747ce7 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "timerUtils", "examples/" ], - "testTimeout": 600000, + "testTimeout": 60000, "transformIgnorePatterns": [ "/node_modules/(?!(@react-native|react-native)/).*/" ] From 1a11103f8ddd6f6487f8c34b760662dd6adf1d88 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 20 Jul 2022 09:40:30 +0200 Subject: [PATCH 35/38] chore: fix ci tests --- examples/reactnavigation/jest-setup.js | 2 +- src/__tests__/within.test.tsx | 4 ++-- .../__tests__/{a11yHint.test.tsx => hintText.test.tsx} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename src/queries/__tests__/{a11yHint.test.tsx => hintText.test.tsx} (100%) diff --git a/examples/reactnavigation/jest-setup.js b/examples/reactnavigation/jest-setup.js index 161b6bc2e..baa4ed853 100644 --- a/examples/reactnavigation/jest-setup.js +++ b/examples/reactnavigation/jest-setup.js @@ -11,4 +11,4 @@ jest.mock('react-native-reanimated', () => { }); // Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing -jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper'); +jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper'); diff --git a/src/__tests__/within.test.tsx b/src/__tests__/within.test.tsx index 4066245e6..144686130 100644 --- a/src/__tests__/within.test.tsx +++ b/src/__tests__/within.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { View, Text, TextInput } from 'react-native'; import { render, within, getQueriesForElement } from '..'; -test('within() exposes basic queries', async () => { +test.skip('within() exposes basic queries', async () => { const rootQueries = render( @@ -91,6 +91,6 @@ test('within() exposes a11y queries', async () => { ).resolves.toHaveLength(1); }); -test('getQueriesForElement is alias to within', () => { +test.skip('getQueriesForElement is alias to within', () => { expect(getQueriesForElement).toBe(within); }); diff --git a/src/queries/__tests__/a11yHint.test.tsx b/src/queries/__tests__/hintText.test.tsx similarity index 100% rename from src/queries/__tests__/a11yHint.test.tsx rename to src/queries/__tests__/hintText.test.tsx From d0c860416834049cc64979464f9fd507806f4c75 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 20 Jul 2022 09:50:38 +0200 Subject: [PATCH 36/38] chore: re-enable disabled tests --- src/__tests__/within.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/__tests__/within.test.tsx b/src/__tests__/within.test.tsx index 144686130..4066245e6 100644 --- a/src/__tests__/within.test.tsx +++ b/src/__tests__/within.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { View, Text, TextInput } from 'react-native'; import { render, within, getQueriesForElement } from '..'; -test.skip('within() exposes basic queries', async () => { +test('within() exposes basic queries', async () => { const rootQueries = render( @@ -91,6 +91,6 @@ test('within() exposes a11y queries', async () => { ).resolves.toHaveLength(1); }); -test.skip('getQueriesForElement is alias to within', () => { +test('getQueriesForElement is alias to within', () => { expect(getQueriesForElement).toBe(within); }); From e0f0795ca986cba28e9da6829aa6649d8be6a8a2 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 20 Jul 2022 10:10:52 +0200 Subject: [PATCH 37/38] chore: reduce jest paralelizaiton --- .circleci/config.yml | 4 +--- package.json | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4a77f3c92..553eb356a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,9 +54,7 @@ jobs: steps: - attach_workspace: at: ~/react-native-testing-library - - run: - command: yarn test - no_output_timeout: 20m + - run: yarn test - store_artifacts: path: coverage destination: coverage diff --git a/package.json b/package.json index aff747ce7..1ef7871e3 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ }, "scripts": { "clean": "del build", - "test": "jest", + "test": "jest --maxWorkers=2", "typecheck": "tsc", "flow": "flow", "copy-flowtypes": "cp typings/index.flow.js build", From 29c9e8856999698c2308ad7ef5ecb5c60bd15683 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 20 Jul 2022 10:20:10 +0200 Subject: [PATCH 38/38] chore: ci tweaks --- .circleci/config.yml | 2 +- jestSetup.js | 1 + package.json | 6 +++++- 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 jestSetup.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 553eb356a..5867dcf81 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,7 +54,7 @@ jobs: steps: - attach_workspace: at: ~/react-native-testing-library - - run: yarn test + - run: yarn test:ci - store_artifacts: path: coverage destination: coverage diff --git a/jestSetup.js b/jestSetup.js new file mode 100644 index 000000000..7060fd312 --- /dev/null +++ b/jestSetup.js @@ -0,0 +1 @@ +jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper'); diff --git a/package.json b/package.json index 1ef7871e3..b7cff3244 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,8 @@ }, "scripts": { "clean": "del build", - "test": "jest --maxWorkers=2", + "test": "jest", + "test:ci": "jest --maxWorkers=2", "typecheck": "tsc", "flow": "flow", "copy-flowtypes": "cp typings/index.flow.js build", @@ -83,6 +84,9 @@ }, "jest": { "preset": "./jest-preset", + "setupFiles": [ + "./jestSetup.js" + ], "testPathIgnorePatterns": [ "timerUtils", "examples/"