The Vitest test is not compatible with PrimeVue3 Dialogs and does not function as intended

I am currently working on a project that involves using PrimeVue components, and the time has come to conduct some tests.

Below is the code for 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())**
  })
})

However, the console log does not display the component. Instead, it shows the following:

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

For instance, if I want to test the functionality of the "Close button" and check if it is displayed, I should write code 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)
})

Unfortunately, the MyDialog.find method cannot find the button, making it impossible to handle the .trigger('click') event.

While I have attempted to use Mount instead of ShallowMount and also tried using .findComponent(Button) instead of .find('.p-button-secondary'), the issue persists.

This problem seems to be specific to Dialog tests, and despite others facing similar challenges, I have not found a viable solution yet.

Thank you.

Answer №1

An effective solution that avoids the need to remove teleports within the production app is to simulate teleports by setting teleport: true in the global stubs option.

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

For more alternative methods, refer to the Testing Teleport documentation for vitest.

To understand the importance of Teleport in the production app, check out: (the Accessibility and Modularity section is particularly crucial, as it addresses the complex issue of compatibility through other means).

Answer №2

Due to the teleportation of the Dialog, it exhibits unique behavior. After encountering this Stackoverflow problem and consulting the vue test utils documentation, I discovered that the desired HTML content is not directly within the component, but rather in the Virtual DOM (which may not be utilized in this case).

Resolution:
To address this issue in MyDialog.vue, consider including append-to="self" within the <Dialog> tag to properly teleport it to the designated location in the DOM.

Although I am unaware of the structure of your MyDialog.vue file, in my case, it comprises a solitary <Dialog> tag enclosing all testable elements, necessitating a mount rather than a shallowMount to ensure the Stub is not the only output of wrapper.html().

This approach worked for me, yielding a dialog-stub instead of the expected portal-stub. If you encounter any issues, sharing your MyDialog.vue file would aid in further troubleshooting.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing several data sources within a single mat-table

Hello, I require assistance with a task. I am trying to display multiple mat-tables with different data sources in my component.ts file Groups(){ this.apiSvc.Cards().subscribe((rsp: any) => { this.groups = rsp; this ...

The ESLint setup specified in the package.json file for eslint-config-react-app is deemed to be incorrect

The property named "overrides" has the incorrect type (expected array but received {"files":["**/*.ts","**/*.tsx"],"parser":"@typescript-eslint/parser","parserOptions":{"ecmaVersion":2018,"sourceType":"module","ecmaFeatures":{"jsx":true},"warnOnUnsupported ...

I am currently facing challenges retrieving data from a post request in my Angular/Typescript frontend application connected to an ASP.NET backend

I am currently working on a web application that relies on backend processing. To communicate between my Angular(v14)/Typescript front end and an ASP.NET backend, I am sending a post request. Backend Code [HttpPost] public async Task<string> Process ...

Watching - transforming / combining

I am a beginner when it comes to working with Observables. Here's the Effect that I am using: My goal is to dispatch the PositionUpdateAction or PositionFailedAction before the SunriseSunsetAction is dispatched. Currently, what happens is that the r ...

Inquiry regarding the TS2322 error encountered in a Svelte Component

I'm currently exploring Svelte using TypeScript. I encountered a TS23 error while working on this piece of code. <script lang="ts"> import ComponentA from './ComponentA.svelte'; import ComponentB from './Compone ...

Is there a way to consolidate two interface types while combining the overlapping properties into a union type?

Is there a way to create a type alias, Combine<A, B>, that can merge properties of any two interfaces, A and B, by combining their property types using union? Let's consider the following two interfaces as an example: interface Interface1 { t ...

Guide to modifying the root directory when deploying a Typescript cloud function from a monorepo using cloud build

Within my monorepo, I have a folder containing Typescript cloud functions that I want to deploy using GCP cloud build. Unfortunately, it appears that cloud build is unable to locate the package.json file within this specific folder. It seems to be expectin ...

Update the mandatory fields in the required interface to extend to another interface, while ensuring that all subfields become

Currently, I have defined 2 interfaces: interface BattleSkills { strength: number; armor: number; magic_resistance: number; health: number; mana: number; intelligence: number; accuracy: number; agility: number; critical_damage: number; } ...

Stop allowing the transmission of unfamiliar string constants, but still permit the transmission of adaptable strings

Consider the TypeScript code snippet below: const namesList = { john: 25, emma: 30, jacob: 35, } type NameType = keyof typeof namesList function getPersonAge< Name extends string, Result = Name extends NameType ? number ...

Angular is throwing an error stating that the type '{ }[]' cannot be assigned to the type '[{ }]'

I'm in need of assistance and clarification regarding the error I encountered in my application... When I receive a JSON response from an API with some data that includes an array of products, I aim to extract these products (izdelki) from the array, ...

Error alert! A token error has been detected while executing Angular tests under <Jasmine>

I've been navigating the world of Angular testing, but I've hit a roadblock that I can't seem to bypass. Despite my efforts to consult the documentation and scour Google for answers, I remain stuck with a cryptic error message stating "Inval ...

Having trouble with Angular 2's Output/emit() function not functioning properly

Struggling to understand why I am unable to send or receive some data. The toggleNavigation() function is triggering, but unsure if the .emit() method is actually functioning as intended. My end goal is to collapse and expand the navigation menu, but for ...

What is the best way to convert one array of types to another array of types in Typescript?

Imagine you have the following: type AwesomeTuple = [string, number, boolean] Now, you're looking to transform that type using a generic approach: type AmazingGeneric<T extends any[]> = ... In this scenario: AmazingGeneric<AwesomeType> w ...

Exploring the use of national flag emojis in VS code

I've been attempting to use flag emojis as reactions on a Discord bot, but they just won't cooperate. Every time I try something like this > ':flag_jp:', I encounter the following error: Error: DiscordAPIError: Unknown Emoji EDIT ...

Developing a continuous running test loop

Currently, I have a code that runs fine, but I am looking to modify it to run in a loop that counts the number of elements with the class="socal" and tests each link. module.exports = { 'Unitel Fitness - click' : function (browser) { bro ...

What is the most effective way to retrieve the value of a child component in Angular 2 and pass it to the parent component?

I am working on a project with a child component (calendar) and a parent component (form). I need to select a value in the calendar and then access that value in the form component. What is the best way to achieve this? Child Component.ts: import { ...

Error message: Issue with AWS Serverless Lambda and Angular - TypeError: express function not defined

I'm encountering an issue when trying to deploy my application from localhost:4200 to AWS serverless Lambda. The error in cloudwatch logs is causing a 500 {"message": "Internal server error"} response when I access the URL. My understanding of AWS is ...

What is the method for returning a string array?

My query is about how to return a string[]. Currently, TypeScript is throwing an error because each element of the array has a type of ( T[keyof T] extends readonly (infer InnerArr)[] ? InnerArr : T[keyof T] ). How can I accept the 'property' arg ...

Support for dark mode in Svelte with Typescript and TailwindCSS is now available

I'm currently working on a Svelte3 project and I'm struggling to enable DarkMode support with TailwindCSS. According to the documentation, it should be working locally? The project is pretty standard at the moment, with Tailwind, Typescript, and ...

Angular: How to Disable Checkbox

Within my table, there is a column that consists solely of checkboxes as values. Using a for loop, I have populated all values into the table. What I have accomplished so far is that when a checkbox is enabled, a message saying "hey" appears. However, if m ...