'How can I test the correct rendering of items in a Vuetify v-select dropdown using jest?
I have been trying to check if the correct values get displayed in a v-select and v-menu dropdown box, but they don't appear in my isolated testing component after I trigger a click event.
<template #append>
<v-menu>
<template #activator="{ on }">
<div v-on="on">
<span
data-testid="type-filter-selector-value"
>{{ type }}</span>
<v-icon class="d-inline-block">
mdi-menu-down
</v-icon>
</div>
</template>
<v-list>
<v-list-item
v-for="t in searchTypes"
:key="t"
@click="type = t"
>
<v-list-item-title class="text-capitalize">
{{ t }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</template>
Test:
test('rendered select filter contains items labels', () => {
component = localMount(SelectFilterComponent, {
propsData: {
filter: {
label: 'icecream',
items: [
{ text: 'Pistaccio' },
],
},
},
});
componentHtml = component.html();
console.log('before click', component.html());
component.find('.v-select').trigger('click');
console.log('after click', component.html());
expect(componentHtml).toContain('Pistaccio');
});
When you look at the html structure of the component in the actual page, you see that the rendered items are actually appended not to the v-select element, but to the outer div with data-app="true". Also Jest through some vuetify error if this element did not exist. After some hacking I was succesful in wrapping my component in such a div with the following jest-helper method:
const localVue = createLocalVue();
const vuetify = new Vuetify();
const inject = {
localVue,
vuetify,
};
export const localMount = (component, options = {}) => {
const child = mount(component, {
...inject,
...options,
});
const app = mount({
template: '<div data-app="true" id="app"></div>',
});
app.element.appendChild(child.element);
return app;
};
And finally here is the selectFilter component, (stripped of unrelevant styles etc):
<template>
<v-select
class="v-select"
:items="filter.items"
:label="filter.label"
:value="filter.value"
:chips="filter.multiple"
:multiple="filter.multiple"
/>
</template>
<script>
export default {
props: {
filter: {
type: Object,
required: true,
},
},
};
</script>
Now the output of the console logs in the test is here:
console.log tests/unit/components/SelectFilter.spec.js:40
before click <div data-app="true" id="app" class="v-application">
<div class="v-input v-select v-input--dense theme--light v-text-field v-select">
<div class="v-input__control">
<div role="button" aria-haspopup="listbox" aria-expanded="false" aria-owns="list-14" class="v-input__slot" style="height: 38px;">
<div class="v-select__slot"><label for="input-14" class="v-label theme--light" style="left: 0px; position: absolute;">icecream</label>
<div class="v-select__selections"><input id="input-14" readonly="readonly" type="text" aria-readonly="false" autocomplete="off"></div>
<div class="v-input__append-inner">
<div class="v-input__icon v-input__icon--append"><i aria-hidden="true" class="v-icon notranslate mdi mdi-menu-down theme--light"></i></div>
</div><input type="hidden">
</div>
<div class="v-menu">
<!---->
</div>
</div>
<div class="v-text-field__details">
<div class="v-messages theme--light">
<transition-group-stub tag="div" name="message-transition" class="v-messages__wrapper"></transition-group-stub>
</div>
</div>
</div>
</div>
</div>
console.log tests/unit/components/SelectFilter.spec.js:42
after click <div data-app="true" id="app" class="v-application">
<div class="v-input v-select v-input--dense theme--light v-text-field v-select">
<div class="v-input__control">
<div role="button" aria-haspopup="listbox" aria-expanded="false" aria-owns="list-14" class="v-input__slot" style="height: 38px;">
<div class="v-select__slot"><label for="input-14" class="v-label theme--light" style="left: 0px; position: absolute;">icecream</label>
<div class="v-select__selections"><input id="input-14" readonly="readonly" type="text" aria-readonly="false" autocomplete="off"></div>
<div class="v-input__append-inner">
<div class="v-input__icon v-input__icon--append"><i aria-hidden="true" class="v-icon notranslate mdi mdi-menu-down theme--light"></i></div>
</div><input type="hidden">
</div>
<div class="v-menu">
<!---->
</div>
</div>
<div class="v-text-field__details">
<div class="v-messages theme--light">
<transition-group-stub tag="div" name="message-transition" class="v-messages__wrapper"></transition-group-stub>
</div>
</div>
</div>
</div>
</div>
In other words, no change after the click. What am I missing? How do I make the component in jest expose the v-select items, so I can probe if they are rendered correctly?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
