-
Notifications
You must be signed in to change notification settings - Fork 560
Expand file tree
/
Copy pathutils.tsx
More file actions
148 lines (135 loc) · 4.18 KB
/
utils.tsx
File metadata and controls
148 lines (135 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import * as React from "react";
import type { MatcherFunction } from "@testing-library/react";
import { render as tlRender, fireEvent } from "@testing-library/react";
import { renderHook as tlRenderHook } from "@testing-library/react-hooks";
import type {
RenderHookOptions,
RenderHookResult,
RenderOptions,
RenderResult,
} from "./types";
/**
* This function is useful if you want to query a DOM element by its text
* string, but the text is split up by nested DOM elements.
*
* @example
* it('tests foo and bar', () => {
* const { getByText } = render(<App />)
* const getByTextWithMarkup = withMarkup(getByText)
* let node = getByTextWithMarkup('Hello, world');
* expect(node).toBeInTheDocument()
* });
*
* function App() {
* return <span>Hello, <span>world</span></span>
* }
*
* @param query The getter function returned from RTL's render method
*/
export function withMarkup(query: Query) {
return (text: string): HTMLElement | null =>
query((content, node) => {
if (!node) {
return false;
}
const hasText = (node: Element) => node.textContent === text;
const childrenDontHaveText = Array.from(node.children).every(
(child) => !hasText(child as HTMLElement)
);
return hasText(node) && childrenDontHaveText;
});
}
/**
* Fire keydown followed immediately by keyup
* @param element
* @param key
*/
export function keyType(element: HTMLElement | Document, key: string) {
fireEvent.keyDown(element, { key });
fireEvent.keyUp(element, { key });
}
export function render<
P extends React.HTMLAttributes<T>,
T extends HTMLElement
>(
element: React.ReactElement<any>,
options: RenderOptions = {}
): RenderResult<P, T> {
let { baseElement, strict = false } = options;
let result = tlRender(element, {
baseElement,
wrapper: strict ? React.StrictMode : React.Fragment,
}) as unknown as RenderResult<P, T>;
// These handy functions courtesy of https://github.com/mui-org/material-ui
result.setProps = function setProps(props: P) {
result.rerender(React.cloneElement(element, props));
return result;
} as any;
result.forceUpdate = function forceUpdate() {
result.rerender(
React.cloneElement(element, {
"data-force-update": String(Math.random()),
})
);
return result;
};
return result;
}
export function renderHook<TProps, TResult>(
callback: (props: TProps) => TResult,
options: RenderHookOptions<TProps> = {}
): RenderHookResult<TResult, TProps> {
const { strict = false, ...restOptions } = options;
return tlRenderHook(callback, {
...restOptions,
wrapper: strict ? React.StrictMode : React.Fragment,
});
}
export async function wait(time: number) {
return await new Promise<void>((res) => setTimeout(res, time));
}
/**
* When a user clicks with a mouse, mousedown, mouseup and then click events
* are fired. Some packages rely on mousedown and mouseup events where click
* might be assumed by most consumers. This helper fires all three events in
* order to make testing a bit more predictable.
* @see https://testing-library.com/docs/guide-events#interactions-vs-events
* @param element
*/
export function simulateMouseClick(element: HTMLElement) {
fireEvent.pointerDown(element, { pointerType: "mouse" });
fireEvent.mouseDown(element);
fireEvent.pointerUp(element, { pointerType: "mouse" });
fireEvent.mouseUp(element);
fireEvent.click(element);
}
export function simulateSpaceKeyClick(
element: HTMLElement,
opts?: { fireClick?: boolean }
) {
let { fireClick } = opts || {};
fireEvent.keyDown(element, { key: " " });
fireEvent.keyUp(element, { key: " " });
if (fireClick) {
fireEvent.click(element);
}
}
export function simulateEnterKeyClick(
element: HTMLElement,
opts?: { fireClick?: boolean }
) {
let { fireClick } = opts || {};
fireEvent.keyDown(element, { key: "Enter" });
fireEvent.keyUp(element, { key: "Enter" });
if (fireClick) {
fireEvent.click(element);
}
}
type Query = (f: MatcherFunction) => HTMLElement | null;
export {
cleanup as cleanupHooks,
act as actHooks,
} from "@testing-library/react-hooks";
export { cleanup, fireEvent, screen, act } from "@testing-library/react";
export { default as userEvent } from "@testing-library/user-event";
export type { RenderOptions, RenderResult };