Events emitted immediately in the mounted hook are not captured by wrapper.emitted(). With something like the below
something is not capturedsomething-else is not captured on first emit in the immediate watcher, but is captured on subsequent watcher callbackstoggle is captured if the toggle method is called after mount, e.g. on user click{
mounted() {
this.$emit('something');
this.$watch('foo', (v) => {
this.$emit('something-else');
}, {
immediate: true
});
},
methods: {
toggle() {
this.$emit('toggle');
}
}
}
This happens, because the wrapper attaches to the component after the component was created and mounted.
I do not know if there is a way to change this, but I have the feeling if we do not attach the wrapper earlier there might be more edge cases where the wrapper is not ready when the component gets created.
One possibility I see is to install the wrapper earlier is via beforeCreate-mixin. It would be called by the Vue-framework after the vm-object is instiated but before the Vue-component is created and mounted, and so we could do the setup then already. We might have to split the actions done in vue-wrapper.js in several hooks.
But maybe there are other ways as well.
I was thinking we could add a listener object before mount and pass it to VueWrapper when it's created and merge that listener object with the current listener object.
Ok, so what worked for me was this (using the logEvents method in src/lib/log-events.js):
localVue.mixin({
beforeCreate: function() {
this.$_emitted = {}
this.$_emittedByOrder = []
logEvents(this, this.$_emitted, this.$_emittedByOrder)
}
})
It does catch all events from beforeCreate on in a variable of the component (in this case $._emitted). In the constructor we could then copy these self-tracked events to the wrapper. The mixin could be added in every localVue instance when creating it.
This approach is quite naive and the installed listener should be removed after the wrapper is created. It also seems a bit hacky and not too clean to use a field on the component.
Those are just my ideas. I would be interested if you know a better way to add the listener.
I can't think of a better way. Would you like to implement @wtho ?
@eddyerburgh I will submit a PR this weekend
Fixed in 1.0.0-beta.7, thanks @wtho!
I'm having similar issues when trying to test a component that has an updated method with an emit in it. Could it be that there is an issue with this as well?
component:
updated () {
this.$emit('table-updated')
}
in my test:
console.log(wrapper.emitted('table-updated'))
result:
console.log test/unit/specs/Table/Table.spec.js:73
undefined
coverage documentation shows that the lines are being executed properly.
Most helpful comment
Ok, so what worked for me was this (using the
logEventsmethod insrc/lib/log-events.js):It does catch all events from
beforeCreateon in a variable of the component (in this case$._emitted). In the constructor we could then copy these self-tracked events to the wrapper. The mixin could be added in everylocalVueinstance when creating it.This approach is quite naive and the installed listener should be removed after the wrapper is created. It also seems a bit hacky and not too clean to use a field on the component.
Those are just my ideas. I would be interested if you know a better way to add the listener.