I'm trying to perform snapshot tests with Vitest on a Vue 3 component with Vuetify 3. Here's my test:
import { createVuetify } from 'vuetify';
import { describe, it, expect } from 'vitest';
import ConfirmationModal from '@/components/ConfirmationModal.vue';
const vuetify = createVuetify();
global.ResizeObserver = require('resize-observer-polyfill');
describe(`Composant ConfirmationModal`, () => {
it(`Match snapshot`, async () => {
const wrapper = mount(
{
template: '<v-layout><confirmation-modal></confirmation-modal></v-layout>'
},
{
props: {
value: true,
title: 'test',
width: 100
},
global: { components: { ConfirmationModal }, plugins: [vuetify] }
}
);
expect(wrapper.html()).toMatchSnapshot();
});
});
It works, the snapshot is ok:
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Composant ConfirmationModal > Match snapshot 1`] = `
"<v-layout title=\\"test\\" width=\\"100\\" value=\\"true\\">
<div class=\\"text-center\\">
<v-dialog width=\\"510\\" class=\\"confirmation-modal\\" persistent=\\"\\" value=\\"false\\">
<v-card>
<v-card-title class=\\"text-h5 grey lighten-2\\" primary-title=\\"\\"></v-card-title>
<v-card-text></v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn class=\\"btn-ok\\" color=\\"primary\\" text=\\"\\"> OK</v-btn>
<v-btn id=\\"btn-annulation\\" color=\\"primary\\" text=\\"\\"> Annuler</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</v-layout>"
`;
But I have a lot of warnings:
[Vue warn]: Failed to resolve component: v-layout
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
at <Anonymous value=true title="test" width=100 ... >
at <VTUROOT>
And the same for each Vuetify component I use.
Following the documentation (https://vuetifyjs.com/en/getting-started/unit-testing/#setup-vitest), I've read that I should use Vuetify in tests this way:
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
const vuetify = createVuetify({
components,
directives,
})
If I do this, no more warnings, but my snapshot becomes useless because almost empty. Here's the full snapshot:
exports[`Composant ConfirmationModal > Correspond au snapshot 1`] = `
"<div class=\\"v-layout\\" title=\\"test\\" width=\\"100\\" value=\\"true\\">
<div class=\\"text-center\\">
<!---->
<!---->
</div>
</div>"
`;
Here's my vitest.config.ts if it can help :
import { defineConfig, loadEnv } from 'vite';
import { fileURLToPath, URL } from 'node:url';
import vue from '@vitejs/plugin-vue';
export default ({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
return defineConfig({
plugins: [vue()],
define: {
'process.env': env
},
test: {
globals: true,
environment: 'jsdom',
deps: {
inline: ['vuetify']
},
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
});
};
By the way, I don't know if it should be vite.config.ts
or vitest.config.ts
. I'm doing this in a component library, so I don't have any Vue app.
Thank you,
Clément
I've finally figured it out. It comes from the VDialog that has nowhere to attach to. Just surrounding it with a
<body>
in the template used for mounting in test wasn't enough, I had to stub the VDialog like in this answer : https://stackoverflow.com/a/76018176/3004275