1
- import {
2
- fireEvent as dtlFireEvent ,
3
- getQueriesForElement ,
4
- prettyDOM ,
5
- } from '@testing-library/dom'
1
+ import * as DOMTestingLibrary from '@testing-library/dom'
6
2
import * as Svelte from 'svelte'
7
3
import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
8
4
9
5
const IS_SVELTE_5 = / ^ 5 \. / . test ( SVELTE_VERSION )
10
6
7
+ /**
8
+ * Customize how Svelte renders the component.
9
+ *
10
+ * @template {Svelte.SvelteComponent} C
11
+ * @typedef {Svelte.ComponentProps<C> | Partial<Svelte.ComponentConstructorOptions<Svelte.ComponentProps<C>>> } SvelteComponentOptions
12
+ */
13
+
14
+ /**
15
+ * Customize how Testing Library sets up the document and binds queries.
16
+ *
17
+ * @template {DOMTestingLibrary.Queries} [Q=typeof DOMTestingLibrary.queries]
18
+ * @typedef {{
19
+ * baseElement?: HTMLElement
20
+ * queries?: Q
21
+ * }} RenderOptions
22
+ */
23
+
24
+ /**
25
+ * The rendered component and bound testing functions.
26
+ *
27
+ * @template {Svelte.SvelteComponent} C
28
+ * @template {DOMTestingLibrary.Queries} [Q=typeof DOMTestingLibrary.queries]
29
+ *
30
+ * @typedef {{
31
+ * container: HTMLElement
32
+ * baseElement: HTMLElement
33
+ * component: C
34
+ * debug: (el?: HTMLElement | DocumentFragment) => void
35
+ * rerender: (props: Partial<Svelte.ComponentProps<C>>) => Promise<void>
36
+ * unmount: () => void
37
+ * } & {
38
+ * [P in keyof Q]: DOMTestingLibrary.BoundFunction<Q[P]>
39
+ * }} RenderResult
40
+ */
41
+
11
42
export class SvelteTestingLibrary {
12
43
svelteComponentOptions = [
13
44
'target' ,
@@ -49,6 +80,17 @@ export class SvelteTestingLibrary {
49
80
return { props : options }
50
81
}
51
82
83
+ /**
84
+ * Render a component into the document.
85
+ *
86
+ * @template {Svelte.SvelteComponent} C
87
+ * @template {DOMTestingLibrary.Queries} [Q=typeof DOMTestingLibrary.queries]
88
+ *
89
+ * @param {Svelte.ComponentType<C> } Component - The component to render.
90
+ * @param {SvelteComponentOptions<C> } componentOptions - Customize how Svelte renders the component.
91
+ * @param {RenderOptions<Q> } renderOptions - Customize how Testing Library sets up the document and binds queries.
92
+ * @returns {RenderResult<C, Q> } The rendered component and bound testing functions.
93
+ */
52
94
render ( Component , componentOptions = { } , renderOptions = { } ) {
53
95
componentOptions = this . checkProps ( componentOptions )
54
96
@@ -72,7 +114,7 @@ export class SvelteTestingLibrary {
72
114
baseElement,
73
115
component,
74
116
container : target ,
75
- debug : ( el = baseElement ) => console . log ( prettyDOM ( el ) ) ,
117
+ debug : ( el = baseElement ) => console . log ( DOMTestingLibrary . prettyDOM ( el ) ) ,
76
118
rerender : async ( props ) => {
77
119
if ( props . props ) {
78
120
console . warn (
@@ -86,7 +128,10 @@ export class SvelteTestingLibrary {
86
128
unmount : ( ) => {
87
129
this . cleanupComponent ( component )
88
130
} ,
89
- ...getQueriesForElement ( baseElement , renderOptions . queries ) ,
131
+ ...DOMTestingLibrary . getQueriesForElement (
132
+ baseElement ,
133
+ renderOptions . queries
134
+ ) ,
90
135
}
91
136
}
92
137
@@ -123,6 +168,9 @@ export class SvelteTestingLibrary {
123
168
}
124
169
}
125
170
171
+ /**
172
+ * Unmount all components and remove elements added to `<body>`.
173
+ */
126
174
cleanup ( ) {
127
175
this . componentCache . forEach ( this . cleanupComponent . bind ( this ) )
128
176
this . targetCache . forEach ( this . cleanupTarget . bind ( this ) )
@@ -135,22 +183,46 @@ export const render = instance.render.bind(instance)
135
183
136
184
export const cleanup = instance . cleanup . bind ( instance )
137
185
186
+ /**
187
+ * Call a function and wait for Svelte to flush pending changes.
188
+ *
189
+ * @param {() => unknown } [fn] - A function, which may be `async`, to call before flushing updates.
190
+ * @returns {Promise<void> }
191
+ */
138
192
export const act = async ( fn ) => {
139
193
if ( fn ) {
140
194
await fn ( )
141
195
}
142
196
return Svelte . tick ( )
143
197
}
144
198
199
+ /**
200
+ * @typedef {(...args: Parameters<DOMTestingLibrary.FireFunction>) => Promise<ReturnType<DOMTestingLibrary.FireFunction>> } FireFunction
201
+ */
202
+
203
+ /**
204
+ * @typedef {{
205
+ * [K in DOMTestingLibrary.EventType]: (...args: Parameters<DOMTestingLibrary.FireObject[K]>) => Promise<ReturnType<DOMTestingLibrary.FireObject[K]>>
206
+ * }} FireObject
207
+ */
208
+
209
+ /**
210
+ * Fire an event on an element.
211
+ *
212
+ * Consider using `@testing-library/user-event` instead, if possible.
213
+ * @see https://testing-library.com/docs/user-event/intro/
214
+ *
215
+ * @type {FireFunction & FireObject }
216
+ */
145
217
export const fireEvent = async ( ...args ) => {
146
- const event = dtlFireEvent ( ...args )
218
+ const event = DOMTestingLibrary . fireEvent ( ...args )
147
219
await Svelte . tick ( )
148
220
return event
149
221
}
150
222
151
- Object . keys ( dtlFireEvent ) . forEach ( ( key ) => {
223
+ Object . keys ( DOMTestingLibrary . fireEvent ) . forEach ( ( key ) => {
152
224
fireEvent [ key ] = async ( ...args ) => {
153
- const event = dtlFireEvent [ key ] ( ...args )
225
+ const event = DOMTestingLibrary . fireEvent [ key ] ( ...args )
154
226
await Svelte . tick ( )
155
227
return event
156
228
}
0 commit comments