@mui/internal-test-utils 2.0.15 → 2.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{src/chai.types.ts → chai.types.d.ts} +7 -40
- package/chai.types.js +5 -0
- package/chaiPlugin.d.ts +4 -0
- package/chaiPlugin.js +287 -0
- package/{build/components.d.ts → components.d.ts} +18 -19
- package/components.js +64 -0
- package/createDOM.d.ts +2 -0
- package/{src/createDOM.js → createDOM.js} +17 -35
- package/createDescribe.d.ts +7 -0
- package/createDescribe.js +26 -0
- package/createRenderer.d.ts +214 -0
- package/createRenderer.js +428 -0
- package/createRenderer.test.d.ts +1 -0
- package/describeConformance.d.ts +200 -0
- package/describeConformance.js +1038 -0
- package/env.d.ts +1 -0
- package/env.js +11 -0
- package/esm/chai.types.d.ts +74 -0
- package/esm/chai.types.js +3 -0
- package/esm/chaiPlugin.d.ts +4 -0
- package/esm/chaiPlugin.js +281 -0
- package/esm/components.d.ts +35 -0
- package/esm/components.js +56 -0
- package/esm/createDOM.d.ts +2 -0
- package/esm/createDOM.js +47 -0
- package/esm/createDescribe.d.ts +7 -0
- package/esm/createDescribe.js +19 -0
- package/esm/createRenderer.d.ts +214 -0
- package/esm/createRenderer.js +390 -0
- package/esm/createRenderer.test.d.ts +1 -0
- package/esm/describeConformance.d.ts +200 -0
- package/esm/describeConformance.js +1024 -0
- package/esm/env.d.ts +1 -0
- package/esm/env.js +5 -0
- package/{build → esm}/fireDiscreteEvent.d.ts +1 -2
- package/{src/fireDiscreteEvent.ts → esm/fireDiscreteEvent.js} +10 -18
- package/esm/flushMicrotasks.d.ts +1 -0
- package/{src/flushMicrotasks.ts → esm/flushMicrotasks.js} +2 -3
- package/{build → esm}/focusVisible.d.ts +1 -2
- package/{src/focusVisible.ts → esm/focusVisible.js} +10 -9
- package/esm/index.d.ts +18 -0
- package/esm/index.js +27 -0
- package/esm/init.d.ts +1 -0
- package/{src → esm}/init.js +4 -2
- package/esm/initMatchers.d.ts +1 -0
- package/esm/initMatchers.js +6 -0
- package/esm/initMatchers.test.d.ts +1 -0
- package/esm/initPlaywrightMatchers.d.ts +24 -0
- package/esm/initPlaywrightMatchers.js +40 -0
- package/esm/package.json +1 -0
- package/esm/reactMajor.d.ts +2 -0
- package/esm/reactMajor.js +2 -0
- package/esm/setup.d.ts +1 -0
- package/{src → esm}/setup.js +2 -4
- package/esm/setupVitest.d.ts +1 -0
- package/esm/setupVitest.js +28 -0
- package/esm/setupVitestBrowser.d.ts +1 -0
- package/esm/setupVitestBrowser.js +30 -0
- package/fireDiscreteEvent.d.ts +6 -0
- package/fireDiscreteEvent.js +79 -0
- package/flushMicrotasks.d.ts +1 -0
- package/flushMicrotasks.js +10 -0
- package/focusVisible.d.ts +7 -0
- package/focusVisible.js +44 -0
- package/index.d.ts +18 -0
- package/index.js +139 -0
- package/init.d.ts +1 -0
- package/init.js +15 -0
- package/initMatchers.d.ts +1 -0
- package/initMatchers.js +10 -0
- package/initMatchers.test.d.ts +1 -0
- package/initPlaywrightMatchers.d.ts +24 -0
- package/initPlaywrightMatchers.js +42 -0
- package/package.json +89 -46
- package/reactMajor.d.ts +2 -0
- package/reactMajor.js +9 -0
- package/setup.d.ts +1 -0
- package/setup.js +10 -0
- package/setupVitest.d.ts +1 -0
- package/setupVitest.js +32 -0
- package/setupVitestBrowser.d.ts +1 -0
- package/setupVitestBrowser.js +34 -0
- package/build/.tsbuildinfo +0 -1
- package/build/KarmaReporterReactProfiler.d.ts +0 -51
- package/build/KarmaReporterReactProfiler.d.ts.map +0 -1
- package/build/KarmaReporterReactProfiler.js +0 -66
- package/build/KarmaReporterReactProfiler.js.map +0 -1
- package/build/chai.types.d.ts +0 -75
- package/build/chai.types.d.ts.map +0 -1
- package/build/chai.types.js +0 -3
- package/build/chai.types.js.map +0 -1
- package/build/chaiPlugin.d.ts +0 -5
- package/build/chaiPlugin.d.ts.map +0 -1
- package/build/chaiPlugin.js +0 -416
- package/build/chaiPlugin.js.map +0 -1
- package/build/components.d.ts.map +0 -1
- package/build/components.js +0 -88
- package/build/components.js.map +0 -1
- package/build/createDOM.d.ts +0 -3
- package/build/createDOM.d.ts.map +0 -1
- package/build/createDOM.js +0 -60
- package/build/createDOM.js.map +0 -1
- package/build/createDescribe.d.ts +0 -8
- package/build/createDescribe.d.ts.map +0 -1
- package/build/createDescribe.js +0 -22
- package/build/createDescribe.js.map +0 -1
- package/build/createRenderer.d.ts +0 -215
- package/build/createRenderer.d.ts.map +0 -1
- package/build/createRenderer.js +0 -564
- package/build/createRenderer.js.map +0 -1
- package/build/createRenderer.test.d.ts +0 -2
- package/build/createRenderer.test.d.ts.map +0 -1
- package/build/createRenderer.test.js +0 -58
- package/build/createRenderer.test.js.map +0 -1
- package/build/describeConformance.d.ts +0 -201
- package/build/describeConformance.d.ts.map +0 -1
- package/build/describeConformance.js +0 -859
- package/build/describeConformance.js.map +0 -1
- package/build/describeSkipIf.d.ts +0 -4
- package/build/describeSkipIf.d.ts.map +0 -1
- package/build/describeSkipIf.js +0 -10
- package/build/describeSkipIf.js.map +0 -1
- package/build/fireDiscreteEvent.d.ts.map +0 -1
- package/build/fireDiscreteEvent.js +0 -77
- package/build/fireDiscreteEvent.js.map +0 -1
- package/build/flushMicrotasks.d.ts +0 -2
- package/build/flushMicrotasks.d.ts.map +0 -1
- package/build/flushMicrotasks.js +0 -8
- package/build/flushMicrotasks.js.map +0 -1
- package/build/focusVisible.d.ts.map +0 -1
- package/build/focusVisible.js +0 -38
- package/build/focusVisible.js.map +0 -1
- package/build/index.d.ts +0 -18
- package/build/index.d.ts.map +0 -1
- package/build/index.js +0 -68
- package/build/index.js.map +0 -1
- package/build/init.d.ts +0 -2
- package/build/init.d.ts.map +0 -1
- package/build/init.js +0 -46
- package/build/init.js.map +0 -1
- package/build/initMatchers.d.ts +0 -2
- package/build/initMatchers.d.ts.map +0 -1
- package/build/initMatchers.js +0 -45
- package/build/initMatchers.js.map +0 -1
- package/build/initMatchers.test.d.ts +0 -2
- package/build/initMatchers.test.d.ts.map +0 -1
- package/build/initMatchers.test.js +0 -101
- package/build/initMatchers.test.js.map +0 -1
- package/build/initPlaywrightMatchers.d.ts +0 -25
- package/build/initPlaywrightMatchers.d.ts.map +0 -1
- package/build/initPlaywrightMatchers.js +0 -73
- package/build/initPlaywrightMatchers.js.map +0 -1
- package/build/mochaHooks.d.ts +0 -24
- package/build/mochaHooks.d.ts.map +0 -1
- package/build/mochaHooks.js +0 -165
- package/build/mochaHooks.js.map +0 -1
- package/build/mochaHooks.test.d.ts +0 -2
- package/build/mochaHooks.test.d.ts.map +0 -1
- package/build/mochaHooks.test.js +0 -128
- package/build/mochaHooks.test.js.map +0 -1
- package/build/reactMajor.d.ts +0 -3
- package/build/reactMajor.d.ts.map +0 -1
- package/build/reactMajor.js +0 -38
- package/build/reactMajor.js.map +0 -1
- package/build/setup.d.ts +0 -2
- package/build/setup.d.ts.map +0 -1
- package/build/setup.js +0 -10
- package/build/setup.js.map +0 -1
- package/build/setupBabel.d.ts +0 -2
- package/build/setupBabel.d.ts.map +0 -1
- package/build/setupBabel.js +0 -5
- package/build/setupBabel.js.map +0 -1
- package/build/setupBabelPlaywright.d.ts +0 -2
- package/build/setupBabelPlaywright.d.ts.map +0 -1
- package/build/setupBabelPlaywright.js +0 -14
- package/build/setupBabelPlaywright.js.map +0 -1
- package/build/setupJSDOM.d.ts +0 -7
- package/build/setupJSDOM.d.ts.map +0 -1
- package/build/setupJSDOM.js +0 -17
- package/build/setupJSDOM.js.map +0 -1
- package/build/setupKarma.d.ts +0 -2
- package/build/setupKarma.d.ts.map +0 -1
- package/build/setupKarma.js +0 -56
- package/build/setupKarma.js.map +0 -1
- package/build/setupVitest.d.ts +0 -2
- package/build/setupVitest.d.ts.map +0 -1
- package/build/setupVitest.js +0 -131
- package/build/setupVitest.js.map +0 -1
- package/src/KarmaReporterReactProfiler.js +0 -82
- package/src/chai-augmentation.d.ts +0 -8
- package/src/chaiPlugin.ts +0 -515
- package/src/components.tsx +0 -61
- package/src/createDOM.d.ts +0 -9
- package/src/createDescribe.ts +0 -31
- package/src/createRenderer.test.js +0 -31
- package/src/createRenderer.tsx +0 -808
- package/src/describeConformance.tsx +0 -1257
- package/src/describeSkipIf.tsx +0 -11
- package/src/index.ts +0 -25
- package/src/initMatchers.test.js +0 -124
- package/src/initMatchers.ts +0 -7
- package/src/initPlaywrightMatchers.ts +0 -101
- package/src/mochaHooks.js +0 -200
- package/src/mochaHooks.test.js +0 -116
- package/src/reactMajor.ts +0 -3
- package/src/setupBabel.js +0 -3
- package/src/setupBabelPlaywright.js +0 -13
- package/src/setupJSDOM.js +0 -20
- package/src/setupKarma.js +0 -65
- package/src/setupVitest.ts +0 -117
- package/tsconfig.build.json +0 -16
- package/tsconfig.json +0 -17
package/src/createRenderer.tsx
DELETED
|
@@ -1,808 +0,0 @@
|
|
|
1
|
-
/* eslint-env mocha */
|
|
2
|
-
/* eslint-disable compat/compat -- Test environment */
|
|
3
|
-
import createEmotionCache from '@emotion/cache';
|
|
4
|
-
import { CacheProvider as EmotionCacheProvider } from '@emotion/react';
|
|
5
|
-
import {
|
|
6
|
-
buildQueries,
|
|
7
|
-
cleanup,
|
|
8
|
-
prettyDOM,
|
|
9
|
-
queries,
|
|
10
|
-
RenderResult,
|
|
11
|
-
act as rtlAct,
|
|
12
|
-
fireEvent as rtlFireEvent,
|
|
13
|
-
screen as rtlScreen,
|
|
14
|
-
Screen,
|
|
15
|
-
render as testingLibraryRender,
|
|
16
|
-
RenderOptions as TestingLibraryRenderOptions,
|
|
17
|
-
within,
|
|
18
|
-
} from '@testing-library/react/pure';
|
|
19
|
-
import { userEvent } from '@testing-library/user-event';
|
|
20
|
-
import * as React from 'react';
|
|
21
|
-
import * as ReactDOMServer from 'react-dom/server';
|
|
22
|
-
import { useFakeTimers } from 'sinon';
|
|
23
|
-
import reactMajor from './reactMajor';
|
|
24
|
-
|
|
25
|
-
interface Interaction {
|
|
26
|
-
id: number;
|
|
27
|
-
name: string;
|
|
28
|
-
timestamp: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const enableDispatchingProfiler = process.env.TEST_GATE === 'enable-dispatching-profiler';
|
|
32
|
-
|
|
33
|
-
function noTrace<T>(interactionName: string, callback: () => T): T {
|
|
34
|
-
return callback();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Path used in Error.prototype.stack.
|
|
39
|
-
*
|
|
40
|
-
* Computed in `before` hook.
|
|
41
|
-
*/
|
|
42
|
-
let workspaceRoot: string;
|
|
43
|
-
|
|
44
|
-
let interactionID = 0;
|
|
45
|
-
const interactionStack: Interaction[] = [];
|
|
46
|
-
/**
|
|
47
|
-
* interactionName - Human readable label for this particular interaction.
|
|
48
|
-
*/
|
|
49
|
-
function traceByStackSync<T>(interactionName: string, callback: () => T): T {
|
|
50
|
-
const { stack } = new Error();
|
|
51
|
-
const testLines = stack!
|
|
52
|
-
.split(/\r?\n/)
|
|
53
|
-
.map((line) => {
|
|
54
|
-
// anonymous functions create a "weird" stackframe like
|
|
55
|
-
// "at path/to/actual.test.js (path/to/utility/file.js <- karma.test.js)"
|
|
56
|
-
// and we just want "path/to/actual.test.js" not "karma.test.js"
|
|
57
|
-
// TODO: Only supports chrome at the moment
|
|
58
|
-
const fileMatch = line.match(/([^\s(]+\.test\.(js|ts|tsx)):(\d+):(\d+)/);
|
|
59
|
-
if (fileMatch === null) {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
return { name: fileMatch[1], line: +fileMatch[3], column: +fileMatch[4] };
|
|
63
|
-
})
|
|
64
|
-
.filter((maybeTestFile): maybeTestFile is NonNullable<typeof maybeTestFile> => {
|
|
65
|
-
return maybeTestFile !== null;
|
|
66
|
-
})
|
|
67
|
-
.map((file) => {
|
|
68
|
-
return `${file.name.replace(workspaceRoot, '')}:${file.line}:${file.column}`;
|
|
69
|
-
});
|
|
70
|
-
const originLine = testLines[testLines.length - 1] ?? 'unknown line';
|
|
71
|
-
|
|
72
|
-
interactionID += 1;
|
|
73
|
-
const interaction: Interaction = {
|
|
74
|
-
id: interactionID,
|
|
75
|
-
name: `${originLine} (${interactionName})`,
|
|
76
|
-
timestamp: performance.now(),
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
interactionStack.push(interaction);
|
|
80
|
-
try {
|
|
81
|
-
return callback();
|
|
82
|
-
} finally {
|
|
83
|
-
interactionStack.pop();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
interface Profiler {
|
|
88
|
-
id: string;
|
|
89
|
-
onRender: import('react').ProfilerOnRenderCallback;
|
|
90
|
-
report(): void;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
class NoopProfiler implements Profiler {
|
|
94
|
-
id = 'noop';
|
|
95
|
-
|
|
96
|
-
onRender() {}
|
|
97
|
-
|
|
98
|
-
report() {}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
type RenderMark = [
|
|
102
|
-
id: string,
|
|
103
|
-
phase: 'mount' | 'update' | 'nested-update',
|
|
104
|
-
actualDuration: number,
|
|
105
|
-
baseDuration: number,
|
|
106
|
-
startTime: number,
|
|
107
|
-
commitTime: number,
|
|
108
|
-
interactions: Interaction[],
|
|
109
|
-
];
|
|
110
|
-
|
|
111
|
-
class DispatchingProfiler implements Profiler {
|
|
112
|
-
id: string;
|
|
113
|
-
|
|
114
|
-
private renders: RenderMark[] = [];
|
|
115
|
-
|
|
116
|
-
constructor(id: string) {
|
|
117
|
-
this.id = id;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
onRender: Profiler['onRender'] = (
|
|
121
|
-
id,
|
|
122
|
-
phase,
|
|
123
|
-
actualDuration,
|
|
124
|
-
baseDuration,
|
|
125
|
-
startTime,
|
|
126
|
-
commitTime,
|
|
127
|
-
) => {
|
|
128
|
-
// Do minimal work here to keep the render fast.
|
|
129
|
-
// Though it's unclear whether work here affects the profiler results.
|
|
130
|
-
// But even if it doesn't we'll keep the test feedback snappy.
|
|
131
|
-
this.renders.push([
|
|
132
|
-
id,
|
|
133
|
-
phase,
|
|
134
|
-
actualDuration,
|
|
135
|
-
baseDuration,
|
|
136
|
-
startTime,
|
|
137
|
-
commitTime,
|
|
138
|
-
interactionStack.slice(),
|
|
139
|
-
]);
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
report() {
|
|
143
|
-
const event = new window.CustomEvent('reactProfilerResults', {
|
|
144
|
-
detail: {
|
|
145
|
-
[this.id]: this.renders.map((entry) => {
|
|
146
|
-
return {
|
|
147
|
-
phase: entry[1],
|
|
148
|
-
actualDuration: entry[2],
|
|
149
|
-
baseDuration: entry[3],
|
|
150
|
-
startTime: entry[4],
|
|
151
|
-
commitTime: entry[5],
|
|
152
|
-
interactions: entry[6],
|
|
153
|
-
};
|
|
154
|
-
}),
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
window.dispatchEvent(event);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const UsedProfiler = enableDispatchingProfiler ? DispatchingProfiler : NoopProfiler;
|
|
162
|
-
const traceSync = enableDispatchingProfiler ? traceByStackSync : noTrace;
|
|
163
|
-
|
|
164
|
-
function queryAllDescriptionsOf(baseElement: HTMLElement, element: Element): HTMLElement[] {
|
|
165
|
-
const ariaDescribedBy = element.getAttribute('aria-describedby');
|
|
166
|
-
if (ariaDescribedBy === null) {
|
|
167
|
-
return [];
|
|
168
|
-
}
|
|
169
|
-
return ariaDescribedBy
|
|
170
|
-
.split(' ')
|
|
171
|
-
.map((id) => {
|
|
172
|
-
return document.getElementById(id);
|
|
173
|
-
})
|
|
174
|
-
.filter((maybeElement): maybeElement is HTMLElement => {
|
|
175
|
-
return maybeElement !== null && baseElement.contains(maybeElement);
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const [
|
|
180
|
-
queryDescriptionOf,
|
|
181
|
-
getAllDescriptionsOf,
|
|
182
|
-
getDescriptionOf,
|
|
183
|
-
findAllDescriptionsOf,
|
|
184
|
-
findDescriptionOf,
|
|
185
|
-
] = buildQueries<[Element]>(
|
|
186
|
-
queryAllDescriptionsOf,
|
|
187
|
-
function getMultipleError() {
|
|
188
|
-
return `Found multiple descriptions.`;
|
|
189
|
-
},
|
|
190
|
-
function getMissingError() {
|
|
191
|
-
return `Found no describing element.`;
|
|
192
|
-
},
|
|
193
|
-
);
|
|
194
|
-
|
|
195
|
-
const customQueries = {
|
|
196
|
-
queryDescriptionOf,
|
|
197
|
-
queryAllDescriptionsOf,
|
|
198
|
-
getDescriptionOf,
|
|
199
|
-
getAllDescriptionsOf,
|
|
200
|
-
findDescriptionOf,
|
|
201
|
-
findAllDescriptionsOf,
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
interface RenderConfiguration extends Pick<TestingLibraryRenderOptions, 'reactStrictMode'> {
|
|
205
|
-
/**
|
|
206
|
-
* https://testing-library.com/docs/react-testing-library/api#container
|
|
207
|
-
*/
|
|
208
|
-
container?: HTMLElement;
|
|
209
|
-
/**
|
|
210
|
-
* if true does not cleanup before mount
|
|
211
|
-
*/
|
|
212
|
-
disableUnmount?: boolean;
|
|
213
|
-
/**
|
|
214
|
-
* wrap in React.StrictMode?
|
|
215
|
-
*/
|
|
216
|
-
strict?: boolean;
|
|
217
|
-
/**
|
|
218
|
-
* Set to `true` if the test fails due to [Strict Effects](https://github.com/reactwg/react-18/discussions/19).
|
|
219
|
-
*/
|
|
220
|
-
strictEffects?: boolean;
|
|
221
|
-
wrapper: React.JSXElementConstructor<{ children?: React.ReactNode }>;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
interface ClientRenderConfiguration extends RenderConfiguration {
|
|
225
|
-
/**
|
|
226
|
-
* https://testing-library.com/docs/react-testing-library/api#hydrate
|
|
227
|
-
*/
|
|
228
|
-
hydrate: boolean;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
interface ServerRenderConfiguration extends RenderConfiguration {
|
|
232
|
-
container: HTMLElement;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export type RenderOptions = Omit<Partial<RenderConfiguration>, 'reactStrictMode'>;
|
|
236
|
-
|
|
237
|
-
export interface MuiRenderResult extends RenderResult<typeof queries & typeof customQueries> {
|
|
238
|
-
user: ReturnType<typeof userEvent.setup>;
|
|
239
|
-
forceUpdate(): void;
|
|
240
|
-
/**
|
|
241
|
-
* convenience helper. Better than repeating all props.
|
|
242
|
-
*/
|
|
243
|
-
setProps(props: object): void;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export interface MuiRenderToStringResult {
|
|
247
|
-
container: HTMLElement;
|
|
248
|
-
hydrate(): MuiRenderResult;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
interface DataAttributes {
|
|
252
|
-
[key: `data-${string}`]: string;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function render(
|
|
256
|
-
element: React.ReactElement<DataAttributes>,
|
|
257
|
-
configuration: ClientRenderConfiguration,
|
|
258
|
-
): MuiRenderResult {
|
|
259
|
-
const { container, hydrate, wrapper, reactStrictMode } = configuration;
|
|
260
|
-
|
|
261
|
-
const testingLibraryRenderResult = traceSync('render', () =>
|
|
262
|
-
testingLibraryRender(element, {
|
|
263
|
-
container,
|
|
264
|
-
hydrate,
|
|
265
|
-
queries: { ...queries, ...customQueries },
|
|
266
|
-
wrapper,
|
|
267
|
-
reactStrictMode,
|
|
268
|
-
}),
|
|
269
|
-
);
|
|
270
|
-
const result: MuiRenderResult = {
|
|
271
|
-
...testingLibraryRenderResult,
|
|
272
|
-
user: userEvent.setup({ document }),
|
|
273
|
-
forceUpdate() {
|
|
274
|
-
traceSync('forceUpdate', () =>
|
|
275
|
-
testingLibraryRenderResult.rerender(
|
|
276
|
-
React.cloneElement(element, {
|
|
277
|
-
'data-force-update': String(Math.random()),
|
|
278
|
-
}),
|
|
279
|
-
),
|
|
280
|
-
);
|
|
281
|
-
},
|
|
282
|
-
setProps(props) {
|
|
283
|
-
traceSync('setProps', () =>
|
|
284
|
-
testingLibraryRenderResult.rerender(React.cloneElement(element, props)),
|
|
285
|
-
);
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
return result;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
function renderToString(
|
|
293
|
-
element: React.ReactElement<DataAttributes>,
|
|
294
|
-
configuration: ServerRenderConfiguration,
|
|
295
|
-
): { container: HTMLElement; hydrate(): MuiRenderResult } {
|
|
296
|
-
const { container, wrapper: Wrapper } = configuration;
|
|
297
|
-
|
|
298
|
-
traceSync('renderToString', () => {
|
|
299
|
-
container.innerHTML = ReactDOMServer.renderToString(<Wrapper>{element}</Wrapper>);
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
return {
|
|
303
|
-
container,
|
|
304
|
-
hydrate() {
|
|
305
|
-
return render(element, { ...configuration, hydrate: true });
|
|
306
|
-
},
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
export interface Clock {
|
|
311
|
-
/**
|
|
312
|
-
* Runs all timers until there are no more remaining.
|
|
313
|
-
* WARNING: This may cause an infinite loop if a timeout constantly schedules another timeout.
|
|
314
|
-
* Prefer to to run only pending timers with `runToLast` and unmount your component directly.
|
|
315
|
-
*/
|
|
316
|
-
runAll(): void;
|
|
317
|
-
/**
|
|
318
|
-
* Runs only the currently pending timers.
|
|
319
|
-
*/
|
|
320
|
-
runToLast(): void;
|
|
321
|
-
/**
|
|
322
|
-
* Tick the clock ahead `timeoutMS` milliseconds.
|
|
323
|
-
* @param timeoutMS
|
|
324
|
-
*/
|
|
325
|
-
tick(timeoutMS: number): void;
|
|
326
|
-
/**
|
|
327
|
-
* Returns true if we're running with "real" i.e. native timers.
|
|
328
|
-
*/
|
|
329
|
-
isReal(): boolean;
|
|
330
|
-
/**
|
|
331
|
-
* Runs the current test suite (i.e. `describe` block) with fake timers.
|
|
332
|
-
*/
|
|
333
|
-
withFakeTimers(): void;
|
|
334
|
-
/**
|
|
335
|
-
* Restore the real timer
|
|
336
|
-
*/
|
|
337
|
-
restore(): void;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
export type ClockConfig = undefined | number | Date;
|
|
341
|
-
|
|
342
|
-
function isVitest(vi: any) {
|
|
343
|
-
return vi != null;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
function createVitestClock(
|
|
347
|
-
defaultMode: 'fake' | 'real',
|
|
348
|
-
config: ClockConfig,
|
|
349
|
-
options: Exclude<Parameters<typeof useFakeTimers>[0], number | Date>,
|
|
350
|
-
vi: any,
|
|
351
|
-
): Clock {
|
|
352
|
-
if (defaultMode === 'fake') {
|
|
353
|
-
beforeEach(() => {
|
|
354
|
-
vi.useFakeTimers(options);
|
|
355
|
-
if (config) {
|
|
356
|
-
vi.setSystemTime(config);
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
afterEach(() => {
|
|
360
|
-
vi.useRealTimers();
|
|
361
|
-
});
|
|
362
|
-
} else {
|
|
363
|
-
beforeEach(() => {
|
|
364
|
-
if (config) {
|
|
365
|
-
vi.setSystemTime(config);
|
|
366
|
-
}
|
|
367
|
-
});
|
|
368
|
-
afterEach(() => {
|
|
369
|
-
vi.useRealTimers();
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return {
|
|
374
|
-
withFakeTimers: () => {
|
|
375
|
-
beforeEach(() => {
|
|
376
|
-
vi.useFakeTimers(options);
|
|
377
|
-
});
|
|
378
|
-
afterEach(() => {
|
|
379
|
-
vi.useRealTimers();
|
|
380
|
-
});
|
|
381
|
-
},
|
|
382
|
-
runToLast: () => {
|
|
383
|
-
traceSync('runToLast', () => {
|
|
384
|
-
rtlAct(() => {
|
|
385
|
-
vi.runOnlyPendingTimers();
|
|
386
|
-
});
|
|
387
|
-
});
|
|
388
|
-
},
|
|
389
|
-
isReal() {
|
|
390
|
-
return !vi.isFakeTimers();
|
|
391
|
-
},
|
|
392
|
-
restore() {
|
|
393
|
-
vi.useRealTimers();
|
|
394
|
-
},
|
|
395
|
-
tick(timeoutMS: number) {
|
|
396
|
-
traceSync('tick', () => {
|
|
397
|
-
rtlAct(() => {
|
|
398
|
-
vi.advanceTimersByTime(timeoutMS);
|
|
399
|
-
});
|
|
400
|
-
});
|
|
401
|
-
},
|
|
402
|
-
runAll() {
|
|
403
|
-
traceSync('runAll', () => {
|
|
404
|
-
rtlAct(() => {
|
|
405
|
-
vi.runAllTimers();
|
|
406
|
-
});
|
|
407
|
-
});
|
|
408
|
-
},
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
function createClock(
|
|
413
|
-
defaultMode: 'fake' | 'real',
|
|
414
|
-
config: ClockConfig,
|
|
415
|
-
options: Exclude<Parameters<typeof useFakeTimers>[0], number | Date>,
|
|
416
|
-
vi: any,
|
|
417
|
-
): Clock {
|
|
418
|
-
if (isVitest(vi)) {
|
|
419
|
-
return createVitestClock(defaultMode, config, options, vi);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
let clock: ReturnType<typeof useFakeTimers> | null = null;
|
|
423
|
-
|
|
424
|
-
let mode = defaultMode;
|
|
425
|
-
|
|
426
|
-
beforeEach(() => {
|
|
427
|
-
if (mode === 'fake') {
|
|
428
|
-
clock = useFakeTimers({
|
|
429
|
-
now: config,
|
|
430
|
-
// useIsFocusVisible schedules a global timer that needs to persist regardless of whether components are mounted or not.
|
|
431
|
-
// Technically we'd want to reset all modules between tests but we don't have that technology.
|
|
432
|
-
// In the meantime just continue to clear native timers like with did for the past years when using `sinon` < 8.
|
|
433
|
-
shouldClearNativeTimers: true,
|
|
434
|
-
...options,
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
afterEach(() => {
|
|
440
|
-
clock?.restore();
|
|
441
|
-
clock = null;
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
return {
|
|
445
|
-
tick(timeoutMS: number) {
|
|
446
|
-
if (clock === null) {
|
|
447
|
-
throw new Error(`Can't advance the real clock. Did you mean to call this on fake clock?`);
|
|
448
|
-
}
|
|
449
|
-
traceSync('tick', () => {
|
|
450
|
-
rtlAct(() => {
|
|
451
|
-
clock!.tick(timeoutMS);
|
|
452
|
-
});
|
|
453
|
-
});
|
|
454
|
-
},
|
|
455
|
-
runAll() {
|
|
456
|
-
if (clock === null) {
|
|
457
|
-
throw new Error(`Can't advance the real clock. Did you mean to call this on fake clock?`);
|
|
458
|
-
}
|
|
459
|
-
traceSync('runAll', () => {
|
|
460
|
-
rtlAct(() => {
|
|
461
|
-
clock!.runAll();
|
|
462
|
-
});
|
|
463
|
-
});
|
|
464
|
-
},
|
|
465
|
-
runToLast() {
|
|
466
|
-
if (clock === null) {
|
|
467
|
-
throw new Error(`Can't advance the real clock. Did you mean to call this on fake clock?`);
|
|
468
|
-
}
|
|
469
|
-
traceSync('runToLast', () => {
|
|
470
|
-
rtlAct(() => {
|
|
471
|
-
clock!.runToLast();
|
|
472
|
-
});
|
|
473
|
-
});
|
|
474
|
-
},
|
|
475
|
-
isReal() {
|
|
476
|
-
return setTimeout.hasOwnProperty('clock') === false;
|
|
477
|
-
},
|
|
478
|
-
withFakeTimers() {
|
|
479
|
-
before(() => {
|
|
480
|
-
mode = 'fake';
|
|
481
|
-
});
|
|
482
|
-
|
|
483
|
-
after(() => {
|
|
484
|
-
mode = defaultMode;
|
|
485
|
-
});
|
|
486
|
-
},
|
|
487
|
-
restore() {
|
|
488
|
-
clock?.restore();
|
|
489
|
-
},
|
|
490
|
-
};
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
export interface Renderer {
|
|
494
|
-
clock: Clock;
|
|
495
|
-
render(element: React.ReactElement<DataAttributes>, options?: RenderOptions): MuiRenderResult;
|
|
496
|
-
renderToString(
|
|
497
|
-
element: React.ReactElement<DataAttributes>,
|
|
498
|
-
options?: RenderOptions,
|
|
499
|
-
): MuiRenderToStringResult;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
export interface CreateRendererOptions extends Pick<RenderOptions, 'strict' | 'strictEffects'> {
|
|
503
|
-
/**
|
|
504
|
-
* @default 'real'
|
|
505
|
-
*/
|
|
506
|
-
clock?: 'fake' | 'real';
|
|
507
|
-
clockConfig?: ClockConfig;
|
|
508
|
-
clockOptions?: Parameters<typeof createClock>[2];
|
|
509
|
-
/**
|
|
510
|
-
* Vitest needs to be injected because this file is transpiled to commonjs and vitest is an esm module.
|
|
511
|
-
* @default {}
|
|
512
|
-
*/
|
|
513
|
-
vi?: any;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
export function createRenderer(globalOptions: CreateRendererOptions = {}): Renderer {
|
|
517
|
-
const {
|
|
518
|
-
clock: clockMode = 'real',
|
|
519
|
-
clockConfig,
|
|
520
|
-
strict: globalStrict = true,
|
|
521
|
-
strictEffects: globalStrictEffects = globalStrict,
|
|
522
|
-
vi = (globalThis as any).vi,
|
|
523
|
-
clockOptions,
|
|
524
|
-
} = globalOptions;
|
|
525
|
-
// save stack to re-use in test-hooks
|
|
526
|
-
const { stack: createClientRenderStack } = new Error();
|
|
527
|
-
const clock = createClock(clockMode, clockConfig, clockOptions, vi);
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Flag whether `createRenderer` was called in a suite i.e. describe() block.
|
|
531
|
-
* For legacy reasons `createRenderer` might accidentally be called in a before(Each) hook.
|
|
532
|
-
*/
|
|
533
|
-
let wasCalledInSuite = false;
|
|
534
|
-
before(function beforeHook() {
|
|
535
|
-
wasCalledInSuite = true;
|
|
536
|
-
|
|
537
|
-
if (enableDispatchingProfiler) {
|
|
538
|
-
// TODO windows?
|
|
539
|
-
const filename = new Error()
|
|
540
|
-
.stack!.split(/\r?\n/)
|
|
541
|
-
.map((line) => {
|
|
542
|
-
const fileMatch =
|
|
543
|
-
// chrome: " at Context.beforeHook (webpack-internal:///./test/utils/createRenderer.tsx:257:24)""
|
|
544
|
-
line.match(/\(([^)]+):\d+:\d+\)/) ??
|
|
545
|
-
// firefox: "beforeHook@webpack-internal:///./test/utils/createRenderer.tsx:257:24"
|
|
546
|
-
line.match(/@(.*?):\d+:\d+$/);
|
|
547
|
-
if (fileMatch === null) {
|
|
548
|
-
return null;
|
|
549
|
-
}
|
|
550
|
-
return fileMatch[1];
|
|
551
|
-
})
|
|
552
|
-
.find((file) => {
|
|
553
|
-
return file?.endsWith('createRenderer.tsx');
|
|
554
|
-
});
|
|
555
|
-
workspaceRoot = filename!.replace('test/utils/createRenderer.tsx', '');
|
|
556
|
-
}
|
|
557
|
-
});
|
|
558
|
-
|
|
559
|
-
let emotionCache: import('@emotion/cache').EmotionCache = null!;
|
|
560
|
-
/**
|
|
561
|
-
* target container for SSR
|
|
562
|
-
*/
|
|
563
|
-
let serverContainer: HTMLElement;
|
|
564
|
-
/**
|
|
565
|
-
* Flag whether all setup for `configuredClientRender` was completed.
|
|
566
|
-
* For legacy reasons `configuredClientRender` might accidentally be called in a before(Each) hook.
|
|
567
|
-
*/
|
|
568
|
-
let prepared = false;
|
|
569
|
-
let profiler: Profiler = null!;
|
|
570
|
-
beforeEach(function beforeEachHook() {
|
|
571
|
-
if (!wasCalledInSuite) {
|
|
572
|
-
const error = new Error(
|
|
573
|
-
'Unable to run `before` hook for `createRenderer`. This usually indicates that `createRenderer` was called in a `before` hook instead of in a `describe()` block.',
|
|
574
|
-
);
|
|
575
|
-
error.stack = createClientRenderStack;
|
|
576
|
-
throw error;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
let id: string | null = null;
|
|
580
|
-
|
|
581
|
-
if (isVitest(vi)) {
|
|
582
|
-
// @ts-expect-error
|
|
583
|
-
id = expect.getState().currentTestName;
|
|
584
|
-
} else {
|
|
585
|
-
id = this.currentTest?.fullTitle() ?? null;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
if (!id) {
|
|
589
|
-
throw new Error(
|
|
590
|
-
'Unable to find the currently running test. This is a bug with the client-renderer. Please report this issue to a maintainer.',
|
|
591
|
-
);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
profiler = new UsedProfiler(id);
|
|
595
|
-
|
|
596
|
-
emotionCache = createEmotionCache({ key: 'emotion-client-render' });
|
|
597
|
-
|
|
598
|
-
serverContainer = document.createElement('div');
|
|
599
|
-
document.body.appendChild(serverContainer);
|
|
600
|
-
|
|
601
|
-
prepared = true;
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
afterEach(() => {
|
|
605
|
-
if (!clock.isReal()) {
|
|
606
|
-
const error = new Error(
|
|
607
|
-
"Can't cleanup before fake timers are restored.\n" +
|
|
608
|
-
'Be sure to:\n' +
|
|
609
|
-
' 1. Only use `clock` from `createRenderer`.\n' +
|
|
610
|
-
' 2. Call `createRenderer` in a suite and not any test hook (for example `beforeEach`) or test itself (for example `it`).',
|
|
611
|
-
);
|
|
612
|
-
// Use saved stack otherwise the stack trace will not include the test location.
|
|
613
|
-
error.stack = createClientRenderStack;
|
|
614
|
-
throw error;
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
cleanup();
|
|
618
|
-
profiler.report();
|
|
619
|
-
profiler = null!;
|
|
620
|
-
|
|
621
|
-
emotionCache.sheet.tags.forEach((styleTag) => {
|
|
622
|
-
styleTag.remove();
|
|
623
|
-
});
|
|
624
|
-
emotionCache = null!;
|
|
625
|
-
|
|
626
|
-
serverContainer.remove();
|
|
627
|
-
serverContainer = null!;
|
|
628
|
-
});
|
|
629
|
-
|
|
630
|
-
function createWrapper(options: Pick<RenderOptions, 'wrapper'>) {
|
|
631
|
-
const { wrapper: InnerWrapper = React.Fragment } = options;
|
|
632
|
-
|
|
633
|
-
return function Wrapper({ children }: { children?: React.ReactNode }) {
|
|
634
|
-
return (
|
|
635
|
-
<EmotionCacheProvider value={emotionCache}>
|
|
636
|
-
<React.Profiler id={profiler.id} onRender={profiler.onRender}>
|
|
637
|
-
<InnerWrapper>{children}</InnerWrapper>
|
|
638
|
-
</React.Profiler>
|
|
639
|
-
</EmotionCacheProvider>
|
|
640
|
-
);
|
|
641
|
-
};
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
return {
|
|
645
|
-
clock,
|
|
646
|
-
render(element: React.ReactElement<DataAttributes>, options: RenderOptions = {}) {
|
|
647
|
-
if (!prepared) {
|
|
648
|
-
throw new Error(
|
|
649
|
-
'Unable to finish setup before `render()` was called. ' +
|
|
650
|
-
'This usually indicates that `render()` was called in a `before()` or `beforeEach` hook. ' +
|
|
651
|
-
'Move the call into each `it()`. Otherwise you cannot run a specific test and we cannot isolate each test.',
|
|
652
|
-
);
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
const usesLegacyRoot = reactMajor < 18;
|
|
656
|
-
const reactStrictMode =
|
|
657
|
-
(options.strict ?? globalStrict) &&
|
|
658
|
-
((options.strictEffects ?? globalStrictEffects) || usesLegacyRoot);
|
|
659
|
-
|
|
660
|
-
return render(element, {
|
|
661
|
-
...options,
|
|
662
|
-
reactStrictMode,
|
|
663
|
-
hydrate: false,
|
|
664
|
-
wrapper: createWrapper(options),
|
|
665
|
-
});
|
|
666
|
-
},
|
|
667
|
-
renderToString(element: React.ReactElement<DataAttributes>, options: RenderOptions = {}) {
|
|
668
|
-
if (!prepared) {
|
|
669
|
-
throw new Error(
|
|
670
|
-
'Unable to finish setup before `render()` was called. ' +
|
|
671
|
-
'This usually indicates that `render()` was called in a `before()` or `beforeEach` hook. ' +
|
|
672
|
-
'Move the call into each `it()`. Otherwise you cannot run a specific test and we cannot isolate each test.',
|
|
673
|
-
);
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
const { container = serverContainer, ...localOptions } = options;
|
|
677
|
-
return renderToString(element, {
|
|
678
|
-
...localOptions,
|
|
679
|
-
container,
|
|
680
|
-
wrapper: createWrapper(options),
|
|
681
|
-
});
|
|
682
|
-
},
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
const fireEvent = ((target, event, ...args) => {
|
|
687
|
-
return traceSync(`firEvent.${event.type}`, () => rtlFireEvent(target, event, ...args));
|
|
688
|
-
}) as typeof rtlFireEvent;
|
|
689
|
-
|
|
690
|
-
Object.keys(rtlFireEvent).forEach(
|
|
691
|
-
// @ts-expect-error
|
|
692
|
-
(eventType: keyof typeof rtlFireEvent) => {
|
|
693
|
-
fireEvent[eventType] = (...args) =>
|
|
694
|
-
traceSync(`firEvent.${eventType}`, () => rtlFireEvent[eventType](...args));
|
|
695
|
-
},
|
|
696
|
-
);
|
|
697
|
-
|
|
698
|
-
const originalFireEventKeyDown = rtlFireEvent.keyDown;
|
|
699
|
-
fireEvent.keyDown = (desiredTarget, options = {}) => {
|
|
700
|
-
const element = desiredTarget as Element | Document;
|
|
701
|
-
// `element` shouldn't be `document` but we catch this later anyway
|
|
702
|
-
const document = element.ownerDocument || element;
|
|
703
|
-
const target = document.activeElement || document.body || document.documentElement;
|
|
704
|
-
if (target !== element) {
|
|
705
|
-
// see https://www.w3.org/TR/uievents/#keydown
|
|
706
|
-
const error = new Error(
|
|
707
|
-
`\`keydown\` events can only be targeted at the active element which is ${prettyDOM(
|
|
708
|
-
target,
|
|
709
|
-
undefined,
|
|
710
|
-
{ maxDepth: 1 },
|
|
711
|
-
)}`,
|
|
712
|
-
);
|
|
713
|
-
// We're only interested in the callsite of fireEvent.keyDown
|
|
714
|
-
error.stack = error
|
|
715
|
-
.stack!.split('\n')
|
|
716
|
-
.filter((line) => !/at Function.key/.test(line))
|
|
717
|
-
.join('\n');
|
|
718
|
-
throw error;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
return traceSync('fireEvent.keyDown', () => originalFireEventKeyDown(element, options));
|
|
722
|
-
};
|
|
723
|
-
|
|
724
|
-
const originalFireEventKeyUp = rtlFireEvent.keyUp;
|
|
725
|
-
fireEvent.keyUp = (desiredTarget, options = {}) => {
|
|
726
|
-
const element = desiredTarget as Element | Document;
|
|
727
|
-
// `element` shouldn't be `document` but we catch this later anyway
|
|
728
|
-
const document = element.ownerDocument || element;
|
|
729
|
-
const target = document.activeElement || document.body || document.documentElement;
|
|
730
|
-
if (target !== element) {
|
|
731
|
-
// see https://www.w3.org/TR/uievents/#keyup
|
|
732
|
-
const error = new Error(
|
|
733
|
-
`\`keyup\` events can only be targeted at the active element which is ${prettyDOM(
|
|
734
|
-
target,
|
|
735
|
-
undefined,
|
|
736
|
-
{ maxDepth: 1 },
|
|
737
|
-
)}`,
|
|
738
|
-
);
|
|
739
|
-
// We're only interested in the callsite of fireEvent.keyUp
|
|
740
|
-
error.stack = error
|
|
741
|
-
.stack!.split('\n')
|
|
742
|
-
.filter((line) => !/at Function.key/.test(line))
|
|
743
|
-
.join('\n');
|
|
744
|
-
throw error;
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
return traceSync('fireEvent.keyUp', () => originalFireEventKeyUp(element, options));
|
|
748
|
-
};
|
|
749
|
-
|
|
750
|
-
export function fireTouchChangedEvent(
|
|
751
|
-
target: Element,
|
|
752
|
-
type: 'touchstart' | 'touchmove' | 'touchend',
|
|
753
|
-
options: { changedTouches: Array<Pick<TouchInit, 'clientX' | 'clientY'>> },
|
|
754
|
-
): void {
|
|
755
|
-
const { changedTouches } = options;
|
|
756
|
-
const originalGetBoundingClientRect = target.getBoundingClientRect;
|
|
757
|
-
target.getBoundingClientRect = () => ({
|
|
758
|
-
x: 0,
|
|
759
|
-
y: 0,
|
|
760
|
-
bottom: 0,
|
|
761
|
-
height: 0,
|
|
762
|
-
left: 0,
|
|
763
|
-
right: 0,
|
|
764
|
-
top: 0,
|
|
765
|
-
width: 0,
|
|
766
|
-
toJSON() {
|
|
767
|
-
return {
|
|
768
|
-
x: 0,
|
|
769
|
-
y: 0,
|
|
770
|
-
bottom: 0,
|
|
771
|
-
height: 0,
|
|
772
|
-
left: 0,
|
|
773
|
-
right: 0,
|
|
774
|
-
top: 0,
|
|
775
|
-
width: 0,
|
|
776
|
-
};
|
|
777
|
-
},
|
|
778
|
-
});
|
|
779
|
-
|
|
780
|
-
const event = new window.TouchEvent(type, {
|
|
781
|
-
bubbles: true,
|
|
782
|
-
cancelable: true,
|
|
783
|
-
composed: true,
|
|
784
|
-
changedTouches: changedTouches.map(
|
|
785
|
-
(opts) =>
|
|
786
|
-
new window.Touch({
|
|
787
|
-
target,
|
|
788
|
-
identifier: 0,
|
|
789
|
-
...opts,
|
|
790
|
-
}),
|
|
791
|
-
),
|
|
792
|
-
});
|
|
793
|
-
|
|
794
|
-
fireEvent(target, event);
|
|
795
|
-
target.getBoundingClientRect = originalGetBoundingClientRect;
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
function act<T>(callback: () => T | Promise<T>): Promise<T>;
|
|
799
|
-
function act(callback: () => void): void;
|
|
800
|
-
function act<T>(callback: () => void | T | Promise<T>) {
|
|
801
|
-
return traceSync('act', () => rtlAct(callback));
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
const bodyBoundQueries = within(document.body, { ...queries, ...customQueries });
|
|
805
|
-
|
|
806
|
-
export * from '@testing-library/react/pure';
|
|
807
|
-
export { act, fireEvent };
|
|
808
|
-
export const screen: Screen & typeof bodyBoundQueries = { ...rtlScreen, ...bodyBoundQueries };
|