Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug Report][3.6.7] Can't test components that require the v-app component as their parent. #19895

Open
Yamadetta opened this issue May 26, 2024 · 3 comments

Comments

@Yamadetta
Copy link

Environment

Vuetify Version: 3.6.7
Vue Version: 3.4.27
Browsers: Chrome 125.0.0.0
OS: Windows 10

Steps to reproduce

Continuing from the discussion (#18076), components like VMain, VNavigationDrawer, VBottomNavigation, VAppBar, and VLayoutItem do not render in tests using @vue/test-utils, making it impossible to test components that contain these components.

For example, the following test:

import { mount } from '@vue/test-utils'
import { describe, test } from 'vitest'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'

const vuetify = createVuetify({
  components,
  directives
})

const mountComponent = (props?: any) => mount(
  {
    template: `
      <v-app>
        <v-app-bar>
          <div>123</div>
        </v-app-bar>
      </v-app>
    `,
    setup() {
      return { props }
    }
  },
  {
    global: {
      plugins: [vuetify]
    },
    props
  }
)

describe('should', () => {
  test('', () => {
    const wrapper = mountComponent({
      mainPage: true,
      title: 'main'
    })
    console.log(wrapper.html())
  })
})

Will have the following markup:

<div class="v-application v-theme--light v-layout v-layout--full-height v-locale--is-ltr" mainpage="true" title="main">
  <div class="v-application__wrap">
    <!---->
  </div>
</div>

The following variant also does not work:

import { mount } from '@vue/test-utils'
import { describe, test } from 'vitest'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'

const vuetify = createVuetify({
  components,
  directives
})

const mountComponent = (props?: any) => mount(
  components.VApp,
  {
    slots: {
      default: components.VLayoutItem
    },
    global: {
      plugins: [vuetify]
    },
    props
  }
)

describe('should', () => {
  test('', () => {
    const wrapper = mountComponent({
      mainPage: true,
      title: 'main'
    })
    console.log(wrapper.html())
  })
})

Expected Behavior

Components must rendering

Actual Behavior

Components are not rendering

Reproduction Link

https://play.vuetifyjs.com/#...

Other comments

Can’t give a link to the repository, since the work is being done in a private repository

@Yamadetta
Copy link
Author

UPD: I managed to fix it using this before the first expect:

    await new Promise((res) => {
      setTimeout(() => res(''), 1)
    })

I'm not sure it's very obvious. It might be worth describing this in the documentation if it can't be fixed.

@thopiddock
Copy link

I believe I can confirm this behaviour is present since 3.6.0.

@jl094
Copy link

jl094 commented Dec 17, 2024

We encountered the same issue in component testing a component with v-app-bar with Playwright, none of the fixes suggested above or in the discussion (#18076) seemed to work. As a workaround we've created a template with v-app and a nested dynamic component that can be passed in as a prop. Posting in case it helps anyone else out.

This is the template:

<template>
  <v-app>
    <component :is=componentToTest></component>
  </v-app>
</template>

<script lang="ts" setup>
  defineProps(['componentToTest'])
</script>

And the test:

import { test, expect } from '@playwright/experimental-ct-vue'
import AppBar from '../../src/components/AppBar.vue'
import ComponentTestAppTemplate from './templates/ComponentTestAppTemplate.vue'

test('app bar title is correct', async ({ mount }) => {
  const appBar = await mount(ComponentTestAppTemplate, {
    props: {
      componentToTest: AppBar
    }
  })

  await expect(appBar).toContainText('App Bar Title')
})

Where AppBar.vue is:

<template>
  <v-app-bar>
    <template #prepend>
    </template>

    <v-app-bar-title>
      App Bar Title
    </v-app-bar-title>

    <template #append>
    </template>
  </v-app-bar>
</template>

<script lang="ts" setup>
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants