Skip to content

Bug: findComponent doesn't not return exposed properties in vm if component is bundled #2591

@renatodeleao

Description

@renatodeleao

Describe the bug
This is a bit hard to describe but hopefully the reproduction demo will clear things up.
I have a big project with 7000+ thousand tests. Recent ones are good, old ones are bad and rely heavily on .vm.

I'm migrating the code base to a monorepo and the design system is now bundled as separate package by vite and the apps import the components’ bundled version instead of the .vue, tests inherently do too. I noticed that most of the tests that rely on vm stopped working.

wrapper.findComponent(VComp).vm.someMethod // someMethod is always undefined, before bundle it wasn't.

Note

I don't know if this is VTU fault or if it's by design, but having in mind that if I import the raw .vue component instead of the bundled .js version everything works I am assuming it is — Please close this issue if my assumption is wrong.

To Reproduce
https://stackblitz.com/edit/vitest-dev-vitest-h8drorow?file=apps%2Fdemo%2Ftest%2Fbasic.test.ts
Should run automatically, if not npm run test

Expected behavior
exposed properties via defineExpose are available though of findComponent returned VueWrapper

Assuming a basic VExample.vue component

<!-- packages/ui/src/VExample.vue -->
<template>
  <div>Example</div>
</template>

<script setup>
const props = defineProps({
  a: String,
});

const exposedFn = () => {
  console.log('hey');
};

defineExpose({
  exposedFn,
});
</script>

Bundles to

import { openBlock as o, createElementBlock as p } from "vue";
const l = {
  __name: "VExample",
  props: {
    a: String
  },
  setup(n, { expose: e }) {
    return e({
      exposedFn: () => {
        console.log("hey");
      }
    }), (s, t) => (o(), p("div", null, "Example"));
  }
};
export {
  l as VExample
};

Faulty test

import { VExample as VExampleRaw } from '../../packages/ui/src/VExample.vue'
import { VExample as VExampleBundled } from 'ui'

// swapping VExampleBundled per VExampleRaw in the components option makes it pass.
it('finds exposed "vm" properties in *bundled* component wrapper via findComponent', () => {
  const wrapped = mount({
    components: {
      VExampleBundled,
    },
    template: `<div><v-example /></div>`,
  });

  const test = wrapped.findComponent({ name: 'VExample' });

  console.log(test.vm); // only has "a" prop
  expect(test.exists()).toBe(true);
  // fails
  expect(test.vm.exposedFn).toBeInstanceOf(Function);
});

Related information:

vue:  3.5.13 
@vue/test-utils: 2.4.6

Additional context
The same behaviour is not found in mount. When passing the bundled version of a component to mount, exposed properties are exposed correctly to vm, that's why I think it's a bug in findComponent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions