2

I have a vue2 component that emits an event in its mounted lifecycle hook. This event is emitted and can be handled by a page using the component. However, I would also like to test that that the event is emitted in my component tests, which use the Cypress Component Test Runner. Here is a boiled down version... The component:

TheComponent = {
    template: `
        <div data-cy="the-component">
        
        </div>`, 
    data() {
        return {

        }
    },
    mounted() {
        this.$emit('the-event')
    },
}

And the test:

describe('Test', () => {
    it('emits an event when mounted', () => {   
        const spy = cy.spy()
        mount(TheComponent)
        .then(() => {
            Cypress.vue.$on('the-event', spy)
        })
        .then(() => {            
            expect(spy).to.be.calledOnce
        })
    })
})

The issue is that the Cypress.vue object is not created until after the component is mounted. But the spy must be registered on the Cypress.vue object. So when it is registered as above, the mounted hook has already run and the spy is not called.

Am I missing something?

Is there another approach that would let me test that the event is emitted from mounted?

Grant Braught
  • 23
  • 1
  • 3

1 Answers1

4

Cypress mount() has the same API as Vue-Test-Utils mount(), so you can add listeners to the mounting options

const spy = cy.spy()
mount(HelloWorld, {
  listeners: {
    'the-event': spy
  }
})
.then(() => {
  expect(spy).to.be.calledOnce
})
Richard Matsen
  • 20,671
  • 3
  • 43
  • 77
  • This works great! Do you know how we could also validate the payload of the event? – kano Aug 17 '21 at 20:27
  • 1
    @kano `expect(spy).to.be.calledWith(payload)` – Rory Nov 28 '21 at 14:50
  • Should this work with Vue3 and Vite? It is consistently coming back with not called. – Andrew MacNeill May 17 '22 at 18:26
  • @AndrewMacNeill - I had to follow the below guide for Vue 3. https://css-tricks.com/testing-vue-components-with-cypress/#aa-accessing-the-vue-test-utils-wrapper Added a custom command in support/commands.ts Then in my tests I can do `cy.get().click()` `cy.vue().then(component => component.emitted('update:modelValue')[0][0])` to get the value(s) emitted. – Shea Lavington May 18 '22 at 09:22
  • Only works with v1 of Vue Test Utils – PaKo Anguiano Apr 12 '23 at 18:49