I'd like to do some integration testing of my svelte
+ page.js
-based router using vitest
, but I'm running into an issue where the jsdom
instance only updates correctly once per test file.
In the following setup, either test will pass when run with .only
or if I split each test into its own file. But when they run in sequence, the second one will always fail. Inspecting the DOM with screen.debug()
reveals that it's empty, and calls to act
or tick
don't seem to do anything.
I suspect it has something to do with how jsdom
is interacting with the History API, but I'm not sure where to go from here.
Root.svelte
<script>
import page from 'page'
import SignIn from './SignIn/SignIn.svelte'
import Upload from './Upload/Upload.svelte'
import { authenticationToken } from './Root.stores.js'
let currentPage
page('/', () => {
page.redirect('/sign-in')
})
page('/sign-in', () => {
currentPage = SignIn
})
page('/upload', () => {
if ($authenticationToken === null) {
return page.redirect('/sign-in')
}
currentPage = Upload
})
page.start()
</script>
<svelte:component this={ currentPage } />
Root.svelte.test.js
import page from 'page'
import Root from './Root.svelte'
import { authenticationToken } from './Root.stores.js'
it('redirects to sign in when not authenticated', async () => {
vi.spyOn(page, 'redirect')
authenticationToken.set(null)
const { act } = setupComponent(Root)
await act(() => page('/upload'))
expect(page.redirect).toHaveBeenCalledWith('/sign-in')
})
it('displays the upload screen when authenticated', async () => {
authenticationToken.set('token')
const { act } = setupComponent(Root)
await act(() => page('/upload'))
expect(document.getElementById('upload')).toBeInTheDocument()
})
Other Research
The issue is similar to this one in the jest
project. In that issue, the recommendation was to call jsdom.reconfigure()
in a beforeEach
block, but I don't know how to get a hold of the jsdom
instance in vitest
in order to try that.
Any ideas or alternative approaches welcome, thanks!
Since version 1.3.0, Vitest exposes a jsdom
global variable, so it should be possible to call
jsdom.reconfigure(/* ... */)
See also https://vitest.dev/config/#environment (scroll to the bottom of the section)