question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Testing Vue Components with Emitted Events + Vuetify

See original GitHub issue

Current 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:closed
  • Created a year ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
lmiller1990commented, Sep 7, 2022

I think the problem is related to how you are wrapping your component in VApp:

Cypress.Commands.add("mount", (component, args) => {
  return mount(
    { render: (h) => h(VApp, [h(component, args)]) },
    { vuetify: new Vuetify({}), ...args }
  );
});

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.

0reactions
lmiller1990commented, Sep 8, 2022

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unit testing — Vuetify
Because of this, Vue has its own testing utility called vue-test-utils . It provides useful features for interacting with Vue components and ...
Read more >
Testing emit event in Vue.js using Jest and Vue Test Utils
The aim of this article is to show how to test emit event using Vue Test Utils and Jest. For this purpose, let...
Read more >
emitted | Vue Test Utils
Return an object containing custom events emitted by the Wrapper vm . ... test('emit demo', async () => { const wrapper = mount(Component)...
Read more >
How to test your vuetify project with jest, vue-test-utils and vue-cli
Setup testing for Vuetify. For vuetify, you will need some changes to make sure everything will work fine. First of all, create a...
Read more >
Vue.js and Vuetify unit testing with Jest - IOBIO
The example.spec.js file is the default test that comes with vue cli 3. ... The event emitted from the ZipCodeInput.vue should be handled...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found