diff --git a/README.md b/README.md index 2cf3dcc68..549ea139c 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ The [public API](https://callstack.github.io/react-native-testing-library/docs/a ## Migration Guides -- [Migration to 2.0](https://callstack.github.io/react-native-testing-library/docs/migration20) +- [Migration to 2.0](https://callstack.github.io/react-native-testing-library/docs/migration-v2) ## Made with ❤️ at Callstack diff --git a/src/__tests__/__snapshots__/render.test.js.snap b/src/__tests__/__snapshots__/render.test.js.snap index d3c4b4d93..55a88ffb7 100644 --- a/src/__tests__/__snapshots__/render.test.js.snap +++ b/src/__tests__/__snapshots__/render.test.js.snap @@ -150,12 +150,12 @@ exports[`debug: shallow 1`] = ` underlineColorAndroid=\\"transparent\\" value=\\"I inspected freshie\\" /> - + @@ -200,12 +200,12 @@ exports[`debug: shallow with message 1`] = ` underlineColorAndroid=\\"transparent\\" value=\\"I inspected freshie\\" /> - + diff --git a/src/__tests__/__snapshots__/shallow.test.js.snap b/src/__tests__/__snapshots__/shallow.test.js.snap deleted file mode 100644 index ac70b9743..000000000 --- a/src/__tests__/__snapshots__/shallow.test.js.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`shallow rendering React Test Instance 1`] = ` - - Press me - -`; - -exports[`shallow rendering React elements 1`] = ` - - - Press me - - -`; diff --git a/src/__tests__/render.test.js b/src/__tests__/render.test.js index 045ae88c4..617cd105b 100644 --- a/src/__tests__/render.test.js +++ b/src/__tests__/render.test.js @@ -17,7 +17,7 @@ const PLACEHOLDER_CHEF = 'Who inspected freshness?'; const INPUT_FRESHNESS = 'Custom Freshie'; const INPUT_CHEF = 'I inspected freshie'; -class Button extends React.Component { +class MyButton extends React.Component { render() { return ( @@ -68,9 +68,9 @@ class Banana extends React.Component { placeholder={PLACEHOLDER_CHEF} value={INPUT_CHEF} /> - + First Text Second Text {test} @@ -109,51 +109,18 @@ test('getAllByTestId, queryAllByTestId', () => { expect(queryAllByTestId('nonExistentTestId')).toHaveLength(0); }); -test('getByName, queryByName', () => { - const { getByText, getByName, queryByName } = render(); - const bananaFresh = getByText('not fresh'); - const button = getByName('Button'); - - button.props.onPress(); - - expect(bananaFresh.props.children).toBe('fresh'); - - const sameButton = getByName(Button); - sameButton.props.onPress(); - - expect(bananaFresh.props.children).toBe('not fresh'); - expect(() => getByName('InExistent')).toThrow('No instances found'); - expect(() => getByName(Text)).toThrow('Expected 1 but found 6'); - - expect(queryByName('Button')).toBe(button); - expect(queryByName('InExistent')).toBeNull(); -}); - -test('getAllByName, queryAllByName', () => { - const { getAllByName, queryAllByName } = render(); - const [text, status, button] = getAllByName('Text'); - - expect(text.props.children).toBe('Is the banana fresh?'); - expect(status.props.children).toBe('not fresh'); - expect(button.props.children).toBe('Change freshness!'); - expect(() => getAllByName('InExistent')).toThrow('No instances found'); - - expect(queryAllByName('Text')[1]).toBe(status); - expect(queryAllByName('InExistent')).toHaveLength(0); -}); - -test('getAllByType, queryAllByType', () => { - const { getAllByType, queryAllByType } = render(); - const [text, status, button] = getAllByType(Text); +test('UNSAFE_getAllByType, UNSAFE_queryAllByType', () => { + const { UNSAFE_getAllByType, UNSAFE_queryAllByType } = render(); + const [text, status, button] = UNSAFE_getAllByType(Text); const InExistent = () => null; expect(text.props.children).toBe('Is the banana fresh?'); expect(status.props.children).toBe('not fresh'); expect(button.props.children).toBe('Change freshness!'); - expect(() => getAllByType(InExistent)).toThrow('No instances found'); + expect(() => UNSAFE_getAllByType(InExistent)).toThrow('No instances found'); - expect(queryAllByType(Text)[1]).toBe(status); - expect(queryAllByType(InExistent)).toHaveLength(0); + expect(UNSAFE_queryAllByType(Text)[1]).toBe(status); + expect(UNSAFE_queryAllByType(InExistent)).toHaveLength(0); }); test('getByText, queryByText', () => { @@ -267,38 +234,37 @@ test('getAllByDisplayValue, queryAllByDisplayValue', () => { expect(queryAllByDisplayValue('no value')).toHaveLength(0); }); -test('getByProps, queryByProps', () => { - const { getByProps, queryByProps } = render(); - const primaryType = getByProps({ type: 'primary' }); +test('UNSAFE_getByProps, UNSAFE_queryByProps', () => { + const { UNSAFE_getByProps, UNSAFE_queryByProps } = render(); + const primaryType = UNSAFE_getByProps({ type: 'primary' }); expect(primaryType.props.children).toBe('Change freshness!'); - expect(() => getByProps({ type: 'inexistent' })).toThrow( + expect(() => UNSAFE_getByProps({ type: 'inexistent' })).toThrow( 'No instances found' ); - expect(queryByProps({ type: 'primary' })).toBe(primaryType); - expect(queryByProps({ type: 'inexistent' })).toBeNull(); + expect(UNSAFE_queryByProps({ type: 'primary' })).toBe(primaryType); + expect(UNSAFE_queryByProps({ type: 'inexistent' })).toBeNull(); }); -test('getAllByProp, queryAllByProps', () => { - const { getAllByProps, queryAllByProps } = render(); - const primaryTypes = getAllByProps({ type: 'primary' }); +test('UNSAFE_getAllByProp, UNSAFE_queryAllByProps', () => { + const { UNSAFE_getAllByProps, UNSAFE_queryAllByProps } = render(); + const primaryTypes = UNSAFE_getAllByProps({ type: 'primary' }); expect(primaryTypes).toHaveLength(1); - expect(() => getAllByProps({ type: 'inexistent' })).toThrow( + expect(() => UNSAFE_getAllByProps({ type: 'inexistent' })).toThrow( 'No instances found' ); - expect(queryAllByProps({ type: 'primary' })).toEqual(primaryTypes); - expect(queryAllByProps({ type: 'inexistent' })).toHaveLength(0); + expect(UNSAFE_queryAllByProps({ type: 'primary' })).toEqual(primaryTypes); + expect(UNSAFE_queryAllByProps({ type: 'inexistent' })).toHaveLength(0); }); test('update', () => { const fn = jest.fn(); - const { getByName, update, rerender } = render(); - const button = getByName('Button'); + const { getByText, update, rerender } = render(); - button.props.onPress(); + fireEvent.press(getByText('Change freshness!')); update(); rerender(); @@ -314,7 +280,7 @@ test('unmount', () => { }); test('toJSON', () => { - const { toJSON } = render(); + const { toJSON } = render(press me); expect(toJSON()).toMatchSnapshot(); }); @@ -345,9 +311,9 @@ test('debug', () => { test('debug changing component', () => { jest.spyOn(console, 'log').mockImplementation((x) => x); - const { getByProps, debug } = render(); + const { UNSAFE_getByProps, debug } = render(); - fireEvent.press(getByProps({ type: 'primary' })); + fireEvent.press(UNSAFE_getByProps({ type: 'primary' })); debug(); diff --git a/src/__tests__/shallow.test.js b/src/__tests__/shallow.test.js deleted file mode 100644 index a31af6c12..000000000 --- a/src/__tests__/shallow.test.js +++ /dev/null @@ -1,27 +0,0 @@ -// @flow -import React from 'react'; -import { View, Text } from 'react-native'; -import { shallow, render } from '..'; - -type Props = {| - +dummyID?: string, -|}; - -const TextPress = ({ dummyID }: Props) => ( - - Press me - -); - -test('shallow rendering React elements', () => { - const { output } = shallow(); - - expect(output).toMatchSnapshot(); -}); - -test('shallow rendering React Test Instance', () => { - const { getByText } = render(); - const { output } = shallow(getByText('Press me')); - - expect(output).toMatchSnapshot(); -}); diff --git a/src/__tests__/waitFor.test.js b/src/__tests__/waitFor.test.js index b05f1fe93..891c8457c 100644 --- a/src/__tests__/waitFor.test.js +++ b/src/__tests__/waitFor.test.js @@ -36,9 +36,9 @@ class BananaContainer extends React.Component<{}, any> { } test('waits for element until it stops throwing', async () => { - const { getByText, getByName, queryByText } = render(); + const { getByText, queryByText } = render(); - fireEvent.press(getByName('TouchableOpacity')); + fireEvent.press(getByText('Change freshness!')); expect(queryByText('Fresh')).toBeNull(); @@ -48,9 +48,9 @@ test('waits for element until it stops throwing', async () => { }); test('waits for element until timeout is met', async () => { - const { getByText, getByName } = render(); + const { getByText } = render(); - fireEvent.press(getByName('TouchableOpacity')); + fireEvent.press(getByText('Change freshness!')); await expect( waitFor(() => getByText('Fresh'), { timeout: 100 }) diff --git a/src/helpers/errors.js b/src/helpers/errors.js index edf108cbc..17a31de83 100644 --- a/src/helpers/errors.js +++ b/src/helpers/errors.js @@ -24,22 +24,7 @@ export const createQueryByError = (error: Error, callsite: Function) => { throw new ErrorWithStack(error.message, callsite); }; -const warned = { - getByName: false, - getAllByName: false, - queryByName: false, - queryAllByName: false, - - getByProps: false, - getAllByProps: false, - queryByProps: false, - queryAllByProps: false, - - getByType: false, - getAllByType: false, - queryByType: false, - queryAllByType: false, -}; +const warned = {}; export function printDeprecationWarning(functionName: string) { if (warned[functionName]) { @@ -67,3 +52,12 @@ export function printUnsafeWarning(functionName: string) { warned[functionName] = true; } + +export function throwRemovedFunctionError( + functionName: string, + docsRef: string +) { + throw new Error( + `${functionName} has been removed in version 2.0.\n\nPlease consult: https://callstack.github.io/react-native-testing-library/docs/${docsRef}` + ); +} diff --git a/src/helpers/getByAPI.js b/src/helpers/getByAPI.js index cc6079607..ea2342655 100644 --- a/src/helpers/getByAPI.js +++ b/src/helpers/getByAPI.js @@ -5,16 +5,11 @@ import { ErrorWithStack, createLibraryNotSupportedError, prepareErrorMessage, - printDeprecationWarning, - printUnsafeWarning, + throwRemovedFunctionError, } from './errors'; const filterNodeByType = (node, type) => node.type === type; -const filterNodeByName = (node, name) => - typeof node.type !== 'string' && - (node.type.displayName === name || node.type.name === name); - const getNodeByText = (node, text) => { try { // eslint-disable-next-line @@ -85,28 +80,6 @@ const getTextInputNodeByDisplayValue = (node, value) => { } }; -export const getByName = (instance: ReactTestInstance, warnFn?: Function) => - function getByNameFn(name: string | React.ComponentType) { - warnFn && warnFn('getByName'); - try { - return typeof name === 'string' - ? instance.find((node) => filterNodeByName(node, name)) - : instance.findByType(name); - } catch (error) { - throw new ErrorWithStack(prepareErrorMessage(error), getByNameFn); - } - }; - -export const getByType = (instance: ReactTestInstance, warnFn?: Function) => - function getByTypeFn(type: React.ComponentType) { - warnFn && warnFn('getByType'); - try { - return instance.findByType(type); - } catch (error) { - throw new ErrorWithStack(prepareErrorMessage(error), getByTypeFn); - } - }; - export const getByText = (instance: ReactTestInstance) => function getByTextFn(text: string | RegExp) { try { @@ -138,16 +111,6 @@ export const getByDisplayValue = (instance: ReactTestInstance) => } }; -export const getByProps = (instance: ReactTestInstance, warnFn?: Function) => - function getByPropsFn(props: { [propName: string]: any }) { - warnFn && warnFn('getByProps'); - try { - return instance.findByProps(props); - } catch (error) { - throw new ErrorWithStack(prepareErrorMessage(error), getByPropsFn); - } - }; - export const getByTestId = (instance: ReactTestInstance) => function getByTestIdFn(testID: string) { try { @@ -167,29 +130,6 @@ export const getByTestId = (instance: ReactTestInstance) => } }; -export const getAllByName = (instance: ReactTestInstance, warnFn?: Function) => - function getAllByNameFn(name: string | React.ComponentType) { - warnFn && warnFn('getAllByName'); - const results = - typeof name === 'string' - ? instance.findAll((node) => filterNodeByName(node, name)) - : instance.findAllByType(name); - if (results.length === 0) { - throw new ErrorWithStack('No instances found', getAllByNameFn); - } - return results; - }; - -export const getAllByType = (instance: ReactTestInstance, warnFn?: Function) => - function getAllByTypeFn(type: React.ComponentType) { - warnFn && warnFn('getAllByType'); - const results = instance.findAllByType(type); - if (results.length === 0) { - throw new ErrorWithStack('No instances found', getAllByTypeFn); - } - return results; - }; - export const getAllByText = (instance: ReactTestInstance) => function getAllByTextFn(text: string | RegExp) { const results = instance.findAll((node) => getNodeByText(node, text)); @@ -230,19 +170,6 @@ export const getAllByDisplayValue = (instance: ReactTestInstance) => return results; }; -export const getAllByProps = (instance: ReactTestInstance, warnFn?: Function) => - function getAllByPropsFn(props: { [propName: string]: any }) { - warnFn && warnFn('getAllByProps'); - const results = instance.findAllByProps(props); - if (results.length === 0) { - throw new ErrorWithStack( - `No instances found with props:\n${prettyFormat(props)}`, - getAllByPropsFn - ); - } - return results; - }; - export const getAllByTestId = (instance: ReactTestInstance) => function getAllByTestIdFn(testID: string): ReactTestInstance[] { const results = instance @@ -258,25 +185,75 @@ export const getAllByTestId = (instance: ReactTestInstance) => return results; }; +export const UNSAFE_getByType = (instance: ReactTestInstance) => + function getByTypeFn(type: React.ComponentType) { + try { + return instance.findByType(type); + } catch (error) { + throw new ErrorWithStack(prepareErrorMessage(error), getByTypeFn); + } + }; + +export const UNSAFE_getByProps = (instance: ReactTestInstance) => + function getByPropsFn(props: { [propName: string]: any }) { + try { + return instance.findByProps(props); + } catch (error) { + throw new ErrorWithStack(prepareErrorMessage(error), getByPropsFn); + } + }; + +export const UNSAFE_getAllByType = (instance: ReactTestInstance) => + function getAllByTypeFn(type: React.ComponentType) { + const results = instance.findAllByType(type); + if (results.length === 0) { + throw new ErrorWithStack('No instances found', getAllByTypeFn); + } + return results; + }; + +export const UNSAFE_getAllByProps = (instance: ReactTestInstance) => + function getAllByPropsFn(props: { [propName: string]: any }) { + const results = instance.findAllByProps(props); + if (results.length === 0) { + throw new ErrorWithStack( + `No instances found with props:\n${prettyFormat(props)}`, + getAllByPropsFn + ); + } + return results; + }; + export const getByAPI = (instance: ReactTestInstance) => ({ - getByTestId: getByTestId(instance), - getByName: getByName(instance, printDeprecationWarning), - getByType: getByType(instance, printUnsafeWarning), getByText: getByText(instance), getByPlaceholder: getByPlaceholder(instance), getByDisplayValue: getByDisplayValue(instance), - getByProps: getByProps(instance, printUnsafeWarning), - getAllByTestId: getAllByTestId(instance), - getAllByName: getAllByName(instance, printDeprecationWarning), - getAllByType: getAllByType(instance, printUnsafeWarning), + getByTestId: getByTestId(instance), getAllByText: getAllByText(instance), getAllByPlaceholder: getAllByPlaceholder(instance), getAllByDisplayValue: getAllByDisplayValue(instance), - getAllByProps: getAllByProps(instance, printUnsafeWarning), + getAllByTestId: getAllByTestId(instance), + + // Unsafe + UNSAFE_getByType: UNSAFE_getByType(instance), + UNSAFE_getAllByType: UNSAFE_getAllByType(instance), + UNSAFE_getByProps: UNSAFE_getByProps(instance), + UNSAFE_getAllByProps: UNSAFE_getAllByProps(instance), - // Unsafe aliases - UNSAFE_getByType: getByType(instance), - UNSAFE_getAllByType: getAllByType(instance), - UNSAFE_getByProps: getByProps(instance), - UNSAFE_getAllByProps: getAllByProps(instance), + // Removed + getByName: () => + throwRemovedFunctionError('getByName', 'migration-v2#removed-functions'), + getAllByName: () => + throwRemovedFunctionError('getAllByName', 'migration-v2#removed-functions'), + getByType: () => + throwRemovedFunctionError('getByType', 'migration-v2#removed-functions'), + getAllByType: () => + throwRemovedFunctionError('getAllByType', 'migration-v2#removed-functions'), + getByProps: () => + throwRemovedFunctionError('getByProps', 'migration-v2#removed-functions'), + getAllByProps: () => + throwRemovedFunctionError( + 'getAllByProps', + 'migration-v2#removed-functions' + ), }); diff --git a/src/helpers/queryByAPI.js b/src/helpers/queryByAPI.js index e2c06b0a0..5566e3e4d 100644 --- a/src/helpers/queryByAPI.js +++ b/src/helpers/queryByAPI.js @@ -2,45 +2,19 @@ import * as React from 'react'; import { getByTestId, - getByName, - getByType, getByText, getByPlaceholder, getByDisplayValue, - getByProps, getAllByTestId, - getAllByName, - getAllByType, getAllByText, getAllByPlaceholder, getAllByDisplayValue, - getAllByProps, + UNSAFE_getByType, + UNSAFE_getByProps, + UNSAFE_getAllByType, + UNSAFE_getAllByProps, } from './getByAPI'; -import { - createQueryByError, - printDeprecationWarning, - printUnsafeWarning, -} from './errors'; - -export const queryByName = (instance: ReactTestInstance, warnFn?: Function) => - function queryByNameFn(name: string | React.ComponentType) { - warnFn && warnFn('queryByName'); - try { - return getByName(instance)(name); - } catch (error) { - return createQueryByError(error, queryByNameFn); - } - }; - -export const queryByType = (instance: ReactTestInstance, warnFn?: Function) => - function queryByTypeFn(type: React.ComponentType) { - warnFn && warnFn('queryByType'); - try { - return getByType(instance)(type); - } catch (error) { - return createQueryByError(error, queryByTypeFn); - } - }; +import { createQueryByError, throwRemovedFunctionError } from './errors'; export const queryByText = (instance: ReactTestInstance) => function queryByTextFn(text: string | RegExp) { @@ -69,16 +43,6 @@ export const queryByDisplayValue = (instance: ReactTestInstance) => } }; -export const queryByProps = (instance: ReactTestInstance, warnFn?: Function) => - function queryByPropsFn(props: { [propName: string]: any }) { - warnFn && warnFn('queryByProps'); - try { - return getByProps(instance)(props); - } catch (error) { - return createQueryByError(error, queryByPropsFn); - } - }; - export const queryByTestId = (instance: ReactTestInstance) => function queryByTestIdFn(testID: string) { try { @@ -88,30 +52,6 @@ export const queryByTestId = (instance: ReactTestInstance) => } }; -export const queryAllByName = ( - instance: ReactTestInstance, - warnFn?: Function -) => (name: string | React.ComponentType) => { - warnFn && warnFn('queryAllByName'); - try { - return getAllByName(instance)(name); - } catch (error) { - return []; - } -}; - -export const queryAllByType = ( - instance: ReactTestInstance, - warnFn?: Function -) => (type: React.ComponentType) => { - warnFn && warnFn('queryAllByType'); - try { - return getAllByType(instance)(type); - } catch (error) { - return []; - } -}; - export const queryAllByText = (instance: ReactTestInstance) => ( text: string | RegExp ) => { @@ -142,23 +82,49 @@ export const queryAllByDisplayValue = (instance: ReactTestInstance) => ( } }; -export const queryAllByProps = ( - instance: ReactTestInstance, - warnFn?: Function -) => (props: { [propName: string]: any }) => { - warnFn && warnFn('queryAllByProps'); +export const queryAllByTestId = (instance: ReactTestInstance) => ( + testID: string +) => { try { - return getAllByProps(instance)(props); + return getAllByTestId(instance)(testID); } catch (error) { return []; } }; -export const queryAllByTestId = (instance: ReactTestInstance) => ( - testID: string +export const UNSAFE_queryByType = (instance: ReactTestInstance) => + function queryByTypeFn(type: React.ComponentType) { + try { + return UNSAFE_getByType(instance)(type); + } catch (error) { + return createQueryByError(error, queryByTypeFn); + } + }; + +export const UNSAFE_queryByProps = (instance: ReactTestInstance) => + function queryByPropsFn(props: { [propName: string]: any }) { + try { + return UNSAFE_getByProps(instance)(props); + } catch (error) { + return createQueryByError(error, queryByPropsFn); + } + }; + +export const UNSAFE_queryAllByType = (instance: ReactTestInstance) => ( + type: React.ComponentType ) => { try { - return getAllByTestId(instance)(testID); + return UNSAFE_getAllByType(instance)(type); + } catch (error) { + return []; + } +}; + +export const UNSAFE_queryAllByProps = (instance: ReactTestInstance) => (props: { + [propName: string]: any, +}) => { + try { + return UNSAFE_getAllByProps(instance)(props); } catch (error) { return []; } @@ -166,23 +132,40 @@ export const queryAllByTestId = (instance: ReactTestInstance) => ( export const queryByAPI = (instance: ReactTestInstance) => ({ queryByTestId: queryByTestId(instance), - queryByName: queryByName(instance, printDeprecationWarning), - queryByType: queryByType(instance, printUnsafeWarning), queryByText: queryByText(instance), queryByPlaceholder: queryByPlaceholder(instance), queryByDisplayValue: queryByDisplayValue(instance), - queryByProps: queryByProps(instance, printUnsafeWarning), queryAllByTestId: queryAllByTestId(instance), - queryAllByName: queryAllByName(instance, printDeprecationWarning), - queryAllByType: queryAllByType(instance, printUnsafeWarning), queryAllByText: queryAllByText(instance), queryAllByPlaceholder: queryAllByPlaceholder(instance), queryAllByDisplayValue: queryAllByDisplayValue(instance), - queryAllByProps: queryAllByProps(instance, printUnsafeWarning), - // Unsafe aliases - UNSAFE_queryByType: queryByType(instance), - UNSAFE_queryAllByType: queryAllByType(instance), - UNSAFE_queryByProps: queryByProps(instance), - UNSAFE_queryAllByProps: queryAllByProps(instance), + // Unsafe + UNSAFE_queryByType: UNSAFE_queryByType(instance), + UNSAFE_queryAllByType: UNSAFE_queryAllByType(instance), + UNSAFE_queryByProps: UNSAFE_queryByProps(instance), + UNSAFE_queryAllByProps: UNSAFE_queryAllByProps(instance), + + // Removed + queryByName: () => + throwRemovedFunctionError('queryByName', 'migration-v2#removed-functions'), + queryAllByName: () => + throwRemovedFunctionError( + 'queryAllByName', + 'migration-v2#removed-functions' + ), + queryByType: () => + throwRemovedFunctionError('queryByType', 'migration-v2#removed-functions'), + queryAllByType: () => + throwRemovedFunctionError( + 'queryAllByType', + 'migration-v2#removed-functions' + ), + queryByProps: () => + throwRemovedFunctionError('queryByProps', 'migration-v2#removed-functions'), + queryAllByProps: () => + throwRemovedFunctionError( + 'queryAllByProps', + 'migration-v2#removed-functions' + ), }); diff --git a/src/index.js b/src/index.js index 8500b3b26..534119714 100644 --- a/src/index.js +++ b/src/index.js @@ -5,7 +5,7 @@ import fireEvent from './fireEvent'; import flushMicrotasksQueue from './flushMicrotasksQueue'; import render from './render'; import shallow from './shallow'; -import waitFor from './waitFor'; +import waitFor, { waitForElement } from './waitFor'; import within from './within'; export { act }; @@ -14,5 +14,5 @@ export { fireEvent }; export { flushMicrotasksQueue }; export { render }; export { shallow }; -export { waitFor }; +export { waitFor, waitForElement }; export { within }; diff --git a/src/shallow.js b/src/shallow.js index 576ac913a..828f4dd61 100644 --- a/src/shallow.js +++ b/src/shallow.js @@ -1,7 +1,7 @@ // @flow import * as React from 'react'; import ShallowRenderer from 'react-test-renderer/shallow'; // eslint-disable-line import/no-extraneous-dependencies -import { printDeprecationWarning } from './helpers/errors'; +import { throwRemovedFunctionError } from './helpers/errors'; /** * Renders test component shallowly using react-test-renderer/shallow @@ -18,10 +18,9 @@ export function shallowInternal( }; } -export default function shallow( - instance: ReactTestInstance | React.Element -) { - printDeprecationWarning('shallow'); - - return shallowInternal(instance); +export default function shallow(_: ReactTestInstance | React.Element) { + throwRemovedFunctionError( + 'shallow', + 'migration-v2#removed-global-shallow-function' + ); } diff --git a/src/waitFor.js b/src/waitFor.js index e947f8631..5275643e5 100644 --- a/src/waitFor.js +++ b/src/waitFor.js @@ -1,5 +1,7 @@ // @flow +import { throwRemovedFunctionError } from './helpers/errors'; + const DEFAULT_TIMEOUT = 4500; const DEFAULT_INTERVAL = 50; @@ -35,3 +37,16 @@ export default function waitFor( setTimeout(runExpectation, 0); }); } + +export function waitForElement( + expectation: () => T, + _timeout: number = 4500, + _interval: number = 50 +): Promise { + throwRemovedFunctionError( + 'waitForElement', + 'migration-v2#waitfor-api-changes' + ); + + return Promise.reject(); +} diff --git a/typings/__tests__/index.test.tsx b/typings/__tests__/index.test.tsx index 2417ae8eb..9981ded7e 100644 --- a/typings/__tests__/index.test.tsx +++ b/typings/__tests__/index.test.tsx @@ -15,9 +15,9 @@ interface HasRequiredProp { requiredProp: string; } -const View = props => props.children; -const Text = props => props.children; -const TextInput = props => props.children; +const View = (props) => props.children; +const Text = (props) => props.children; +const TextInput = (props) => props.children; const ElementWithRequiredProps = (props: HasRequiredProp) => ( {props.requiredProp} ); @@ -32,10 +32,8 @@ const TestComponent = () => ( const tree = render(); // getByAPI tests -const getByNameString: ReactTestInstance = tree.getByName('View'); -const getByNameContructor: ReactTestInstance = tree.getByName(View); -const getByType: ReactTestInstance = tree.getByType(View); -const getByTypeWithRequiredProps: ReactTestInstance = tree.getByType( +const getByType: ReactTestInstance = tree.UNSAFE_getByType(View); +const getByTypeWithRequiredProps: ReactTestInstance = tree.UNSAFE_getByType( ElementWithRequiredProps ); const getByTextString: ReactTestInstance = tree.getByText(''); @@ -52,30 +50,24 @@ const getByDisplayValueString: ReactTestInstance = tree.getByDisplayValue( const getByDisplayValueRegExp: ReactTestInstance = tree.getByDisplayValue( /value/g ); -const getByProps: ReactTestInstance = tree.getByProps({ value: 2 }); +const getByProps: ReactTestInstance = tree.UNSAFE_getByProps({ value: 2 }); const getByTestId: ReactTestInstance = tree.getByTestId('test-id'); const getAllByTestId: ReactTestInstance[] = tree.getAllByTestId('test-id'); -const getAllByNameString: Array = tree.getAllByName('View'); -const getAllByNameConstructor: Array = tree.getAllByName( - View +const getAllByType: Array = tree.UNSAFE_getAllByType(View); +const getAllByTypeWithRequiredProps: Array = tree.UNSAFE_getAllByType( + ElementWithRequiredProps ); -const getAllByType: Array = tree.getAllByType(View); -const getAllByTypeWithRequiredProps: Array< - ReactTestInstance -> = tree.getAllByType(ElementWithRequiredProps); const getAllByTextString: Array = tree.getAllByText( '' ); const getAllByTextRegExp: Array = tree.getAllByText(/Text/g); -const getAllByProps: Array = tree.getAllByProps({ +const getAllByProps: Array = tree.UNSAFE_getAllByProps({ value: 2, }); // queuryByAPI tests -const queryByNameString: ReactTestInstance | null = tree.queryByName('View'); -const queryByNameConstructor: ReactTestInstance | null = tree.queryByName(View); -const queryByType: ReactTestInstance | null = tree.queryByType(View); -const queryByTypeWithRequiredProps: ReactTestInstance | null = tree.queryByType( +const queryByType: ReactTestInstance | null = tree.UNSAFE_queryByType(View); +const queryByTypeWithRequiredProps: ReactTestInstance | null = tree.UNSAFE_queryByType( ElementWithRequiredProps ); const queryByTextString: ReactTestInstance | null = tree.queryByText('View'); @@ -92,33 +84,31 @@ const queryByDisplayValueString: ReactTestInstance | null = tree.queryByDisplayV const queryByDisplayValueRegExp: ReactTestInstance | null = tree.queryByDisplayValue( /value/g ); -const queryByProps: ReactTestInstance | null = tree.queryByProps({ value: 2 }); +const queryByProps: ReactTestInstance | null = tree.UNSAFE_queryByProps({ + value: 2, +}); const queryByTestId: ReactTestInstance | null = tree.queryByTestId('test-id'); const queryAllByTestId: ReactTestInstance[] | null = tree.queryAllByTestId( 'test-id' ); -const queryAllByNameString: Array = tree.queryAllByName( - 'View' -); -const queryAllByNameConstructor: Array = tree.queryAllByName( +const queryAllByType: Array = tree.UNSAFE_queryAllByType( View ); -const queryAllByType: Array = tree.queryAllByType(View); -const queryAllByTypeWithRequiredProps: Array< - ReactTestInstance -> = tree.queryAllByType(ElementWithRequiredProps); +const queryAllByTypeWithRequiredProps: Array = tree.UNSAFE_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 +); // findBy API tests const findBy: Promise[] = [ @@ -200,33 +190,45 @@ const queryAllByA11yRole: Array = tree.queryAllByA11yRole( ); 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 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 debugFn = tree.debug(); const debugFnWithMessage = tree.debug('my message'); @@ -236,12 +238,12 @@ tree.rerender(); tree.unmount(); // fireEvent API tests -fireEvent(getByNameString, 'press'); -fireEvent(getByNameString, 'press', 'data'); -fireEvent(getByNameString, 'press', 'param1', 'param2'); -fireEvent.press(getByNameString); -fireEvent.changeText(getByNameString, 'string'); -fireEvent.scroll(getByNameString, 'eventData'); +fireEvent(getByA11yLabel, 'press'); +fireEvent(getByA11yLabel, 'press', 'data'); +fireEvent(getByA11yLabel, 'press', 'param1', 'param2'); +fireEvent.press(getByA11yLabel); +fireEvent.changeText(getByA11yLabel, 'string'); +fireEvent.scroll(getByA11yLabel, 'eventData'); // shallow API const shallowTree: { output: React.ReactElement } = shallow( @@ -251,10 +253,10 @@ const shallowTree: { output: React.ReactElement } = shallow( const waitForFlush: Promise = flushMicrotasksQueue(); const waitBy: Promise = waitFor(() => - tree.getByName('View') + tree.getByA11yLabel('label') ); const waitByAll: Promise = waitFor( - () => tree.getAllByName('View'), + () => tree.getAllByA11yLabel('label'), { timeout: 1000, interval: 50 } ); diff --git a/typings/index.d.ts b/typings/index.d.ts index 4fd91e76d..d38f9c0c6 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1,5 +1,9 @@ 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; @@ -10,48 +14,62 @@ type FindReturn = Promise; type FindAllReturn = Promise; interface GetByAPI { - getByName: (name: React.ReactType | string) => ReactTestInstance; - getByType:

(type: React.ComponentType

) => ReactTestInstance; getByText: (text: string | RegExp) => ReactTestInstance; getByPlaceholder: (placeholder: string | RegExp) => ReactTestInstance; getByDisplayValue: (value: string | RegExp) => ReactTestInstance; - getByProps: (props: Record) => ReactTestInstance; getByTestId: (testID: string) => ReactTestInstance; getAllByTestId: (testID: string) => Array; - getAllByName: (name: React.ReactType | string) => Array; - getAllByType:

(type: React.ComponentType

) => Array; getAllByText: (text: string | RegExp) => Array; getAllByPlaceholder: ( placeholder: string | RegExp ) => Array; 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; + + // Removed + /** + * @deprecated This function has been removed. Please use other queries. + */ + getByName: (name: React.ReactType | string) => ReactTestInstance; + /** + * @deprecated This function has been renamed to `UNSAFE_getByType`. + */ + getByType:

(type: React.ComponentType

) => ReactTestInstance; + /** + * @deprecated This function has been renamed to `UNSAFE_getByProps`. + */ + getByProps: (props: Record) => ReactTestInstance; + /** + * @deprecated This function has been removed. Please use other queries. + */ + getAllByName: (name: React.ReactType | string) => Array; + /** + * @deprecated This function has been renamed to `UNSAFE_getAllByType`. + */ + getAllByType:

(type: React.ComponentType

) => Array; + /** + * @deprecated This function has been renamed to `UNSAFE_getAllByProps`. + */ + getAllByProps: (props: Record) => Array; } interface QueryByAPI { - queryByName: (name: React.ReactType | string) => ReactTestInstance | null; - queryByType:

(type: React.ComponentType

) => ReactTestInstance | null; queryByText: (name: string | RegExp) => ReactTestInstance | null; queryByPlaceholder: ( placeholder: string | RegExp ) => ReactTestInstance | null; queryByDisplayValue: (value: string | RegExp) => ReactTestInstance | null; - queryByProps: (props: Record) => ReactTestInstance | null; queryByTestId: (testID: string) => ReactTestInstance | null; queryAllByTestId: (testID: string) => Array | null; - queryAllByName: ( - name: React.ReactType | string - ) => Array | []; - queryAllByType:

( - type: React.ComponentType

- ) => Array | []; queryAllByText: (text: string | RegExp) => Array | []; queryAllByPlaceholder: ( placeholder: string | RegExp @@ -59,20 +77,50 @@ interface QueryByAPI { queryAllByDisplayValue: ( value: string | RegExp ) => Array | []; - queryAllByProps: ( - props: Record - ) => 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 { - timeout: number; - interval: number; + // Removed + /** + * @deprecated This function has been removed. Please use other queries. + */ + queryByName: (name: React.ReactType | string) => ReactTestInstance | null; + /** + * @deprecated This function has been renamed to `UNSAFE_queryByType`. + */ + queryByType:

(type: React.ComponentType

) => ReactTestInstance | null; + /** + * @deprecated This function has been renamed to `UNSAFE_queryByProps`. + */ + queryByProps: (props: Record) => ReactTestInstance | null; + /** + * @deprecated This function has been removed. Please use other queries. + */ + queryAllByName: ( + name: React.ReactType | string + ) => Array | []; + /** + * @deprecated This function has been renamed to `UNSAFE_queryAllByType`. + */ + queryAllByType:

( + type: React.ComponentType

+ ) => Array | []; + /** + * @deprecated This function has been renamed to `UNSAFE_queryAllByProps`. + */ + queryAllByProps: ( + props: Record + ) => Array | []; } interface FindByAPI { @@ -109,18 +157,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 @@ -131,10 +179,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 @@ -145,10 +193,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 @@ -159,16 +207,24 @@ 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 @@ -179,10 +235,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 @@ -238,12 +294,22 @@ export declare const render: ( component: React.ReactElement, options?: RenderOptions ) => RenderAPI; -export declare const shallow:

( - instance: ReactTestInstance | React.ReactElement

-) => { output: React.ReactElement

}; + export declare const flushMicrotasksQueue: () => Promise; export declare const cleanup: () => void; export declare const fireEvent: FireEventAPI; export declare const waitFor: WaitForFunction; export declare const act: (callback: () => void) => Thenable; export declare const within: (instance: ReactTestInstance) => Queries; + +/** + * @deprecated This function has been removed. Please use `waitFor` function. + */ +export declare const waitForElement: WaitForFunction; + +/** + * @deprecated This function has been removed. + */ +export declare const shallow:

( + instance: ReactTestInstance | React.ReactElement

+) => { output: React.ReactElement

}; diff --git a/website/docs/Migration20.md b/website/docs/Migration20.md index 088fa291d..cdf4ecd85 100644 --- a/website/docs/Migration20.md +++ b/website/docs/Migration20.md @@ -1,5 +1,5 @@ --- -id: migration20 +id: migration-v2 title: Migration to 2.0 --- @@ -41,7 +41,44 @@ Please note that in many cases `waitFor` call can be replaced by proper use of ` ## Removed global `debug` function -Global debug function has been removed in favor of `debug()` method returned from `render()` function. +Global `debug()` function has been removed in favor of `debug()` method returned from `render()` function. + +## Removed global `shallow` function + +Global `shallow()` functions which has been previously deprecated has been removed. + +Shallow rendering React component is usually not a good idea, so we decided to remove the API. However, if you find it useful or need to support legacy tests, feel free to implement it yourself. Here's a sample implementation: + +```js +import ShallowRenderer from 'react-test-renderer/shallow'; + +export function shallow(instance: ReactTestInstance | React.Element) { + const renderer = new ShallowRenderer(); + renderer.render(React.createElement(instance.type, instance.props)); + + return { output: renderer.getRenderOutput() }; +} +``` + +## Removed functions + +Following query functions have been removed after being deprecated for more than a year now: + +- `getByName` +- `getAllByName` +- `queryByName` +- `queryAllByName` + +The `*ByType` and `*ByProps` queries has been prefixed with `UNSAFE_`. You can safely rename them using global search/replace in your project: + +- `getByType` -> `UNSAFE_getByType` +- `getAllByType` -> `UNSAFE_getAllByType` +- `queryByType` -> `UNSAFE_queryByType` +- `queryAllByType` -> `UNSAFE_queryAllByType` +- `getByProps` -> `UNSAFE_getByProps` +- `getAllByProps` -> `UNSAFE_getAllByProps` +- `queryByProps` -> `UNSAFE_queryByProps` +- `queryAllByProps` -> `UNSAFE_queryAllByProps` ## Some `byTestId` queries behavior changes diff --git a/website/sidebars.js b/website/sidebars.js index d3c764e26..1d5e0411a 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -2,7 +2,7 @@ module.exports = { docs: { Introduction: ['getting-started'], 'API Reference': ['api', 'api-queries'], - Guides: ['migration20'], + Guides: ['migration-v2'], Examples: ['react-navigation', 'redux-integration'], }, };