1- import {
2- fireEvent as dtlFireEvent ,
3- getQueriesForElement ,
4- prettyDOM ,
5- } from '@testing-library/dom'
1+ import * as DOMTestingLibrary from '@testing-library/dom'
62import * as Svelte from 'svelte'
73import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
84
95const IS_SVELTE_5 = / ^ 5 \. / . test ( SVELTE_VERSION )
106
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+
1142export class SvelteTestingLibrary {
1243 svelteComponentOptions = [
1344 'target' ,
@@ -49,6 +80,17 @@ export class SvelteTestingLibrary {
4980 return { props : options }
5081 }
5182
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+ */
5294 render ( Component , componentOptions = { } , renderOptions = { } ) {
5395 componentOptions = this . checkProps ( componentOptions )
5496
@@ -72,7 +114,7 @@ export class SvelteTestingLibrary {
72114 baseElement,
73115 component,
74116 container : target ,
75- debug : ( el = baseElement ) => console . log ( prettyDOM ( el ) ) ,
117+ debug : ( el = baseElement ) => console . log ( DOMTestingLibrary . prettyDOM ( el ) ) ,
76118 rerender : async ( props ) => {
77119 if ( props . props ) {
78120 console . warn (
@@ -86,7 +128,10 @@ export class SvelteTestingLibrary {
86128 unmount : ( ) => {
87129 this . cleanupComponent ( component )
88130 } ,
89- ...getQueriesForElement ( baseElement , renderOptions . queries ) ,
131+ ...DOMTestingLibrary . getQueriesForElement (
132+ baseElement ,
133+ renderOptions . queries
134+ ) ,
90135 }
91136 }
92137
@@ -123,6 +168,9 @@ export class SvelteTestingLibrary {
123168 }
124169 }
125170
171+ /**
172+ * Unmount all components and remove elements added to `<body>`.
173+ */
126174 cleanup ( ) {
127175 this . componentCache . forEach ( this . cleanupComponent . bind ( this ) )
128176 this . targetCache . forEach ( this . cleanupTarget . bind ( this ) )
@@ -135,22 +183,46 @@ export const render = instance.render.bind(instance)
135183
136184export const cleanup = instance . cleanup . bind ( instance )
137185
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+ */
138192export const act = async ( fn ) => {
139193 if ( fn ) {
140194 await fn ( )
141195 }
142196 return Svelte . tick ( )
143197}
144198
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+ */
145217export const fireEvent = async ( ...args ) => {
146- const event = dtlFireEvent ( ...args )
218+ const event = DOMTestingLibrary . fireEvent ( ...args )
147219 await Svelte . tick ( )
148220 return event
149221}
150222
151- Object . keys ( dtlFireEvent ) . forEach ( ( key ) => {
223+ Object . keys ( DOMTestingLibrary . fireEvent ) . forEach ( ( key ) => {
152224 fireEvent [ key ] = async ( ...args ) => {
153- const event = dtlFireEvent [ key ] ( ...args )
225+ const event = DOMTestingLibrary . fireEvent [ key ] ( ...args )
154226 await Svelte . tick ( )
155227 return event
156228 }
0 commit comments