Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
renatodeleao opened this issue Jan 9, 2025 · 0 comments
Labels
bug Something isn't working

Comments

@renatodeleao
Copy link
Contributor

renatodeleao commented Jan 9, 2025

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.

@renatodeleao renatodeleao added the bug Something isn't working label Jan 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant