mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
feat: add getAllByTestId and queryAllByTestId queries (#198)
* feat: add getAllByTestId and queryAllByTestId queries * Add test for getAllByTestId and queryAllByTestId - Filter out intermediate components in getAllByTestId. testIDs may be passed down to child components and appearing multiple times in the render tree. Some React Native components render multiple anyways. <Text> is an example. * Update TypeScript typings * Fix flow types * Update TS typings test
This commit is contained in:
committed by
Michał Pierzchała
parent
9369efee73
commit
fead652013
@@ -45,6 +45,16 @@ exports[`debug 1`] = `
|
||||
Change freshness!
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
testID=\\"duplicateText\\"
|
||||
>
|
||||
First Text
|
||||
</Text>
|
||||
<Text
|
||||
testID=\\"duplicateText\\"
|
||||
>
|
||||
Second Text
|
||||
</Text>
|
||||
</View>"
|
||||
`;
|
||||
|
||||
@@ -93,6 +103,16 @@ exports[`debug changing component: bananaFresh button message should now be "fre
|
||||
Change freshness!
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
testID=\\"duplicateText\\"
|
||||
>
|
||||
First Text
|
||||
</Text>
|
||||
<Text
|
||||
testID=\\"duplicateText\\"
|
||||
>
|
||||
Second Text
|
||||
</Text>
|
||||
</View>"
|
||||
`;
|
||||
|
||||
@@ -128,6 +148,16 @@ exports[`debug: shallow 1`] = `
|
||||
>
|
||||
Change freshness!
|
||||
</Button>
|
||||
<Text
|
||||
testID=\\"duplicateText\\"
|
||||
>
|
||||
First Text
|
||||
</Text>
|
||||
<Text
|
||||
testID=\\"duplicateText\\"
|
||||
>
|
||||
Second Text
|
||||
</Text>
|
||||
</View>"
|
||||
`;
|
||||
|
||||
@@ -165,6 +195,16 @@ exports[`debug: shallow with message 1`] = `
|
||||
>
|
||||
Change freshness!
|
||||
</Button>
|
||||
<Text
|
||||
testID=\\"duplicateText\\"
|
||||
>
|
||||
First Text
|
||||
</Text>
|
||||
<Text
|
||||
testID=\\"duplicateText\\"
|
||||
>
|
||||
Second Text
|
||||
</Text>
|
||||
</View>"
|
||||
`;
|
||||
|
||||
@@ -215,6 +255,16 @@ exports[`debug: with message 1`] = `
|
||||
Change freshness!
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
testID=\\"duplicateText\\"
|
||||
>
|
||||
First Text
|
||||
</Text>
|
||||
<Text
|
||||
testID=\\"duplicateText\\"
|
||||
>
|
||||
Second Text
|
||||
</Text>
|
||||
</View>"
|
||||
`;
|
||||
|
||||
|
||||
@@ -71,6 +71,8 @@ class Banana extends React.Component<*, *> {
|
||||
<Button onPress={this.changeFresh} type="primary">
|
||||
Change freshness!
|
||||
</Button>
|
||||
<Text testID="duplicateText">First Text</Text>
|
||||
<Text testID="duplicateText">Second Text</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -87,6 +89,25 @@ test('getByTestId, queryByTestId', () => {
|
||||
expect(queryByTestId('InExistent')).toBeNull();
|
||||
});
|
||||
|
||||
test('getAllByTestId, queryAllByTestId', () => {
|
||||
const { getAllByTestId, queryAllByTestId } = render(<Banana />);
|
||||
const textElements = getAllByTestId('duplicateText');
|
||||
|
||||
expect(textElements.length).toBe(2);
|
||||
expect(textElements[0].props.children).toBe('First Text');
|
||||
expect(textElements[1].props.children).toBe('Second Text');
|
||||
expect(() => getAllByTestId('nonExistentTestId')).toThrow(
|
||||
'No instances found'
|
||||
);
|
||||
|
||||
const queriedTextElements = queryAllByTestId('duplicateText');
|
||||
|
||||
expect(queriedTextElements.length).toBe(2);
|
||||
expect(queriedTextElements[0]).toBe(textElements[0]);
|
||||
expect(queriedTextElements[1]).toBe(textElements[1]);
|
||||
expect(queryAllByTestId('nonExistentTestId')).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('getByName, queryByName', () => {
|
||||
const { getByTestId, getByName, queryByName } = render(<Banana />);
|
||||
const bananaFresh = getByTestId('bananaFresh');
|
||||
@@ -101,7 +122,7 @@ test('getByName, queryByName', () => {
|
||||
|
||||
expect(bananaFresh.props.children).toBe('not fresh');
|
||||
expect(() => getByName('InExistent')).toThrow('No instances found');
|
||||
expect(() => getByName(Text)).toThrow('Expected 1 but found 3');
|
||||
expect(() => getByName(Text)).toThrow('Expected 1 but found 5');
|
||||
|
||||
expect(queryByName('Button')).toBe(button);
|
||||
expect(queryByName('InExistent')).toBeNull();
|
||||
|
||||
@@ -212,6 +212,21 @@ export const getAllByProps = (instance: ReactTestInstance) =>
|
||||
return results;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
export const getByAPI = (instance: ReactTestInstance) => ({
|
||||
getByTestId: getByTestId(instance),
|
||||
getByName: getByName(instance),
|
||||
@@ -220,6 +235,7 @@ export const getByAPI = (instance: ReactTestInstance) => ({
|
||||
getByPlaceholder: getByPlaceholder(instance),
|
||||
getByDisplayValue: getByDisplayValue(instance),
|
||||
getByProps: getByProps(instance),
|
||||
getAllByTestId: getAllByTestId(instance),
|
||||
getAllByName: getAllByName(instance),
|
||||
getAllByType: getAllByType(instance),
|
||||
getAllByText: getAllByText(instance),
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
getByPlaceholder,
|
||||
getByDisplayValue,
|
||||
getByProps,
|
||||
getAllByTestId,
|
||||
getAllByName,
|
||||
getAllByType,
|
||||
getAllByText,
|
||||
@@ -142,6 +143,16 @@ export const queryAllByProps = (instance: ReactTestInstance) => (props: {
|
||||
}
|
||||
};
|
||||
|
||||
export const queryAllByTestId = (instance: ReactTestInstance) => (
|
||||
testID: string
|
||||
) => {
|
||||
try {
|
||||
return getAllByTestId(instance)(testID);
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export const queryByAPI = (instance: ReactTestInstance) => ({
|
||||
queryByTestId: queryByTestId(instance),
|
||||
queryByName: queryByName(instance),
|
||||
@@ -150,6 +161,7 @@ export const queryByAPI = (instance: ReactTestInstance) => ({
|
||||
queryByPlaceholder: queryByPlaceholder(instance),
|
||||
queryByDisplayValue: queryByDisplayValue(instance),
|
||||
queryByProps: queryByProps(instance),
|
||||
queryAllByTestId: queryAllByTestId(instance),
|
||||
queryAllByName: queryAllByName(instance),
|
||||
queryAllByType: queryAllByType(instance),
|
||||
queryAllByText: queryAllByText(instance),
|
||||
|
||||
@@ -54,6 +54,7 @@ const getByDisplayValueRegExp: ReactTestInstance = tree.getByDisplayValue(
|
||||
);
|
||||
const getByProps: ReactTestInstance = tree.getByProps({ value: 2 });
|
||||
const getByTestId: ReactTestInstance = tree.getByTestId('test-id');
|
||||
const getAllByTestId: ReactTestInstance[] = tree.getAllByTestId('test-id');
|
||||
const getAllByNameString: Array<ReactTestInstance> = tree.getAllByName('View');
|
||||
const getAllByNameConstructor: Array<ReactTestInstance> = tree.getAllByName(
|
||||
View
|
||||
@@ -93,6 +94,9 @@ const queryByDisplayValueRegExp: ReactTestInstance | null = tree.queryByDisplayV
|
||||
);
|
||||
const queryByProps: ReactTestInstance | null = tree.queryByProps({ value: 2 });
|
||||
const queryByTestId: ReactTestInstance | null = tree.queryByTestId('test-id');
|
||||
const queryAllByTestId: ReactTestInstance[] | null = tree.queryAllByTestId(
|
||||
'test-id'
|
||||
);
|
||||
const queryAllByNameString: Array<ReactTestInstance> = tree.queryAllByName(
|
||||
'View'
|
||||
);
|
||||
|
||||
Vendored
+2
@@ -9,6 +9,7 @@ export interface GetByAPI {
|
||||
getByDisplayValue: (value: string | RegExp) => ReactTestInstance;
|
||||
getByProps: (props: Record<string, any>) => ReactTestInstance;
|
||||
getByTestId: (testID: string) => ReactTestInstance;
|
||||
getAllByTestId: (testID: string) => Array<ReactTestInstance>;
|
||||
getAllByName: (name: React.ReactType | string) => Array<ReactTestInstance>;
|
||||
getAllByType: <P>(type: React.ComponentType<P>) => Array<ReactTestInstance>;
|
||||
getAllByText: (text: string | RegExp) => Array<ReactTestInstance>;
|
||||
@@ -29,6 +30,7 @@ export interface QueryByAPI {
|
||||
queryByDisplayValue: (value: string | RegExp) => ReactTestInstance | null;
|
||||
queryByProps: (props: Record<string, any>) => ReactTestInstance | null;
|
||||
queryByTestId: (testID: string) => ReactTestInstance | null;
|
||||
queryAllByTestId: (testID: string) => Array<ReactTestInstance> | null;
|
||||
queryAllByName: (
|
||||
name: React.ReactType | string
|
||||
) => Array<ReactTestInstance> | [];
|
||||
|
||||
Reference in New Issue
Block a user