I have been killing myself trying to figure out how to test a Vue component with a v-dialog, something which worked perfectly fine in Vue2. Currently I am using Vue3, Vitest, Vuetify3.
here is a very simple component which demonstrates a problem
<template>
<div>
<v-btn @click.stop="dialog=true" class="open-dialog-btn">click me please</v-btn>
<v-dialog v-model="dialog" max-width="290" >
<div class="dialog-content">
<v-card>welcome to dialog</v-card>
</div>
</v-dialog>
</div>
</template>
<script setup>
import {ref} from "vue";
const dialog = ref(false);
</script>
and here is a unit test for it:
import '../setup';
import { mount } from '@vue/test-utils';
import { createVuetify } from "vuetify";
import HelloDialog from "@/components/HelloDialog.vue";
describe('HelloDialog', () => {
let wrapper;
let vuetify;
beforeEach(() => {
vuetify = createVuetify();
});
describe('dialog tests', () => {
beforeEach(() => {
wrapper = mount(HelloDialog, {
global: {
plugins: [vuetify],
},
});
});
test('test dialog', async () => {
expect(wrapper.find('.dialog-content').exists()).toBeFalsy();
await wrapper.find('.open-dialog-btn').trigger('click');
console.log(wrapper.html());
expect(wrapper.find('.dialog-content').exists()).toBeTruthy();
});
});
});
the last line in unit test is not working - dialog content is not displayed. Here is an output from wrapper.html() after button is clicked:
<div><button type="button" class="v-btn v-btn--elevated v-theme--light v-btn--density-default v-btn--size-default v-btn--variant-elevated open-dialog-btn"><span class="v-btn__overlay"></span><span class="v-btn__underlay"></span>
<!----><span class="v-btn__content" data-no-activator="">click me please</span>
<!---->
<!---->
</button>
<!---->
<!--teleport start-->
<!--teleport end-->
</div>
AssertionError: expected false to be truthy
at ....../HelloDialog.spec.js:27:56
here is test section from vite.config.js:
test: {
// https://vitest.dev/config/
globals:true,
environment: 'happy-dom',
setupFiles: "vuetify.config.js",
deps: {
inline: ["vuetify"],
},
},
and here is vuetify.config.js:
global.CSS = { supports: () => false };
here some versions from package.json:
"dependencies": {
"@mdi/font": "7.1.96",
"@pinia/testing": "^0.0.14",
"axios": "^1.2.0",
"dotenv": "^16.0.3",
"happy-dom": "^8.1.1",
"jsdom": "^20.0.3",
"lodash": "^4.17.21",
"pinia": "^2.0.27",
"roboto-fontface": "*",
"vue": "^3.2.45",
"vuetify": "3.0.6",
"webfontloader": "^1.0.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.0.0",
"@vue/test-utils": "^2.2.6",
"vite": "^4.0.3",
"vite-plugin-vuetify": "^1.0.0-alpha.12",
"vitest": "^0.26.2"
}
I have tried everything at this point, and I think the problem has something to do with v-dialog using teleport component. After struggling for several days trying to figure out I settled on using a stub to not use a real dialog when testing but I really don't like this approach.
any ideas would be greatly appreciated