mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
feat: add findBy* queries (#304)
* Basic async findBy queries * Refactored findBy queries to be built with makeFindQuery * findBy queries for A11y selectors * Custom findByTestId implementation that avoids current getByTestId issues * Fixed prettier issue * Updates Queries.md with findBy queries * Trying to fix test timeout error appearing only on CI * Code review changes * Added typescript types & tests * prettier did reformat some code arround * Removed export of GetByAPI, QueryByAPI and FindByAPI interfaces in TS * Reversed prettier run on typings * Added overlapping pieces with `within` operator * Small cleanup * Update website/docs/Queries.md * Moved async/await tests to the end of test methods Co-authored-by: Michał Pierzchała <thymikee@gmail.com>
This commit is contained in:
committed by
GitHub
parent
1809825313
commit
ab34712133
+123
-106
@@ -121,6 +121,57 @@ const queryAllByDisplayValueRegExp: Array<
|
||||
ReactTestInstance
|
||||
> = tree.queryAllByDisplayValue(/View/g);
|
||||
|
||||
// findBy API tests
|
||||
const findBy: Promise<ReactTestInstance>[] = [
|
||||
tree.findByText('View'),
|
||||
tree.findByText('View', { timeout: 10, interval: 10 }),
|
||||
tree.findByText(/View/g),
|
||||
tree.findByText(/View/g, { timeout: 10, interval: 5 }),
|
||||
tree.findByPlaceholder('my placeholder'),
|
||||
tree.findByPlaceholder('my placeholder', { timeout: 10, interval: 5 }),
|
||||
tree.findByPlaceholder(/placeholder/g),
|
||||
tree.findByPlaceholder(/placeholder/g, { timeout: 10, interval: 5 }),
|
||||
tree.findByDisplayValue('my value'),
|
||||
tree.findByDisplayValue('my value', { timeout: 10, interval: 10 }),
|
||||
tree.findByDisplayValue(/value/g),
|
||||
tree.findByDisplayValue(/value/g, { timeout: 10, interval: 10 }),
|
||||
tree.findByTestId('test-id'),
|
||||
tree.findByTestId('test-id', { timeout: 10, interval: 10 }),
|
||||
tree.findByA11yLabel('label'),
|
||||
tree.findByA11yLabel('label', { timeout: 10, interval: 10 }),
|
||||
tree.findByA11yHint('label'),
|
||||
tree.findByA11yHint('label', { timeout: 10, interval: 10 }),
|
||||
tree.findByA11yRole('button'),
|
||||
tree.findByA11yRole('button', { timeout: 10, interval: 10 }),
|
||||
tree.findByA11yState({ busy: true }),
|
||||
tree.findByA11yState({ busy: true }, { timeout: 10, interval: 10 }),
|
||||
tree.findByA11yValue({ min: 10 }),
|
||||
tree.findByA11yValue({ min: 10 }, { timeout: 10, interval: 10 }),
|
||||
];
|
||||
|
||||
const findAllBy: Promise<ReactTestInstance[]>[] = [
|
||||
tree.findAllByText('View'),
|
||||
tree.findAllByText('View', { timeout: 10, interval: 10 }),
|
||||
tree.findAllByText(/View/g),
|
||||
tree.findAllByText(/View/g, { timeout: 10, interval: 5 }),
|
||||
tree.findAllByPlaceholder('my placeholder'),
|
||||
tree.findAllByPlaceholder('my placeholder', { timeout: 10, interval: 10 }),
|
||||
tree.findAllByPlaceholder(/placeholder/g),
|
||||
tree.findAllByPlaceholder(/placeholder/g, { timeout: 10, interval: 10 }),
|
||||
tree.findAllByDisplayValue('View'),
|
||||
tree.findAllByDisplayValue('View', { timeout: 10, interval: 10 }),
|
||||
tree.findAllByDisplayValue(/View/g),
|
||||
tree.findAllByDisplayValue(/View/g, { timeout: 10, interval: 10 }),
|
||||
tree.findAllByTestId('test-id'),
|
||||
tree.findAllByTestId('test-id', { timeout: 10, interval: 10 }),
|
||||
tree.findAllByA11yHint('label'),
|
||||
tree.findAllByA11yHint('label', { timeout: 10, interval: 10 }),
|
||||
tree.findAllByA11yState({ busy: true }),
|
||||
tree.findAllByA11yState({ busy: true }, { timeout: 10, interval: 10 }),
|
||||
tree.findAllByA11yValue({ min: 10 }),
|
||||
tree.findAllByA11yValue({ min: 10 }, { timeout: 10, interval: 10 }),
|
||||
];
|
||||
|
||||
// Accessibility queries
|
||||
const getByA11yLabel: ReactTestInstance = tree.getByA11yLabel('label');
|
||||
const getAllByA11yLabel: Array<ReactTestInstance> = tree.getAllByA11yLabel(
|
||||
@@ -130,6 +181,7 @@ const queryByA11yLabel: ReactTestInstance = tree.queryByA11yLabel('label');
|
||||
const queryAllByA11yLabel: Array<ReactTestInstance> = tree.queryAllByA11yLabel(
|
||||
'label'
|
||||
);
|
||||
|
||||
const getByA11yHint: ReactTestInstance = tree.getByA11yHint('label');
|
||||
const getAllByA11yHint: Array<ReactTestInstance> = tree.getAllByA11yHint(
|
||||
'label'
|
||||
@@ -138,6 +190,7 @@ const queryByA11yHint: ReactTestInstance = tree.queryByA11yHint('label');
|
||||
const queryAllByA11yHint: Array<ReactTestInstance> = tree.queryAllByA11yHint(
|
||||
'label'
|
||||
);
|
||||
|
||||
const getByA11yRole: ReactTestInstance = tree.getByA11yRole('button');
|
||||
const getAllByA11yRole: Array<ReactTestInstance> = tree.getAllByA11yRole(
|
||||
'button'
|
||||
@@ -146,6 +199,7 @@ const queryByA11yRole: ReactTestInstance = tree.queryByA11yRole('button');
|
||||
const queryAllByA11yRole: Array<ReactTestInstance> = tree.queryAllByA11yRole(
|
||||
'button'
|
||||
);
|
||||
|
||||
const getByA11yStates: ReactTestInstance = tree.getByA11yStates('selected');
|
||||
const getByA11yStatesArray: ReactTestInstance = tree.getByA11yStates(['selected']);
|
||||
const getAllByA11yStates: Array<ReactTestInstance> = tree.getAllByA11yStates(
|
||||
@@ -221,112 +275,75 @@ act(() => {
|
||||
|
||||
// within API
|
||||
const instance: ReactTestInstance = tree.getByText('<View />');
|
||||
const withinGetByText: ReactTestInstance = within(instance).getByText('Test');
|
||||
const withinGetAllByText: ReactTestInstance[] = within(instance).getAllByText(
|
||||
'Test'
|
||||
);
|
||||
const withinGetByDisplayValue: ReactTestInstance = within(
|
||||
instance
|
||||
).getByDisplayValue('Test');
|
||||
const withinGetAllByDisplayValue: ReactTestInstance[] = within(
|
||||
instance
|
||||
).getAllByDisplayValue('Test');
|
||||
const withinGetByPlaceholder: ReactTestInstance = within(
|
||||
instance
|
||||
).getByPlaceholder('Test');
|
||||
const withinGetAllByPlaceholder: ReactTestInstance[] = within(
|
||||
instance
|
||||
).getAllByPlaceholder('Test');
|
||||
const withinGetByTestId: ReactTestInstance = within(instance).getByTestId(
|
||||
'Test'
|
||||
);
|
||||
const withinGetAllByTestId: ReactTestInstance[] = within(
|
||||
instance
|
||||
).getAllByTestId('Test');
|
||||
|
||||
const withinQueryByText: ReactTestInstance | null = within(
|
||||
instance
|
||||
).queryByText('Test');
|
||||
const withinQueryAllByText: ReactTestInstance[] = within(
|
||||
instance
|
||||
).queryAllByText('Test');
|
||||
const withinQueryByDisplayValue: ReactTestInstance | null = within(
|
||||
instance
|
||||
).queryByDisplayValue('Test');
|
||||
const withinQueryAllByDisplayValue: ReactTestInstance[] = within(
|
||||
instance
|
||||
).queryAllByDisplayValue('Test');
|
||||
const withinQueryByPlaceholder: ReactTestInstance | null = within(
|
||||
instance
|
||||
).queryByPlaceholder('Test');
|
||||
const withinQueryAllByPlaceholder: ReactTestInstance[] = within(
|
||||
instance
|
||||
).queryAllByPlaceholder('Test');
|
||||
const withinQueryByTestId: ReactTestInstance | null = within(
|
||||
instance
|
||||
).queryByTestId('Test');
|
||||
const withinQueryAllByTestId: ReactTestInstance[] = within(
|
||||
instance
|
||||
).queryAllByTestId('Test');
|
||||
const withinGet: Array<ReactTestInstance> = [
|
||||
within(instance).getByText('Test'),
|
||||
within(instance).getByDisplayValue('Test'),
|
||||
within(instance).getByPlaceholder('Test'),
|
||||
within(instance).getByTestId('Test'),
|
||||
within(instance).getByA11yLabel('Test'),
|
||||
within(instance).getByA11yHint('Test'),
|
||||
within(instance).getByA11yRole('button'),
|
||||
within(instance).getByA11yState({ busy: true }),
|
||||
within(instance).getByA11yValue({ min: 10 }),
|
||||
];
|
||||
|
||||
const withinGetByA11yLabel: ReactTestInstance = within(instance).getByA11yLabel(
|
||||
'Test'
|
||||
);
|
||||
const withinGetAllByA11yLabel: ReactTestInstance[] = within(
|
||||
instance
|
||||
).getAllByA11yLabel('Test');
|
||||
const withinGetByA11yHint: ReactTestInstance = within(instance).getByA11yHint(
|
||||
'Test'
|
||||
);
|
||||
const withinGetAllByA11yHint: ReactTestInstance[] = within(
|
||||
instance
|
||||
).getAllByA11yHint('Test');
|
||||
const withinGetByA11yRole: ReactTestInstance = within(instance).getByA11yRole(
|
||||
'button'
|
||||
);
|
||||
const withinGetAllByA11yRole: ReactTestInstance[] = within(
|
||||
instance
|
||||
).getAllByA11yRole('button');
|
||||
const withinGetByA11yState: ReactTestInstance = within(
|
||||
instance
|
||||
).getByA11yState({ busy: true });
|
||||
const withinGetAllByA11yState: ReactTestInstance[] = within(
|
||||
instance
|
||||
).getAllByA11yState({ busy: true });
|
||||
const withinGetByA11yValue: ReactTestInstance = within(
|
||||
instance
|
||||
).getByA11yValue({ min: 10 });
|
||||
const withinGetAllByA11yValue: ReactTestInstance[] = within(
|
||||
instance
|
||||
).getAllByA11yValue({ min: 10 });
|
||||
const withinGetAll: Array<ReactTestInstance[]> = [
|
||||
within(instance).getAllByText('Test'),
|
||||
within(instance).getAllByDisplayValue('Test'),
|
||||
within(instance).getAllByPlaceholder('Test'),
|
||||
within(instance).getAllByTestId('Test'),
|
||||
within(instance).getAllByA11yLabel('Test'),
|
||||
within(instance).getAllByA11yHint('Test'),
|
||||
within(instance).getAllByA11yRole('button'),
|
||||
within(instance).getAllByA11yState({ busy: true }),
|
||||
within(instance).getAllByA11yValue({ min: 10 }),
|
||||
];
|
||||
|
||||
const withinQueryByA11yLabel: ReactTestInstance | null = within(
|
||||
instance
|
||||
).queryByA11yLabel('Test');
|
||||
const withinQueryAllByA11yLabel: ReactTestInstance[] = within(
|
||||
instance
|
||||
).queryAllByA11yLabel('Test');
|
||||
const withinQueryByA11yHint: ReactTestInstance | null = within(
|
||||
instance
|
||||
).queryByA11yHint('Test');
|
||||
const withinQueryAllByA11yHint: ReactTestInstance[] = within(
|
||||
instance
|
||||
).queryAllByA11yHint('Test');
|
||||
const withinQueryByA11yRole: ReactTestInstance | null = within(
|
||||
instance
|
||||
).queryByA11yRole('button');
|
||||
const withinQueryAllByA11yRole: ReactTestInstance[] = within(
|
||||
instance
|
||||
).queryAllByA11yRole('button');
|
||||
const withinQueryByA11yState: ReactTestInstance | null = within(
|
||||
instance
|
||||
).queryByA11yState({ busy: true });
|
||||
const withinQueryAllByA11yState: ReactTestInstance[] = within(
|
||||
instance
|
||||
).queryAllByA11yState({ busy: true });
|
||||
const withinQueryByA11yValue: ReactTestInstance | null = within(
|
||||
instance
|
||||
).queryByA11yValue({ min: 10 });
|
||||
const withinQueryAllByA11yValue: ReactTestInstance[] = within(
|
||||
instance
|
||||
).queryAllByA11yValue({ min: 10 });
|
||||
const withinQuery: Array<ReactTestInstance | null> = [
|
||||
within(instance).queryByText('Test'),
|
||||
within(instance).queryByDisplayValue('Test'),
|
||||
within(instance).queryByPlaceholder('Test'),
|
||||
within(instance).queryByTestId('Test'),
|
||||
within(instance).queryByA11yLabel('Test'),
|
||||
within(instance).queryByA11yHint('Test'),
|
||||
within(instance).queryByA11yRole('button'),
|
||||
within(instance).queryByA11yState({ busy: true }),
|
||||
within(instance).queryByA11yValue({ min: 10 }),
|
||||
];
|
||||
|
||||
const withinQueryAll: Array<ReactTestInstance[]> = [
|
||||
within(instance).queryAllByText('Test'),
|
||||
within(instance).queryAllByDisplayValue('Test'),
|
||||
within(instance).queryAllByPlaceholder('Test'),
|
||||
within(instance).queryAllByTestId('Test'),
|
||||
within(instance).queryAllByA11yLabel('Test'),
|
||||
within(instance).queryAllByA11yHint('Test'),
|
||||
within(instance).queryAllByA11yRole('button'),
|
||||
within(instance).queryAllByA11yState({ busy: true }),
|
||||
within(instance).queryAllByA11yValue({ min: 10 }),
|
||||
];
|
||||
|
||||
const withinFind: Promise<ReactTestInstance>[] = [
|
||||
within(instance).findByText('Test'),
|
||||
within(instance).findByDisplayValue('Test'),
|
||||
within(instance).findByPlaceholder('Test'),
|
||||
within(instance).findByTestId('Test'),
|
||||
within(instance).findByA11yLabel('Test'),
|
||||
within(instance).findByA11yHint('Test'),
|
||||
within(instance).findByA11yRole('button'),
|
||||
within(instance).findByA11yState({ busy: true }),
|
||||
within(instance).findByA11yValue({ min: 10 }),
|
||||
];
|
||||
|
||||
const withinFindAll: Promise<ReactTestInstance[]>[] = [
|
||||
within(instance).findAllByText('Test'),
|
||||
within(instance).findAllByDisplayValue('Test'),
|
||||
within(instance).findAllByPlaceholder('Test'),
|
||||
within(instance).findAllByTestId('Test'),
|
||||
within(instance).findAllByA11yLabel('Test'),
|
||||
within(instance).findAllByA11yHint('Test'),
|
||||
within(instance).findAllByA11yRole('button'),
|
||||
within(instance).findAllByA11yState({ busy: true }),
|
||||
within(instance).findAllByA11yValue({ min: 10 }),
|
||||
];
|
||||
|
||||
Vendored
+86
-7
@@ -2,7 +2,14 @@ import * as React from 'react';
|
||||
import { AccessibilityState, AccessibilityStates, AccessibilityRole } from 'react-native';
|
||||
import { ReactTestInstance, ReactTestRendererJSON } from 'react-test-renderer';
|
||||
|
||||
export interface GetByAPI {
|
||||
type GetReturn = ReactTestInstance;
|
||||
type GetAllReturn = Array<ReactTestInstance>;
|
||||
type QueryReturn = ReactTestInstance | null;
|
||||
type QueryAllReturn = Array<ReactTestInstance> | [];
|
||||
type FindReturn = Promise<ReactTestInstance>;
|
||||
type FindAllReturn = Promise<ReactTestInstance[]>;
|
||||
|
||||
interface GetByAPI {
|
||||
getByName: (name: React.ReactType | string) => ReactTestInstance;
|
||||
getByType: <P>(type: React.ComponentType<P>) => ReactTestInstance;
|
||||
getByText: (text: string | RegExp) => ReactTestInstance;
|
||||
@@ -28,7 +35,7 @@ export interface GetByAPI {
|
||||
UNSAFE_getAllByProps: (props: Record<string, any>) => Array<ReactTestInstance>,
|
||||
}
|
||||
|
||||
export interface QueryByAPI {
|
||||
interface QueryByAPI {
|
||||
queryByName: (name: React.ReactType | string) => ReactTestInstance | null;
|
||||
queryByType: <P>(type: React.ComponentType<P>) => ReactTestInstance | null;
|
||||
queryByText: (name: string | RegExp) => ReactTestInstance | null;
|
||||
@@ -63,10 +70,42 @@ export interface QueryByAPI {
|
||||
UNSAFE_queryAllByProps: (props: Record<string, any>) => Array<ReactTestInstance> | [],
|
||||
}
|
||||
|
||||
type GetReturn = ReactTestInstance;
|
||||
type GetAllReturn = Array<ReactTestInstance>;
|
||||
type QueryReturn = ReactTestInstance | null;
|
||||
type QueryAllReturn = Array<ReactTestInstance> | [];
|
||||
export interface WaitForOptions {
|
||||
timeout: number;
|
||||
interval: number;
|
||||
}
|
||||
|
||||
interface FindByAPI {
|
||||
findByText: (
|
||||
text: string | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindReturn;
|
||||
findByPlaceholder: (
|
||||
placeholder: string | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindReturn;
|
||||
findByDisplayValue: (
|
||||
value: string | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindReturn;
|
||||
findByTestId: (testID: string, waitForOptions?: WaitForOptions) => FindReturn;
|
||||
findAllByText: (
|
||||
text: string | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindAllReturn;
|
||||
findAllByPlaceholder: (
|
||||
placeholder: string | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindAllReturn;
|
||||
findAllByDisplayValue: (
|
||||
value: string | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindAllReturn;
|
||||
findAllByTestId: (
|
||||
testID: string,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindAllReturn;
|
||||
}
|
||||
|
||||
// Not yet available in DefinitelyTyped
|
||||
export type A11yValue = {
|
||||
@@ -82,18 +121,42 @@ type A11yAPI = {
|
||||
getAllByA11yLabel: (matcher: string | RegExp) => GetAllReturn,
|
||||
queryByA11yLabel: (matcher: string | RegExp) => QueryReturn,
|
||||
queryAllByA11yLabel: (matcher: string | RegExp) => QueryAllReturn,
|
||||
findByA11yLabel: (
|
||||
matcher: string | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindReturn;
|
||||
findAllByA11yLabel: (
|
||||
matcher: string | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindAllReturn;
|
||||
|
||||
// Hint
|
||||
getByA11yHint: (matcher: string | RegExp) => GetReturn,
|
||||
getAllByA11yHint: (matcher: string | RegExp) => GetAllReturn,
|
||||
queryByA11yHint: (matcher: string | RegExp) => QueryReturn,
|
||||
queryAllByA11yHint: (matcher: string | RegExp) => QueryAllReturn,
|
||||
findByA11yHint: (
|
||||
matcher: string | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindReturn;
|
||||
findAllByA11yHint: (
|
||||
matcher: string | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindAllReturn;
|
||||
|
||||
// Role
|
||||
getByA11yRole: (matcher: AccessibilityRole | RegExp) => GetReturn,
|
||||
getAllByA11yRole: (matcher: AccessibilityRole | RegExp) => GetAllReturn,
|
||||
queryByA11yRole: (matcher: AccessibilityRole | RegExp) => QueryReturn,
|
||||
queryAllByA11yRole: (matcher: AccessibilityRole | RegExp) => QueryAllReturn,
|
||||
findByA11yRole: (
|
||||
matcher: AccessibilityRole | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindReturn;
|
||||
findAllByA11yRole: (
|
||||
matcher: AccessibilityRole | RegExp,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindAllReturn;
|
||||
|
||||
// States
|
||||
getByA11yStates: (matcher: AccessibilityStates | Array<AccessibilityStates>) => GetReturn,
|
||||
@@ -106,12 +169,28 @@ type A11yAPI = {
|
||||
getAllByA11yState: (matcher: AccessibilityState) => GetAllReturn,
|
||||
queryByA11yState: (matcher: AccessibilityState) => QueryReturn,
|
||||
queryAllByA11yState: (matcher: AccessibilityState) => QueryAllReturn,
|
||||
findByA11yState: (
|
||||
matcher: AccessibilityState,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindReturn;
|
||||
findAllByA11yState: (
|
||||
matcher: AccessibilityState,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindAllReturn;
|
||||
|
||||
// Value
|
||||
getByA11yValue: (matcher: A11yValue) => GetReturn,
|
||||
getAllByA11yValue: (matcher: A11yValue) => GetAllReturn,
|
||||
queryByA11yValue: (matcher: A11yValue) => QueryReturn,
|
||||
queryAllByA11yValue: (matcher: A11yValue) => QueryAllReturn,
|
||||
findByA11yValue: (
|
||||
matcher: A11yValue,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindReturn;
|
||||
findAllByA11yValue: (
|
||||
matcher: A11yValue,
|
||||
waitForOptions?: WaitForOptions
|
||||
) => FindAllReturn;
|
||||
};
|
||||
|
||||
export interface Thenable {
|
||||
@@ -123,7 +202,7 @@ export interface RenderOptions {
|
||||
createNodeMock?: (element: React.ReactElement<any>) => any;
|
||||
}
|
||||
|
||||
type Queries = GetByAPI & QueryByAPI & A11yAPI;
|
||||
type Queries = GetByAPI & QueryByAPI & FindByAPI & A11yAPI;
|
||||
|
||||
export interface RenderAPI extends Queries {
|
||||
update(nextElement: React.ReactElement<any>): void;
|
||||
|
||||
Reference in New Issue
Block a user