#Vitest Headless UI HTML not rendered correctly

3 messages · Page 1 of 1 (latest)

dense roverBOT
#

Hi @neon rose. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Based on the information provided in the knowledge sources, I can offer some insights and suggestions regarding your issue with testing a Headless UI dialog using Vitest in a Nuxt application.

The problem you're experiencing seems to be related to how Teleport components are handled during testing. Teleport is a Vue feature that allows rendering content elsewhere in the DOM tree, which is commonly used for modals and dialogs.

Here are a few points to consider:

  1. Nuxt's SSR support for teleports: According to the Nuxt documentation on Teleport (https://nuxt.com/docs/api/components/teleports), Nuxt currently has SSR support for teleports to #teleports only. For other targets, client-side support is available using a <ClientOnly> wrapper.

  2. Testing environment: Make sure you're using the Nuxt testing environment. In your Vitest configuration, you should have environment: 'nuxt' set. This ensures that a global Nuxt app is initialized before your tests run, including plugins and code defined in your app.vue Nuxt Testing Setup (https://nuxt.com/docs/getting-started/testing#setup).

  3. Using mountSuspended: You're correctly using mountSuspended from @nuxt/test-utils/runtime, which allows mounting Vue components within the Nuxt environment Nuxt Test Helpers (https://nuxt.com/docs/getting-started/testing#-helpers).

To address your specific issue, you might try the following:

  1. Ensure your dialog is wrapped in a <ClientOnly> component if it's using Teleport to a target other than #teleports.

  2. Instead of using wrapper.html(), try using the screen utility from @testing-library/vue. This might give you a more accurate representation of what's actually rendered. Here's an example:

#
import { renderSuspended } from '@nuxt/test-utils/runtime'
import { screen } from '@testing-library/vue'
import CreateDaytisticDialog from './CreateDaytisticDialog.vue'

it('should render the dialog', async () => {
  await renderSuspended(CreateDaytisticDialog, {
    props: {
      open: true,
    }
  })
  
  // Now use screen to query the rendered content
  const dialogContent = screen.getByText('Your expected dialog content')
  expect(dialogContent).toBeDefined()
})
  1. If you're still having issues, you might need to add a specific target for your Teleport in your test environment. You can do this by adding a div with the appropriate id to your test file:
beforeEach(() => {
  const teleportTarget = document.createElement('div')
  teleportTarget.id = 'teleports'  // or whatever id you're using
  document.body.appendChild(teleportTarget)
})

Remember that when testing with the Nuxt environment, you're running in a happy-dom or jsdom environment, which might behave slightly differently from a real browser Nuxt Testing Environment (https://nuxt.com/docs/getting-started/testing#setup).

If these suggestions don't resolve your issue, you might need to provide more details about your CreateDaytisticDialog component and how it's implemented, particularly how it's using Teleport and Headless UI.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: