svelte-htm
svelte-htm copied to clipboard
Event Handlers don't work as expected
Hi, first of all, we appreciate this library so much, thank you for the hard work!
In our tests, we have come across some odd behavior. We created a repro repository here: https://github.com/cannahum/svelte-htm-issue-repro
Firstly our stack:
{
...
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^1.1.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/svelte": "^3.2.2",
"@testing-library/user-event": "^14.4.3",
"@types/testing-library__jest-dom": "^5.14.5",
"i": "^0.3.7",
"jsdom": "^20.0.2",
"npm": "^9.1.1",
"patch-package": "^6.5.0",
"svelte": "^3.52.0",
"svelte-htm": "^1.2.0",
"vite": "^3.2.3",
"vitest": "^0.25.1"
}
}
In setupTests.js
:
import matchers from '@testing-library/jest-dom/matchers';
import { expect } from 'vitest';
In vite.config.js
:
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [svelte()],
test: {
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
globals: true,
environment: 'jsdom',
// Extend jest-dom matchers
setupFiles: ['./setupTests.js'],
}
})
expect.extend(matchers);
In the repository, if you run the tests you will see that in Menu.test.js
the item we "click" doesn't register the correct value in our callback unless you "click" twice, or the menu item you select is the first on menu. If you run the project npm run dev
, you can see that the code works as expected.
Here is some more explanation. In src/components/Menu.test.js
we have:
const mockChangeHandler = vi.fn();
render(html`
<${Menu}
selectedOption=${chocChipMint}
onSelectionChange=${mockChangeHandler}
/>
`);
const cncInput = document.querySelector('#cookies_n_cream');
expect(cncInput).not.toBeChecked();
const ccmInput = document.querySelector('#choc_chip_mint');
expect(ccmInput).toBeChecked();
const rInput = document.querySelector('#raspberry');
expect(rInput).not.toBeChecked();
mockChangeHandler.mockReset();
await user.click(rInput);
expect(mockChangeHandler).toBeCalledWith(raspberry);
When we execute await user.click(rInput)
which should select raspberry ice cream, instead we see the mockChangeHandler register chocolate chip mint
.
- BUT, If we click twice, it works as expected.
- If instead of clicking raspberry we click cookies and cream (first item on the menu), it works as expected.
- If we switch (on the Menu component) raspberry to be the first element on the list, it works as expected.