Skip to content

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

Open
@renatodeleao

Description

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions