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!
|
Change freshness!
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
<Text
|
||||||
|
testID=\\"duplicateText\\"
|
||||||
|
>
|
||||||
|
First Text
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
testID=\\"duplicateText\\"
|
||||||
|
>
|
||||||
|
Second Text
|
||||||
|
</Text>
|
||||||
</View>"
|
</View>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -93,6 +103,16 @@ exports[`debug changing component: bananaFresh button message should now be "fre
|
|||||||
Change freshness!
|
Change freshness!
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
<Text
|
||||||
|
testID=\\"duplicateText\\"
|
||||||
|
>
|
||||||
|
First Text
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
testID=\\"duplicateText\\"
|
||||||
|
>
|
||||||
|
Second Text
|
||||||
|
</Text>
|
||||||
</View>"
|
</View>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -128,6 +148,16 @@ exports[`debug: shallow 1`] = `
|
|||||||
>
|
>
|
||||||
Change freshness!
|
Change freshness!
|
||||||
</Button>
|
</Button>
|
||||||
|
<Text
|
||||||
|
testID=\\"duplicateText\\"
|
||||||
|
>
|
||||||
|
First Text
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
testID=\\"duplicateText\\"
|
||||||
|
>
|
||||||
|
Second Text
|
||||||
|
</Text>
|
||||||
</View>"
|
</View>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -165,6 +195,16 @@ exports[`debug: shallow with message 1`] = `
|
|||||||
>
|
>
|
||||||
Change freshness!
|
Change freshness!
|
||||||
</Button>
|
</Button>
|
||||||
|
<Text
|
||||||
|
testID=\\"duplicateText\\"
|
||||||
|
>
|
||||||
|
First Text
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
testID=\\"duplicateText\\"
|
||||||
|
>
|
||||||
|
Second Text
|
||||||
|
</Text>
|
||||||
</View>"
|
</View>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -215,6 +255,16 @@ exports[`debug: with message 1`] = `
|
|||||||
Change freshness!
|
Change freshness!
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
<Text
|
||||||
|
testID=\\"duplicateText\\"
|
||||||
|
>
|
||||||
|
First Text
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
testID=\\"duplicateText\\"
|
||||||
|
>
|
||||||
|
Second Text
|
||||||
|
</Text>
|
||||||
</View>"
|
</View>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ class Banana extends React.Component<*, *> {
|
|||||||
<Button onPress={this.changeFresh} type="primary">
|
<Button onPress={this.changeFresh} type="primary">
|
||||||
Change freshness!
|
Change freshness!
|
||||||
</Button>
|
</Button>
|
||||||
|
<Text testID="duplicateText">First Text</Text>
|
||||||
|
<Text testID="duplicateText">Second Text</Text>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -87,6 +89,25 @@ test('getByTestId, queryByTestId', () => {
|
|||||||
expect(queryByTestId('InExistent')).toBeNull();
|
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', () => {
|
test('getByName, queryByName', () => {
|
||||||
const { getByTestId, getByName, queryByName } = render(<Banana />);
|
const { getByTestId, getByName, queryByName } = render(<Banana />);
|
||||||
const bananaFresh = getByTestId('bananaFresh');
|
const bananaFresh = getByTestId('bananaFresh');
|
||||||
@@ -101,7 +122,7 @@ test('getByName, queryByName', () => {
|
|||||||
|
|
||||||
expect(bananaFresh.props.children).toBe('not fresh');
|
expect(bananaFresh.props.children).toBe('not fresh');
|
||||||
expect(() => getByName('InExistent')).toThrow('No instances found');
|
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('Button')).toBe(button);
|
||||||
expect(queryByName('InExistent')).toBeNull();
|
expect(queryByName('InExistent')).toBeNull();
|
||||||
|
|||||||
@@ -212,6 +212,21 @@ export const getAllByProps = (instance: ReactTestInstance) =>
|
|||||||
return results;
|
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) => ({
|
export const getByAPI = (instance: ReactTestInstance) => ({
|
||||||
getByTestId: getByTestId(instance),
|
getByTestId: getByTestId(instance),
|
||||||
getByName: getByName(instance),
|
getByName: getByName(instance),
|
||||||
@@ -220,6 +235,7 @@ export const getByAPI = (instance: ReactTestInstance) => ({
|
|||||||
getByPlaceholder: getByPlaceholder(instance),
|
getByPlaceholder: getByPlaceholder(instance),
|
||||||
getByDisplayValue: getByDisplayValue(instance),
|
getByDisplayValue: getByDisplayValue(instance),
|
||||||
getByProps: getByProps(instance),
|
getByProps: getByProps(instance),
|
||||||
|
getAllByTestId: getAllByTestId(instance),
|
||||||
getAllByName: getAllByName(instance),
|
getAllByName: getAllByName(instance),
|
||||||
getAllByType: getAllByType(instance),
|
getAllByType: getAllByType(instance),
|
||||||
getAllByText: getAllByText(instance),
|
getAllByText: getAllByText(instance),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
getByPlaceholder,
|
getByPlaceholder,
|
||||||
getByDisplayValue,
|
getByDisplayValue,
|
||||||
getByProps,
|
getByProps,
|
||||||
|
getAllByTestId,
|
||||||
getAllByName,
|
getAllByName,
|
||||||
getAllByType,
|
getAllByType,
|
||||||
getAllByText,
|
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) => ({
|
export const queryByAPI = (instance: ReactTestInstance) => ({
|
||||||
queryByTestId: queryByTestId(instance),
|
queryByTestId: queryByTestId(instance),
|
||||||
queryByName: queryByName(instance),
|
queryByName: queryByName(instance),
|
||||||
@@ -150,6 +161,7 @@ export const queryByAPI = (instance: ReactTestInstance) => ({
|
|||||||
queryByPlaceholder: queryByPlaceholder(instance),
|
queryByPlaceholder: queryByPlaceholder(instance),
|
||||||
queryByDisplayValue: queryByDisplayValue(instance),
|
queryByDisplayValue: queryByDisplayValue(instance),
|
||||||
queryByProps: queryByProps(instance),
|
queryByProps: queryByProps(instance),
|
||||||
|
queryAllByTestId: queryAllByTestId(instance),
|
||||||
queryAllByName: queryAllByName(instance),
|
queryAllByName: queryAllByName(instance),
|
||||||
queryAllByType: queryAllByType(instance),
|
queryAllByType: queryAllByType(instance),
|
||||||
queryAllByText: queryAllByText(instance),
|
queryAllByText: queryAllByText(instance),
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ const getByDisplayValueRegExp: ReactTestInstance = tree.getByDisplayValue(
|
|||||||
);
|
);
|
||||||
const getByProps: ReactTestInstance = tree.getByProps({ value: 2 });
|
const getByProps: ReactTestInstance = tree.getByProps({ value: 2 });
|
||||||
const getByTestId: ReactTestInstance = tree.getByTestId('test-id');
|
const getByTestId: ReactTestInstance = tree.getByTestId('test-id');
|
||||||
|
const getAllByTestId: ReactTestInstance[] = tree.getAllByTestId('test-id');
|
||||||
const getAllByNameString: Array<ReactTestInstance> = tree.getAllByName('View');
|
const getAllByNameString: Array<ReactTestInstance> = tree.getAllByName('View');
|
||||||
const getAllByNameConstructor: Array<ReactTestInstance> = tree.getAllByName(
|
const getAllByNameConstructor: Array<ReactTestInstance> = tree.getAllByName(
|
||||||
View
|
View
|
||||||
@@ -93,6 +94,9 @@ const queryByDisplayValueRegExp: ReactTestInstance | null = tree.queryByDisplayV
|
|||||||
);
|
);
|
||||||
const queryByProps: ReactTestInstance | null = tree.queryByProps({ value: 2 });
|
const queryByProps: ReactTestInstance | null = tree.queryByProps({ value: 2 });
|
||||||
const queryByTestId: ReactTestInstance | null = tree.queryByTestId('test-id');
|
const queryByTestId: ReactTestInstance | null = tree.queryByTestId('test-id');
|
||||||
|
const queryAllByTestId: ReactTestInstance[] | null = tree.queryAllByTestId(
|
||||||
|
'test-id'
|
||||||
|
);
|
||||||
const queryAllByNameString: Array<ReactTestInstance> = tree.queryAllByName(
|
const queryAllByNameString: Array<ReactTestInstance> = tree.queryAllByName(
|
||||||
'View'
|
'View'
|
||||||
);
|
);
|
||||||
|
|||||||
Vendored
+2
@@ -9,6 +9,7 @@ export interface GetByAPI {
|
|||||||
getByDisplayValue: (value: string | RegExp) => ReactTestInstance;
|
getByDisplayValue: (value: string | RegExp) => ReactTestInstance;
|
||||||
getByProps: (props: Record<string, any>) => ReactTestInstance;
|
getByProps: (props: Record<string, any>) => ReactTestInstance;
|
||||||
getByTestId: (testID: string) => ReactTestInstance;
|
getByTestId: (testID: string) => ReactTestInstance;
|
||||||
|
getAllByTestId: (testID: string) => Array<ReactTestInstance>;
|
||||||
getAllByName: (name: React.ReactType | string) => Array<ReactTestInstance>;
|
getAllByName: (name: React.ReactType | string) => Array<ReactTestInstance>;
|
||||||
getAllByType: <P>(type: React.ComponentType<P>) => Array<ReactTestInstance>;
|
getAllByType: <P>(type: React.ComponentType<P>) => Array<ReactTestInstance>;
|
||||||
getAllByText: (text: string | RegExp) => Array<ReactTestInstance>;
|
getAllByText: (text: string | RegExp) => Array<ReactTestInstance>;
|
||||||
@@ -29,6 +30,7 @@ export interface QueryByAPI {
|
|||||||
queryByDisplayValue: (value: string | RegExp) => ReactTestInstance | null;
|
queryByDisplayValue: (value: string | RegExp) => ReactTestInstance | null;
|
||||||
queryByProps: (props: Record<string, any>) => ReactTestInstance | null;
|
queryByProps: (props: Record<string, any>) => ReactTestInstance | null;
|
||||||
queryByTestId: (testID: string) => ReactTestInstance | null;
|
queryByTestId: (testID: string) => ReactTestInstance | null;
|
||||||
|
queryAllByTestId: (testID: string) => Array<ReactTestInstance> | null;
|
||||||
queryAllByName: (
|
queryAllByName: (
|
||||||
name: React.ReactType | string
|
name: React.ReactType | string
|
||||||
) => Array<ReactTestInstance> | [];
|
) => Array<ReactTestInstance> | [];
|
||||||
|
|||||||
Reference in New Issue
Block a user