bootstrap5 with vue3: the vue-test-utils problem

32 Views Asked by At

I'm using bootstrap5 in my vue3 app, I integrated it as follow

// mains.ts
import 'uno.css';
import '../src/styles/bootstrap_customization.css';
import VTooltip from 'floating-vue'

import { createPinia } from 'pinia';
import { createApp } from 'vue';

import App from './App.vue';
import router from './router';

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(VTooltip)
app.mount('#app')

import "bootstrap/dist/js/bootstrap.js";

everything work great! But when I want to unit-test a functionality that uses some bootstrap.js function that modify the DOM such as Dropdowns, the test fails as bootstrap is not being loaded during the Mount

with a component being a simple dropdown as follow

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

<template>
  <div>
    <div class="dropdown d-flex flex-fill w-100">
      <button
        class="dropdown-toggle"
        type="button"
        id="dropdownAction1"
        data-bs-toggle="dropdown"
        aria-expanded="false"
        data-test="selected-action"
      >
       action1
      </button>
      <ul
      class="dropdown-menu w-100"
      aria-labelledby="dropdownAction1"
      data-test="action-list"
      >
        <li><button>action1</button></li>
        <li><button>action2</button></li>
        <li><button>action3</button></li>
      </ul>
    </div>
  </div>
</template>

<style lang="css" scoped>
</style>

</template>

It works well in the browser and in Cypress e2e tests but the following simplistic test fails with vue-test-utils

import DropdownTest from '@/components/form/DropdownTest.vue'
import { VueWrapper, flushPromises, mount } from '@vue/test-utils'
import { beforeEach, describe, expect, it } from 'vitest'


let wrapper: VueWrapper<any>

beforeEach(async () => {
  wrapper = mount(DropdownTest, {})
  await flushPromises()
})

describe('DropdownAction.vue', () => {
  it('opens the dropdown menu', async () => {
    const dropdownButton = wrapper.find('[data-test="selected-action"]')

    expect(dropdownButton.attributes('aria-expanded')).toBe('false');
    // Simulate the user clicking the dropdown button
    await dropdownButton.trigger('click')
    // tried all wait methods I found
    await wrapper.vm.$nextTick()
    await flushPromises()
    // menu dropdown options should be visible
    expect(dropdownButton.attributes('aria-expanded')).toBe('true');
  })
})

I feel I should use the Plugins function of vue-test-utils, but I'm at lost on how I should use it. Wandering if anyone add the same problem.

0

There are 0 best solutions below