25

I try to bootstrap a simple app based on the following Vue3, Vite, Vitest

I also installed the vue 3 compatible version of vue test utils to test vue components.

I have an error trying to replicate the basic example in the docs :

import { mount } from "@vue/test-utils";
import { expect, test } from 'vitest'


// The component to test
const MessageComponent = {
  template: "<p>{{ msg }}</p>",
  props: ["msg"],
};

test("displays message", () => {
  const wrapper = mount(MessageComponent, {
    props: {
      msg: "Hello world",
    },
  });

  // Assert the rendered text of the component
  expect(wrapper.text()).toContain("Hello world");
});

 FAIL  src/tests/hello-world.test.ts > displays message
ReferenceError: document is not defined
 ❯ Proxy.mount node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js:7840:14
    7838|     addToDoNotStubComponents(component);
    7839|     registerStub({ source: originalComponent, stub: component });
    7840|     var el = document.createElement('div');
       |              ^
    7841|     if (options === null || options === void 0 ? void 0 : options.attachTo) {
    7842|         var to = void 0;
Re-running tests... [ src/tests/hello-world.test.ts ]

My package.json

{
  "name": "vite-vue3-poc",
  "version": "0.0.0",
  "scripts": {
    "serve": "vite preview",
    "build": "vite build",
    "coverage": "vitest --coverage",
    "dev": "vite",
    "preview": "vite preview",
    "test": "vitest"
  },
  "dependencies": {
    "@mdi/font": "5.9.55",
    "prettier": "^2.5.1",
    "roboto-fontface": "*",
    "vue": "^3.2.25",
    "vuetify": "^3.0.0-alpha.0",
    "webfontloader": "^1.0.0"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^2.0.0",
    "@vue/cli-plugin-babel": "5.0.0-beta.7",
    "@vue/cli-service": "5.0.0-beta.7",
    "@vue/test-utils": "^2.0.0-rc.18",
    "@vuetify/vite-plugin": "^1.0.0-alpha.3",
    "sass": "^1.38.0",
    "sass-loader": "^10.0.0",
    "vite": "^2.7.2",
    "vitest": "^0.1.23",
    "vue-cli-plugin-vuetify": "~2.4.5",
    "vuetify-loader": "^2.0.0-alpha.0"
  }
}

vite.config.js

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vuetify from "@vuetify/vite-plugin";

import path from "path";
/// <reference types="vitest" />

// Configure Vitest (https://vitest.dev/config)

// https://vitejs.dev/config/
export default defineConfig({
  test: {
    /* for example, use global to avoid globals imports (describe, test, expect): */
    // globals: true,
  },
  plugins: [
    vue(),

    // https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vite-plugin
    vuetify({
      autoImport: true,
    }),
  ],
  define: { "process.env": {} },
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "src"),
    },
  },
});

2
  • 2
    The problem is specific to testing framework you're using, vitest, not anything else. You're not in a good situation when using low-profile libs that don't have extensive support from the community. Since it seems to use Jest internally, this is likely solved from Jest side by enforcing Jest's jsdom environment. Commented Jan 19, 2022 at 12:13
  • Thx. This helped me finding a way (see below) Commented Jan 19, 2022 at 13:20

4 Answers 4

34

Finally fixed it by manually installing jsdom and declaring it in vite.config.ts

export default defineConfig({
  test: {

    globals: true,
    environment: "jsdom",
  },
...
}
Sign up to request clarification or add additional context in comments.

1 Comment

this works as well in a separate vitest.config.ts file. It might be possible then to add the file to your tsconfig.config.json
12

Like others have pointed out, you need to set environment: 'jsdom' in vitest.config.ts. Alternatively, you could set environment: 'happy-dom'.

In the example provided by the Vitest documentation, they used to use happy-dom instead of jsdom. From what I gather, happy-dom is a faster alternative to jsdom. I'm using happy-dom in my project, and I'm happy with it! :)

EDIT: I changed my wording to reflect the fact that the Vitest example used to use happy-dom. As of this writing, it uses jsdom.

2 Comments

Seems like they use jsdom now
Thanks, I changed the wording of my answer to reflect that they now use jsdom.
6

This config helped me

Your vite.config.ts

import { fileURLToPath, URL } from "node:url"
import { defineConfig } from "vite"
import type { UserConfig as VitestUserConfigInterface } from "vitest/config"
import vue from "@vitejs/plugin-vue"

const vitestConfig: VitestUserConfigInterface = {
  test: {
    globals: true,
    environment: "jsdom",
  },
}

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
  test: vitestConfig.test,
})

1 Comment

Yes - searching all over, and this solved it for me :-)
4

No need to install jsdom manually. By setting environment: "jsdom" in the test property, Vitest automatically asks you if you want to install it.

Comments

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.