Skip to content

Testing this.$root.$emit with wrapper.emitted #980

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

Closed
rossta opened this issue Sep 24, 2018 · 5 comments
Closed

Testing this.$root.$emit with wrapper.emitted #980

rossta opened this issue Sep 24, 2018 · 5 comments

Comments

@rossta
Copy link

rossta commented Sep 24, 2018

Version

1.0.0-beta.25

Reproduction link

https://jsfiddle.net/rossta/50wL7mdz/749387/

Steps to reproduce

Given a component that triggers an event on its root via this.$root.$emit:

// ChildComponent
export default {
  mounted() {
    this.$root.$emit('say', 'New message!')
  },
  render: h => h('div', 'Child content')
};

Test the event is emitted using the wrapper API, i.e., wrapper.emitted('say'):

import { mount } from '@vue/test-utils'
import ChildComponent from './ChildComponent.vue'

describe('ChildComponent', () => {
  it('emits event to $root', () => {
    const wrapper = mount(ChildComponent)
    expect(wrapper.emitted('say')).toBeTruthy() // test fails in 1.0.0-beta.25
  })
})

What is expected?

In version 1.0.0-beta.16, the wrapper.emitted('say') test passes for the event emitted on the component's root.

What is actually happening?

In version 1.0.0-beta.25, the test does not pass.

I'm actually not sure what the intended behavior since I do not believe it is documented; I wanted to raise the issue just in case this change was not intended.


We came across this change in behavior while upgrading from 1.0.0-beta.16 to 1.0.0-beta.25.

For those interested, an alternative way to test this behavior is suggested in #481 by overriding the parentComponent option, which will behave as the $root component.

@eddyerburgh
Copy link
Member

I've marked this as a feature request since (as you suspected) this is not currently intended behavior, but I can see that it could be useful.

@eddyerburgh
Copy link
Member

You can do this by creating a wrapper from the $root:

it('captures emitted events on $root instance', () => {
  const wrapper = mount(TestComponent)
  wrapper.vm.$root.$emit('foo')
  const rootWrapper = createWrapper(wrapper.vm.$root)
  expect(rootWrapper.emitted('foo')).to.exist
})

@flozero
Copy link

flozero commented Feb 25, 2019

I did what you did but

import { shallowMount, createLocalVue, mount, createWrapper } from '@vue/test-utils';
import Vue from 'vue'
import Modal from './Modal.vue';
import {i18n} from '../../plugins/i18n-setup'

const localVue = createLocalVue()

Vue.component('Modal', Modal)

const Parent = Vue.component("Parent", {
    name: "Parent",
    template: "<div><Modal /></div>"
})

describe('Modals', () => {
    it('should create an empty modal', () => {

        const wrapper = mount(Parent, {
            localVue,
            i18n
        })
        // console.log(wrapper.html())
      
        wrapper.vm.$root.$emit('openModal', {
            activeComponent: 'AddSection',
            title: "I am a modal title"
        })

        const rootWrapper = createWrapper(wrapper.vm.$root)
        console.log(wrapper.emitted('openModal'));
        // expect(rootWrapper._emitted('openModal')).to.exist
        Vue.nextTick(() => {
            console.log(wrapper.html())
        })
    })
})

It should normally populate the Modal with slot but it doesn't

@flozero
Copy link

flozero commented Feb 25, 2019

Catching the event doest mean it does function in it ?

I have a parent

<div>
 <Modal/>
<Child />
</div>

the Mocal listen to $root.$on("openModal")

@flozero
Copy link

flozero commented Feb 25, 2019

ok my bad it is working...

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

No branches or pull requests

3 participants