I'm having trouble working out how to do a simple test of a Vue component (using the Cypress Component Test Runner) to see if a button click results in an event being emitted
// MyButton.vue component
<template>
<Button
data-testid="button"
label="Click Button"
@click="clickButton()"
/>
</template>
<script setup lang="ts">
import { defineEmits } from "vue";
const emit = defineEmits(["clickButtonEvent"]);
function clickButton() {
emit("clickButtonEvent");
}
</script>
// MyButton.spec.ts
it.only("should emit an even when clicked", () => {
const clickButtonSpy = cy.spy().as("clickButtonEvent");
mount(FulfilButton, {
global: {
components: {
Button,
},
},
})
.get('[data-testid="button"]')
.click();
cy.get("@clickButtonEvent").should("have.been.called");
});
This doesn't work - in the console I see
mount
get
-click
but then this:
expect clickButtonEvent to have been called at least once, but it was never called
So I guess I am not hooking up this cy.spy
correctly - presumably because I am not doing it as part of the mount? What do I need to do? The button itself is a PrimeVue button component but I'm pretty sure that should not stop me doing this test?
CodePudding user response:
Well, you are not hooking the spy at all.
The Cypress mount
command has the same interface as vue-test-utils
mount
(it is using vue-test-utils
under the hood)
In vue-test-utils
v1 (for Vue 2) you can use listeners mount option to attach the spy as demonstrated in this answer
But since you are using Vue 3 and in turn vue-test-utils v2 where listeners
mount option was removed, probably your best option to use recommended API of the wrapper - emitted
This example is taken from the recent talk of Jessica Sachs (Cypress team member) (repo) where she does something like this:
mount(FulfilButton, {
global: {
components: {
Button,
},
},
})
.get('[data-testid="button"]')
.click()
.vue()
.then((wrapper) => {
expect(wrapper.emitted('clickButtonEvent')).to.have.length(1)
})
Note that vue()
is not a build-in Cypress command. In this demo/repo it was added by Jessica in the support file
// ./cypress/support/index.js
Cypress.Commands.add('vue', () => {
return cy.wrap(Cypress.vueWrapper)
})
You can do something very similar without introducing any helper (example)
it('emits "increment" event on click', () => {
cy.get('button')
.click()
.click()
.then(() => {
cy.wrap(Cypress.vueWrapper.emitted()).should('have.property', 'increment')
})
})