0

I have configured vue project with vuetify and vitest. I am using happy-dom (but also tried jsdom) to run unit tests. I am able to run unit tests unless my component has a v-dialog component. I get the following error:

TypeError: globalStack.at is not a function
    at ......./node_modules/vuetify/src/composables/stack.ts:58:3
    at callWithErrorHandling (......./node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:157:22)
    at callWithAsyncErrorHandling (......./node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:166:21)
    at ReactiveEffect.getter [as fn] (......./node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:1724:24)
    at ReactiveEffect.run (......./node_modules/@vue/reactivity/dist/reactivity.cjs.js:191:25)
    at doWatch (......./node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:1839:16)
    at Module.globalTop (......./node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:1644:12)
    at Module.useStack (......./node_modules/vuetify/src/composables/stack.ts:56:24)
    at Object.setup [as _setup] (......./node_modules/vuetify/src/components/VOverlay/VOverlay.tsx:160:41)
    at setup (/......./node_modules/vuetify/src/util/defineComponent.tsx:83:27)

At first I was getting this error running the app as well, but after I got newer version of Chrome this error went away. But now I am having this running a unit test. Here is my sample component:

<template>
  <div>
    <v-dialog>hello world</v-dialog>
  </div>
</template>

and here is my sample unit test which shows this error

import { mount } from '@vue/test-utils';
import DialogSample from '@/components/DialogSample.vue'
import { createVuetify } from "vuetify";

describe('DialogSample', () => {
  let wrapper;
  let vuetify;

  beforeEach(() => {
    vuetify = createVuetify();
  });

  afterEach(() => {

  });

  describe('logged in tests', () => {
    beforeEach(() => {
      wrapper = mount(DialogSample, {
        global: {
          plugins: [vuetify],
        },
        props: {},
      });
    });

    test('sample test', async () => {
      expect(true).toBeTruthy();
    });
  });
});

here some versions from package.json:

  "dependencies": {
    "@mdi/font": "7.1.96",
    "@pinia/testing": "^0.0.14",
    "axios": "^1.2.0",
    "dotenv": "^16.0.3",
    "happy-dom": "^8.1.1",
    "jsdom": "^20.0.3",
    "lodash": "^4.17.21",
    "pinia": "^2.0.27",
    "roboto-fontface": "*",
    "vue": "^3.2.45",
    "vuetify": "3.0.6",
    "webfontloader": "^1.0.0"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.0.0",
    "@vue/test-utils": "^2.2.6",
    "vite": "^4.0.3",
    "vite-plugin-vuetify": "^1.0.0-alpha.12",
    "vitest": "^0.26.2"
  }

here is test section from vite.config.js:

  test: {
    // https://vitest.dev/config/
    globals:true,
    environment: 'happy-dom',
    setupFiles: "vuetify.config.js",
    deps: {
      inline: ["vuetify"],
    },
  },

and here is vuetify.config.js (without this setting I was getting CSS errors running tests):

global.CSS = { supports: () => false };

I was able to change my unit test to use shallowMount() instead of mount() just to see if unit test would work and it did. However, I do need mount() working so that I can test my dialogs. Other vuetify components I tried so far (I only tried a few so far) worked fine.

Any ideas how to get passed this would be greatly appreciated. thanks

Andrey
  • 408
  • 2
  • 10
  • I managed to solve this by adding a polyfill as described here https://stackoverflow.com/questions/68464114/why-am-i-getting-at-is-not-a-function/70557417#70557417 – Andrey Dec 31 '22 at 20:20
  • 1
    polyfill didn't work - upgrading to node 16.6 did the trick (it supports at function) – Andrey Jan 01 '23 at 17:20

1 Answers1

0

The "TypeError: globalStack.at is not a function" error triggered when running Vitest unit test can come from an outdated Node version.

According to the Node.js changelog, the .at method has been added post-2021 from version 16.6.

Upgrading Node.js to any version after 16.6 should fix this issue.

Related answer here.

Nicolas Lagarde
  • 208
  • 2
  • 6