How to get slot content to render so I can test it for vue 3 vue-test-utils with jest

95 Views Asked by At

Versions: Vue 3.3.6, Vuetify 3.4

I've come to a problem that somehow no one else seems to have encountered or I am just going about it wrong. The docs on slot testing has not been helpful and no amount of await wrapper.vm.$nextTick(); is doing the trick.

Issue: I cannot test the conditional content inside the vuetify v-window content for a v-tab because I'm using a slot and that slot is not rendering and I also can't have a fake mocked slot because I need to actually test what's inside it.

Example: I want to be able to test which conditional div is being rendered for foo and bar.

Goal: Be able to test the v-tab's v-window content as seen below in the test.

Tab wrapper component: Wrapper for the vuetify component using slots

<template>
    <v-tabs active-class="active-tab" v-bind="$attrs">
        <v-tab v-for="tab in tabs" :key="tab">
            {{ tab }}
        </v-tab>
    </v-tabs>
    <v-window v-bind="$attrs">
        <v-window-item v-for="tab in tabs" :key="tab">
            <slot :name="tab"></slot>
        </v-window-item>
    </v-window>
</template>

<script>
export default {
    name: 'BaseTabs',
    props: {
        tabs: {
            type: Array
        }
    }
};
</script>

Component I'm trying to test: has tabs and uses the BaseTabs component

<base-tabs v-model="activeTab" :tabs="[foo, bar]">
        <template #foo>
             <div v-if="foo.length == 1" class="foo-one">I only have one item</div>
            <div v-if="foo.length > 1" class="foo-more">I have more than one item</div>
        </template>
        <template #bar>
             <div v-if="bar.length == 1" class="bar-one">I only have one item</div>
            <div v-if="bar.length > 1" class="bar-more">I have more than one item</div>
        </template>
</base-tabs>
<script>
import BaseTabs from './BaseTabs.vue';
export default {
    name: 'FooBar',
    components: { BaseTabs },
    props: {
        foo: Array,
        bar: Array
    }
};
</script>

Test file

import { mount } from "@vue/test-utils";
import FooBar from "@/components/FooBar.vue";

describe("FooBar component", () => {
   it('test that correct content shows for foo tab when bar length > 1', () => {
       const wrapper = mount(FooBar, {
          props: {
             foo: [{...object}, {...object}]
             bar: [{...object}]
          }
       });
       expect(wrapper.find('.foo-one').exists()).toBe(false);
       expect(wrapper.find('.food-more').isVisible()).toBe(true);
   });
});

What I'm seeing in the console:

<div>
      <div class="v-slide-group" active-class="active-tab">
        <!---->
        <div class="v-slide-group__container">
          <div class="v-slide-group__content" style="transform: translateX(0px);"><button type="button" class="v-btn v-theme--light v-btn--density-default v-btn--size-default v-btn--variant-text v-tab" tabindex="-1" role="tab" aria-selected="false"<span class="v-btn__overlay"></span><span class="v-btn__underlay"></span>
              <!----><span class="v-btn__content" data-no-activator="">foo<div class="v-tab__slider text-white"></div></span>
              <!---->
              <!---->
            </button><button type="button" class="v-btn v-theme--light v-btn--density-default v-btn--size-default v-btn--variant-text v-tab" tabindex="-1" role="tab" aria-selected="false" data-testid="bar"><span class="v-btn__overlay"></span><span class="v-btn__underlay"></span>
              <!----><span class="v-btn__content" data-no-activator="">bar<div class="v-tab__slider text-white"></div></span>
              <!---->
              <!---->
            </button>
        </div>
        <!---->
      </div>
      <div class="v-window v-theme--light">
        <div class="v-window__container">
          <div class="v-window-item v-leave-from v-leave-active" disabled="true"></div>
          <div class="v-window-item" data-testid="foo-content" disabled="true" style="display: none;">
            <!---->
          </div>
          <div class="v-window-item v-window-item--active v-enter-from v-enter-active" data-testid="bar-content" disabled="true" style=""></div>
          <!---->
        </div>
        <!---->
      </div>
      <!---->
      <!---->
      <!---->
      <!---->
      <!---->
      <!---->
      <!---->
      <!---->
    </div>
0

There are 0 best solutions below