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:
Scotty Waggoner
2019-07-03 01:17:32 -07:00
committed by Michał Pierzchała
parent 9369efee73
commit fead652013
6 changed files with 106 additions and 1 deletions
@@ -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>"
`;
+22 -1
View File
@@ -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();
+16
View File
@@ -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),
+12
View File
@@ -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),