3

I am currently trying to write a test using vitest/vue-test-utils for an app which uses vuetifyjs 3.

My issue currently is I am unable to set values through the v-select and v-autocomplete component (the second one inherits from v-select I believe). On the other hand v-text-field and v-combobox work fine.

I tried to see if I could hook up somewhere in the DOM within the component itself but to no avail. I also tried to access the v-menu component within but here I couldn't access that sub component in the first place. Adding await nextTick() didn't help either.

In a live environment the components work just fine, I can click and choose the values and using vue plugin I see that the v-model gets updated.

Here is the example component code that reproduces my issue:

<template>
    <v-select
        variant="outlined"
        class="bar"
        label="context"
        :items="items"
        v-model="context"
        density="compact"
    />
    <v-autocomplete
        variant="outlined"
        class="bat"
        label="context"
        :items="items"
        v-model="context"
        density="compact"
    />
    <v-combobox
        variant="outlined"
        class="baz"
        label="context"
        :items="items"
        v-model="context"
        density="compact"
    />
</template>
<script setup lang="ts">
    const items = [
        { title: "a", value: "A" },
        { title: "b", value: "B" },
        { title: "c", value: "C" },
    ];
    var context: string = "D";
</script>

and here is the an example test:

import { describe, test, expect, afterEach, beforeEach } from "vitest";
import { VueWrapper, mount } from "@vue/test-utils";
import Context from "~~/components/context.vue";
describe("context", () => {
    let wrapper: VueWrapper;
    let state: { context: string };

    beforeEach(async () => {
        wrapper = mount(Context);
        state = wrapper.vm as unknown as { context: string };
    });

    afterEach(() => {
        wrapper.unmount();
    });

    test("check if context is correctly set", async () => {
        await wrapper.findComponent(".bar").setValue("A");

        expect(state.context).toBe("A");
    });

    test("check if context is correctly set", async () => {
        await wrapper.findComponent(".bat").setValue("B");

        expect(state.context).toBe("B");
    });

    test("check if context is correctly set", async () => {
        await wrapper.findComponent(".baz").setValue("C");

        expect(state.context).toBe("C");
    });
});

vitest screenshot

Also even though I am using nuxt, vitest does not use SSR, all the components are tested with client side rendering.

here is the vitest.config.ts:

import vue from "@vitejs/plugin-vue";
import { alias } from "./aliases";
import vuetify from "vite-plugin-vuetify";
import { defineConfig } from "vite";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";

export default defineConfig({
    plugins: [
        vue(),
        vuetify({
            autoImport: true,
        }),
        AutoImport({
            imports: ["vue", "vitest"],
            dirs: ["utils"],
        }),
        Components({
            dirs: ["components"],
        }),
    ],
    test: {
        setupFiles: ["css.test.config.js", "plugins.test.config.ts"],
        environment: "happy-dom",
        deps: {
            inline: ["vuetify", "echarts", "vue-echarts"],
        },
        globals: true,
        coverage: {
            provider: "istanbul",
        },
    },
    resolve: {
        alias,
    },
});

css.test.config.js: global.CSS = { supports: () => false };

plugins.test.config.ts:


import { config } from "@vue/test-utils";
import vuetifyConfig from "~~/vuetify.config";

config.global.plugins = [vuetifyConfig];

vuetify.config.ts


import { ThemeDefinition, createVuetify } from "vuetify/lib/framework.mjs";
import * as components from "vuetify/components";
import * as directives from "vuetify/directives";
import * as labs from "vuetify/labs/components";


const vuetifyConfig = createVuetify({
    components: {
        ...labs,
        ...components
    },
    directives,
});

export default vuetifyConfig;

My hope is to be able to set the value through the component either directly or through hooking into an element within.

2 Answers 2

0

Faced a similar problem and there is no normal solution like setValue(). There are two options: use value and set the initial value, or use the select(item: ListItem) method of the VSelect component itself.

Below is a working example, it looks like there is no other solution yet:

const component = await wrapper.findComponent(".bar")

component.vm.select({ value: 'a', title: 'A' })

VSelect sources see here: https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/components/VSelect/VSelect.tsx

Sign up to request clarification or add additional context in comments.

Comments

-3

I have similar issue using setValue on $refs in Vuetify 3

MyComponent:

<template>
<v-combobox v-model=elements />
</template>
<script>
...
    methods:{
     setValue(val) {
          this.elements= val
        }
    }
</script>

Parent Component

<template>
<MyComponent ref="childComponent" />
</template>
<script>
...
methods:{
 clear(){
this.$refs.childComponent.setValue([])
}
}
</scipt>

1 Comment

This question is related to vue/test-utils

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.