From fb9f2e4d238bc3663e2178ac65220fa7c9044502 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 13 May 2020 09:46:17 +0200 Subject: [PATCH 01/15] Basic async findBy queries --- src/__tests__/findByApi.test.js | 54 +++++++++++++++++ src/helpers/findByAPI.js | 103 ++++++++++++++++++++++++++++++++ src/render.js | 6 +- 3 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 src/__tests__/findByApi.test.js create mode 100644 src/helpers/findByAPI.js diff --git a/src/__tests__/findByApi.test.js b/src/__tests__/findByApi.test.js new file mode 100644 index 000000000..e802febdc --- /dev/null +++ b/src/__tests__/findByApi.test.js @@ -0,0 +1,54 @@ +// @flow +import React from 'react'; +import { View, Text, TextInput } from 'react-native'; +import { render } from '..'; + +test('findBy queries work asynchronously', async () => { + const options = { timeout: 10 }; // Short timeout so that this test runs quickly + const { + rerender, + findByTestId, + findAllByTestId, + findByText, + findAllByText, + findByPlaceholder, + findAllByPlaceholder, + findByDisplayValue, + findAllByDisplayValue, + } = render(); + await expect(findByTestId('aTestId', options)).rejects.toBeTruthy(); + await expect(findAllByTestId('aTestId', options)).rejects.toBeTruthy(); + await expect(findByText('Some Text', options)).rejects.toBeTruthy(); + await expect(findAllByText('Some Text', options)).rejects.toBeTruthy(); + await expect( + findByPlaceholder('Placeholder Text', options) + ).rejects.toBeTruthy(); + await expect( + findAllByPlaceholder('Placeholder Text', options) + ).rejects.toBeTruthy(); + await expect(findByDisplayValue('Display Value')).rejects.toBeTruthy(); + await expect(findAllByDisplayValue('Display Value')).rejects.toBeTruthy(); + + setTimeout( + () => + rerender( + + Some Text + + + + ), + 20 + ); + + await expect(findByTestId('aTestId')).resolves.toBeTruthy(); + await expect(findAllByTestId('aTestId')).resolves.toHaveLength(1); + await expect(findByText('Some Text')).resolves.toBeTruthy(); + await expect(findAllByText('Some Text')).resolves.toHaveLength(1); + await expect(findByPlaceholder('Placeholder Text')).resolves.toBeTruthy(); + await expect(findAllByPlaceholder('Placeholder Text')).resolves.toHaveLength( + 1 + ); + await expect(findByDisplayValue('Display Value')).resolves.toBeTruthy(); + await expect(findAllByDisplayValue('Display Value')).resolves.toHaveLength(1); +}); diff --git a/src/helpers/findByAPI.js b/src/helpers/findByAPI.js new file mode 100644 index 000000000..22caf3fd6 --- /dev/null +++ b/src/helpers/findByAPI.js @@ -0,0 +1,103 @@ +// @flow +import { + getByTestId, + getAllByTestId, + getByText, + getAllByText, + getByPlaceholder, + getAllByPlaceholder, + getByDisplayValue, + getAllByDisplayValue, +} from './getByAPI'; +import waitForElement from '../waitForElement'; + +export const findByTestId = (instance: ReactTestInstance) => ( + testID: string, + waitForOptions: any = {} +) => + waitForElement( + () => getByTestId(instance)(testID), + waitForOptions.timeout, + waitForOptions.interval + ); + +export const findAllByTestId = (instance: ReactTestInstance) => ( + testID: string, + waitForOptions: any = {} +) => + waitForElement( + () => getAllByTestId(instance)(testID), + waitForOptions.timeout, + waitForOptions.interval + ); + +export const findByText = (instance: ReactTestInstance) => ( + text: string | RegExp, + waitForOptions: any = {} +) => + waitForElement( + () => getByText(instance)(text), + waitForOptions.timeout, + waitForOptions.interval + ); + +export const findAllByText = (instance: ReactTestInstance) => ( + text: string | RegExp, + waitForOptions: any = {} +) => + waitForElement( + () => getAllByText(instance)(text), + waitForOptions.timeout, + waitForOptions.interval + ); + +export const findByPlaceholder = (instance: ReactTestInstance) => ( + placeholder: string | RegExp, + waitForOptions: any = {} +) => + waitForElement( + () => getByPlaceholder(instance)(placeholder), + waitForOptions.timeout, + waitForOptions.interval + ); + +export const findAllByPlaceholder = (instance: ReactTestInstance) => ( + placeholder: string | RegExp, + waitForOptions: any = {} +) => + waitForElement( + () => getAllByPlaceholder(instance)(placeholder), + waitForOptions.timeout, + waitForOptions.interval + ); + +export const findByDisplayValue = (instance: ReactTestInstance) => ( + value: string | RegExp, + waitForOptions: any = {} +) => + waitForElement( + () => getByDisplayValue(instance)(value), + waitForOptions.timeout, + waitForOptions.interval + ); + +export const findAllByDisplayValue = (instance: ReactTestInstance) => ( + value: string | RegExp, + waitForOptions: any = {} +) => + waitForElement( + () => getAllByDisplayValue(instance)(value), + waitForOptions.timeout, + waitForOptions.interval + ); + +export const findByAPI = (instance: ReactTestInstance) => ({ + findByTestId: findByTestId(instance), + findByText: findByText(instance), + findByPlaceholder: findByPlaceholder(instance), + findByDisplayValue: findByDisplayValue(instance), + findAllByTestId: findAllByTestId(instance), + findAllByText: findAllByText(instance), + findAllByPlaceholder: findAllByPlaceholder(instance), + findAllByDisplayValue: findAllByDisplayValue(instance), +}); diff --git a/src/render.js b/src/render.js index cb46f726e..3adfcc8d7 100644 --- a/src/render.js +++ b/src/render.js @@ -5,6 +5,7 @@ import act from './act'; import { addToCleanupQueue } from './cleanup'; import { getByAPI } from './helpers/getByAPI'; import { queryByAPI } from './helpers/queryByAPI'; +import { findByAPI } from './helpers/findByAPI'; import a11yAPI from './helpers/a11yAPI'; import debugShallow from './helpers/debugShallow'; import debugDeep from './helpers/debugDeep'; @@ -40,6 +41,7 @@ export default function render( return { ...getByAPI(instance), ...queryByAPI(instance), + ...findByAPI(instance), ...a11yAPI(instance), update, rerender: update, // alias for `update` @@ -66,7 +68,7 @@ function updateWithAct( renderer: ReactTestRenderer, wrap: (innerElement: React.Element) => React.Element ) { - return function(component: React.Element) { + return function (component: React.Element) { act(() => { renderer.update(wrap(component)); }); @@ -77,6 +79,6 @@ function debug(instance: ReactTestInstance, renderer) { function debugImpl(message?: string) { return debugDeep(renderer.toJSON(), message); } - debugImpl.shallow = message => debugShallow(instance, message); + debugImpl.shallow = (message) => debugShallow(instance, message); return debugImpl; } From 852335996741afb2418c5f0d0fc9a6b203f4d05d Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 13 May 2020 11:52:45 +0200 Subject: [PATCH 02/15] Refactored findBy queries to be built with makeFindQuery --- src/__tests__/findByApi.test.js | 8 +++- src/helpers/findByAPI.js | 80 +++++++++++++++------------------ 2 files changed, 42 insertions(+), 46 deletions(-) diff --git a/src/__tests__/findByApi.test.js b/src/__tests__/findByApi.test.js index e802febdc..a1bb40697 100644 --- a/src/__tests__/findByApi.test.js +++ b/src/__tests__/findByApi.test.js @@ -26,8 +26,12 @@ test('findBy queries work asynchronously', async () => { await expect( findAllByPlaceholder('Placeholder Text', options) ).rejects.toBeTruthy(); - await expect(findByDisplayValue('Display Value')).rejects.toBeTruthy(); - await expect(findAllByDisplayValue('Display Value')).rejects.toBeTruthy(); + await expect( + findByDisplayValue('Display Value', options) + ).rejects.toBeTruthy(); + await expect( + findAllByDisplayValue('Display Value', options) + ).rejects.toBeTruthy(); setTimeout( () => diff --git a/src/helpers/findByAPI.js b/src/helpers/findByAPI.js index 22caf3fd6..7a7e1e438 100644 --- a/src/helpers/findByAPI.js +++ b/src/helpers/findByAPI.js @@ -11,9 +11,31 @@ import { } from './getByAPI'; import waitForElement from '../waitForElement'; +type WaitForOptions = { + timeout?: number, + interval?: number, +}; + +const makeFindQuery = ( + instance: ReactTestInstance, + getQuery: (instance: ReactTestInstance) => (text: Text) => Result, + text: Text, + waitForOptions: WaitForOptions +): Promise => + waitForElement( + () => getQuery(instance)(text), + waitForOptions.timeout, + waitForOptions.interval + ); + export const findByTestId = (instance: ReactTestInstance) => ( + testId: string, + waitForOptions: WaitForOptions = {} +) => makeFindQuery(instance, getByTestId, testId, waitForOptions); + +export const findByTestId2 = (instance: ReactTestInstance) => ( testID: string, - waitForOptions: any = {} + waitForOptions: WaitForOptions = {} ) => waitForElement( () => getByTestId(instance)(testID), @@ -23,7 +45,7 @@ export const findByTestId = (instance: ReactTestInstance) => ( export const findAllByTestId = (instance: ReactTestInstance) => ( testID: string, - waitForOptions: any = {} + waitForOptions: WaitForOptions = {} ) => waitForElement( () => getAllByTestId(instance)(testID), @@ -33,63 +55,33 @@ export const findAllByTestId = (instance: ReactTestInstance) => ( export const findByText = (instance: ReactTestInstance) => ( text: string | RegExp, - waitForOptions: any = {} -) => - waitForElement( - () => getByText(instance)(text), - waitForOptions.timeout, - waitForOptions.interval - ); + waitForOptions: WaitForOptions = {} +) => makeFindQuery(instance, getByText, text, waitForOptions); export const findAllByText = (instance: ReactTestInstance) => ( text: string | RegExp, - waitForOptions: any = {} -) => - waitForElement( - () => getAllByText(instance)(text), - waitForOptions.timeout, - waitForOptions.interval - ); + waitForOptions: WaitForOptions = {} +) => makeFindQuery(instance, getAllByText, text, waitForOptions); export const findByPlaceholder = (instance: ReactTestInstance) => ( placeholder: string | RegExp, - waitForOptions: any = {} -) => - waitForElement( - () => getByPlaceholder(instance)(placeholder), - waitForOptions.timeout, - waitForOptions.interval - ); + waitForOptions: WaitForOptions = {} +) => makeFindQuery(instance, getByPlaceholder, placeholder, waitForOptions); export const findAllByPlaceholder = (instance: ReactTestInstance) => ( placeholder: string | RegExp, - waitForOptions: any = {} -) => - waitForElement( - () => getAllByPlaceholder(instance)(placeholder), - waitForOptions.timeout, - waitForOptions.interval - ); + waitForOptions: WaitForOptions = {} +) => makeFindQuery(instance, getAllByPlaceholder, placeholder, waitForOptions); export const findByDisplayValue = (instance: ReactTestInstance) => ( value: string | RegExp, - waitForOptions: any = {} -) => - waitForElement( - () => getByDisplayValue(instance)(value), - waitForOptions.timeout, - waitForOptions.interval - ); + waitForOptions: WaitForOptions = {} +) => makeFindQuery(instance, getByDisplayValue, value, waitForOptions); export const findAllByDisplayValue = (instance: ReactTestInstance) => ( value: string | RegExp, - waitForOptions: any = {} -) => - waitForElement( - () => getAllByDisplayValue(instance)(value), - waitForOptions.timeout, - waitForOptions.interval - ); + waitForOptions: WaitForOptions = {} +) => makeFindQuery(instance, getAllByDisplayValue, value, waitForOptions); export const findByAPI = (instance: ReactTestInstance) => ({ findByTestId: findByTestId(instance), From ec9d7d0265e55ef83e9e2e4b0c81b4e5ce616cd8 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 13 May 2020 12:37:43 +0200 Subject: [PATCH 03/15] findBy queries for A11y selectors --- src/__tests__/a11yAPI.test.js | 155 +++++++++++++++++++++++++++------- src/helpers/a11yAPI.js | 27 ++++++ src/helpers/findByAPI.js | 2 +- src/helpers/makeQuery.js | 22 +++++ 4 files changed, 176 insertions(+), 30 deletions(-) diff --git a/src/__tests__/a11yAPI.test.js b/src/__tests__/a11yAPI.test.js index dad5b1b83..83950502a 100644 --- a/src/__tests__/a11yAPI.test.js +++ b/src/__tests__/a11yAPI.test.js @@ -18,6 +18,8 @@ const Typography = ({ children, ...rest }: any) => { return {children}; }; +const waitForOptions = { timeout: 10 }; + class Button extends React.Component { render() { return ( @@ -62,74 +64,127 @@ function Section() { ); } -test('getByA11yLabel, queryByA11yLabel', () => { - const { getByA11yLabel, queryByA11yLabel } = render(
); +test('getByA11yLabel, queryByA11yLabel, findByA11yLabel', async () => { + const { getByA11yLabel, queryByA11yLabel, findByA11yLabel } = render( +
+ ); expect(getByA11yLabel(BUTTON_LABEL).props.accessibilityLabel).toEqual( BUTTON_LABEL ); const button = queryByA11yLabel(/button/g); expect(button && button.props.accessibilityLabel).toEqual(BUTTON_LABEL); + + const asyncButton = await findByA11yLabel(BUTTON_LABEL); + expect(asyncButton.props.accessibilityLabel).toEqual(BUTTON_LABEL); + expect(() => getByA11yLabel(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryByA11yLabel(NO_MATCHES_TEXT)).toBeNull(); + await expect( + findByA11yLabel(NO_MATCHES_TEXT, waitForOptions) + ).rejects.toThrow(NO_INSTANCES_FOUND); expect(() => getByA11yLabel(TEXT_LABEL)).toThrow(FOUND_TWO_INSTANCES); expect(() => queryByA11yLabel(TEXT_LABEL)).toThrow(FOUND_TWO_INSTANCES); + await expect(findByA11yLabel(TEXT_LABEL, waitForOptions)).rejects.toThrow( + FOUND_TWO_INSTANCES + ); }); -test('getAllByA11yLabel, queryAllByA11yLabel', () => { - const { getAllByA11yLabel, queryAllByA11yLabel } = render(
); +test('getAllByA11yLabel, queryAllByA11yLabel', async () => { + const { getAllByA11yLabel, queryAllByA11yLabel, findAllByA11yLabel } = render( +
+ ); expect(getAllByA11yLabel(TEXT_LABEL)).toHaveLength(2); expect(queryAllByA11yLabel(/cool/g)).toHaveLength(3); + await expect(findAllByA11yLabel(TEXT_LABEL)).resolves.toHaveLength(2); + expect(() => getAllByA11yLabel(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryAllByA11yLabel(NO_MATCHES_TEXT)).toEqual([]); + await expect(findAllByA11yLabel(NO_MATCHES_TEXT)).rejects.toThrow( + NO_INSTANCES_FOUND + ); }); -test('getByA11yHint, queryByA11yHint', () => { - const { getByA11yHint, queryByA11yHint } = render(
); +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 && button.props.accessibilityHint).toEqual(BUTTON_HINT); + const asyncButton = await findByA11yHint(BUTTON_HINT); + expect(asyncButton.props.accessibilityHint).toEqual(BUTTON_HINT); + expect(() => getByA11yHint(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryByA11yHint(NO_MATCHES_TEXT)).toBeNull(); + await expect(findByA11yHint(NO_MATCHES_TEXT, waitForOptions)).rejects.toThrow( + NO_INSTANCES_FOUND + ); expect(() => getByA11yHint(TEXT_HINT)).toThrow(FOUND_TWO_INSTANCES); expect(() => queryByA11yHint(TEXT_HINT)).toThrow(FOUND_TWO_INSTANCES); + await expect(findByA11yHint(TEXT_HINT, waitForOptions)).rejects.toThrow( + FOUND_TWO_INSTANCES + ); }); -test('getAllByA11yHint, queryAllByA11yHint', () => { - const { getAllByA11yHint, queryAllByA11yHint } = render(
); +test('getAllByA11yHint, queryAllByA11yHint', async () => { + const { getAllByA11yHint, queryAllByA11yHint, findAllByA11yHint } = render( +
+ ); expect(getAllByA11yHint(TEXT_HINT)).toHaveLength(2); expect(queryAllByA11yHint(/static/g)).toHaveLength(2); + await expect(findAllByA11yHint(TEXT_HINT)).resolves.toHaveLength(2); + expect(() => getAllByA11yHint(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryAllByA11yHint(NO_MATCHES_TEXT)).toEqual([]); + await expect(findAllByA11yHint(NO_MATCHES_TEXT)).rejects.toThrow( + NO_INSTANCES_FOUND + ); }); -test('getByA11yRole, queryByA11yRole', () => { - const { getByA11yRole, queryByA11yRole } = render(
); +test('getByA11yRole, queryByA11yRole, findByA11yRole', async () => { + const { getByA11yRole, queryByA11yRole, findByA11yRole } = render( +
+ ); expect(getByA11yRole('button').props.accessibilityRole).toEqual('button'); const button = queryByA11yRole(/button/g); expect(button && button.props.accessibilityRole).toEqual('button'); + const asyncButton = await findByA11yRole('button'); + expect(asyncButton.props.accessibilityRole).toEqual('button'); + expect(() => getByA11yRole(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryByA11yRole(NO_MATCHES_TEXT)).toBeNull(); + await expect(findByA11yRole(NO_MATCHES_TEXT, waitForOptions)).rejects.toThrow( + NO_INSTANCES_FOUND + ); expect(() => getByA11yRole('link')).toThrow(FOUND_TWO_INSTANCES); expect(() => queryByA11yRole('link')).toThrow(FOUND_TWO_INSTANCES); + await expect(findByA11yRole('link')).rejects.toThrow(FOUND_TWO_INSTANCES); }); -test('getAllByA11yRole, queryAllByA11yRole', () => { - const { getAllByA11yRole, queryAllByA11yRole } = render(
); +test('getAllByA11yRole, queryAllByA11yRole, findAllByA11yRole', async () => { + const { getAllByA11yRole, queryAllByA11yRole, findAllByA11yRole } = render( +
+ ); expect(getAllByA11yRole('link')).toHaveLength(2); expect(queryAllByA11yRole(/ink/g)).toHaveLength(2); + await expect(findAllByA11yRole('link')).resolves.toHaveLength(2); + expect(() => getAllByA11yRole(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryAllByA11yRole(NO_MATCHES_TEXT)).toEqual([]); + await expect( + findAllByA11yRole(NO_MATCHES_TEXT, waitForOptions) + ).rejects.toThrow(NO_INSTANCES_FOUND); }); // TODO: accessibilityStates was removed from RN 0.62 @@ -169,8 +224,10 @@ test.skip('getAllByA11yStates, queryAllByA11yStates', () => { expect(queryAllByA11yStates(NO_MATCHES_TEXT)).toEqual([]); }); -test('getByA11yState, queryByA11yState', () => { - const { getByA11yState, queryByA11yState } = render(
); +test('getByA11yState, queryByA11yState, findByA11yState', async () => { + const { getByA11yState, queryByA11yState, findByA11yState } = render( +
+ ); expect(getByA11yState({ selected: true }).props.accessibilityState).toEqual({ selected: true, @@ -182,9 +239,17 @@ test('getByA11yState, queryByA11yState', () => { selected: true, expanded: false, }); + const asyncButton = await findByA11yState({ selected: true }); + expect(asyncButton.props.accessibilityState).toEqual({ + selected: true, + expanded: false, + }); expect(() => getByA11yState({ disabled: true })).toThrow(NO_INSTANCES_FOUND); expect(queryByA11yState({ disabled: true })).toEqual(null); + await expect( + findByA11yState({ disabled: true }, waitForOptions) + ).rejects.toThrow(NO_INSTANCES_FOUND); expect(() => getByA11yState({ expanded: false })).toThrow( FOUND_TWO_INSTANCES @@ -192,25 +257,39 @@ test('getByA11yState, queryByA11yState', () => { expect(() => queryByA11yState({ expanded: false })).toThrow( FOUND_TWO_INSTANCES ); + await expect( + findByA11yState({ expanded: false }, waitForOptions) + ).rejects.toThrow(FOUND_TWO_INSTANCES); }); -test('getAllByA11yState, queryAllByA11yState', () => { - const { getAllByA11yState, queryAllByA11yState } = render(
); +test('getAllByA11yState, queryAllByA11yState, findAllByA11yState', async () => { + const { getAllByA11yState, queryAllByA11yState, findAllByA11yState } = render( +
+ ); - expect(getAllByA11yState({ selected: true }).length).toEqual(1); - expect(queryAllByA11yState({ selected: true }).length).toEqual(1); + expect(getAllByA11yState({ selected: true })).toHaveLength(1); + expect(queryAllByA11yState({ selected: true })).toHaveLength(1); + await expect(findAllByA11yState({ selected: true })).resolves.toHaveLength(1); expect(() => getAllByA11yState({ disabled: true })).toThrow( NO_INSTANCES_FOUND ); expect(queryAllByA11yState({ disabled: true })).toEqual([]); - - expect(getAllByA11yState({ expanded: false }).length).toEqual(2); - expect(queryAllByA11yState({ expanded: false }).length).toEqual(2); + await expect( + findAllByA11yState({ disabled: true }, waitForOptions) + ).rejects.toThrow(NO_INSTANCES_FOUND); + + expect(getAllByA11yState({ expanded: false })).toHaveLength(2); + expect(queryAllByA11yState({ expanded: false })).toHaveLength(2); + await expect(findAllByA11yState({ expanded: false })).resolves.toHaveLength( + 2 + ); }); -test('getByA11yValue, queryByA11yValue', () => { - const { getByA11yValue, queryByA11yValue } = render(
); +test('getByA11yValue, queryByA11yValue, findByA11yValue', async () => { + const { getByA11yValue, queryByA11yValue, findByA11yValue } = render( +
+ ); expect(getByA11yValue({ min: 40 }).props.accessibilityValue).toEqual({ min: 40, @@ -220,23 +299,41 @@ test('getByA11yValue, queryByA11yValue', () => { min: 40, max: 60, }); + const asyncElement = await findByA11yValue({ min: 40 }); + expect(asyncElement.props.accessibilityValue).toEqual({ + min: 40, + max: 60, + }); expect(() => getByA11yValue({ min: 50 })).toThrow(NO_INSTANCES_FOUND); expect(queryByA11yValue({ min: 50 })).toEqual(null); + await expect(findByA11yValue({ min: 50 }, waitForOptions)).rejects.toThrow( + NO_INSTANCES_FOUND + ); expect(() => getByA11yValue({ max: 60 })).toThrow(FOUND_TWO_INSTANCES); expect(() => queryByA11yValue({ max: 60 })).toThrow(FOUND_TWO_INSTANCES); + await expect(findByA11yValue({ max: 60 }, waitForOptions)).rejects.toThrow( + FOUND_TWO_INSTANCES + ); }); -test('getAllByA11yValue, queryAllByA11yValue', () => { - const { getAllByA11yValue, queryAllByA11yValue } = render(
); +test('getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue', async () => { + const { getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue } = render( +
+ ); - expect(getAllByA11yValue({ min: 40 }).length).toEqual(1); - expect(queryAllByA11yValue({ min: 40 }).length).toEqual(1); + expect(getAllByA11yValue({ min: 40 })).toHaveLength(1); + expect(queryAllByA11yValue({ min: 40 })).toHaveLength(1); + await expect(findAllByA11yValue({ min: 40 })).resolves.toHaveLength(1); expect(() => getAllByA11yValue({ min: 50 })).toThrow(NO_INSTANCES_FOUND); expect(queryAllByA11yValue({ min: 50 })).toEqual([]); + await expect(findAllByA11yValue({ min: 50 }, waitForOptions)).rejects.toThrow( + NO_INSTANCES_FOUND + ); - expect(getAllByA11yValue({ max: 60 }).length).toEqual(2); - expect(queryAllByA11yValue({ max: 60 }).length).toEqual(2); + expect(getAllByA11yValue({ max: 60 })).toHaveLength(2); + expect(queryAllByA11yValue({ max: 60 })).toHaveLength(2); + await expect(findAllByA11yValue({ max: 60 })).resolves.toHaveLength(2); }); diff --git a/src/helpers/a11yAPI.js b/src/helpers/a11yAPI.js index b3629110b..3e6edf79f 100644 --- a/src/helpers/a11yAPI.js +++ b/src/helpers/a11yAPI.js @@ -1,11 +1,14 @@ // @flow import makeQuery from './makeQuery'; import type { A11yRole, A11yStates, A11yState, A11yValue } from '../types.flow'; +import type { WaitForOptions } from './findByAPI'; type GetReturn = ReactTestInstance; type GetAllReturn = Array; type QueryReturn = ReactTestInstance | null; type QueryAllReturn = Array | []; +type FindReturn = Promise; +type FindAllReturn = Promise; type A11yAPI = {| // Label @@ -13,36 +16,48 @@ type A11yAPI = {| getAllByA11yLabel: (string | RegExp) => GetAllReturn, queryByA11yLabel: (string | RegExp) => QueryReturn, queryAllByA11yLabel: (string | RegExp) => QueryAllReturn, + findByA11yLabel: (string | RegExp, ?WaitForOptions) => FindReturn, + findAllByA11yLabel: (string | RegExp, ?WaitForOptions) => FindAllReturn, // Hint getByA11yHint: (string | RegExp) => GetReturn, getAllByA11yHint: (string | RegExp) => GetAllReturn, queryByA11yHint: (string | RegExp) => QueryReturn, queryAllByA11yHint: (string | RegExp) => QueryAllReturn, + findByA11yHint: (string | RegExp, ?WaitForOptions) => FindReturn, + findAllByA11yHint: (string | RegExp, ?WaitForOptions) => FindAllReturn, // Role getByA11yRole: (A11yRole | RegExp) => GetReturn, getAllByA11yRole: (A11yRole | RegExp) => GetAllReturn, queryByA11yRole: (A11yRole | RegExp) => QueryReturn, queryAllByA11yRole: (A11yRole | RegExp) => QueryAllReturn, + findByA11yRole: (A11yRole, ?WaitForOptions) => FindReturn, + findAllByA11yRole: (A11yRole, ?WaitForOptions) => FindAllReturn, // States getByA11yStates: (A11yStates | Array) => GetReturn, getAllByA11yStates: (A11yStates | Array) => GetAllReturn, queryByA11yStates: (A11yStates | Array) => QueryReturn, queryAllByA11yStates: (A11yStates | Array) => QueryAllReturn, + findByA11yStates: (A11yStates, ?WaitForOptions) => FindReturn, + findAllByA11yStates: (A11yStates, ?WaitForOptions) => FindAllReturn, // State getByA11yState: A11yState => GetReturn, getAllByA11yState: A11yState => GetAllReturn, queryByA11yState: A11yState => QueryReturn, queryAllByA11yState: A11yState => QueryAllReturn, + findByA11yState: (A11yState, ?WaitForOptions) => FindReturn, + findAllByA11yState: (A11yState, ?WaitForOptions) => FindAllReturn, // Value getByA11yValue: A11yValue => GetReturn, getAllByA11yValue: A11yValue => GetAllReturn, queryByA11yValue: A11yValue => QueryReturn, queryAllByA11yValue: A11yValue => QueryAllReturn, + findByA11yValue: (A11yValue, ?WaitForOptions) => FindReturn, + findAllByA11yValue: (A11yValue, ?WaitForOptions) => FindAllReturn, |}; export function matchStringValue( @@ -92,6 +107,8 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI => getAllBy: ['getAllByA11yLabel', 'getAllByAccessibilityLabel'], queryBy: ['queryByA11yLabel', 'queryByAccessibilityLabel'], queryAllBy: ['queryAllByA11yLabel', 'queryAllByAccessibilityLabel'], + findBy: ['findByA11yLabel', 'findByAccessibilityLabel'], + findAllBy: ['findAllByA11yLabel', 'findAllByAccessibilityLabel'], }, matchStringValue )(instance), @@ -102,6 +119,8 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI => getAllBy: ['getAllByA11yHint', 'getAllByAccessibilityHint'], queryBy: ['queryByA11yHint', 'queryByAccessibilityHint'], queryAllBy: ['queryAllByA11yHint', 'queryAllByAccessibilityHint'], + findBy: ['findByA11yHint', 'findByAccessibilityHint'], + findAllBy: ['findAllByA11yHint', 'findAllByAccessibilityHint'], }, matchStringValue )(instance), @@ -112,6 +131,8 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI => getAllBy: ['getAllByA11yRole', 'getAllByAccessibilityRole'], queryBy: ['queryByA11yRole', 'queryByAccessibilityRole'], queryAllBy: ['queryAllByA11yRole', 'queryAllByAccessibilityRole'], + findBy: ['findByA11yRole', 'findByAccessibilityRole'], + findAllBy: ['findAllByA11yRole', 'findAllByAccessibilityRole'], }, matchStringValue )(instance), @@ -122,6 +143,8 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI => getAllBy: ['getAllByA11yStates', 'getAllByAccessibilityStates'], queryBy: ['queryByA11yStates', 'queryByAccessibilityStates'], queryAllBy: ['queryAllByA11yStates', 'queryAllByAccessibilityStates'], + findBy: ['findByA11yStates', 'findByAccessibilityStates'], + findAllBy: ['findAllByA11yStates', 'findAllByAccessibilityStates'], }, matchArrayValue )(instance), @@ -132,6 +155,8 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI => getAllBy: ['getAllByA11yState', 'getAllByAccessibilityState'], queryBy: ['queryByA11yState', 'queryByAccessibilityState'], queryAllBy: ['queryAllByA11yState', 'queryAllByAccessibilityState'], + findBy: ['findByA11yState', 'findByAccessibilityState'], + findAllBy: ['findAllByA11yState', 'findAllByAccessibilityState'], }, matchObject )(instance), @@ -142,6 +167,8 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI => getAllBy: ['getAllByA11yValue', 'getAllByAccessibilityValue'], queryBy: ['queryByA11yValue', 'queryByAccessibilityValue'], queryAllBy: ['queryAllByA11yValue', 'queryAllByAccessibilityValue'], + findBy: ['findByA11yValue', 'findByAccessibilityValue'], + findAllBy: ['findAllByA11yValue', 'findAllByAccessibilityValue'], }, matchObject )(instance), diff --git a/src/helpers/findByAPI.js b/src/helpers/findByAPI.js index 7a7e1e438..97272fa01 100644 --- a/src/helpers/findByAPI.js +++ b/src/helpers/findByAPI.js @@ -11,7 +11,7 @@ import { } from './getByAPI'; import waitForElement from '../waitForElement'; -type WaitForOptions = { +export type WaitForOptions = { timeout?: number, interval?: number, }; diff --git a/src/helpers/makeQuery.js b/src/helpers/makeQuery.js index 059a853b2..fe257708f 100644 --- a/src/helpers/makeQuery.js +++ b/src/helpers/makeQuery.js @@ -4,6 +4,8 @@ import { prepareErrorMessage, createQueryByError, } from './errors'; +import waitForElement from '../waitForElement'; +import type { WaitForOptions } from './findByAPI'; function isNodeValid(node: ReactTestInstance) { return typeof node.type === 'string'; @@ -20,6 +22,8 @@ type QueryNames = { getAllBy: Array, queryBy: Array, queryAllBy: Array, + findBy: Array, + findAllBy: Array, }; const makeQuery = ( @@ -65,11 +69,29 @@ const makeQuery = ( } }; + const findBy = (matcher: M, waitForOptions?: WaitForOptions) => { + return waitForElement( + () => getBy(matcher), + waitForOptions?.timeout, + waitForOptions?.interval + ); + }; + + const findAllBy = (matcher: M, waitForOptions?: WaitForOptions) => { + return waitForElement( + () => getAllBy(matcher), + waitForOptions?.timeout, + waitForOptions?.interval + ); + }; + 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), }; }; From 69ee9e5ca2f0936a742ed47ab0fb5aa9744dd03d Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 13 May 2020 14:33:43 +0200 Subject: [PATCH 04/15] Custom findByTestId implementation that avoids current getByTestId issues --- src/helpers/findByAPI.js | 23 ++++------------------- src/helpers/getByAPI.js | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/helpers/findByAPI.js b/src/helpers/findByAPI.js index 97272fa01..f7878ad51 100644 --- a/src/helpers/findByAPI.js +++ b/src/helpers/findByAPI.js @@ -1,6 +1,6 @@ // @flow import { - getByTestId, + fixedGetByTestId, getAllByTestId, getByText, getAllByText, @@ -31,27 +31,12 @@ const makeFindQuery = ( export const findByTestId = (instance: ReactTestInstance) => ( testId: string, waitForOptions: WaitForOptions = {} -) => makeFindQuery(instance, getByTestId, testId, waitForOptions); - -export const findByTestId2 = (instance: ReactTestInstance) => ( - testID: string, - waitForOptions: WaitForOptions = {} -) => - waitForElement( - () => getByTestId(instance)(testID), - waitForOptions.timeout, - waitForOptions.interval - ); +) => makeFindQuery(instance, fixedGetByTestId, testId, waitForOptions); export const findAllByTestId = (instance: ReactTestInstance) => ( - testID: string, + testId: string, waitForOptions: WaitForOptions = {} -) => - waitForElement( - () => getAllByTestId(instance)(testID), - waitForOptions.timeout, - waitForOptions.interval - ); +) => makeFindQuery(instance, getAllByTestId, testId, waitForOptions); export const findByText = (instance: ReactTestInstance) => ( text: string | RegExp, diff --git a/src/helpers/getByAPI.js b/src/helpers/getByAPI.js index ecc0e31d9..a645b73db 100644 --- a/src/helpers/getByAPI.js +++ b/src/helpers/getByAPI.js @@ -151,6 +151,23 @@ export const getByTestId = (instance: ReactTestInstance) => } }; +export const fixedGetByTestId = (instance: ReactTestInstance) => + function getByTestIdFn(testID: string) { + try { + const results = getAllByTestId(instance)(testID); + if (results.length === 1) return results[0]; + else + throw new ErrorWithStack( + ` Expected 1 but found ${ + results.length + } instances with testID: ${String(testID)}`, + getByTestIdFn + ); + } catch (error) { + throw new ErrorWithStack(prepareErrorMessage(error), getByTestIdFn); + } + }; + export const getAllByName = (instance: ReactTestInstance, warnFn?: Function) => function getAllByNameFn(name: string | React.ComponentType) { warnFn && warnFn('getAllByName'); From 8ac5fc3b7492bf8f804f6bd8cae0501e1c928128 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 13 May 2020 14:35:15 +0200 Subject: [PATCH 05/15] Fixed prettier issue --- src/render.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render.js b/src/render.js index 3adfcc8d7..658aba1c1 100644 --- a/src/render.js +++ b/src/render.js @@ -68,7 +68,7 @@ function updateWithAct( renderer: ReactTestRenderer, wrap: (innerElement: React.Element) => React.Element ) { - return function (component: React.Element) { + return function(component: React.Element) { act(() => { renderer.update(wrap(component)); }); @@ -79,6 +79,6 @@ function debug(instance: ReactTestInstance, renderer) { function debugImpl(message?: string) { return debugDeep(renderer.toJSON(), message); } - debugImpl.shallow = (message) => debugShallow(instance, message); + debugImpl.shallow = message => debugShallow(instance, message); return debugImpl; } From 51b911147d12e2539996df7a119fc8275ae215a0 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 13 May 2020 15:12:29 +0200 Subject: [PATCH 06/15] Updates Queries.md with findBy queries --- docs/Queries.md | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/docs/Queries.md b/docs/Queries.md index e4330e4ae..43b903199 100644 --- a/docs/Queries.md +++ b/docs/Queries.md @@ -24,6 +24,17 @@ title: Queries `queryAllBy*` queries return an array of all matching nodes for a query, and return an empty array (`[]`) if no elements match. +### findBy + +`findBy` queries return a promise which resolves when a matching element is found. The promise is rejected if no elements match or if more than one match is found after a default timeout of 4500ms. If you need to find more than one element, then use `findAllBy`. + +### findAllBy + +`findAllBy` queries return a promise which resolves to an array when any matching elements are found. The promise is rejected if no elements match after a default timeout of 4500ms. + + +*Note:* `findBy` and `findAllBy` queries accept optional `waitForOptions` object argument which can contain `timeout` and `interval` properies which have the same meaning as respective arguments to [`waitForElement`](https://callstack.github.io/react-native-testing-library/docs/api#waitforelement) function. + ## Queries _Note: most methods like this one return a [`ReactTestInstance`](https://reactjs.org/docs/test-renderer.html#testinstance) with following properties that you may be interested in:_ @@ -39,7 +50,7 @@ type ReactTestInstance = { ### `ByText` -> getByText, getAllByText, queryByText, queryAllByText +> getByText, getAllByText, queryByText, queryAllByText, findByText, findAllByText Returns a `ReactTestInstance` with matching text – may be a string or regular expression. @@ -54,7 +65,7 @@ const element = getByText('banana'); ### `ByPlaceholder` -> getByPlaceholder, getAllByPlaceholder, queryByPlaceholder, queryAllByPlaceholder +> getByPlaceholder, getAllByPlaceholder, queryByPlaceholder, queryAllByPlaceholder, findByPlaceholder, findAllByPlaceholder Returns a `ReactTestInstance` for a `TextInput` with a matching placeholder – may be a string or regular expression. @@ -67,7 +78,7 @@ const element = getByPlaceholder('username'); ### `ByDisplayValue` -> getByDisplayValue, getAllByDisplayValue, queryByDisplayValue, queryAllByDisplayValue +> getByDisplayValue, getAllByDisplayValue, queryByDisplayValue, queryAllByDisplayValue, findByDisplayValue, findAllByDisplayValue Returns a `ReactTestInstance` for a `TextInput` with a matching display value – may be a string or regular expression. @@ -80,7 +91,7 @@ const element = getByDisplayValue('username'); ### `ByTestId` -> getByTestId, getAllByTestId, queryByTestId, queryAllByTestId +> getByTestId, getAllByTestId, queryByTestId, queryAllByTestId, findByTestId, findAllByTestId Returns a `ReactTestInstance` with matching `testID` prop. @@ -93,8 +104,8 @@ const element = getByTestId('unique-id'); ### `ByA11yLabel`, `ByAccessibilityLabel` -> getByA11yLabel, getAllByA11yLabel, queryByA11yLabel, queryAllByA11yLabel -> getByAccessibilityLabel, getAllByAccessibilityLabel, queryByAccessibilityLabel, queryAllByAccessibilityLabel +> getByA11yLabel, getAllByA11yLabel, queryByA11yLabel, queryAllByA11yLabel, findByA11yLabel, findAllByA11yLabel +> getByAccessibilityLabel, getAllByAccessibilityLabel, queryByAccessibilityLabel, queryAllByAccessibilityLabel, findByAccessibilityLabel, findAllByAccessibilityLabel Returns a `ReactTestInstance` with matching `accessibilityLabel` prop. @@ -107,8 +118,8 @@ const element = getByA11yLabel('my-label'); ### `ByA11yHint`, `ByAccessibilityHint` -> getByA11yHint, getAllByA11yHint, queryByA11yHint, queryAllByA11yHint -> getByAccessibilityHint, getAllByAccessibilityHint, queryByAccessibilityHint, queryAllByAccessibilityHint +> getByA11yHint, getAllByA11yHint, queryByA11yHint, queryAllByA11yHint, findByA11yHint, findAllByA11yHint +> getByAccessibilityHint, getAllByAccessibilityHint, queryByAccessibilityHint, queryAllByAccessibilityHint, findByAccessibilityHint, findAllByAccessibilityHint Returns a `ReactTestInstance` with matching `accessibilityHint` prop. @@ -136,8 +147,8 @@ const element2 = getByA11yStates('checked'); ### `ByA11yRole`, `ByAccessibilityRole` -> getByA11yRole, getAllByA11yRole, queryByA11yRole, queryAllByA11yRole -> getByAccessibilityRole, getAllByAccessibilityRole, queryByAccessibilityRole, queryAllByAccessibilityRole +> getByA11yRole, getAllByA11yRole, queryByA11yRole, queryAllByA11yRole, findByA11yRole, findAllByA11yRole +> getByAccessibilityRole, getAllByAccessibilityRole, queryByAccessibilityRole, queryAllByAccessibilityRole, findByAccessibilityRole, findAllByAccessibilityRole Returns a `ReactTestInstance` with matching `accessibilityRole` prop. @@ -150,8 +161,8 @@ const element = getByA11yRole('button'); ### `ByA11yState`, `ByAccessibilityState` -> getByA11yState, getAllByA11yState, queryByA11yState, queryAllByA11yState -> getByAccessibilityState, getAllByAccessibilityState, queryByAccessibilityState, queryAllByAccessibilityState +> getByA11yState, getAllByA11yState, queryByA11yState, queryAllByA11yState, findByA11yState, findAllByA11yState +> getByAccessibilityState, getAllByAccessibilityState, queryByAccessibilityState, queryAllByAccessibilityState, findByAccessibilityState, findAllByAccessibilityState Returns a `ReactTestInstance` with matching `accessibilityState` prop. @@ -164,8 +175,8 @@ const element = getByA11yState({ disabled: true }); ### `ByA11Value`, `ByAccessibilityValue` -> getByA11yValue, getAllByA11yValue, queryByA11yValue, queryAllByA11yValue -> getByAccessibilityValue, getAllByAccessibilityValue, queryByAccessibilityValue, queryAllByAccessibilityValue +> getByA11yValue, getAllByA11yValue, queryByA11yValue, queryAllByA11yValue, findByA11yValue, findAllByA11yValue +> getByAccessibilityValue, getAllByAccessibilityValue, queryByAccessibilityValue, queryAllByAccessibilityValue, findByAccessibilityValue, findAllByAccessibilityValue Returns a `ReactTestInstance` with matching `accessibilityValue` prop. From 52c3e08e6280704080c93e3e59c2e710e0820cbd Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 13 May 2020 15:29:15 +0200 Subject: [PATCH 07/15] Trying to fix test timeout error appearing only on CI --- src/__tests__/findByApi.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/__tests__/findByApi.test.js b/src/__tests__/findByApi.test.js index a1bb40697..3f15c7840 100644 --- a/src/__tests__/findByApi.test.js +++ b/src/__tests__/findByApi.test.js @@ -55,4 +55,4 @@ test('findBy queries work asynchronously', async () => { ); await expect(findByDisplayValue('Display Value')).resolves.toBeTruthy(); await expect(findAllByDisplayValue('Display Value')).resolves.toHaveLength(1); -}); +}, 10000); From 97b4aa967f431b3e46f18c3d342fd7aec58add59 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 13 May 2020 15:55:25 +0200 Subject: [PATCH 08/15] Code review changes --- src/helpers/getByAPI.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/helpers/getByAPI.js b/src/helpers/getByAPI.js index 306f7b247..6ed49f47f 100644 --- a/src/helpers/getByAPI.js +++ b/src/helpers/getByAPI.js @@ -161,14 +161,16 @@ export const fixedGetByTestId = (instance: ReactTestInstance) => function getByTestIdFn(testID: string) { try { const results = getAllByTestId(instance)(testID); - if (results.length === 1) return results[0]; - else + if (results.length === 1) { + return results[0]; + } else { throw new ErrorWithStack( ` Expected 1 but found ${ results.length } instances with testID: ${String(testID)}`, getByTestIdFn ); + } } catch (error) { throw new ErrorWithStack(prepareErrorMessage(error), getByTestIdFn); } From d4afa24ec2756342dd01e5268fe08fded7860559 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Wed, 13 May 2020 16:25:49 +0200 Subject: [PATCH 09/15] Added typescript types & tests * prettier did reformat some code arround --- typings/__tests__/index.test.tsx | 227 +++++++++++++++++++++++++++---- typings/index.d.ts | 186 +++++++++++++++++++------ 2 files changed, 342 insertions(+), 71 deletions(-) diff --git a/typings/__tests__/index.test.tsx b/typings/__tests__/index.test.tsx index c4a5ad020..e3c3b47f0 100644 --- a/typings/__tests__/index.test.tsx +++ b/typings/__tests__/index.test.tsx @@ -60,9 +60,9 @@ const getAllByNameConstructor: Array = tree.getAllByName( View ); const getAllByType: Array = tree.getAllByType(View); -const getAllByTypeWithRequiredProps: Array< - ReactTestInstance -> = tree.getAllByType(ElementWithRequiredProps); +const getAllByTypeWithRequiredProps: Array = tree.getAllByType( + ElementWithRequiredProps +); const getAllByTextString: Array = tree.getAllByText( '' ); @@ -71,7 +71,7 @@ const getAllByProps: Array = tree.getAllByProps({ value: 2, }); -// queuryByAPI tests +// queryByAPI tests const queryByNameString: ReactTestInstance | null = tree.queryByName('View'); const queryByNameConstructor: ReactTestInstance | null = tree.queryByName(View); const queryByType: ReactTestInstance | null = tree.queryByType(View); @@ -104,21 +104,101 @@ const queryAllByNameConstructor: Array = tree.queryAllByName( View ); const queryAllByType: Array = tree.queryAllByType(View); -const queryAllByTypeWithRequiredProps: Array< - ReactTestInstance -> = tree.queryAllByType(ElementWithRequiredProps); +const queryAllByTypeWithRequiredProps: Array = tree.queryAllByType( + ElementWithRequiredProps +); const queryAllByTextString: Array = tree.queryAllByText( 'View' ); const queryAllByTextRegExp: Array = tree.queryAllByText( /View/g ); -const queryAllByDisplayValueString: Array< - ReactTestInstance -> = tree.queryAllByDisplayValue('View'); -const queryAllByDisplayValueRegExp: Array< - ReactTestInstance -> = tree.queryAllByDisplayValue(/View/g); +const queryAllByDisplayValueString: Array = tree.queryAllByDisplayValue( + 'View' +); +const queryAllByDisplayValueRegExp: Array = tree.queryAllByDisplayValue( + /View/g +); + +// findByAPI tests +const findByTextString: Promise = tree.findByText('View'); +const findByTextRegExp: Promise = tree.findByText(/View/g); +const findByTextStringWithTimeout: Promise = tree.findByText( + 'View', + { timeout: 10, interval: 10 } +); +const findByTextRegExpWithTimeout: Promise = tree.findByText( + /View/g, + { + timeout: 10, + interval: 5, + } +); +const findAllByTextRegExp: Promise = tree.findAllByText( + /View/g +); +const findAllByTextRegExpWithTimeout: Promise = tree.findAllByText( + /View/g, + { + timeout: 10, + interval: 5, + } +); + +const findByPlaceholderString: Promise = tree.findByPlaceholder( + 'my placeholder' +); +const findByPlaceholderRegExp: Promise = tree.findByPlaceholder( + /placeholder/g +); +const findByPlaceholderStringWithTimeout: Promise = tree.findByPlaceholder( + 'my placeholder', + { timeout: 10, interval: 10 } +); +const findByPlaceholderRegExpWithTimeout: Promise = tree.findByPlaceholder( + /placeholder/g, + { timeout: 10, interval: 10 } +); +const findByDisplayValueString: Promise = tree.findByDisplayValue( + 'my value' +); +const findByDisplayValueRegExp: Promise = tree.findByDisplayValue( + /value/g +); +const findByDisplayValueStringWithTimeout: Promise = tree.findByDisplayValue( + 'my value', + { timeout: 10, interval: 10 } +); +const findByDisplayValueRegExpWithTimeout: Promise = tree.findByDisplayValue( + /value/g, + { timeout: 10, interval: 10 } +); +const findAllByDisplayValueString: Promise = tree.findAllByDisplayValue( + 'View' +); +const findAllByDisplayValueStringWithTimeout: Promise = tree.findAllByDisplayValue( + 'View', + { timeout: 10, interval: 10 } +); +const findAllByDisplayValueRegExp: Promise = tree.findAllByDisplayValue( + /View/g +); +const findAllByDisplayValueRegExpWithTimeout: Promise = tree.findAllByDisplayValue( + /View/g, + { timeout: 10, interval: 10 } +); +const findByTestId: Promise = tree.findByTestId('test-id'); +const findByTestIdWithTimeout: Promise = tree.findByTestId( + 'test-id', + { timeout: 10, interval: 10 } +); +const findAllByTestId: Promise = tree.findAllByTestId( + 'test-id' +); +const findAllByTestIdWithTimeout: Promise = tree.findAllByTestId( + 'test-id', + { timeout: 10, interval: 10 } +); // Accessibility queries const getByA11yLabel: ReactTestInstance = tree.getByA11yLabel('label'); @@ -129,6 +209,21 @@ const queryByA11yLabel: ReactTestInstance = tree.queryByA11yLabel('label'); const queryAllByA11yLabel: Array = tree.queryAllByA11yLabel( 'label' ); +const findByA11yLabel: Promise = tree.findByA11yLabel( + 'label' +); +const findAllByA11yLabel: Promise = tree.findAllByA11yLabel( + 'label' +); +const findByA11yLabelWithTimeout: Promise = tree.findByA11yLabel( + 'label', + { timeout: 10, interval: 10 } +); +const findAllByA11yLabelWithTimeout: Promise = tree.findAllByA11yLabel( + 'label', + { timeout: 10, interval: 10 } +); + const getByA11yHint: ReactTestInstance = tree.getByA11yHint('label'); const getAllByA11yHint: Array = tree.getAllByA11yHint( 'label' @@ -137,6 +232,19 @@ const queryByA11yHint: ReactTestInstance = tree.queryByA11yHint('label'); const queryAllByA11yHint: Array = tree.queryAllByA11yHint( 'label' ); +const findByA11yHint: Promise = tree.findByA11yHint('label'); +const findAllByA11yHint: Promise = tree.findAllByA11yHint( + 'label', + { timeout: 10, interval: 10 } +); +const findByA11yHintWithTimeout: Promise = tree.findByA11yHint( + 'label' +); +const findAllByA11yHintWithTimeout: Promise = tree.findAllByA11yHint( + 'label', + { timeout: 10, interval: 10 } +); + const getByA11yRole: ReactTestInstance = tree.getByA11yRole('button'); const getAllByA11yRole: Array = tree.getAllByA11yRole( 'button' @@ -145,34 +253,97 @@ const queryByA11yRole: ReactTestInstance = tree.queryByA11yRole('button'); const queryAllByA11yRole: Array = tree.queryAllByA11yRole( 'button' ); +const findByA11yRole: Promise = tree.findByA11yRole( + 'button' +); +const findAllByA11yRole: Promise = tree.findAllByA11yRole( + 'button', + { timeout: 10, interval: 10 } +); +const findByA11yRoleWithTimeout: Promise = tree.findByA11yRole( + 'button' +); +const findAllByA11yRoleWithTimeout: Promise = tree.findAllByA11yRole( + 'button', + { timeout: 10, interval: 10 } +); + const getByA11yStates: ReactTestInstance = tree.getByA11yStates('selected'); -const getByA11yStatesArray: ReactTestInstance = tree.getByA11yStates(['selected']); +const getByA11yStatesArray: ReactTestInstance = tree.getByA11yStates([ + 'selected', +]); const getAllByA11yStates: Array = tree.getAllByA11yStates( 'selected' ); -const getAllByA11yStatesArray: Array< - ReactTestInstance -> = tree.getAllByA11yStates(['selected']); +const getAllByA11yStatesArray: Array = tree.getAllByA11yStates( + ['selected'] +); const queryByA11yStates: ReactTestInstance = tree.queryByA11yStates('selected'); const queryByA11yStatesArray: ReactTestInstance = tree.queryByA11yStates([ 'selected', ]); -const queryAllByA11yStates: Array< - ReactTestInstance -> = tree.queryAllByA11yStates('selected'); -const queryAllByA11yStatesArray: Array< - ReactTestInstance -> = tree.queryAllByA11yStates(['selected']); +const queryAllByA11yStates: Array = tree.queryAllByA11yStates( + 'selected' +); +const queryAllByA11yStatesArray: Array = tree.queryAllByA11yStates( + ['selected'] +); const getByA11yState: ReactTestInstance = tree.getByA11yState({ busy: true }); -const getAllByA11yState: Array = tree.getAllByA11yState({ busy: true }); -const queryByA11yState: ReactTestInstance = tree.queryByA11yState({ busy: true }); -const queryAllByA11yState: Array = tree.queryAllByA11yState({ busy: true }); +const getAllByA11yState: Array = tree.getAllByA11yState({ + busy: true, +}); +const queryByA11yState: ReactTestInstance = tree.queryByA11yState({ + busy: true, +}); +const queryAllByA11yState: Array = tree.queryAllByA11yState({ + busy: true, +}); +const findByA11yState: Promise = tree.findByA11yState({ + busy: true, +}); +const findAllByA11yState: Promise = tree.findAllByA11yState( + { + busy: true, + } +); +const findByA11yStateWithTimeout: Promise = tree.findByA11yState( + { busy: true }, + { timeout: 10, interval: 10 } +); +const findAllByA11yStateWithTimeout: Promise = tree.findAllByA11yState( + { + busy: true, + }, + { timeout: 10, interval: 10 } +); const getByA11yValue: ReactTestInstance = tree.getByA11yValue({ min: 10 }); -const getAllByA11yValue: Array = tree.getAllByA11yValue({ min: 10 }); +const getAllByA11yValue: Array = tree.getAllByA11yValue({ + min: 10, +}); const queryByA11yValue: ReactTestInstance = tree.queryByA11yValue({ min: 10 }); -const queryAllByA11yValue: Array = tree.queryAllByA11yValue({ min: 10 }); +const queryAllByA11yValue: Array = tree.queryAllByA11yValue({ + min: 10, +}); +const findByA11yValue: Promise = tree.findByA11yValue({ + min: 10, +}); +const findAllByA11yValue: Promise = tree.findAllByA11yValue( + { + min: 10, + }, + { timeout: 10, interval: 10 } +); +const findByA11yValueWithTimeout: Promise = tree.findByA11yValue( + { min: 10 } +); +const findAllByA11yValueWithTimeout: Promise = tree.findAllByA11yValue( + { + min: 10, + }, + { timeout: 10, interval: 10 } +); const debugFn = tree.debug(); const debugFnWithMessage = tree.debug('my message'); diff --git a/typings/index.d.ts b/typings/index.d.ts index 1c03ed410..e04b906e8 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1,7 +1,18 @@ import * as React from 'react'; -import { AccessibilityState, AccessibilityStates, AccessibilityRole } from 'react-native'; +import { + AccessibilityState, + AccessibilityStates, + AccessibilityRole, +} from 'react-native'; import { ReactTestInstance, ReactTestRendererJSON } from 'react-test-renderer'; +type GetReturn = ReactTestInstance; +type GetAllReturn = Array; +type QueryReturn = ReactTestInstance | null; +type QueryAllReturn = Array | []; +type FindReturn = Promise; +type FindAllReturn = Promise; + export interface GetByAPI { getByName: (name: React.ReactType | string) => ReactTestInstance; getByType:

(type: React.ComponentType

) => ReactTestInstance; @@ -20,12 +31,15 @@ export interface GetByAPI { getAllByDisplayValue: (value: string | RegExp) => Array; getAllByProps: (props: Record) => Array; - // Unsafe aliases - UNSAFE_getByType:

(type: React.ComponentType

) => ReactTestInstance, - UNSAFE_getAllByType:

(type: React.ComponentType

) => Array, - UNSAFE_getByProps: (props: Record) => ReactTestInstance, - UNSAFE_getAllByProps: (props: Record) => Array, + UNSAFE_getByType:

(type: React.ComponentType

) => ReactTestInstance; + UNSAFE_getAllByType:

( + type: React.ComponentType

+ ) => Array; + UNSAFE_getByProps: (props: Record) => ReactTestInstance; + UNSAFE_getAllByProps: ( + props: Record + ) => Array; } export interface QueryByAPI { @@ -57,61 +71,147 @@ export interface QueryByAPI { ) => Array | []; // Unsafe aliases - UNSAFE_queryByType:

(type: React.ComponentType

) => ReactTestInstance | null, - UNSAFE_queryAllByType:

(type: React.ComponentType

) => Array | [], - UNSAFE_queryByProps: (props: Record) => ReactTestInstance | null, - UNSAFE_queryAllByProps: (props: Record) => Array | [], + UNSAFE_queryByType:

( + type: React.ComponentType

+ ) => ReactTestInstance | null; + UNSAFE_queryAllByType:

( + type: React.ComponentType

+ ) => Array | []; + UNSAFE_queryByProps: (props: Record) => ReactTestInstance | null; + UNSAFE_queryAllByProps: ( + props: Record + ) => Array | []; } -type GetReturn = ReactTestInstance; -type GetAllReturn = Array; -type QueryReturn = ReactTestInstance | null; -type QueryAllReturn = Array | []; +export interface WaitForOptions { + timeout: number; + interval: number; +} + +export interface FindByAPI { + findByText: ( + text: string | RegExp, + waitForOptions?: WaitForOptions + ) => FindReturn; + findByPlaceholder: ( + placeholder: string | RegExp, + waitForOptions?: WaitForOptions + ) => FindReturn; + findByDisplayValue: ( + value: string | RegExp, + waitForOptions?: WaitForOptions + ) => FindReturn; + findByTestId: (testID: string, waitForOptions?: WaitForOptions) => FindReturn; + findAllByText: ( + text: string | RegExp, + waitForOptions?: WaitForOptions + ) => FindAllReturn; + findAllByPlaceholder: ( + placeholder: string | RegExp, + waitForOptions?: WaitForOptions + ) => FindAllReturn; + findAllByDisplayValue: ( + value: string | RegExp, + waitForOptions?: WaitForOptions + ) => FindAllReturn; + findAllByTestId: ( + testID: string, + waitForOptions?: WaitForOptions + ) => FindAllReturn; +} // Not yet available in DefinitelyTyped export type A11yValue = { - min?: number, - max?: number, - now?: number, - text?: string, + min?: number; + max?: number; + now?: number; + text?: string; }; type A11yAPI = { // Label - getByA11yLabel: (matcher: string | RegExp) => GetReturn, - getAllByA11yLabel: (matcher: string | RegExp) => GetAllReturn, - queryByA11yLabel: (matcher: string | RegExp) => QueryReturn, - queryAllByA11yLabel: (matcher: string | RegExp) => QueryAllReturn, + getByA11yLabel: (matcher: string | RegExp) => GetReturn; + getAllByA11yLabel: (matcher: string | RegExp) => GetAllReturn; + queryByA11yLabel: (matcher: string | RegExp) => QueryReturn; + queryAllByA11yLabel: (matcher: string | RegExp) => QueryAllReturn; + findByA11yLabel: ( + matcher: string | RegExp, + waitForOptions?: WaitForOptions + ) => FindReturn; + findAllByA11yLabel: ( + matcher: string | RegExp, + waitForOptions?: WaitForOptions + ) => FindAllReturn; // Hint - getByA11yHint: (matcher: string | RegExp) => GetReturn, - getAllByA11yHint: (matcher: string | RegExp) => GetAllReturn, - queryByA11yHint: (matcher: string | RegExp) => QueryReturn, - queryAllByA11yHint: (matcher: string | RegExp) => QueryAllReturn, + getByA11yHint: (matcher: string | RegExp) => GetReturn; + getAllByA11yHint: (matcher: string | RegExp) => GetAllReturn; + queryByA11yHint: (matcher: string | RegExp) => QueryReturn; + queryAllByA11yHint: (matcher: string | RegExp) => QueryAllReturn; + findByA11yHint: ( + matcher: string | RegExp, + waitForOptions?: WaitForOptions + ) => FindReturn; + findAllByA11yHint: ( + matcher: string | RegExp, + waitForOptions?: WaitForOptions + ) => FindAllReturn; // Role - getByA11yRole: (matcher: AccessibilityRole | RegExp) => GetReturn, - getAllByA11yRole: (matcher: AccessibilityRole | RegExp) => GetAllReturn, - queryByA11yRole: (matcher: AccessibilityRole | RegExp) => QueryReturn, - queryAllByA11yRole: (matcher: AccessibilityRole | RegExp) => QueryAllReturn, + getByA11yRole: (matcher: AccessibilityRole | RegExp) => GetReturn; + getAllByA11yRole: (matcher: AccessibilityRole | RegExp) => GetAllReturn; + queryByA11yRole: (matcher: AccessibilityRole | RegExp) => QueryReturn; + queryAllByA11yRole: (matcher: AccessibilityRole | RegExp) => QueryAllReturn; + findByA11yRole: ( + matcher: AccessibilityRole | RegExp, + waitForOptions?: WaitForOptions + ) => FindReturn; + findAllByA11yRole: ( + matcher: AccessibilityRole | RegExp, + waitForOptions?: WaitForOptions + ) => FindAllReturn; // States - getByA11yStates: (matcher: AccessibilityStates | Array) => GetReturn, - getAllByA11yStates: (matcher: AccessibilityStates | Array) => GetAllReturn, - queryByA11yStates: (matcher: AccessibilityStates | Array) => QueryReturn, - queryAllByA11yStates: (matcher: AccessibilityStates | Array) => QueryAllReturn, + getByA11yStates: ( + matcher: AccessibilityStates | Array + ) => GetReturn; + getAllByA11yStates: ( + matcher: AccessibilityStates | Array + ) => GetAllReturn; + queryByA11yStates: ( + matcher: AccessibilityStates | Array + ) => QueryReturn; + queryAllByA11yStates: ( + matcher: AccessibilityStates | Array + ) => QueryAllReturn; // State - getByA11yState: (matcher: AccessibilityState) => GetReturn, - getAllByA11yState: (matcher: AccessibilityState) => GetAllReturn, - queryByA11yState: (matcher: AccessibilityState) => QueryReturn, - queryAllByA11yState: (matcher: AccessibilityState) => QueryAllReturn, + getByA11yState: (matcher: AccessibilityState) => GetReturn; + getAllByA11yState: (matcher: AccessibilityState) => GetAllReturn; + queryByA11yState: (matcher: AccessibilityState) => QueryReturn; + queryAllByA11yState: (matcher: AccessibilityState) => QueryAllReturn; + findByA11yState: ( + matcher: AccessibilityState, + waitForOptions?: WaitForOptions + ) => FindReturn; + findAllByA11yState: ( + matcher: AccessibilityState, + waitForOptions?: WaitForOptions + ) => FindAllReturn; // Value - getByA11yValue: (matcher: A11yValue) => GetReturn, - getAllByA11yValue: (matcher: A11yValue) => GetAllReturn, - queryByA11yValue: (matcher: A11yValue) => QueryReturn, - queryAllByA11yValue: (matcher: A11yValue) => QueryAllReturn, + getByA11yValue: (matcher: A11yValue) => GetReturn; + getAllByA11yValue: (matcher: A11yValue) => GetAllReturn; + queryByA11yValue: (matcher: A11yValue) => QueryReturn; + queryAllByA11yValue: (matcher: A11yValue) => QueryAllReturn; + findByA11yValue: ( + matcher: A11yValue, + waitForOptions?: WaitForOptions + ) => FindReturn; + findAllByA11yValue: ( + matcher: A11yValue, + waitForOptions?: WaitForOptions + ) => FindAllReturn; }; export interface Thenable { @@ -123,7 +223,7 @@ export interface RenderOptions { createNodeMock?: (element: React.ReactElement) => any; } -export interface RenderAPI extends GetByAPI, QueryByAPI, A11yAPI { +export interface RenderAPI extends GetByAPI, QueryByAPI, FindByAPI, A11yAPI { update(nextElement: React.ReactElement): void; rerender(nextElement: React.ReactElement): void; unmount(nextElement?: React.ReactElement): void; From 01510929c455d89f66cc50b1132f8dba6af4cc44 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Thu, 14 May 2020 08:31:36 +0200 Subject: [PATCH 10/15] Removed export of GetByAPI, QueryByAPI and FindByAPI interfaces in TS --- typings/index.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index e04b906e8..0200a33d6 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -13,7 +13,7 @@ type QueryAllReturn = Array | []; type FindReturn = Promise; type FindAllReturn = Promise; -export interface GetByAPI { +interface GetByAPI { getByName: (name: React.ReactType | string) => ReactTestInstance; getByType:

(type: React.ComponentType

) => ReactTestInstance; getByText: (text: string | RegExp) => ReactTestInstance; @@ -42,7 +42,7 @@ export interface GetByAPI { ) => Array; } -export interface QueryByAPI { +interface QueryByAPI { queryByName: (name: React.ReactType | string) => ReactTestInstance | null; queryByType:

(type: React.ComponentType

) => ReactTestInstance | null; queryByText: (name: string | RegExp) => ReactTestInstance | null; @@ -88,7 +88,7 @@ export interface WaitForOptions { interval: number; } -export interface FindByAPI { +interface FindByAPI { findByText: ( text: string | RegExp, waitForOptions?: WaitForOptions From 0c7c58b74ca697db70da1e873cb1ff401e6b9a4b Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Thu, 14 May 2020 11:14:24 +0200 Subject: [PATCH 11/15] Reversed prettier run on typings --- typings/__tests__/index.test.tsx | 70 ++++++++++------------- typings/index.d.ts | 97 +++++++++++++------------------- 2 files changed, 67 insertions(+), 100 deletions(-) diff --git a/typings/__tests__/index.test.tsx b/typings/__tests__/index.test.tsx index e3c3b47f0..8165bf824 100644 --- a/typings/__tests__/index.test.tsx +++ b/typings/__tests__/index.test.tsx @@ -60,9 +60,9 @@ const getAllByNameConstructor: Array = tree.getAllByName( View ); const getAllByType: Array = tree.getAllByType(View); -const getAllByTypeWithRequiredProps: Array = tree.getAllByType( - ElementWithRequiredProps -); +const getAllByTypeWithRequiredProps: Array< + ReactTestInstance +> = tree.getAllByType(ElementWithRequiredProps); const getAllByTextString: Array = tree.getAllByText( '' ); @@ -71,7 +71,7 @@ const getAllByProps: Array = tree.getAllByProps({ value: 2, }); -// queryByAPI tests +// queuryByAPI tests const queryByNameString: ReactTestInstance | null = tree.queryByName('View'); const queryByNameConstructor: ReactTestInstance | null = tree.queryByName(View); const queryByType: ReactTestInstance | null = tree.queryByType(View); @@ -104,23 +104,23 @@ const queryAllByNameConstructor: Array = tree.queryAllByName( View ); const queryAllByType: Array = tree.queryAllByType(View); -const queryAllByTypeWithRequiredProps: Array = tree.queryAllByType( - ElementWithRequiredProps -); +const queryAllByTypeWithRequiredProps: Array< + ReactTestInstance +> = tree.queryAllByType(ElementWithRequiredProps); const queryAllByTextString: Array = tree.queryAllByText( 'View' ); const queryAllByTextRegExp: Array = tree.queryAllByText( /View/g ); -const queryAllByDisplayValueString: Array = tree.queryAllByDisplayValue( - 'View' -); -const queryAllByDisplayValueRegExp: Array = tree.queryAllByDisplayValue( - /View/g -); +const queryAllByDisplayValueString: Array< + ReactTestInstance +> = tree.queryAllByDisplayValue('View'); +const queryAllByDisplayValueRegExp: Array< + ReactTestInstance +> = tree.queryAllByDisplayValue(/View/g); -// findByAPI tests +// findBy API tests const findByTextString: Promise = tree.findByText('View'); const findByTextRegExp: Promise = tree.findByText(/View/g); const findByTextStringWithTimeout: Promise = tree.findByText( @@ -269,36 +269,28 @@ const findAllByA11yRoleWithTimeout: Promise = tree.findAllB ); const getByA11yStates: ReactTestInstance = tree.getByA11yStates('selected'); -const getByA11yStatesArray: ReactTestInstance = tree.getByA11yStates([ - 'selected', -]); +const getByA11yStatesArray: ReactTestInstance = tree.getByA11yStates(['selected']); const getAllByA11yStates: Array = tree.getAllByA11yStates( 'selected' ); -const getAllByA11yStatesArray: Array = tree.getAllByA11yStates( - ['selected'] -); +const getAllByA11yStatesArray: Array< + ReactTestInstance +> = tree.getAllByA11yStates(['selected']); const queryByA11yStates: ReactTestInstance = tree.queryByA11yStates('selected'); const queryByA11yStatesArray: ReactTestInstance = tree.queryByA11yStates([ 'selected', ]); -const queryAllByA11yStates: Array = tree.queryAllByA11yStates( - 'selected' -); -const queryAllByA11yStatesArray: Array = tree.queryAllByA11yStates( - ['selected'] -); +const queryAllByA11yStates: Array< + ReactTestInstance +> = tree.queryAllByA11yStates('selected'); +const queryAllByA11yStatesArray: Array< + ReactTestInstance +> = tree.queryAllByA11yStates(['selected']); const getByA11yState: ReactTestInstance = tree.getByA11yState({ busy: true }); -const getAllByA11yState: Array = tree.getAllByA11yState({ - busy: true, -}); -const queryByA11yState: ReactTestInstance = tree.queryByA11yState({ - busy: true, -}); -const queryAllByA11yState: Array = tree.queryAllByA11yState({ - busy: true, -}); +const getAllByA11yState: Array = tree.getAllByA11yState({ busy: true }); +const queryByA11yState: ReactTestInstance = tree.queryByA11yState({ busy: true }); +const queryAllByA11yState: Array = tree.queryAllByA11yState({ busy: true }); const findByA11yState: Promise = tree.findByA11yState({ busy: true, }); @@ -319,13 +311,9 @@ const findAllByA11yStateWithTimeout: Promise = tree.findAll ); const getByA11yValue: ReactTestInstance = tree.getByA11yValue({ min: 10 }); -const getAllByA11yValue: Array = tree.getAllByA11yValue({ - min: 10, -}); +const getAllByA11yValue: Array = tree.getAllByA11yValue({ min: 10 }); const queryByA11yValue: ReactTestInstance = tree.queryByA11yValue({ min: 10 }); -const queryAllByA11yValue: Array = tree.queryAllByA11yValue({ - min: 10, -}); +const queryAllByA11yValue: Array = tree.queryAllByA11yValue({ min: 10 }); const findByA11yValue: Promise = tree.findByA11yValue({ min: 10, }); diff --git a/typings/index.d.ts b/typings/index.d.ts index 0200a33d6..730631585 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1,9 +1,5 @@ import * as React from 'react'; -import { - AccessibilityState, - AccessibilityStates, - AccessibilityRole, -} from 'react-native'; +import { AccessibilityState, AccessibilityStates, AccessibilityRole } from 'react-native'; import { ReactTestInstance, ReactTestRendererJSON } from 'react-test-renderer'; type GetReturn = ReactTestInstance; @@ -31,15 +27,12 @@ interface GetByAPI { getAllByDisplayValue: (value: string | RegExp) => Array; getAllByProps: (props: Record) => Array; + // Unsafe aliases - UNSAFE_getByType:

(type: React.ComponentType

) => ReactTestInstance; - UNSAFE_getAllByType:

( - type: React.ComponentType

- ) => Array; - UNSAFE_getByProps: (props: Record) => ReactTestInstance; - UNSAFE_getAllByProps: ( - props: Record - ) => Array; + UNSAFE_getByType:

(type: React.ComponentType

) => ReactTestInstance, + UNSAFE_getAllByType:

(type: React.ComponentType

) => Array, + UNSAFE_getByProps: (props: Record) => ReactTestInstance, + UNSAFE_getAllByProps: (props: Record) => Array, } interface QueryByAPI { @@ -71,16 +64,10 @@ interface QueryByAPI { ) => Array | []; // Unsafe aliases - UNSAFE_queryByType:

( - type: React.ComponentType

- ) => ReactTestInstance | null; - UNSAFE_queryAllByType:

( - type: React.ComponentType

- ) => Array | []; - UNSAFE_queryByProps: (props: Record) => ReactTestInstance | null; - UNSAFE_queryAllByProps: ( - props: Record - ) => Array | []; + UNSAFE_queryByType:

(type: React.ComponentType

) => ReactTestInstance | null, + UNSAFE_queryAllByType:

(type: React.ComponentType

) => Array | [], + UNSAFE_queryByProps: (props: Record) => ReactTestInstance | null, + UNSAFE_queryAllByProps: (props: Record) => Array | [], } export interface WaitForOptions { @@ -122,18 +109,18 @@ interface FindByAPI { // Not yet available in DefinitelyTyped export type A11yValue = { - min?: number; - max?: number; - now?: number; - text?: string; + min?: number, + max?: number, + now?: number, + text?: string, }; type A11yAPI = { // Label - getByA11yLabel: (matcher: string | RegExp) => GetReturn; - getAllByA11yLabel: (matcher: string | RegExp) => GetAllReturn; - queryByA11yLabel: (matcher: string | RegExp) => QueryReturn; - queryAllByA11yLabel: (matcher: string | RegExp) => QueryAllReturn; + getByA11yLabel: (matcher: string | RegExp) => GetReturn, + getAllByA11yLabel: (matcher: string | RegExp) => GetAllReturn, + queryByA11yLabel: (matcher: string | RegExp) => QueryReturn, + queryAllByA11yLabel: (matcher: string | RegExp) => QueryAllReturn, findByA11yLabel: ( matcher: string | RegExp, waitForOptions?: WaitForOptions @@ -144,10 +131,10 @@ type A11yAPI = { ) => FindAllReturn; // Hint - getByA11yHint: (matcher: string | RegExp) => GetReturn; - getAllByA11yHint: (matcher: string | RegExp) => GetAllReturn; - queryByA11yHint: (matcher: string | RegExp) => QueryReturn; - queryAllByA11yHint: (matcher: string | RegExp) => QueryAllReturn; + getByA11yHint: (matcher: string | RegExp) => GetReturn, + getAllByA11yHint: (matcher: string | RegExp) => GetAllReturn, + queryByA11yHint: (matcher: string | RegExp) => QueryReturn, + queryAllByA11yHint: (matcher: string | RegExp) => QueryAllReturn, findByA11yHint: ( matcher: string | RegExp, waitForOptions?: WaitForOptions @@ -158,10 +145,10 @@ type A11yAPI = { ) => FindAllReturn; // Role - getByA11yRole: (matcher: AccessibilityRole | RegExp) => GetReturn; - getAllByA11yRole: (matcher: AccessibilityRole | RegExp) => GetAllReturn; - queryByA11yRole: (matcher: AccessibilityRole | RegExp) => QueryReturn; - queryAllByA11yRole: (matcher: AccessibilityRole | RegExp) => QueryAllReturn; + getByA11yRole: (matcher: AccessibilityRole | RegExp) => GetReturn, + getAllByA11yRole: (matcher: AccessibilityRole | RegExp) => GetAllReturn, + queryByA11yRole: (matcher: AccessibilityRole | RegExp) => QueryReturn, + queryAllByA11yRole: (matcher: AccessibilityRole | RegExp) => QueryAllReturn, findByA11yRole: ( matcher: AccessibilityRole | RegExp, waitForOptions?: WaitForOptions @@ -172,24 +159,16 @@ type A11yAPI = { ) => FindAllReturn; // States - getByA11yStates: ( - matcher: AccessibilityStates | Array - ) => GetReturn; - getAllByA11yStates: ( - matcher: AccessibilityStates | Array - ) => GetAllReturn; - queryByA11yStates: ( - matcher: AccessibilityStates | Array - ) => QueryReturn; - queryAllByA11yStates: ( - matcher: AccessibilityStates | Array - ) => QueryAllReturn; + getByA11yStates: (matcher: AccessibilityStates | Array) => GetReturn, + getAllByA11yStates: (matcher: AccessibilityStates | Array) => GetAllReturn, + queryByA11yStates: (matcher: AccessibilityStates | Array) => QueryReturn, + queryAllByA11yStates: (matcher: AccessibilityStates | Array) => QueryAllReturn, // State - getByA11yState: (matcher: AccessibilityState) => GetReturn; - getAllByA11yState: (matcher: AccessibilityState) => GetAllReturn; - queryByA11yState: (matcher: AccessibilityState) => QueryReturn; - queryAllByA11yState: (matcher: AccessibilityState) => QueryAllReturn; + getByA11yState: (matcher: AccessibilityState) => GetReturn, + getAllByA11yState: (matcher: AccessibilityState) => GetAllReturn, + queryByA11yState: (matcher: AccessibilityState) => QueryReturn, + queryAllByA11yState: (matcher: AccessibilityState) => QueryAllReturn, findByA11yState: ( matcher: AccessibilityState, waitForOptions?: WaitForOptions @@ -200,10 +179,10 @@ type A11yAPI = { ) => FindAllReturn; // Value - getByA11yValue: (matcher: A11yValue) => GetReturn; - getAllByA11yValue: (matcher: A11yValue) => GetAllReturn; - queryByA11yValue: (matcher: A11yValue) => QueryReturn; - queryAllByA11yValue: (matcher: A11yValue) => QueryAllReturn; + getByA11yValue: (matcher: A11yValue) => GetReturn, + getAllByA11yValue: (matcher: A11yValue) => GetAllReturn, + queryByA11yValue: (matcher: A11yValue) => QueryReturn, + queryAllByA11yValue: (matcher: A11yValue) => QueryAllReturn, findByA11yValue: ( matcher: A11yValue, waitForOptions?: WaitForOptions From 48559d3d5d0f347c22393f349b42be9f7c1bb311 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Thu, 14 May 2020 14:07:13 +0200 Subject: [PATCH 12/15] Added overlapping pieces with `within` operator --- src/__tests__/within.test.js | 24 ++++- src/within.js | 2 + typings/__tests__/index.test.tsx | 175 ++++++++++++------------------- website/docs/API.md | 11 +- 4 files changed, 99 insertions(+), 113 deletions(-) diff --git a/src/__tests__/within.test.js b/src/__tests__/within.test.js index 97bf5252b..a4fb956c1 100644 --- a/src/__tests__/within.test.js +++ b/src/__tests__/within.test.js @@ -3,7 +3,7 @@ import React from 'react'; import { View, Text, TextInput } from 'react-native'; import { render, within } from '..'; -test('within() exposes basic queries', () => { +test('within() exposes basic queries', async () => { const rootQueries = render( @@ -28,6 +28,12 @@ test('within() exposes basic queries', () => { expect(firstQueries.queryByText('Same Text')).toBeTruthy(); expect(firstQueries.getByDisplayValue('Same Value')).toBeTruthy(); expect(firstQueries.getByPlaceholder('Same Placeholder')).toBeTruthy(); + await expect( + firstQueries.findByDisplayValue('Same Value') + ).resolves.toBeTruthy(); + await expect( + firstQueries.findAllByPlaceholder('Same Placeholder') + ).resolves.toHaveLength(1); const secondQueries = within(rootQueries.getByA11yHint('second')); expect(secondQueries.getAllByText('Same Text')).toHaveLength(1); @@ -38,7 +44,7 @@ test('within() exposes basic queries', () => { expect(secondQueries.getByPlaceholder('Same Placeholder')).toBeTruthy(); }); -test('within() exposes a11y queries', () => { +test('within() exposes a11y queries', async () => { const rootQueries = render( @@ -64,8 +70,22 @@ test('within() exposes a11y queries', () => { const firstQueries = within(rootQueries.getByA11yHint('first')); expect(firstQueries.getByA11yLabel('Same Label')).toBeTruthy(); expect(firstQueries.getByA11yHint('Same Hint')).toBeTruthy(); + expect(firstQueries.queryByA11yLabel('Same Label')).toBeTruthy(); + expect(firstQueries.queryByA11yHint('Same Hint')).toBeTruthy(); + await expect( + firstQueries.findByA11yLabel('Same Label') + ).resolves.toBeTruthy(); + await expect(firstQueries.findByA11yHint('Same Hint')).resolves.toBeTruthy(); const secondQueries = within(rootQueries.getByA11yHint('second')); expect(secondQueries.getAllByA11yLabel('Same Label')).toHaveLength(1); expect(secondQueries.getAllByA11yHint('Same Hint')).toHaveLength(1); + expect(secondQueries.queryAllByA11yLabel('Same Label')).toHaveLength(1); + expect(secondQueries.queryAllByA11yHint('Same Hint')).toHaveLength(1); + await expect( + secondQueries.findAllByA11yLabel('Same Label') + ).resolves.toHaveLength(1); + await expect( + secondQueries.findAllByA11yHint('Same Hint') + ).resolves.toHaveLength(1); }); diff --git a/src/within.js b/src/within.js index a7dd00b40..3b12c3e06 100644 --- a/src/within.js +++ b/src/within.js @@ -1,12 +1,14 @@ // @flow import { getByAPI } from './helpers/getByAPI'; import { queryByAPI } from './helpers/queryByAPI'; +import { findByAPI } from './helpers/findByAPI'; import a11yAPI from './helpers/a11yAPI'; export default function within(instance: ReactTestInstance) { return { ...getByAPI(instance), ...queryByAPI(instance), + ...findByAPI(instance), ...a11yAPI(instance), }; } diff --git a/typings/__tests__/index.test.tsx b/typings/__tests__/index.test.tsx index e5cf30c14..c88c273b3 100644 --- a/typings/__tests__/index.test.tsx +++ b/typings/__tests__/index.test.tsx @@ -380,112 +380,75 @@ act(() => { // within API const instance: ReactTestInstance = tree.getByText(''); -const withinGetByText: ReactTestInstance = within(instance).getByText('Test'); -const withinGetAllByText: ReactTestInstance[] = within(instance).getAllByText( - 'Test' -); -const withinGetByDisplayValue: ReactTestInstance = within( - instance -).getByDisplayValue('Test'); -const withinGetAllByDisplayValue: ReactTestInstance[] = within( - instance -).getAllByDisplayValue('Test'); -const withinGetByPlaceholder: ReactTestInstance = within( - instance -).getByPlaceholder('Test'); -const withinGetAllByPlaceholder: ReactTestInstance[] = within( - instance -).getAllByPlaceholder('Test'); -const withinGetByTestId: ReactTestInstance = within(instance).getByTestId( - 'Test' -); -const withinGetAllByTestId: ReactTestInstance[] = within( - instance -).getAllByTestId('Test'); -const withinQueryByText: ReactTestInstance | null = within( - instance -).queryByText('Test'); -const withinQueryAllByText: ReactTestInstance[] = within( - instance -).queryAllByText('Test'); -const withinQueryByDisplayValue: ReactTestInstance | null = within( - instance -).queryByDisplayValue('Test'); -const withinQueryAllByDisplayValue: ReactTestInstance[] = within( - instance -).queryAllByDisplayValue('Test'); -const withinQueryByPlaceholder: ReactTestInstance | null = within( - instance -).queryByPlaceholder('Test'); -const withinQueryAllByPlaceholder: ReactTestInstance[] = within( - instance -).queryAllByPlaceholder('Test'); -const withinQueryByTestId: ReactTestInstance | null = within( - instance -).queryByTestId('Test'); -const withinQueryAllByTestId: ReactTestInstance[] = within( - instance -).queryAllByTestId('Test'); +const withinGet: Array = [ + within(instance).getByText('Test'), + within(instance).getByDisplayValue('Test'), + within(instance).getByPlaceholder('Test'), + within(instance).getByTestId('Test'), + within(instance).getByA11yLabel('Test'), + within(instance).getByA11yHint('Test'), + within(instance).getByA11yRole('button'), + within(instance).getByA11yState({ busy: true }), + within(instance).getByA11yValue({ min: 10 }), +]; -const withinGetByA11yLabel: ReactTestInstance = within(instance).getByA11yLabel( - 'Test' -); -const withinGetAllByA11yLabel: ReactTestInstance[] = within( - instance -).getAllByA11yLabel('Test'); -const withinGetByA11yHint: ReactTestInstance = within(instance).getByA11yHint( - 'Test' -); -const withinGetAllByA11yHint: ReactTestInstance[] = within( - instance -).getAllByA11yHint('Test'); -const withinGetByA11yRole: ReactTestInstance = within(instance).getByA11yRole( - 'button' -); -const withinGetAllByA11yRole: ReactTestInstance[] = within( - instance -).getAllByA11yRole('button'); -const withinGetByA11yState: ReactTestInstance = within( - instance -).getByA11yState({ busy: true }); -const withinGetAllByA11yState: ReactTestInstance[] = within( - instance -).getAllByA11yState({ busy: true }); -const withinGetByA11yValue: ReactTestInstance = within( - instance -).getByA11yValue({ min: 10 }); -const withinGetAllByA11yValue: ReactTestInstance[] = within( - instance -).getAllByA11yValue({ min: 10 }); +const withinGetAll: Array = [ + within(instance).getAllByText('Test'), + within(instance).getAllByDisplayValue('Test'), + within(instance).getAllByPlaceholder('Test'), + within(instance).getAllByTestId('Test'), + within(instance).getAllByA11yLabel('Test'), + within(instance).getAllByA11yHint('Test'), + within(instance).getAllByA11yRole('button'), + within(instance).getAllByA11yState({ busy: true }), + within(instance).getAllByA11yValue({ min: 10 }), +]; + +const withinQuery: Array = [ + within(instance).queryByText('Test'), + within(instance).queryByDisplayValue('Test'), + within(instance).queryByPlaceholder('Test'), + within(instance).queryByTestId('Test'), + within(instance).queryByA11yLabel('Test'), + within(instance).queryByA11yHint('Test'), + within(instance).queryByA11yRole('button'), + within(instance).queryByA11yState({ busy: true }), + within(instance).queryByA11yValue({ min: 10 }), +]; + +const withinQueryAll: Array = [ + within(instance).queryAllByText('Test'), + within(instance).queryAllByDisplayValue('Test'), + within(instance).queryAllByPlaceholder('Test'), + within(instance).queryAllByTestId('Test'), + within(instance).queryAllByA11yLabel('Test'), + within(instance).queryAllByA11yHint('Test'), + within(instance).queryAllByA11yRole('button'), + within(instance).queryAllByA11yState({ busy: true }), + within(instance).queryAllByA11yValue({ min: 10 }), +]; + +const withinFind: Promise[] = [ + within(instance).findByText('Test'), + within(instance).findByDisplayValue('Test'), + within(instance).findByPlaceholder('Test'), + within(instance).findByTestId('Test'), + within(instance).findByA11yLabel('Test'), + within(instance).findByA11yHint('Test'), + within(instance).findByA11yRole('button'), + within(instance).findByA11yState({ busy: true }), + within(instance).findByA11yValue({ min: 10 }), +]; -const withinQueryByA11yLabel: ReactTestInstance | null = within( - instance -).queryByA11yLabel('Test'); -const withinQueryAllByA11yLabel: ReactTestInstance[] = within( - instance -).queryAllByA11yLabel('Test'); -const withinQueryByA11yHint: ReactTestInstance | null = within( - instance -).queryByA11yHint('Test'); -const withinQueryAllByA11yHint: ReactTestInstance[] = within( - instance -).queryAllByA11yHint('Test'); -const withinQueryByA11yRole: ReactTestInstance | null = within( - instance -).queryByA11yRole('button'); -const withinQueryAllByA11yRole: ReactTestInstance[] = within( - instance -).queryAllByA11yRole('button'); -const withinQueryByA11yState: ReactTestInstance | null = within( - instance -).queryByA11yState({ busy: true }); -const withinQueryAllByA11yState: ReactTestInstance[] = within( - instance -).queryAllByA11yState({ busy: true }); -const withinQueryByA11yValue: ReactTestInstance | null = within( - instance -).queryByA11yValue({ min: 10 }); -const withinQueryAllByA11yValue: ReactTestInstance[] = within( - instance -).queryAllByA11yValue({ min: 10 }); +const withinFindAll: Promise[] = [ + within(instance).findAllByText('Test'), + within(instance).findAllByDisplayValue('Test'), + within(instance).findAllByPlaceholder('Test'), + within(instance).findAllByTestId('Test'), + within(instance).findAllByA11yLabel('Test'), + within(instance).findAllByA11yHint('Test'), + within(instance).findAllByA11yRole('button'), + within(instance).findAllByA11yState({ busy: true }), + within(instance).findAllByA11yValue({ min: 10 }), +]; diff --git a/website/docs/API.md b/website/docs/API.md index f3037d779..62176f09b 100644 --- a/website/docs/API.md +++ b/website/docs/API.md @@ -351,7 +351,7 @@ Defined as: function within(instance: ReactTestInstance): Queries ``` -Perform [queries](./Queries.md) scoped to given element. +Perform [queries](./Queries.md) scoped to given element. :::note Please note that additional `render` specific operations like `update`, `unmount`, `debug`, `toJSON` are _not_ included. @@ -361,13 +361,14 @@ Please note that additional `render` specific operations like `update`, `unmount const detailsScreen = within(getByA11yHint('Details Screen')); expect(detailsScreen.getByText('Some Text')).toBeTruthy(); expect(detailsScreen.getByDisplayValue('Some Value')).toBeTruthy(); -expect(detailsScreen.getByA11yLabel('Some Label')).toBeTruthy(); -expect(detailsScreen.getByA11yHint('Some Label')).toBeTruthy(); +expect(detailsScreen.queryByA11yLabel('Some Label')).toBeTruthy(); +await expect(detailsScreen.findByA11yHint('Some Label')).resolves.toBeTruthy(); ``` Use cases for scoped queries include: -* queries scoped to a single item inside a FlatList containing many items -* queries scoped to a single screen in tests involving screen transitions (e.g. with react-navigation) + +- queries scoped to a single item inside a FlatList containing many items +- queries scoped to a single screen in tests involving screen transitions (e.g. with react-navigation) ## `debug` From 1c2a653b90c183bcdadcbde09c122625d342539a Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Thu, 14 May 2020 14:35:06 +0200 Subject: [PATCH 13/15] Small cleanup --- typings/__tests__/index.test.tsx | 201 ++++++++----------------------- 1 file changed, 48 insertions(+), 153 deletions(-) diff --git a/typings/__tests__/index.test.tsx b/typings/__tests__/index.test.tsx index c88c273b3..3caf5f299 100644 --- a/typings/__tests__/index.test.tsx +++ b/typings/__tests__/index.test.tsx @@ -122,84 +122,55 @@ const queryAllByDisplayValueRegExp: Array< > = tree.queryAllByDisplayValue(/View/g); // findBy API tests -const findByTextString: Promise = tree.findByText('View'); -const findByTextRegExp: Promise = tree.findByText(/View/g); -const findByTextStringWithTimeout: Promise = tree.findByText( - 'View', - { timeout: 10, interval: 10 } -); -const findByTextRegExpWithTimeout: Promise = tree.findByText( - /View/g, - { - timeout: 10, - interval: 5, - } -); -const findAllByTextRegExp: Promise = tree.findAllByText( - /View/g -); -const findAllByTextRegExpWithTimeout: Promise = tree.findAllByText( - /View/g, - { - timeout: 10, - interval: 5, - } -); +const findBy: Promise[] = [ + tree.findByText('View'), + tree.findByText('View', { timeout: 10, interval: 10 }), + tree.findByText(/View/g), + tree.findByText(/View/g, { timeout: 10, interval: 5 }), + tree.findByPlaceholder('my placeholder'), + tree.findByPlaceholder('my placeholder', { timeout: 10, interval: 5 }), + tree.findByPlaceholder(/placeholder/g), + tree.findByPlaceholder(/placeholder/g, { timeout: 10, interval: 5 }), + tree.findByDisplayValue('my value'), + tree.findByDisplayValue('my value', { timeout: 10, interval: 10 }), + tree.findByDisplayValue(/value/g), + tree.findByDisplayValue(/value/g, { timeout: 10, interval: 10 }), + tree.findByTestId('test-id'), + tree.findByTestId('test-id', { timeout: 10, interval: 10 }), + tree.findByA11yLabel('label'), + tree.findByA11yLabel('label', { timeout: 10, interval: 10 }), + tree.findByA11yHint('label'), + tree.findByA11yHint('label', { timeout: 10, interval: 10 }), + tree.findByA11yRole('button'), + tree.findByA11yRole('button', { timeout: 10, interval: 10 }), + tree.findByA11yState({ busy: true }), + tree.findByA11yState({ busy: true }, { timeout: 10, interval: 10 }), + tree.findByA11yValue({ min: 10 }), + tree.findByA11yValue({ min: 10 }, { timeout: 10, interval: 10 }), +]; -const findByPlaceholderString: Promise = tree.findByPlaceholder( - 'my placeholder' -); -const findByPlaceholderRegExp: Promise = tree.findByPlaceholder( - /placeholder/g -); -const findByPlaceholderStringWithTimeout: Promise = tree.findByPlaceholder( - 'my placeholder', - { timeout: 10, interval: 10 } -); -const findByPlaceholderRegExpWithTimeout: Promise = tree.findByPlaceholder( - /placeholder/g, - { timeout: 10, interval: 10 } -); -const findByDisplayValueString: Promise = tree.findByDisplayValue( - 'my value' -); -const findByDisplayValueRegExp: Promise = tree.findByDisplayValue( - /value/g -); -const findByDisplayValueStringWithTimeout: Promise = tree.findByDisplayValue( - 'my value', - { timeout: 10, interval: 10 } -); -const findByDisplayValueRegExpWithTimeout: Promise = tree.findByDisplayValue( - /value/g, - { timeout: 10, interval: 10 } -); -const findAllByDisplayValueString: Promise = tree.findAllByDisplayValue( - 'View' -); -const findAllByDisplayValueStringWithTimeout: Promise = tree.findAllByDisplayValue( - 'View', - { timeout: 10, interval: 10 } -); -const findAllByDisplayValueRegExp: Promise = tree.findAllByDisplayValue( - /View/g -); -const findAllByDisplayValueRegExpWithTimeout: Promise = tree.findAllByDisplayValue( - /View/g, - { timeout: 10, interval: 10 } -); -const findByTestId: Promise = tree.findByTestId('test-id'); -const findByTestIdWithTimeout: Promise = tree.findByTestId( - 'test-id', - { timeout: 10, interval: 10 } -); -const findAllByTestId: Promise = tree.findAllByTestId( - 'test-id' -); -const findAllByTestIdWithTimeout: Promise = tree.findAllByTestId( - 'test-id', - { timeout: 10, interval: 10 } -); +const findAllBy: Promise[] = [ + tree.findAllByText('View'), + tree.findAllByText('View', { timeout: 10, interval: 10 }), + tree.findAllByText(/View/g), + tree.findAllByText(/View/g, { timeout: 10, interval: 5 }), + tree.findAllByPlaceholder('my placeholder'), + tree.findAllByPlaceholder('my placeholder', { timeout: 10, interval: 10 }), + tree.findAllByPlaceholder(/placeholder/g), + tree.findAllByPlaceholder(/placeholder/g, { timeout: 10, interval: 10 }), + tree.findAllByDisplayValue('View'), + tree.findAllByDisplayValue('View', { timeout: 10, interval: 10 }), + tree.findAllByDisplayValue(/View/g), + tree.findAllByDisplayValue(/View/g, { timeout: 10, interval: 10 }), + tree.findAllByTestId('test-id'), + tree.findAllByTestId('test-id', { timeout: 10, interval: 10 }), + tree.findAllByA11yHint('label'), + tree.findAllByA11yHint('label', { timeout: 10, interval: 10 }), + tree.findAllByA11yState({ busy: true }), + tree.findAllByA11yState({ busy: true }, { timeout: 10, interval: 10 }), + tree.findAllByA11yValue({ min: 10 }), + tree.findAllByA11yValue({ min: 10 }, { timeout: 10, interval: 10 }), +]; // Accessibility queries const getByA11yLabel: ReactTestInstance = tree.getByA11yLabel('label'); @@ -210,20 +181,6 @@ const queryByA11yLabel: ReactTestInstance = tree.queryByA11yLabel('label'); const queryAllByA11yLabel: Array = tree.queryAllByA11yLabel( 'label' ); -const findByA11yLabel: Promise = tree.findByA11yLabel( - 'label' -); -const findAllByA11yLabel: Promise = tree.findAllByA11yLabel( - 'label' -); -const findByA11yLabelWithTimeout: Promise = tree.findByA11yLabel( - 'label', - { timeout: 10, interval: 10 } -); -const findAllByA11yLabelWithTimeout: Promise = tree.findAllByA11yLabel( - 'label', - { timeout: 10, interval: 10 } -); const getByA11yHint: ReactTestInstance = tree.getByA11yHint('label'); const getAllByA11yHint: Array = tree.getAllByA11yHint( @@ -233,18 +190,6 @@ const queryByA11yHint: ReactTestInstance = tree.queryByA11yHint('label'); const queryAllByA11yHint: Array = tree.queryAllByA11yHint( 'label' ); -const findByA11yHint: Promise = tree.findByA11yHint('label'); -const findAllByA11yHint: Promise = tree.findAllByA11yHint( - 'label', - { timeout: 10, interval: 10 } -); -const findByA11yHintWithTimeout: Promise = tree.findByA11yHint( - 'label' -); -const findAllByA11yHintWithTimeout: Promise = tree.findAllByA11yHint( - 'label', - { timeout: 10, interval: 10 } -); const getByA11yRole: ReactTestInstance = tree.getByA11yRole('button'); const getAllByA11yRole: Array = tree.getAllByA11yRole( @@ -254,20 +199,6 @@ const queryByA11yRole: ReactTestInstance = tree.queryByA11yRole('button'); const queryAllByA11yRole: Array = tree.queryAllByA11yRole( 'button' ); -const findByA11yRole: Promise = tree.findByA11yRole( - 'button' -); -const findAllByA11yRole: Promise = tree.findAllByA11yRole( - 'button', - { timeout: 10, interval: 10 } -); -const findByA11yRoleWithTimeout: Promise = tree.findByA11yRole( - 'button' -); -const findAllByA11yRoleWithTimeout: Promise = tree.findAllByA11yRole( - 'button', - { timeout: 10, interval: 10 } -); const getByA11yStates: ReactTestInstance = tree.getByA11yStates('selected'); const getByA11yStatesArray: ReactTestInstance = tree.getByA11yStates(['selected']); @@ -292,47 +223,11 @@ const getByA11yState: ReactTestInstance = tree.getByA11yState({ busy: true }); const getAllByA11yState: Array = tree.getAllByA11yState({ busy: true }); const queryByA11yState: ReactTestInstance = tree.queryByA11yState({ busy: true }); const queryAllByA11yState: Array = tree.queryAllByA11yState({ busy: true }); -const findByA11yState: Promise = tree.findByA11yState({ - busy: true, -}); -const findAllByA11yState: Promise = tree.findAllByA11yState( - { - busy: true, - } -); -const findByA11yStateWithTimeout: Promise = tree.findByA11yState( - { busy: true }, - { timeout: 10, interval: 10 } -); -const findAllByA11yStateWithTimeout: Promise = tree.findAllByA11yState( - { - busy: true, - }, - { timeout: 10, interval: 10 } -); const getByA11yValue: ReactTestInstance = tree.getByA11yValue({ min: 10 }); const getAllByA11yValue: Array = tree.getAllByA11yValue({ min: 10 }); const queryByA11yValue: ReactTestInstance = tree.queryByA11yValue({ min: 10 }); const queryAllByA11yValue: Array = tree.queryAllByA11yValue({ min: 10 }); -const findByA11yValue: Promise = tree.findByA11yValue({ - min: 10, -}); -const findAllByA11yValue: Promise = tree.findAllByA11yValue( - { - min: 10, - }, - { timeout: 10, interval: 10 } -); -const findByA11yValueWithTimeout: Promise = tree.findByA11yValue( - { min: 10 } -); -const findAllByA11yValueWithTimeout: Promise = tree.findAllByA11yValue( - { - min: 10, - }, - { timeout: 10, interval: 10 } -); const debugFn = tree.debug(); const debugFnWithMessage = tree.debug('my message'); From 4f455b3f5f70109a84f755f42e68b1c857db2fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 14 May 2020 21:09:04 +0200 Subject: [PATCH 14/15] Update website/docs/Queries.md --- website/docs/Queries.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/docs/Queries.md b/website/docs/Queries.md index b04dec44a..ab1465f1a 100644 --- a/website/docs/Queries.md +++ b/website/docs/Queries.md @@ -33,7 +33,9 @@ title: Queries `findAllBy` queries return a promise which resolves to an array when any matching elements are found. The promise is rejected if no elements match after a default timeout of 4500ms. -*Note:* `findBy` and `findAllBy` queries accept optional `waitForOptions` object argument which can contain `timeout` and `interval` properies which have the same meaning as respective arguments to [`waitForElement`](https://callstack.github.io/react-native-testing-library/docs/api#waitforelement) function. +:::info +`findBy` and `findAllBy` queries accept optional `waitForOptions` object argument which can contain `timeout` and `interval` properies which have the same meaning as respective arguments to [`waitForElement`](https://callstack.github.io/react-native-testing-library/docs/api#waitforelement) function. +::: ## Queries From 77df8447d362673da3c9a63de901039039092067 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Fri, 15 May 2020 08:44:28 +0200 Subject: [PATCH 15/15] Moved async/await tests to the end of test methods --- src/__tests__/a11yAPI.test.js | 90 +++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/src/__tests__/a11yAPI.test.js b/src/__tests__/a11yAPI.test.js index 83950502a..a5cebd7e9 100644 --- a/src/__tests__/a11yAPI.test.js +++ b/src/__tests__/a11yAPI.test.js @@ -75,17 +75,18 @@ test('getByA11yLabel, queryByA11yLabel, findByA11yLabel', async () => { const button = queryByA11yLabel(/button/g); expect(button && button.props.accessibilityLabel).toEqual(BUTTON_LABEL); - const asyncButton = await findByA11yLabel(BUTTON_LABEL); - expect(asyncButton.props.accessibilityLabel).toEqual(BUTTON_LABEL); - expect(() => getByA11yLabel(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryByA11yLabel(NO_MATCHES_TEXT)).toBeNull(); + + expect(() => getByA11yLabel(TEXT_LABEL)).toThrow(FOUND_TWO_INSTANCES); + expect(() => queryByA11yLabel(TEXT_LABEL)).toThrow(FOUND_TWO_INSTANCES); + + const asyncButton = await findByA11yLabel(BUTTON_LABEL); + expect(asyncButton.props.accessibilityLabel).toEqual(BUTTON_LABEL); await expect( findByA11yLabel(NO_MATCHES_TEXT, waitForOptions) ).rejects.toThrow(NO_INSTANCES_FOUND); - expect(() => getByA11yLabel(TEXT_LABEL)).toThrow(FOUND_TWO_INSTANCES); - expect(() => queryByA11yLabel(TEXT_LABEL)).toThrow(FOUND_TWO_INSTANCES); await expect(findByA11yLabel(TEXT_LABEL, waitForOptions)).rejects.toThrow( FOUND_TWO_INSTANCES ); @@ -98,10 +99,11 @@ test('getAllByA11yLabel, queryAllByA11yLabel', async () => { expect(getAllByA11yLabel(TEXT_LABEL)).toHaveLength(2); expect(queryAllByA11yLabel(/cool/g)).toHaveLength(3); - await expect(findAllByA11yLabel(TEXT_LABEL)).resolves.toHaveLength(2); expect(() => getAllByA11yLabel(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryAllByA11yLabel(NO_MATCHES_TEXT)).toEqual([]); + + await expect(findAllByA11yLabel(TEXT_LABEL)).resolves.toHaveLength(2); await expect(findAllByA11yLabel(NO_MATCHES_TEXT)).rejects.toThrow( NO_INSTANCES_FOUND ); @@ -117,17 +119,18 @@ test('getByA11yHint, queryByA11yHint, findByA11yHint', async () => { ); const button = queryByA11yHint(/button/g); expect(button && button.props.accessibilityHint).toEqual(BUTTON_HINT); - const asyncButton = await findByA11yHint(BUTTON_HINT); - expect(asyncButton.props.accessibilityHint).toEqual(BUTTON_HINT); expect(() => getByA11yHint(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryByA11yHint(NO_MATCHES_TEXT)).toBeNull(); - await expect(findByA11yHint(NO_MATCHES_TEXT, waitForOptions)).rejects.toThrow( - NO_INSTANCES_FOUND - ); 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( + NO_INSTANCES_FOUND + ); await expect(findByA11yHint(TEXT_HINT, waitForOptions)).rejects.toThrow( FOUND_TWO_INSTANCES ); @@ -140,10 +143,11 @@ test('getAllByA11yHint, queryAllByA11yHint', async () => { expect(getAllByA11yHint(TEXT_HINT)).toHaveLength(2); expect(queryAllByA11yHint(/static/g)).toHaveLength(2); - await expect(findAllByA11yHint(TEXT_HINT)).resolves.toHaveLength(2); expect(() => getAllByA11yHint(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryAllByA11yHint(NO_MATCHES_TEXT)).toEqual([]); + + await expect(findAllByA11yHint(TEXT_HINT)).resolves.toHaveLength(2); await expect(findAllByA11yHint(NO_MATCHES_TEXT)).rejects.toThrow( NO_INSTANCES_FOUND ); @@ -157,17 +161,18 @@ test('getByA11yRole, queryByA11yRole, findByA11yRole', async () => { expect(getByA11yRole('button').props.accessibilityRole).toEqual('button'); const button = queryByA11yRole(/button/g); expect(button && button.props.accessibilityRole).toEqual('button'); - const asyncButton = await findByA11yRole('button'); - expect(asyncButton.props.accessibilityRole).toEqual('button'); expect(() => getByA11yRole(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryByA11yRole(NO_MATCHES_TEXT)).toBeNull(); - await expect(findByA11yRole(NO_MATCHES_TEXT, waitForOptions)).rejects.toThrow( - NO_INSTANCES_FOUND - ); expect(() => getByA11yRole('link')).toThrow(FOUND_TWO_INSTANCES); expect(() => queryByA11yRole('link')).toThrow(FOUND_TWO_INSTANCES); + + const asyncButton = await findByA11yRole('button'); + expect(asyncButton.props.accessibilityRole).toEqual('button'); + await expect(findByA11yRole(NO_MATCHES_TEXT, waitForOptions)).rejects.toThrow( + NO_INSTANCES_FOUND + ); await expect(findByA11yRole('link')).rejects.toThrow(FOUND_TWO_INSTANCES); }); @@ -178,10 +183,11 @@ test('getAllByA11yRole, queryAllByA11yRole, findAllByA11yRole', async () => { expect(getAllByA11yRole('link')).toHaveLength(2); expect(queryAllByA11yRole(/ink/g)).toHaveLength(2); - await expect(findAllByA11yRole('link')).resolves.toHaveLength(2); expect(() => getAllByA11yRole(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND); expect(queryAllByA11yRole(NO_MATCHES_TEXT)).toEqual([]); + + await expect(findAllByA11yRole('link')).resolves.toHaveLength(2); await expect( findAllByA11yRole(NO_MATCHES_TEXT, waitForOptions) ).rejects.toThrow(NO_INSTANCES_FOUND); @@ -239,17 +245,9 @@ test('getByA11yState, queryByA11yState, findByA11yState', async () => { selected: true, expanded: false, }); - const asyncButton = await findByA11yState({ selected: true }); - expect(asyncButton.props.accessibilityState).toEqual({ - selected: true, - expanded: false, - }); expect(() => getByA11yState({ disabled: true })).toThrow(NO_INSTANCES_FOUND); expect(queryByA11yState({ disabled: true })).toEqual(null); - await expect( - findByA11yState({ disabled: true }, waitForOptions) - ).rejects.toThrow(NO_INSTANCES_FOUND); expect(() => getByA11yState({ expanded: false })).toThrow( FOUND_TWO_INSTANCES @@ -257,6 +255,15 @@ test('getByA11yState, queryByA11yState, findByA11yState', async () => { 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(NO_INSTANCES_FOUND); await expect( findByA11yState({ expanded: false }, waitForOptions) ).rejects.toThrow(FOUND_TWO_INSTANCES); @@ -269,18 +276,19 @@ test('getAllByA11yState, queryAllByA11yState, findAllByA11yState', async () => { expect(getAllByA11yState({ selected: true })).toHaveLength(1); expect(queryAllByA11yState({ selected: true })).toHaveLength(1); - await expect(findAllByA11yState({ selected: true })).resolves.toHaveLength(1); expect(() => getAllByA11yState({ disabled: true })).toThrow( NO_INSTANCES_FOUND ); expect(queryAllByA11yState({ disabled: true })).toEqual([]); - await expect( - findAllByA11yState({ disabled: true }, waitForOptions) - ).rejects.toThrow(NO_INSTANCES_FOUND); 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(NO_INSTANCES_FOUND); await expect(findAllByA11yState({ expanded: false })).resolves.toHaveLength( 2 ); @@ -299,20 +307,21 @@ test('getByA11yValue, queryByA11yValue, findByA11yValue', async () => { min: 40, max: 60, }); + + expect(() => getByA11yValue({ min: 50 })).toThrow(NO_INSTANCES_FOUND); + 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, }); - - expect(() => getByA11yValue({ min: 50 })).toThrow(NO_INSTANCES_FOUND); - expect(queryByA11yValue({ min: 50 })).toEqual(null); await expect(findByA11yValue({ min: 50 }, waitForOptions)).rejects.toThrow( NO_INSTANCES_FOUND ); - - expect(() => getByA11yValue({ max: 60 })).toThrow(FOUND_TWO_INSTANCES); - expect(() => queryByA11yValue({ max: 60 })).toThrow(FOUND_TWO_INSTANCES); await expect(findByA11yValue({ max: 60 }, waitForOptions)).rejects.toThrow( FOUND_TWO_INSTANCES ); @@ -325,15 +334,16 @@ test('getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue', async () => { expect(getAllByA11yValue({ min: 40 })).toHaveLength(1); expect(queryAllByA11yValue({ min: 40 })).toHaveLength(1); - await expect(findAllByA11yValue({ min: 40 })).resolves.toHaveLength(1); expect(() => getAllByA11yValue({ min: 50 })).toThrow(NO_INSTANCES_FOUND); 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( NO_INSTANCES_FOUND ); - - expect(getAllByA11yValue({ max: 60 })).toHaveLength(2); - expect(queryAllByA11yValue({ max: 60 })).toHaveLength(2); await expect(findAllByA11yValue({ max: 60 })).resolves.toHaveLength(2); });