2018-10-06 23:42:52 +02:00
|
|
|
// @flow
|
|
|
|
|
import * as React from 'react';
|
2018-11-17 19:13:44 +01:00
|
|
|
import prettyFormat from 'pretty-format';
|
2018-11-19 15:16:33 +01:00
|
|
|
import {
|
|
|
|
|
ErrorWithStack,
|
|
|
|
|
createLibraryNotSupportedError,
|
2019-05-28 20:47:06 +02:00
|
|
|
prepareErrorMessage,
|
2020-03-18 10:30:41 +01:00
|
|
|
printDeprecationWarning,
|
|
|
|
|
printUnsafeWarning,
|
2018-11-19 15:16:33 +01:00
|
|
|
} from './errors';
|
2018-10-06 23:42:52 +02:00
|
|
|
|
2018-11-17 19:13:44 +01:00
|
|
|
const filterNodeByType = (node, type) => node.type === type;
|
2018-10-06 23:42:52 +02:00
|
|
|
|
2018-11-17 19:13:44 +01:00
|
|
|
const filterNodeByName = (node, name) =>
|
|
|
|
|
typeof node.type !== 'string' &&
|
|
|
|
|
(node.type.displayName === name || node.type.name === name);
|
2018-10-06 23:42:52 +02:00
|
|
|
|
2018-11-17 19:13:44 +01:00
|
|
|
const getNodeByText = (node, text) => {
|
|
|
|
|
try {
|
|
|
|
|
// eslint-disable-next-line
|
2020-05-01 12:54:12 +01:00
|
|
|
const { Text } = require('react-native');
|
2019-06-10 17:30:27 +02:00
|
|
|
const isTextComponent = filterNodeByType(node, Text);
|
2019-03-18 11:25:13 -04:00
|
|
|
if (isTextComponent) {
|
2020-05-01 12:54:12 +01:00
|
|
|
const textChildren = getChildrenAsText(node.props.children);
|
2019-03-18 11:25:13 -04:00
|
|
|
if (textChildren) {
|
|
|
|
|
const textToTest = textChildren.join('');
|
|
|
|
|
return typeof text === 'string'
|
|
|
|
|
? text === textToTest
|
|
|
|
|
: text.test(textToTest);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2018-11-17 19:13:44 +01:00
|
|
|
} catch (error) {
|
|
|
|
|
throw createLibraryNotSupportedError(error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-05-01 12:54:12 +01:00
|
|
|
const getChildrenAsText = children => {
|
|
|
|
|
return React.Children.map(children, child => {
|
|
|
|
|
if (typeof child === 'string') {
|
|
|
|
|
return child;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeof child === 'number') {
|
|
|
|
|
return child.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return '';
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2018-12-22 17:09:28 -05:00
|
|
|
const getTextInputNodeByPlaceholder = (node, placeholder) => {
|
|
|
|
|
try {
|
|
|
|
|
// eslint-disable-next-line
|
|
|
|
|
const { TextInput } = require('react-native');
|
|
|
|
|
return (
|
|
|
|
|
filterNodeByType(node, TextInput) &&
|
|
|
|
|
(typeof placeholder === 'string'
|
|
|
|
|
? placeholder === node.props.placeholder
|
|
|
|
|
: placeholder.test(node.props.placeholder))
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw createLibraryNotSupportedError(error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-10 17:30:27 +02:00
|
|
|
const getTextInputNodeByDisplayValue = (node, value) => {
|
|
|
|
|
try {
|
|
|
|
|
// eslint-disable-next-line
|
|
|
|
|
const { TextInput } = require('react-native');
|
|
|
|
|
return (
|
|
|
|
|
filterNodeByType(node, TextInput) &&
|
|
|
|
|
(typeof value === 'string'
|
|
|
|
|
? value === node.props.value
|
|
|
|
|
: value.test(node.props.value))
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw createLibraryNotSupportedError(error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-03-18 10:30:41 +01:00
|
|
|
export const getByName = (instance: ReactTestInstance, warnFn?: Function) =>
|
2019-12-09 11:43:05 +01:00
|
|
|
function getByNameFn(name: string | React.ComponentType<any>) {
|
2020-03-18 10:30:41 +01:00
|
|
|
warnFn && warnFn('getByName');
|
2018-10-07 17:10:26 +02:00
|
|
|
try {
|
2018-11-17 19:13:44 +01:00
|
|
|
return typeof name === 'string'
|
|
|
|
|
? instance.find(node => filterNodeByName(node, name))
|
|
|
|
|
: instance.findByType(name);
|
2018-10-07 17:10:26 +02:00
|
|
|
} catch (error) {
|
2018-11-17 19:13:44 +01:00
|
|
|
throw new ErrorWithStack(prepareErrorMessage(error), getByNameFn);
|
2018-10-07 17:10:26 +02:00
|
|
|
}
|
|
|
|
|
};
|
2018-10-06 23:42:52 +02:00
|
|
|
|
2020-03-18 10:30:41 +01:00
|
|
|
export const getByType = (instance: ReactTestInstance, warnFn?: Function) =>
|
2019-12-09 11:43:05 +01:00
|
|
|
function getByTypeFn(type: React.ComponentType<any>) {
|
2020-03-18 10:30:41 +01:00
|
|
|
warnFn && warnFn('getByType');
|
2018-11-19 13:44:51 +01:00
|
|
|
try {
|
|
|
|
|
return instance.findByType(type);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw new ErrorWithStack(prepareErrorMessage(error), getByTypeFn);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2018-10-07 17:10:26 +02:00
|
|
|
export const getByText = (instance: ReactTestInstance) =>
|
|
|
|
|
function getByTextFn(text: string | RegExp) {
|
|
|
|
|
try {
|
|
|
|
|
return instance.find(node => getNodeByText(node, text));
|
|
|
|
|
} catch (error) {
|
2018-11-17 19:13:44 +01:00
|
|
|
throw new ErrorWithStack(prepareErrorMessage(error), getByTextFn);
|
2018-10-07 17:10:26 +02:00
|
|
|
}
|
|
|
|
|
};
|
2018-10-06 23:42:52 +02:00
|
|
|
|
2018-12-22 17:09:28 -05:00
|
|
|
export const getByPlaceholder = (instance: ReactTestInstance) =>
|
|
|
|
|
function getByPlaceholderFn(placeholder: string | RegExp) {
|
|
|
|
|
try {
|
|
|
|
|
return instance.find(node =>
|
|
|
|
|
getTextInputNodeByPlaceholder(node, placeholder)
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw new ErrorWithStack(prepareErrorMessage(error), getByPlaceholderFn);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-10 17:30:27 +02:00
|
|
|
export const getByDisplayValue = (instance: ReactTestInstance) =>
|
|
|
|
|
function getByDisplayValueFn(placeholder: string | RegExp) {
|
|
|
|
|
try {
|
|
|
|
|
return instance.find(node =>
|
|
|
|
|
getTextInputNodeByDisplayValue(node, placeholder)
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw new ErrorWithStack(prepareErrorMessage(error), getByDisplayValueFn);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-03-18 10:30:41 +01:00
|
|
|
export const getByProps = (instance: ReactTestInstance, warnFn?: Function) =>
|
2018-10-07 17:10:26 +02:00
|
|
|
function getByPropsFn(props: { [propName: string]: any }) {
|
2020-03-18 10:30:41 +01:00
|
|
|
warnFn && warnFn('getByProps');
|
2018-10-07 17:10:26 +02:00
|
|
|
try {
|
|
|
|
|
return instance.findByProps(props);
|
|
|
|
|
} catch (error) {
|
2018-11-17 19:13:44 +01:00
|
|
|
throw new ErrorWithStack(prepareErrorMessage(error), getByPropsFn);
|
2018-10-07 17:10:26 +02:00
|
|
|
}
|
|
|
|
|
};
|
2018-10-06 23:42:52 +02:00
|
|
|
|
2018-10-07 17:10:26 +02:00
|
|
|
export const getByTestId = (instance: ReactTestInstance) =>
|
|
|
|
|
function getByTestIdFn(testID: string) {
|
|
|
|
|
try {
|
|
|
|
|
return instance.findByProps({ testID });
|
|
|
|
|
} catch (error) {
|
2018-11-17 19:13:44 +01:00
|
|
|
throw new ErrorWithStack(prepareErrorMessage(error), getByTestIdFn);
|
2018-10-07 17:10:26 +02:00
|
|
|
}
|
|
|
|
|
};
|
2018-10-06 23:42:52 +02:00
|
|
|
|
2020-03-18 10:30:41 +01:00
|
|
|
export const getAllByName = (instance: ReactTestInstance, warnFn?: Function) =>
|
2019-12-09 11:43:05 +01:00
|
|
|
function getAllByNameFn(name: string | React.ComponentType<any>) {
|
2020-03-18 10:30:41 +01:00
|
|
|
warnFn && warnFn('getAllByName');
|
2018-11-17 19:13:44 +01:00
|
|
|
const results =
|
|
|
|
|
typeof name === 'string'
|
|
|
|
|
? instance.findAll(node => filterNodeByName(node, name))
|
|
|
|
|
: instance.findAllByType(name);
|
2018-10-07 17:10:26 +02:00
|
|
|
if (results.length === 0) {
|
2018-11-17 19:13:44 +01:00
|
|
|
throw new ErrorWithStack('No instances found', getAllByNameFn);
|
2018-10-07 17:10:26 +02:00
|
|
|
}
|
|
|
|
|
return results;
|
|
|
|
|
};
|
2018-10-06 23:42:52 +02:00
|
|
|
|
2020-03-18 10:30:41 +01:00
|
|
|
export const getAllByType = (instance: ReactTestInstance, warnFn?: Function) =>
|
2019-12-09 11:43:05 +01:00
|
|
|
function getAllByTypeFn(type: React.ComponentType<any>) {
|
2020-03-18 10:30:41 +01:00
|
|
|
warnFn && warnFn('getAllByType');
|
2018-11-19 13:44:51 +01:00
|
|
|
const results = instance.findAllByType(type);
|
|
|
|
|
if (results.length === 0) {
|
|
|
|
|
throw new ErrorWithStack('No instances found', getAllByTypeFn);
|
|
|
|
|
}
|
|
|
|
|
return results;
|
|
|
|
|
};
|
|
|
|
|
|
2018-10-07 17:10:26 +02:00
|
|
|
export const getAllByText = (instance: ReactTestInstance) =>
|
|
|
|
|
function getAllByTextFn(text: string | RegExp) {
|
|
|
|
|
const results = instance.findAll(node => getNodeByText(node, text));
|
|
|
|
|
if (results.length === 0) {
|
2018-11-17 19:13:44 +01:00
|
|
|
throw new ErrorWithStack(
|
|
|
|
|
`No instances found with text: ${String(text)}`,
|
|
|
|
|
getAllByTextFn
|
|
|
|
|
);
|
2018-10-07 17:10:26 +02:00
|
|
|
}
|
|
|
|
|
return results;
|
|
|
|
|
};
|
2018-10-06 23:42:52 +02:00
|
|
|
|
2018-12-22 17:09:28 -05:00
|
|
|
export const getAllByPlaceholder = (instance: ReactTestInstance) =>
|
|
|
|
|
function getAllByPlaceholderFn(placeholder: string | RegExp) {
|
|
|
|
|
const results = instance.findAll(node =>
|
|
|
|
|
getTextInputNodeByPlaceholder(node, placeholder)
|
|
|
|
|
);
|
|
|
|
|
if (results.length === 0) {
|
|
|
|
|
throw new ErrorWithStack(
|
|
|
|
|
`No instances found with placeholder: ${String(placeholder)}`,
|
|
|
|
|
getAllByPlaceholderFn
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return results;
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-10 17:30:27 +02:00
|
|
|
export const getAllByDisplayValue = (instance: ReactTestInstance) =>
|
|
|
|
|
function getAllByDisplayValueFn(value: string | RegExp) {
|
|
|
|
|
const results = instance.findAll(node =>
|
|
|
|
|
getTextInputNodeByDisplayValue(node, value)
|
|
|
|
|
);
|
|
|
|
|
if (results.length === 0) {
|
|
|
|
|
throw new ErrorWithStack(
|
|
|
|
|
`No instances found with display value: ${String(value)}`,
|
|
|
|
|
getAllByDisplayValueFn
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return results;
|
|
|
|
|
};
|
|
|
|
|
|
2020-03-18 10:30:41 +01:00
|
|
|
export const getAllByProps = (instance: ReactTestInstance, warnFn?: Function) =>
|
2018-10-07 17:10:26 +02:00
|
|
|
function getAllByPropsFn(props: { [propName: string]: any }) {
|
2020-03-18 10:30:41 +01:00
|
|
|
warnFn && warnFn('getAllByProps');
|
2018-10-07 17:10:26 +02:00
|
|
|
const results = instance.findAllByProps(props);
|
|
|
|
|
if (results.length === 0) {
|
2018-11-17 19:13:44 +01:00
|
|
|
throw new ErrorWithStack(
|
|
|
|
|
`No instances found with props:\n${prettyFormat(props)}`,
|
|
|
|
|
getAllByPropsFn
|
|
|
|
|
);
|
2018-10-07 17:10:26 +02:00
|
|
|
}
|
|
|
|
|
return results;
|
|
|
|
|
};
|
2018-10-07 10:59:27 +02:00
|
|
|
|
2019-07-03 01:17:32 -07:00
|
|
|
export const getAllByTestId = (instance: ReactTestInstance) =>
|
|
|
|
|
function getAllByTestIdFn(testID: string): ReactTestInstance[] {
|
|
|
|
|
const results = instance
|
|
|
|
|
.findAllByProps({ testID })
|
|
|
|
|
.filter(element => typeof element.type === 'string');
|
|
|
|
|
|
|
|
|
|
if (results.length === 0) {
|
|
|
|
|
throw new ErrorWithStack(
|
|
|
|
|
`No instances found with testID: ${String(testID)}`,
|
|
|
|
|
getAllByTestIdFn
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return results;
|
|
|
|
|
};
|
|
|
|
|
|
2018-10-07 10:59:27 +02:00
|
|
|
export const getByAPI = (instance: ReactTestInstance) => ({
|
|
|
|
|
getByTestId: getByTestId(instance),
|
2020-03-18 10:30:41 +01:00
|
|
|
getByName: getByName(instance, printDeprecationWarning),
|
|
|
|
|
getByType: getByType(instance, printUnsafeWarning),
|
2018-10-07 10:59:27 +02:00
|
|
|
getByText: getByText(instance),
|
2018-12-22 17:09:28 -05:00
|
|
|
getByPlaceholder: getByPlaceholder(instance),
|
2019-06-10 17:30:27 +02:00
|
|
|
getByDisplayValue: getByDisplayValue(instance),
|
2020-03-18 10:30:41 +01:00
|
|
|
getByProps: getByProps(instance, printUnsafeWarning),
|
2019-07-03 01:17:32 -07:00
|
|
|
getAllByTestId: getAllByTestId(instance),
|
2020-03-18 10:30:41 +01:00
|
|
|
getAllByName: getAllByName(instance, printDeprecationWarning),
|
|
|
|
|
getAllByType: getAllByType(instance, printUnsafeWarning),
|
2018-10-07 10:59:27 +02:00
|
|
|
getAllByText: getAllByText(instance),
|
2018-12-22 17:09:28 -05:00
|
|
|
getAllByPlaceholder: getAllByPlaceholder(instance),
|
2019-06-10 17:30:27 +02:00
|
|
|
getAllByDisplayValue: getAllByDisplayValue(instance),
|
2020-03-18 10:30:41 +01:00
|
|
|
getAllByProps: getAllByProps(instance, printUnsafeWarning),
|
|
|
|
|
|
|
|
|
|
// Unsafe aliases
|
|
|
|
|
UNSAFE_getByType: getByType(instance),
|
|
|
|
|
UNSAFE_getAllByType: getAllByType(instance),
|
|
|
|
|
UNSAFE_getByProps: getByProps(instance),
|
|
|
|
|
UNSAFE_getAllByProps: getAllByProps(instance),
|
2018-10-07 10:59:27 +02:00
|
|
|
});
|