I am new to the Jest test suite for Vue JS and integrating it into my Nuxt JS application. I've set up some basic tests to check if the component is a Vue instance and these tests pass successfully.
I'm now trying to find an element on my page and check if it exists, and what content might be in it.
This is my structure
pages/application/begin.vue
<template> <div> <LoanTerm /> </div> </template>
Components/Forms/Steps/Loan/LoanTerm.vue
<template> <article> <article class="tw-px-7 tw-pb-7"> <StepHeader title="About your loan" subtitle="How long do you need the money for?" /> </article> <hr class="tw-mt-7" /> <article class="tw-p-7 tw-space-y-7"> <section> <validation-provider vvid="loan.term" name="Loan term" rules="required" v-slot="{ errors, classes }" > <div class="tw-grid tw-grid-cols-2 tw-gap-4"> <label v-for="(term, index) in datasets.terms.slice(0, 12)" v-if="index % 2 == 0" :key="index" :for="`term-${index}`" class="tw-flex-1 tw-relative tw-bg-gray-50 tw-rounded-xl tw-p-7 tw-border-b-4 tw-border-gray-200 tw-text-center tw-cursor-pointer" :class="$getClasses(classes, true, fields.loan.term === term.value)"> <input type="radio" name="term" :id="`term-${index}`" :value="term.value" v-model="fields.loan.term" class="tw-absolute tw-top-4 tw-right-4 tw-h-4 tw-w-4 focus:tw-ring-green-500 tw-text-green-600 tw-border-gray-300 jest__datasets-terms" /> <span class="tw-block"> {{ term.label }} </span> </label> </div> <ValidationMessage :message="errors[0]" /> </validation-provider> </section> <section class="tw-space-y-4"> <modal title="Choose address" :is-open="termSelectionModalIsOpen"> <template #action-close> <button @click="termSelectionModalIsOpen = false" type="button" class="tw-p-3 tw-rounded-full tw-text-gray-800 tw-border tw-border-gray-300 tw-font-extrabold focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-offset-2 focus:tw-ring-offset-gray-200 focus:tw-ring-white"> <svg xmlns="http://www.w3.org/2000/svg" class="tw-h-5 tw-w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> </svg> </button> </template> <template #iterable-data> <section v-for="(term, index) in datasets.terms" :key="index"> <button @click="chooseTerm(term)" type="button" class="tw-w-full tw-block md:hover:tw-bg-gray-50 tw-p-6 tw-text-left"> <div class="tw-grid tw-grid-cols-3 tw-gap-6"> <div class="tw-col-span-2 tw-flex tw-items-center tw-text-gray-600"> {{ term.label }} </div> <div class="tw-text-right"> <button type="button" class="tw-p-3 tw-rounded-full tw-text-gray-800 tw-border tw-border-transparent tw-font-extrabold focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-offset-2 focus:tw-ring-offset-gray-200 focus:tw-ring-white"> <svg xmlns="http://www.w3.org/2000/svg" class="tw-h-5 tw-w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /> </svg> </button> </div> </div> </button> <hr /> </section> </template> </modal> <button @click="termSelectionModalIsOpen = true" type="button" class="tw-py-5 tw-px-5 tw-rounded-xl tw-bg-gray-100 tw-flex tw-w-full tw-text-gray-600 tw-border tw-border-gray-200 tw-font-medium focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-offset-2 focus:tw-ring-offset-gray-100 focus:tw-ring-white"> <div class="tw-flex tw-mx-auto"> <svg xmlns="http://www.w3.org/2000/svg" class="tw-h-5 tw-w-5 tw-mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> </svg> Choose another term </div> </button> <div class="md:tw-shadow-lg"> <button type="submit" class="tw-py-5 tw-px-5 tw-rounded-xl tw-bg-green-500 md:hover:tw-bg-green-600 tw-block tw-w-full tw-text-white tw-border tw-border-gray-300 tw-font-medium focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-offset-2 focus:tw-ring-offset-gray-200 focus:tw-ring-white"> Continue </button> </div> </section> </article> </article> </template> <script> export default { props: { minTerm: { type: Number, default: 1 }, term: { type: Number, default: 7 }, maxTerm: { type: Number, default: 36 }, fields: { type: Object, default: () => ({ }) } }, data () { return { termSelectionModalIsOpen: false, datasets: { terms: [] } } }, created () { this.availableTerms() }, methods: { /* ** Generate available terms */ availableTerms () { for (let term = this.minTerm; term < this.maxTerm; term++) { this.datasets.terms.push({ label: `${term} month${term == 1 ? '' : 's'}`, value: term }) } }, /* ** Choose term */ chooseTerm (term = null) { this.fields.loan.term = term.value this.termSelectionModalIsOpen = false this.$store.commit('application/stepForwards') } } } </script>
The test I set up provides the following:
import { mount } from '@vue/test-utils' import LoanTerm from '@/components/Form/Steps/Loan/LoanTerm' describe('LoanTerm', () => { test('is a Vue instance', () => { const wrapper = mount(LoanTerm) expect(wrapper.vm).toBeTruthy() }) test('terms are available for selection', async () => { const wrapper = mount(LoanTerm) const terms = await wrapper.find('.jest__datasets-terms') expect(terms.exists()).toBe(true) }) })
The results I get when I run this test are my "Terms to choose from" "The test failed because it received error.
I also tried using findAll
and it returns nothing
What did I miss?
It looks like the contents of
modal
(including the "datasets-terms" button your test is looking for) are not rendered initially becausetermSelectionModalIsOpen
is initialized tofalse
and there is no setting to set it totrue
. The pattern might look similar to this:solution
Mount
LoanTerm
using thedata()
property, which initializestermSelectionModalIsOpen
totrue
so that the contents of the modal are rendered:I noticed that the
jest__datasets-terms
class is missing fromLoanTerm.vue
, but I think it's just a copy-paste error.Demo