When writing tests, use root.flush() to synchronously execute all pending updates and tasks. This ensures the DOM and component state are fully synchronized before making assertions.
The main use case is flushing after events that call handle.update(). Since updates are asynchronous, you need to flush to ensure the DOM reflects the changes:
function Counter(handle: Handle) {
let count = 0
return () => (
<button
mix={[
on('click', () => {
count++
handle.update()
}),
]}
>
Count: {count}
</button>
)
}
// In your test
let container = document.createElement('div')
let root = createRoot(container)
root.render(<Counter />)
root.flush() // Ensure initial render completes
let button = container.querySelector('button')
button.click() // Triggers handle.update()
root.flush() // Flush to apply the update
expect(container.textContent).toBe('Count: 1')You should also flush after the initial root.render() to ensure event listeners are attached and the DOM is ready for interaction:
let root = createRoot(container)
root.render(<MyComponent />)
root.flush() // Event listeners now attached
// Safe to interact
container.querySelector('button').click()For components with async operations in queueTask, flush after each step:
function AsyncLoader(handle: Handle) {
let data: string | null = null
handle.queueTask(async (signal) => {
let response = await fetch('/api/data', { signal })
let json = await response.json()
if (signal.aborted) return
data = json.value
handle.update()
})
return () => <div>{data ?? 'Loading...'}</div>
}
// In your test (with mocked fetch)
let root = createRoot(container)
root.render(<AsyncLoader />)
root.flush()
expect(container.textContent).toBe('Loading...')
// After fetch resolves
await waitForFetch()
root.flush()
expect(container.textContent).toBe('Expected data')Use root.dispose() to clean up and verify cleanup behavior:
let root = createRoot(container)
root.render(<MyComponent />)
root.flush()
// Verify setup behavior
expect(container.querySelector('.content')).toBeTruthy()
// Remove and verify cleanup
root.dispose()
expect(container.innerHTML).toBe('')- Getting Started - Root methods reference
- Handle API -
handle.queueTask()behavior