Skip to content

feat: add findBy* queries #304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
May 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 135 additions & 28 deletions src/__tests__/a11yAPI.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ const Typography = ({ children, ...rest }: any) => {
return <Text {...rest}>{children}</Text>;
};

const waitForOptions = { timeout: 10 };

class Button extends React.Component<any> {
render() {
return (
Expand Down Expand Up @@ -62,74 +64,133 @@ function Section() {
);
}

test('getByA11yLabel, queryByA11yLabel', () => {
const { getByA11yLabel, queryByA11yLabel } = render(<Section />);
test('getByA11yLabel, queryByA11yLabel, findByA11yLabel', async () => {
const { getByA11yLabel, queryByA11yLabel, findByA11yLabel } = render(
<Section />
);

expect(getByA11yLabel(BUTTON_LABEL).props.accessibilityLabel).toEqual(
BUTTON_LABEL
);
const button = queryByA11yLabel(/button/g);
expect(button && button.props.accessibilityLabel).toEqual(BUTTON_LABEL);

expect(() => getByA11yLabel(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND);
expect(queryByA11yLabel(NO_MATCHES_TEXT)).toBeNull();

expect(() => getByA11yLabel(TEXT_LABEL)).toThrow(FOUND_TWO_INSTANCES);
expect(() => queryByA11yLabel(TEXT_LABEL)).toThrow(FOUND_TWO_INSTANCES);

const asyncButton = await findByA11yLabel(BUTTON_LABEL);
expect(asyncButton.props.accessibilityLabel).toEqual(BUTTON_LABEL);
await expect(
findByA11yLabel(NO_MATCHES_TEXT, waitForOptions)
).rejects.toThrow(NO_INSTANCES_FOUND);

await expect(findByA11yLabel(TEXT_LABEL, waitForOptions)).rejects.toThrow(
FOUND_TWO_INSTANCES
);
});

test('getAllByA11yLabel, queryAllByA11yLabel', () => {
const { getAllByA11yLabel, queryAllByA11yLabel } = render(<Section />);
test('getAllByA11yLabel, queryAllByA11yLabel', async () => {
const { getAllByA11yLabel, queryAllByA11yLabel, findAllByA11yLabel } = render(
<Section />
);

expect(getAllByA11yLabel(TEXT_LABEL)).toHaveLength(2);
expect(queryAllByA11yLabel(/cool/g)).toHaveLength(3);

expect(() => getAllByA11yLabel(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND);
expect(queryAllByA11yLabel(NO_MATCHES_TEXT)).toEqual([]);

await expect(findAllByA11yLabel(TEXT_LABEL)).resolves.toHaveLength(2);
await expect(findAllByA11yLabel(NO_MATCHES_TEXT)).rejects.toThrow(
NO_INSTANCES_FOUND
);
});

test('getByA11yHint, queryByA11yHint', () => {
const { getByA11yHint, queryByA11yHint } = render(<Section />);
test('getByA11yHint, queryByA11yHint, findByA11yHint', async () => {
const { getByA11yHint, queryByA11yHint, findByA11yHint } = render(
<Section />
);

expect(getByA11yHint(BUTTON_HINT).props.accessibilityHint).toEqual(
BUTTON_HINT
);
const button = queryByA11yHint(/button/g);
expect(button && button.props.accessibilityHint).toEqual(BUTTON_HINT);

expect(() => getByA11yHint(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND);
expect(queryByA11yHint(NO_MATCHES_TEXT)).toBeNull();

expect(() => getByA11yHint(TEXT_HINT)).toThrow(FOUND_TWO_INSTANCES);
expect(() => queryByA11yHint(TEXT_HINT)).toThrow(FOUND_TWO_INSTANCES);

const asyncButton = await findByA11yHint(BUTTON_HINT);
expect(asyncButton.props.accessibilityHint).toEqual(BUTTON_HINT);
await expect(findByA11yHint(NO_MATCHES_TEXT, waitForOptions)).rejects.toThrow(
NO_INSTANCES_FOUND
);
await expect(findByA11yHint(TEXT_HINT, waitForOptions)).rejects.toThrow(
FOUND_TWO_INSTANCES
);
});

test('getAllByA11yHint, queryAllByA11yHint', () => {
const { getAllByA11yHint, queryAllByA11yHint } = render(<Section />);
test('getAllByA11yHint, queryAllByA11yHint', async () => {
const { getAllByA11yHint, queryAllByA11yHint, findAllByA11yHint } = render(
<Section />
);

expect(getAllByA11yHint(TEXT_HINT)).toHaveLength(2);
expect(queryAllByA11yHint(/static/g)).toHaveLength(2);

expect(() => getAllByA11yHint(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND);
expect(queryAllByA11yHint(NO_MATCHES_TEXT)).toEqual([]);

await expect(findAllByA11yHint(TEXT_HINT)).resolves.toHaveLength(2);
await expect(findAllByA11yHint(NO_MATCHES_TEXT)).rejects.toThrow(
NO_INSTANCES_FOUND
);
});

test('getByA11yRole, queryByA11yRole', () => {
const { getByA11yRole, queryByA11yRole } = render(<Section />);
test('getByA11yRole, queryByA11yRole, findByA11yRole', async () => {
const { getByA11yRole, queryByA11yRole, findByA11yRole } = render(
<Section />
);

expect(getByA11yRole('button').props.accessibilityRole).toEqual('button');
const button = queryByA11yRole(/button/g);
expect(button && button.props.accessibilityRole).toEqual('button');

expect(() => getByA11yRole(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND);
expect(queryByA11yRole(NO_MATCHES_TEXT)).toBeNull();

expect(() => getByA11yRole('link')).toThrow(FOUND_TWO_INSTANCES);
expect(() => queryByA11yRole('link')).toThrow(FOUND_TWO_INSTANCES);

const asyncButton = await findByA11yRole('button');
expect(asyncButton.props.accessibilityRole).toEqual('button');
await expect(findByA11yRole(NO_MATCHES_TEXT, waitForOptions)).rejects.toThrow(
NO_INSTANCES_FOUND
);
await expect(findByA11yRole('link')).rejects.toThrow(FOUND_TWO_INSTANCES);
});

test('getAllByA11yRole, queryAllByA11yRole', () => {
const { getAllByA11yRole, queryAllByA11yRole } = render(<Section />);
test('getAllByA11yRole, queryAllByA11yRole, findAllByA11yRole', async () => {
const { getAllByA11yRole, queryAllByA11yRole, findAllByA11yRole } = render(
<Section />
);

expect(getAllByA11yRole('link')).toHaveLength(2);
expect(queryAllByA11yRole(/ink/g)).toHaveLength(2);

expect(() => getAllByA11yRole(NO_MATCHES_TEXT)).toThrow(NO_INSTANCES_FOUND);
expect(queryAllByA11yRole(NO_MATCHES_TEXT)).toEqual([]);

await expect(findAllByA11yRole('link')).resolves.toHaveLength(2);
await expect(
findAllByA11yRole(NO_MATCHES_TEXT, waitForOptions)
).rejects.toThrow(NO_INSTANCES_FOUND);
});

// TODO: accessibilityStates was removed from RN 0.62
Expand Down Expand Up @@ -169,8 +230,10 @@ test.skip('getAllByA11yStates, queryAllByA11yStates', () => {
expect(queryAllByA11yStates(NO_MATCHES_TEXT)).toEqual([]);
});

test('getByA11yState, queryByA11yState', () => {
const { getByA11yState, queryByA11yState } = render(<Section />);
test('getByA11yState, queryByA11yState, findByA11yState', async () => {
const { getByA11yState, queryByA11yState, findByA11yState } = render(
<Section />
);

expect(getByA11yState({ selected: true }).props.accessibilityState).toEqual({
selected: true,
Expand All @@ -192,25 +255,49 @@ test('getByA11yState, queryByA11yState', () => {
expect(() => queryByA11yState({ expanded: false })).toThrow(
FOUND_TWO_INSTANCES
);

const asyncButton = await findByA11yState({ selected: true });
expect(asyncButton.props.accessibilityState).toEqual({
selected: true,
expanded: false,
});
await expect(
findByA11yState({ disabled: true }, waitForOptions)
).rejects.toThrow(NO_INSTANCES_FOUND);
await expect(
findByA11yState({ expanded: false }, waitForOptions)
).rejects.toThrow(FOUND_TWO_INSTANCES);
});

test('getAllByA11yState, queryAllByA11yState', () => {
const { getAllByA11yState, queryAllByA11yState } = render(<Section />);
test('getAllByA11yState, queryAllByA11yState, findAllByA11yState', async () => {
const { getAllByA11yState, queryAllByA11yState, findAllByA11yState } = render(
<Section />
);

expect(getAllByA11yState({ selected: true }).length).toEqual(1);
expect(queryAllByA11yState({ selected: true }).length).toEqual(1);
expect(getAllByA11yState({ selected: true })).toHaveLength(1);
expect(queryAllByA11yState({ selected: true })).toHaveLength(1);

expect(() => getAllByA11yState({ disabled: true })).toThrow(
NO_INSTANCES_FOUND
);
expect(queryAllByA11yState({ disabled: true })).toEqual([]);

expect(getAllByA11yState({ expanded: false }).length).toEqual(2);
expect(queryAllByA11yState({ expanded: false }).length).toEqual(2);
expect(getAllByA11yState({ expanded: false })).toHaveLength(2);
expect(queryAllByA11yState({ expanded: false })).toHaveLength(2);

await expect(findAllByA11yState({ selected: true })).resolves.toHaveLength(1);
await expect(
findAllByA11yState({ disabled: true }, waitForOptions)
).rejects.toThrow(NO_INSTANCES_FOUND);
await expect(findAllByA11yState({ expanded: false })).resolves.toHaveLength(
2
);
});

test('getByA11yValue, queryByA11yValue', () => {
const { getByA11yValue, queryByA11yValue } = render(<Section />);
test('getByA11yValue, queryByA11yValue, findByA11yValue', async () => {
const { getByA11yValue, queryByA11yValue, findByA11yValue } = render(
<Section />
);

expect(getByA11yValue({ min: 40 }).props.accessibilityValue).toEqual({
min: 40,
Expand All @@ -226,17 +313,37 @@ test('getByA11yValue, queryByA11yValue', () => {

expect(() => getByA11yValue({ max: 60 })).toThrow(FOUND_TWO_INSTANCES);
expect(() => queryByA11yValue({ max: 60 })).toThrow(FOUND_TWO_INSTANCES);

const asyncElement = await findByA11yValue({ min: 40 });
expect(asyncElement.props.accessibilityValue).toEqual({
min: 40,
max: 60,
});
await expect(findByA11yValue({ min: 50 }, waitForOptions)).rejects.toThrow(
NO_INSTANCES_FOUND
);
await expect(findByA11yValue({ max: 60 }, waitForOptions)).rejects.toThrow(
FOUND_TWO_INSTANCES
);
});

test('getAllByA11yValue, queryAllByA11yValue', () => {
const { getAllByA11yValue, queryAllByA11yValue } = render(<Section />);
test('getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue', async () => {
const { getAllByA11yValue, queryAllByA11yValue, findAllByA11yValue } = render(
<Section />
);

expect(getAllByA11yValue({ min: 40 }).length).toEqual(1);
expect(queryAllByA11yValue({ min: 40 }).length).toEqual(1);
expect(getAllByA11yValue({ min: 40 })).toHaveLength(1);
expect(queryAllByA11yValue({ min: 40 })).toHaveLength(1);

expect(() => getAllByA11yValue({ min: 50 })).toThrow(NO_INSTANCES_FOUND);
expect(queryAllByA11yValue({ min: 50 })).toEqual([]);

expect(getAllByA11yValue({ max: 60 }).length).toEqual(2);
expect(queryAllByA11yValue({ max: 60 }).length).toEqual(2);
expect(queryAllByA11yValue({ max: 60 })).toHaveLength(2);
expect(getAllByA11yValue({ max: 60 })).toHaveLength(2);

await expect(findAllByA11yValue({ min: 40 })).resolves.toHaveLength(1);
await expect(findAllByA11yValue({ min: 50 }, waitForOptions)).rejects.toThrow(
NO_INSTANCES_FOUND
);
await expect(findAllByA11yValue({ max: 60 })).resolves.toHaveLength(2);
});
58 changes: 58 additions & 0 deletions src/__tests__/findByApi.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// @flow
import React from 'react';
import { View, Text, TextInput } from 'react-native';
import { render } from '..';

test('findBy queries work asynchronously', async () => {
const options = { timeout: 10 }; // Short timeout so that this test runs quickly
const {
rerender,
findByTestId,
findAllByTestId,
findByText,
findAllByText,
findByPlaceholder,
findAllByPlaceholder,
findByDisplayValue,
findAllByDisplayValue,
} = render(<View />);
await expect(findByTestId('aTestId', options)).rejects.toBeTruthy();
await expect(findAllByTestId('aTestId', options)).rejects.toBeTruthy();
await expect(findByText('Some Text', options)).rejects.toBeTruthy();
await expect(findAllByText('Some Text', options)).rejects.toBeTruthy();
await expect(
findByPlaceholder('Placeholder Text', options)
).rejects.toBeTruthy();
await expect(
findAllByPlaceholder('Placeholder Text', options)
).rejects.toBeTruthy();
await expect(
findByDisplayValue('Display Value', options)
).rejects.toBeTruthy();
await expect(
findAllByDisplayValue('Display Value', options)
).rejects.toBeTruthy();

setTimeout(
() =>
rerender(
<View testID="aTestId">
<Text>Some Text</Text>
<TextInput placeholder="Placeholder Text" />
<TextInput value="Display Value" />
</View>
),
20
);

await expect(findByTestId('aTestId')).resolves.toBeTruthy();
await expect(findAllByTestId('aTestId')).resolves.toHaveLength(1);
await expect(findByText('Some Text')).resolves.toBeTruthy();
await expect(findAllByText('Some Text')).resolves.toHaveLength(1);
await expect(findByPlaceholder('Placeholder Text')).resolves.toBeTruthy();
await expect(findAllByPlaceholder('Placeholder Text')).resolves.toHaveLength(
1
);
await expect(findByDisplayValue('Display Value')).resolves.toBeTruthy();
await expect(findAllByDisplayValue('Display Value')).resolves.toHaveLength(1);
}, 10000);
24 changes: 22 additions & 2 deletions src/__tests__/within.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import { View, Text, TextInput } from 'react-native';
import { render, within } from '..';

test('within() exposes basic queries', () => {
test('within() exposes basic queries', async () => {
const rootQueries = render(
<View>
<View accessibilityHint="first">
Expand All @@ -28,6 +28,12 @@ test('within() exposes basic queries', () => {
expect(firstQueries.queryByText('Same Text')).toBeTruthy();
expect(firstQueries.getByDisplayValue('Same Value')).toBeTruthy();
expect(firstQueries.getByPlaceholder('Same Placeholder')).toBeTruthy();
await expect(
firstQueries.findByDisplayValue('Same Value')
).resolves.toBeTruthy();
await expect(
firstQueries.findAllByPlaceholder('Same Placeholder')
).resolves.toHaveLength(1);

const secondQueries = within(rootQueries.getByA11yHint('second'));
expect(secondQueries.getAllByText('Same Text')).toHaveLength(1);
Expand All @@ -38,7 +44,7 @@ test('within() exposes basic queries', () => {
expect(secondQueries.getByPlaceholder('Same Placeholder')).toBeTruthy();
});

test('within() exposes a11y queries', () => {
test('within() exposes a11y queries', async () => {
const rootQueries = render(
<View>
<View accessibilityHint="first">
Expand All @@ -64,8 +70,22 @@ test('within() exposes a11y queries', () => {
const firstQueries = within(rootQueries.getByA11yHint('first'));
expect(firstQueries.getByA11yLabel('Same Label')).toBeTruthy();
expect(firstQueries.getByA11yHint('Same Hint')).toBeTruthy();
expect(firstQueries.queryByA11yLabel('Same Label')).toBeTruthy();
expect(firstQueries.queryByA11yHint('Same Hint')).toBeTruthy();
await expect(
firstQueries.findByA11yLabel('Same Label')
).resolves.toBeTruthy();
await expect(firstQueries.findByA11yHint('Same Hint')).resolves.toBeTruthy();

const secondQueries = within(rootQueries.getByA11yHint('second'));
expect(secondQueries.getAllByA11yLabel('Same Label')).toHaveLength(1);
expect(secondQueries.getAllByA11yHint('Same Hint')).toHaveLength(1);
expect(secondQueries.queryAllByA11yLabel('Same Label')).toHaveLength(1);
expect(secondQueries.queryAllByA11yHint('Same Hint')).toHaveLength(1);
await expect(
secondQueries.findAllByA11yLabel('Same Label')
).resolves.toHaveLength(1);
await expect(
secondQueries.findAllByA11yHint('Same Hint')
).resolves.toHaveLength(1);
});
Loading