vuejs / test-utils

Vue Test Utils for Vue 3
https://test-utils.vuejs.org
MIT License
1.04k stars 244 forks source link

Bug: Stencil Custom Element is not stubbed #1953

Closed paddelboot closed 1 year ago

paddelboot commented 1 year ago

Describe the bug Stencil Custom Element is not being stubbed

To Reproduce In App.vue we import a Stencil custom element:

import { defineCustomElements as defineCustomWebComponentLoaderElement } from '@xyz/web-component-loader/loader';
defineCustomWebComponentLoaderElement(window);

In our test file, we try to stub this element:

const wrapper = mount(App, {
  global: {
    stubs: {
      'web-component-loader': true,
    },
  },
});

Expected behavior web-component-loader should be stubbed. Instead, it is rendered fully.

cexbrayat commented 1 year ago

Hi @paddelboot

Stubs are only stubbing Vue components not web components or components from other frameworks, so this behavior is expected. If you want to stub a Web Component, you'll have to do this manually in your test (for example, by not registering the web component in the test).

Does that answer your question?

paddelboot commented 1 year ago

Thanks for the quick answer. Well, that's unfortunate that we cannot just stub any non native HTML element.

wassim-ben-amor commented 1 year ago

Hello @cexbrayat , do you know please if Stubs are only stubbing Vue components not web components is documented somewhere ? When migrating from test-utils 1 to 2, I noticed that web components are not transformed to stubs anymore. Do you think it's a breaking change ? Thank you,

cexbrayat commented 1 year ago

@wassim-ben-amor I don't think it's documented somewhere. If that was supported out of the box in VTU v1 (I don't know because I never used web components in a Vue v2 project), then it is indeed a breaking change.

wassim-ben-amor commented 1 year ago

Hello @cexbrayat , sorry for adding replies to a closed thread. I just wanted to understand more the part: If you want to stub a Web Component, you'll have to do this manually in your test (for example, by not registering the web component in the test). Can you please give an example ? Let's say in my vue component, I have in the DOM <my-custom-element @stateChange="doSomething" />. How can I create a stub ? I tried to pass in the global stubs, but it seems to be not recognized. What I have noticed is that when I don't specify the customElements in the vite config by removing this part:

      vue({
        //customElement: true,
        //template: {
          //compilerOptions: {
            //isCustomElement: tag => tag.includes('-'),
          //},
        //},
      //}
     ),

The stub works correctly, but I can no more trigger custom events for example. If I keep this part in the config, I can stub the webcomponent but I can not trigger custom events from it by using wrapper.find(...).trigger('stateChange', { detail: 'helloWorld' }); Thank you,

cexbrayat commented 1 year ago

Hi @wassim-ben-amor

Can you provide us a small repro online using https://stackblitz.com/github/vuejs/create-vue-templates/tree/main/typescript-vitest?file=src%2Fcomponents%2F__tests__%2FHelloWorld.spec.ts ?

It only takes a few minutes, and we'll be able to take a look

wassim-ben-amor commented 1 year ago

Hello @cexbrayat , Yes sure, I have created a small repo for each scenario: 1- Custom elements enabled on vite config, the custom element can not be stubbed, I can trigger custom event: Repo link 2- Custom elements disabled on vitest-config, the custom element is correctly stubbed, I can trigger custom event only by using vm.$emit method: Repo link

Just FYI, I thought about a workaround by having the possibility to edit the vitest config dynamically (decide on each mount if we want to enable custom elements or not, so we decide to go with scneario 1 or scenario2). But it seems to be not possible and these configs can not be changed during the test. I have created a thread on vite-plugin-vue to evaluate this possibility.

cexbrayat commented 1 year ago

@wassim-ben-amor Thanks for the reproductionsand yes, I think it is the expected behaviors.

Especially 2 because you are in fact running into https://github.com/vuejs/test-utils/issues/2087, so vm.$emit is the way to go for now