Skip to content

Commit

Permalink
[@testing-library/react_v9.x.x] render() type safety for custom queri…
Browse files Browse the repository at this point in the history
…es (#3705)
  • Loading branch information
valscion authored and pascalduez committed Jan 26, 2020
1 parent 35950c1 commit 9facc3c
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,182 +115,204 @@ declare module '@testing-library/react' {
eventProperties?: TInit
) => boolean;

declare type RenderResult = {|
declare type RenderResult<Queries = GetsAndQueries> = {|
container: HTMLDivElement,
unmount: () => void,
baseElement: HTMLElement,
asFragment: () => DocumentFragment,
debug: (baseElement?: HTMLElement) => void,
rerender: (ui: React$Element<*>) => void,
|} & GetsAndQueries;
|} & Queries;
declare type RenderResultWithCustomQueries<CustomQueries> = {
...CustomQueries,
container: HTMLDivElement,
unmount: () => void,
baseElement: HTMLElement,
asFragment: () => DocumentFragment,
debug: (baseElement?: HTMLElement) => void,
rerender: (ui: React$Element<*>) => void,
...
};

declare export type RenderOptions = {|
declare export type RenderOptionsWithoutCustomQueries = {|
container?: HTMLElement,
baseElement?: HTMLElement,
hydrate?: boolean,
queries?: any,
wrapper?: React.ComponentType,
|};

declare module.exports: {
render(
ui: React.ReactElement<any>,
options?: RenderOptions
): RenderResult,
declare export type RenderOptionsWithCustomQueries<
CustomQueries: { ... }
> = {|
queries: CustomQueries,
container?: HTMLElement,
baseElement?: HTMLElement,
hydrate?: boolean,
wrapper?: React.ComponentType,
|};

act: ReactDOMTestUtilsAct,
cleanup: () => void,
wait: (
callback?: () => void,
options?: {
timeout?: number,
interval?: number,
...
}
) => Promise<void>,
waitForDomChange: <T>(options?: {
declare export function render(
ui: React.ReactElement<any>,
options?: RenderOptionsWithoutCustomQueries
): RenderResult<>;
declare export function render<
CustomQueries: { [string]: (...args: Array<any>) => any, ... }
>(
ui: React.ReactElement<any>,
options: RenderOptionsWithCustomQueries<CustomQueries>
): RenderResultWithCustomQueries<CustomQueries>;

declare export var act: ReactDOMTestUtilsAct;
declare export function cleanup(): void;
declare export function wait(
callback?: () => void,
options?: {
timeout?: number,
interval?: number,
...
}
): Promise<void>;
declare export function waitForDomChange<T>(options?: {
container?: HTMLElement,
timeout?: number,
mutationObserverOptions?: MutationObserverInit,
...
}): Promise<T>;
declare export function waitForElement<T>(
callback?: () => T,
options?: {
container?: HTMLElement,
timeout?: number,
mutationObserverOptions?: MutationObserverInit,
...
}) => Promise<T>,
waitForElement: <T>(
callback?: () => T,
options?: {
container?: HTMLElement,
timeout?: number,
mutationObserverOptions?: MutationObserverInit,
...
}
) => Promise<T>,
within: (
element: HTMLElement,
queriesToBind?: GetsAndQueries | Array<GetsAndQueries>
) => GetsAndQueries,
fireEvent: {|
(element: HTMLElement, event: Event): void,
}
): Promise<T>;
declare export function within(
element: HTMLElement,
queriesToBind?: GetsAndQueries | Array<GetsAndQueries>
): GetsAndQueries;
declare export var fireEvent: {|
(element: HTMLElement, event: Event): void,

copy: FireEvent<Event$Init>,
cut: FireEvent<Event$Init>,
paste: FireEvent<Event$Init>,
compositionEnd: FireEvent<Event$Init>,
compositionStart: FireEvent<Event$Init>,
compositionUpdate: FireEvent<Event$Init>,
keyDown: FireEvent<Event$Init>,
keyPress: FireEvent<Event$Init>,
keyUp: FireEvent<Event$Init>,
focus: FireEvent<Event$Init>,
blur: FireEvent<Event$Init>,
change: FireEvent<Event$Init>,
input: FireEvent<Event$Init>,
invalid: FireEvent<Event$Init>,
submit: FireEvent<Event$Init>,
click: FireEvent<MouseEvent$MouseEventInit>,
contextMenu: FireEvent<MouseEvent$MouseEventInit>,
dblClick: FireEvent<MouseEvent$MouseEventInit>,
doubleClick: FireEvent<MouseEvent$MouseEventInit>,
drag: FireEvent<MouseEvent$MouseEventInit>,
dragEnd: FireEvent<MouseEvent$MouseEventInit>,
dragEnter: FireEvent<MouseEvent$MouseEventInit>,
dragExit: FireEvent<MouseEvent$MouseEventInit>,
dragLeave: FireEvent<MouseEvent$MouseEventInit>,
dragOver: FireEvent<MouseEvent$MouseEventInit>,
dragStart: FireEvent<MouseEvent$MouseEventInit>,
drop: FireEvent<MouseEvent$MouseEventInit>,
mouseDown: FireEvent<MouseEvent$MouseEventInit>,
mouseEnter: FireEvent<MouseEvent$MouseEventInit>,
mouseLeave: FireEvent<MouseEvent$MouseEventInit>,
mouseMove: FireEvent<MouseEvent$MouseEventInit>,
mouseOut: FireEvent<MouseEvent$MouseEventInit>,
mouseOver: FireEvent<MouseEvent$MouseEventInit>,
mouseUp: FireEvent<MouseEvent$MouseEventInit>,
select: FireEvent<Event$Init>,
touchCancel: FireEvent<Event$Init>,
touchEnd: FireEvent<Event$Init>,
touchMove: FireEvent<Event$Init>,
touchStart: FireEvent<Event$Init>,
scroll: FireEvent<Event$Init>,
wheel: FireEvent<MouseEvent$MouseEventInit>,
abort: FireEvent<Event$Init>,
canPlay: FireEvent<Event$Init>,
canPlayThrough: FireEvent<Event$Init>,
durationChange: FireEvent<Event$Init>,
emptied: FireEvent<Event$Init>,
encrypted: FireEvent<Event$Init>,
ended: FireEvent<Event$Init>,
loadedData: FireEvent<Event$Init>,
loadedMetadata: FireEvent<Event$Init>,
loadStart: FireEvent<Event$Init>,
pause: FireEvent<Event$Init>,
play: FireEvent<Event$Init>,
playing: FireEvent<Event$Init>,
progress: FireEvent<Event$Init>,
rateChange: FireEvent<Event$Init>,
seeked: FireEvent<Event$Init>,
seeking: FireEvent<Event$Init>,
stalled: FireEvent<Event$Init>,
suspend: FireEvent<Event$Init>,
timeUpdate: FireEvent<Event$Init>,
volumeChange: FireEvent<Event$Init>,
waiting: FireEvent<Event$Init>,
load: FireEvent<Event$Init>,
error: FireEvent<Event$Init>,
animationStart: FireEvent<Event$Init>,
animationEnd: FireEvent<Event$Init>,
animationIteration: FireEvent<Event$Init>,
transitionEnd: FireEvent<Event$Init>,
|},
// dom-testing-library re-exports
queryByTestId: (
container: HTMLElement,
id: TextMatch,
options?: TextMatchOptions
) => ?HTMLElement,
getByTestId: (
container: HTMLElement,
id: TextMatch,
options?: TextMatchOptions
) => HTMLElement,
queryByText: (
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
) => ?HTMLElement,
getByText: (
container: HTMLElement,
text: TextMatch,
options?: { selector?: string, ... } & TextMatchOptions
) => HTMLElement,
queryByPlaceholderText: (
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
) => ?HTMLElement,
getByPlaceholderText: (
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
) => HTMLElement,
queryByLabelText: (
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
) => ?HTMLElement,
getByLabelText: (
container: HTMLElement,
text: TextMatch,
options?: { selector?: string, ... } & TextMatchOptions
) => HTMLElement,
queryByAltText: (
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
) => ?HTMLElement,
getByAltText: (
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
) => HTMLElement,
...
};
copy: FireEvent<Event$Init>,
cut: FireEvent<Event$Init>,
paste: FireEvent<Event$Init>,
compositionEnd: FireEvent<Event$Init>,
compositionStart: FireEvent<Event$Init>,
compositionUpdate: FireEvent<Event$Init>,
keyDown: FireEvent<Event$Init>,
keyPress: FireEvent<Event$Init>,
keyUp: FireEvent<Event$Init>,
focus: FireEvent<Event$Init>,
blur: FireEvent<Event$Init>,
change: FireEvent<Event$Init>,
input: FireEvent<Event$Init>,
invalid: FireEvent<Event$Init>,
submit: FireEvent<Event$Init>,
click: FireEvent<MouseEvent$MouseEventInit>,
contextMenu: FireEvent<MouseEvent$MouseEventInit>,
dblClick: FireEvent<MouseEvent$MouseEventInit>,
doubleClick: FireEvent<MouseEvent$MouseEventInit>,
drag: FireEvent<MouseEvent$MouseEventInit>,
dragEnd: FireEvent<MouseEvent$MouseEventInit>,
dragEnter: FireEvent<MouseEvent$MouseEventInit>,
dragExit: FireEvent<MouseEvent$MouseEventInit>,
dragLeave: FireEvent<MouseEvent$MouseEventInit>,
dragOver: FireEvent<MouseEvent$MouseEventInit>,
dragStart: FireEvent<MouseEvent$MouseEventInit>,
drop: FireEvent<MouseEvent$MouseEventInit>,
mouseDown: FireEvent<MouseEvent$MouseEventInit>,
mouseEnter: FireEvent<MouseEvent$MouseEventInit>,
mouseLeave: FireEvent<MouseEvent$MouseEventInit>,
mouseMove: FireEvent<MouseEvent$MouseEventInit>,
mouseOut: FireEvent<MouseEvent$MouseEventInit>,
mouseOver: FireEvent<MouseEvent$MouseEventInit>,
mouseUp: FireEvent<MouseEvent$MouseEventInit>,
select: FireEvent<Event$Init>,
touchCancel: FireEvent<Event$Init>,
touchEnd: FireEvent<Event$Init>,
touchMove: FireEvent<Event$Init>,
touchStart: FireEvent<Event$Init>,
scroll: FireEvent<Event$Init>,
wheel: FireEvent<MouseEvent$MouseEventInit>,
abort: FireEvent<Event$Init>,
canPlay: FireEvent<Event$Init>,
canPlayThrough: FireEvent<Event$Init>,
durationChange: FireEvent<Event$Init>,
emptied: FireEvent<Event$Init>,
encrypted: FireEvent<Event$Init>,
ended: FireEvent<Event$Init>,
loadedData: FireEvent<Event$Init>,
loadedMetadata: FireEvent<Event$Init>,
loadStart: FireEvent<Event$Init>,
pause: FireEvent<Event$Init>,
play: FireEvent<Event$Init>,
playing: FireEvent<Event$Init>,
progress: FireEvent<Event$Init>,
rateChange: FireEvent<Event$Init>,
seeked: FireEvent<Event$Init>,
seeking: FireEvent<Event$Init>,
stalled: FireEvent<Event$Init>,
suspend: FireEvent<Event$Init>,
timeUpdate: FireEvent<Event$Init>,
volumeChange: FireEvent<Event$Init>,
waiting: FireEvent<Event$Init>,
load: FireEvent<Event$Init>,
error: FireEvent<Event$Init>,
animationStart: FireEvent<Event$Init>,
animationEnd: FireEvent<Event$Init>,
animationIteration: FireEvent<Event$Init>,
transitionEnd: FireEvent<Event$Init>,
|};
// dom-testing-library re-exports
declare export function queryByTestId(
container: HTMLElement,
id: TextMatch,
options?: TextMatchOptions
): ?HTMLElement;
declare export function getByTestId(
container: HTMLElement,
id: TextMatch,
options?: TextMatchOptions
): HTMLElement;
declare export function queryByText(
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
): ?HTMLElement;
declare export function getByText(
container: HTMLElement,
text: TextMatch,
options?: { selector?: string, ... } & TextMatchOptions
): HTMLElement;
declare export function queryByPlaceholderText(
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
): ?HTMLElement;
declare export function getByPlaceholderText(
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
): HTMLElement;
declare export function queryByLabelText(
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
): ?HTMLElement;
declare export function getByLabelText(
container: HTMLElement,
text: TextMatch,
options?: { selector?: string, ... } & TextMatchOptions
): HTMLElement;
declare export function queryByAltText(
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
): ?HTMLElement;
declare export function getByAltText(
container: HTMLElement,
text: TextMatch,
options?: TextMatchOptions
): HTMLElement;
}
Original file line number Diff line number Diff line change
Expand Up @@ -1134,4 +1134,20 @@ describe('render() parameters', () => {
wrapper: CustomWrapper,
});
});

it('allows overriding render() with custom queries', () => {
type CustomReturnType = 123456;
declare var customValue: CustomReturnType;
const customQueries = {
getByOverride: (param1: string) => customValue,
};
const result = render(<Component />, { queries: customQueries });
const a: CustomReturnType = result.getByOverride('something');
// $ExpectError bad type for getByOverride parameter
result.getByOverride(1234);
// $ExpectError missing getByOverride parameter
result.getByOverride();
// $ExpectError default queries are not available when using custom queries
result.getByTestId('indifferent');
});
});

0 comments on commit 9facc3c

Please sign in to comment.