quasar-testing: QDialog is not mounted in tests when used with mount()
Follow up on this Discord chat: https://discordapp.com/channels/415874313728688138/450312684790087691/560449585307320322
I am using 1.0.
If used with shallowMount()
, it mounts the stub fine. If used with mount()
the wrapper.html()
doesn’t have any mention of the <q-dialog>
component.
Some Quasar components run in their own context (QDialog, QMenu, QTooltip). I am not sure, but maybe this is somehow causing this problem.
Usually, I would just full mount the component that uses Quasar components and then trigger the events on components like QBtn. Currently, I can’t do that.
My component:
<template>
<div>
<q-dialog
v-model="sendFailureModalOpened"
persistent
:maximized="true"
transition-show="slide-up"
transition-hide="slide-down"
content-class="dark-modal"
>
// HTML, Vue components and other Quasar components
</q-dialog>
</div>
</template>
My test:
import { mount, createWrapper } from '@vue/test-utils';
import SendFailure from '@/components/Modals/SendFailure';
import { localVue, i18n } from '@/helpers/SetupLocalVue';
import Vuex from 'vuex';
import * as All from 'quasar'
const { Quasar, date } = All;
const components = Object.keys(All).reduce((object, key) => {
const val = All[key]
if (val && val.component && val.component.name != null) {
object[key] = val
}
return object
}, {})
describe('SendFailure component', () => {
let store;
localVue.use(Quasar, { components });
beforeEach(() => {
store = new Vuex.Store();
});
it('renders and matches snapshot', () => {
const wrapper = mount(SendFailure, {
i18n,
localVue,
store,
});
expect(wrapper.element).toMatchSnapshot();
});
});
Snapshot output:
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SendFailure component renders and matches snapshot 1`] = `
<div>
<!---->
</div>
`;
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 1
- Comments: 19 (6 by maintainers)
Commits related to this issue
- fix: QDialog is not mounted in tests when used with mount() (fix #72) (#213) — committed to quasarframework/quasar-testing by OneFourFree 2 years ago
Based on @Abuntxa 's awesome answer I use the following technique to test
q-dialog
in my component tests:The good thing is that
createWrapper
acceptsHTMLElement
(I am onv1.0.0-beta.29
), so no knowledge ofvue
’s internal structures and private properties is needed.The bad thing is - as @kennyki mentioned - that even if I create a brand new
wrapper
for every test case,document
is not re-rendered, so I have to manually remove theq-dialog
at the end of each test.Thanks guys!
Sorry for reviving the thread. Just to sum up for people still looking how to deal with QDialog testing in Vue 3 usingTest Utils V2 :
Thanks @OneFourFree updating MyDialog.spec.js
I’ve been able to get this to work with Vue 3 and quasar 2 using the attachTo property when mounting the component.
I use the following code to be able to test the components in the QDialog.
@rstoenescu Could it be considered the use of portal-vue?
@AlphaJuliettOmega Play necromancer in Diablo, but not GitHub
Please do us a favor and open a new issue
@Shinigami92 Ok, will try do so!
@IlCallo yeah I’ll have time to add that this week
@OneFourFree I think you saved me multiple hours of struggle ❤️ Works perfectly 👌
This is a long-standing problem with Portal-based components, but still could not find a workaround If you need to test a component which calls a dialog, stub
Dialog.create
or$q.dialog
(depending on which you’re using), as unit testing is meant to test a single component in isolation, not the interaction between componentsIf you need to test the dialog content, abstract the dialog inside its own component and mount that component for testing
Hi,
The QDialog, QMenu and QTooltip components do not mount in the same place that they are used. They are mounted at the end of
<body>
when they are opened through a Quasar Portal.What you should do is to use
content-class
prop, trigger QDialog to show, wait for it to be opened (attach a Vue ref and@show
event handler –this.$refs.dialog.$once('show', handlerFn)
) then look in DOM for that class --> that would be your DOM node that has the QDialog content.