Testing Vue Components with Emitted Events + Vuetify
See original GitHub issueCurrent behavior
I have recently tried to use the feature Component Testing
in my component lib.
FYI, I used Vuetify v2 with Vue2. And I have added the command mount
as follow to import vuetify during Component Testing:
// commands.js
import { mount } from "cypress/vue2";
import vuetify from "@/plugins/vuetify";
import { VApp } from "vuetify/lib";
// Override default command mount to use it with Vuetify
Cypress.Commands.add("mount", (component, args) => {
return mount(
{ render: (h) => h(VApp, [h(component, args)]) },
{ vuetify, ...args }
);
});
// Also add a command to use easily vue-test-utils as describe by Jessica Sachs
// https://github.com/JessicaSachs/cypress-loves-vite/blob/develop/cypress/support/index.js#L19
Cypress.Commands.add("vue", () => {
return cy.wrap(Cypress.vueWrapper);
});
With that configuration, my components are mounted correctly and I can test them. But when, I have to test a use case with emit event. I look closely different way to achieve that (documentation, forum, etc…). I’m not able to handle emit event during my tests.
Here a simple example:
//Test.vue
<template>
<button @click="handleClick">Click Me</button>
</template>
<script>
export default {
methods: {
handleClick() {
this.$emit("click", "HELLO WORLD");
},
},
};
</script>
//Test.cy.js
import Test from "./Test.vue";
import { mount } from "cypress/vue2";
describe("<Test />", () => {
it("Test1: when button is clicked, should call onClick (standard mount: WORKS)", () => {
const onClickSpy = cy.spy().as("onClickSpy");
// Use standard command `mount`
mount(Test, {
listeners: { click: onClickSpy },
});
// Trigger emit event
cy.get("button").contains("Click Me").click();
// Assert event using Cypress.vue.$on
cy.then(() => {
Cypress.vue.$on("click", onClickSpy);
expect(onClickSpy).to.be.calledOnce;
});
// Assert event using spies
cy.get("@onClickSpy").should("have.been.calledOnce");
// Assert event using listener from vue-test-utils
cy.vue().then((wrapper) => {
expect(wrapper.emitted("click")).to.have.length(1);
});
});
it("Test2: when button is clicked, should call onClick (custom mount: NOT WORKS)", () => {
const onClickSpy = cy.spy().as("onClickSpy");
// Use custom command `mount`
cy.mount(Test, {
listeners: { click: onClickSpy },
});
// Trigger emit event
cy.get("button").contains("Click Me").click();
// Assert event using Cypress.vue.$on
cy.then(() => {
Cypress.vue.$on("click", onClickSpy);
expect(onClickSpy).to.be.calledOnce;
});
// Assert event using spies
cy.get("@onClickSpy").should("have.been.calledOnce");
// Assert event using listener from vue-test-utils
cy.vue().then((wrapper) => {
expect(wrapper.emitted("click")).to.have.length(1);
});
});
});
When I use my custom command mount
(Test2), the differents assert won’t work (expected onClickSpy to have been called exactly once, but it was never called
) but with the standard command mount
it works (Test1). I don’t understand why.
Can someone could give me more explaination pls? Thanks in advance.
Desired behavior
All the tests should passed with custom command mount
(+Vuetify) as it does with standard command mount
.
Test code to reproduce
See above.
Cypress Version
10.6.0
Node version
v14.18.1
Operating System
Windows
Debug Logs
No response
Other
No response
Issue Analytics
- State:
- Created a year ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
I think the problem is related to how you are wrapping your component in
VApp
:It’s expected the
VApp
component to have emitted a click event - but your spy is on the inner component.I tried a few things and I made a PR showing you how I like to do this for Vue 2: https://github.com/MichelMan/test-ct-vuetify-emit-event/pull/1. I think Vue 3 changed the internal API a little bit, but something similar is possible there, too.
Let me know if this addresses your question or if you’d like to discuss it more. There’s a few ways to do things with the traditional Test Utils API and the Cypress API on top of it, we definitely need better docs and to standardise on one way to do things.
Sure - feel free to make another issue or discussion and tag me if you have any more questions.
I think we need better docs and guides around how to do certain things. This is something we are exploring now.