11import {
2+ configure as configureDTL ,
23 fireEvent as baseFireEvent ,
4+ getConfig as getDTLConfig ,
35 getQueriesForElement ,
46 prettyDOM ,
57} from '@testing-library/dom'
6- import { tick } from 'svelte'
8+ import * as Svelte from 'svelte'
79
810import { mount , unmount , updateProps , validateOptions } from './core/index.js'
911
@@ -94,7 +96,7 @@ const render = (Component, options = {}, renderOptions = {}) => {
9496 }
9597
9698 updateProps ( component , props )
97- await tick ( )
99+ await Svelte . tick ( )
98100 } ,
99101 unmount : ( ) => {
100102 cleanupComponent ( component )
@@ -103,6 +105,33 @@ const render = (Component, options = {}, renderOptions = {}) => {
103105 }
104106}
105107
108+ /** @type {import('@testing-library/dom'.Config | undefined } */
109+ let originalDTLConfig
110+ 111+ /**
112+ * Configure `@testing-library/dom` for usage with Svelte.
113+ *
114+ * Ensures events fired from `@testing-library/dom`
115+ * and `@testing-library/user-event` wait for Svelte
116+ * to flush changes to the DOM before proceeding.
117+ */
118+ const setup = ( ) => {
119+ originalDTLConfig = getDTLConfig ( )
120+ 121+ configureDTL ( {
122+ asyncWrapper : act ,
123+ eventWrapper : Svelte . flushSync ?? ( ( cb ) => cb ( ) ) ,
124+ } )
125+ }
126+ 127+ /** Reset dom-testing-library config. */
128+ const cleanupDTL = ( ) => {
129+ if ( originalDTLConfig ) {
130+ configureDTL ( originalDTLConfig )
131+ originalDTLConfig = undefined
132+ }
133+ }
134+ 106135/** Remove a component from the component cache. */
107136const cleanupComponent = ( component ) => {
108137 const inCache = componentCache . delete ( component )
@@ -121,27 +150,31 @@ const cleanupTarget = (target) => {
121150 }
122151}
123152
124- /** Unmount all components and remove elements added to `<body>`. */
153+ /** Unmount components, remove elements added to `<body>`, and reset `@testing-library/dom `. */
125154const cleanup = ( ) => {
126155 for ( const component of componentCache ) {
127156 cleanupComponent ( component )
128157 }
129158 for ( const target of targetCache ) {
130159 cleanupTarget ( target )
131160 }
161+ cleanupDTL ( )
132162}
133163
134164/**
135165 * Call a function and wait for Svelte to flush pending changes.
136166 *
137- * @param {() => unknown } [fn] - A function, which may be `async`, to call before flushing updates.
138- * @returns {Promise<void> }
167+ * @template T
168+ * @param {(() => Promise<T>) | () => T } [fn] - A function, which may be `async`, to call before flushing updates.
169+ * @returns {Promise<T> }
139170 */
140171const act = async ( fn ) => {
172+ let result
141173 if ( fn ) {
142- await fn ( )
174+ result = await fn ( )
143175 }
144- return tick ( )
176+ await Svelte . tick ( )
177+ return result
145178}
146179
147180/**
@@ -162,18 +195,10 @@ const act = async (fn) => {
162195 *
163196 * @type {FireFunction & FireObject }
164197 */
165- const fireEvent = async ( ...args ) => {
166- const event = baseFireEvent ( ...args )
167- await tick ( )
168- return event
169- }
198+ const fireEvent = async ( ...args ) => act ( ( ) => baseFireEvent ( ...args ) )
170199
171200for ( const [ key , baseEvent ] of Object . entries ( baseFireEvent ) ) {
172- fireEvent [ key ] = async ( ...args ) => {
173- const event = baseEvent ( ...args )
174- await tick ( )
175- return event
176- }
201+ fireEvent [ key ] = async ( ...args ) => act ( ( ) => baseEvent ( ...args ) )
177202}
178203
179- export { act , cleanup , fireEvent , render }
204+ export { act , cleanup , fireEvent , render , setup }
0 commit comments