2

I've got a project where I use PrimeVue components and it's time to do some tests.

This is the code of the test:

import { beforeEach, describe, expect, it } from 'vitest'
import type { VueWrapper } from '@vue/test-utils'
import { shallowMount } from '@vue/test-utils'
import Dialog from 'primevue/dialog'
import MyDialog from '@/components/modal/MyDialog.vue'
// Other imports...



describe('MyDialog', () => {
  let myDialogWrapper: VueWrapper

  beforeEach(() => {
    myDialogWrapper= shallowMount(MyDialog , {
      props: {
        visible: false
      },
      global: {
        stubs: {
          // Some elements
        },
      }
    })
  })

  it('mount', () => {
    expect(myDialogWrapper).toBeTruthy()
    expect(myDialogWrapper.html()).toMatchSnapshot()
    **console.log(myDialogWrapper.html())**
  })
})

But that console log does not print the component. It prints the following:

<portal-stub data-v-eb267b8d="" appendto="body" disabled="false"></portal-stub>

If I want to test, for example, that the "Close button" works, I'm trying to see if the button is displayed, so I should do something like this:

it('displays close button', async () => {
   myDialogWrapper.setProps({ visible: true })
   await myDialogWrapper.vm.$nextTick()
   const button = myDialogWrapper.find('.p-button-secondary')
   expect(button.exists()).toBe(true)
})

But, MyDialog.find does not find the button, so I can't handle the .trigger('click') event.

Instead of ShallowMount i've tried using Mount but, although the print is different, it's still not the fullth component.

I've also tried .findComponent(Button) instead of .find('.p-button-secondary') but it doesn't work either.

It only happens with Dialog tests and I've find that more people is struggling with this, but no one gives a solution that I can apply.

Thank you.

RafaB
  • 31
  • 2

1 Answers1

1

Because the Dialog gets teleported, it has some special behavior. With this Stackoverflow issue and this vue test utils docs, I found out that the html you are looking for is not inside the component (only in the Virtual Dom, which is not used somehow?).

My Solution:
Inside the MyDialog.vue you could add append-to="self" to the <Dialog> so it does get teleported to the correct location in the DOM.

I do not know how your MyDialog.vue looks, but mine only contains a single <Dialog>, with everything i want to test inside the Dialog-Tag, so i need to do a mount instead of a shallowMount. Otherwise you only get the Stub in your wrapper.html().

I hope this helps, it worked for me but i get a dialog-stub instead of your portal-stub. If it does not help, providing your MyDialog.vue could help me analyze your issue furter.

Marvin
  • 11
  • 2