Skip to content

Trigger not calling method with dynamic listener name #1955

Open
@alexmccabe

Description

@alexmccabe

Subject of the issue

Vue supports dynamic listener names, here's a contrived example of what I mean:

<MyElement @[clickListenerName]="onClick" />
// ...

computed: {
  clickListenerName() {
    return this.someCondition ? 'click.native' : 'click';
  }
}

This works in the real world code running in a web browser. However inside vue-test-utils when calling wrapper.trigger('click') on the element, the handler is never called. Replacing the template with <MyElement @click.native="onClick" /> works as expected.

This isn't due to a timing issue since logging the return value of the computed property elsewhere in the component, dumping to the DOM and using a whole bunch of await wrapper.vm.nextTick() in the test yields no result with the dynamic listener name.

Just to note that we are using the @vue/composition-api helpers in a Vue 2 application.

Steps to reproduce

CustomComponent.vue

<script lang="ts">
import { defineComponent } from '@vue/composition-api';

export default defineComponent({
    setup(_props, context) {
        return () => context.slots.default?.();
    },
});
</script>

TestComponent.vue

<template>
    <Component :is="tag" @[customEventName]="onClick" />
</template>

<script lang="ts">
import { defineComponent } from '@vue/composition-api';
import CustomComponent from './CustomComponent.vue';

export default defineComponent({
    components: { CustomComponent },
    setup(_props, context) {
        const condition = true;

        return {
            onClick() {
                console.log('event called');
                context.emit('click');
            },
            customEventName: condition ? 'click.native' : 'click',
            condition,
            tag: condition ? 'CustomComponent' : 'button',
        };
    },
});
</script>

TestComponent.test.ts

import { shallowMount } from '@vue/test-utils';
import TestComponent from './Test.vue';

describe('<TestComponent />', () => {
    it('calls the onClickMethod', async () => {
        const wrapper = shallowMount(TestComponent);

        await wrapper.trigger('click');
        expect(wrapper.emitted().click).toBeTruthy();
    });
});

Expected behaviour

I would expect the tested expectation to pass and there to be a console.log

Actual behaviour

CleanShot 2022-02-02 at 14 37 56@2x

Changing the template to below yields a test pass

<template>
    <Component :is="tag" @click.native="onClick" />
</template>

CleanShot 2022-02-02 at 14 40 51@2x

Possible Solution

Since it's not valid to attach .native modifiers to non-Vue elements, this doesn't work as intended.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions