Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible issue with dispatching events #886

Closed
marina-mosti opened this issue Aug 26, 2021 · 5 comments
Closed

Possible issue with dispatching events #886

marina-mosti opened this issue Aug 26, 2021 · 5 comments

Comments

@marina-mosti
Copy link
Contributor

Consider the following component:

<template>
    <input
      @keyup.enter="$emit('enter')"
      @keyup.esc="$emit('esc')"
      @click="$emit('click')"
    >
</template>

And the following test:

import TestInput from '../../src/components/TestInput'

import { shallowMount } from '@vue/test-utils'

describe('TestInput', () => {
    it('should fire the enter key', () => {
        const wrapper = shallowMount(TestInput)

        wrapper.find('input').element.dispatchEvent(
            new KeyboardEvent('keyup', { keyCode: 13 })
        )

        console.log(wrapper.emitted())
        expect(wrapper.emitted().enter).toHaveLength(1)
    })

    it('should fire click', () => {
        const wrapper = shallowMount(TestInput)

        wrapper.find('input').element.dispatchEvent(
            new MouseEvent('click')
        )

        console.log(wrapper.emitted())
        expect(wrapper.emitted().click).toHaveLength(1)
    })
})

We would expect the test to pass (it did on Vue 2/VTU 1) but I've noticed two problems.

  1. The event for the keyboard event never fires.
    I believe this may be an underlying problem of how the keyup modifier is working on Vue 3 possibly. Im testing this with the 3.1 compact build.

  2. The click event fires, BUT for both tests there's an additional emit that is happening.

The second test actually fails because the emitted() is adding a second event.

  console.log tests/unit/TestInput.spec.js:24
    {
      'hook:beforeMount': [ [] ],
      'hook:mounted': [ [] ],
      click: [ [], [ [MouseEvent] ] ]
    }


   Expected length: 1
    Received length: 2
    Received array:  [[], [{"isTrusted": false}]]

The first element in the array is the actual click emit that the input should fire, the second one is being injected by either vtu or vue.

On the first test, with the keyboard event we have a similar problem.

  console.log tests/unit/TestInput.spec.js:13
    {
      'hook:beforeMount': [ [] ],
      'hook:mounted': [ [] ],
      keyup: [ [ [KeyboardEvent] ] ]
    }

There is an emitted keyup event by the component, where there should not be since there is no keyup $emit anywhere.

Hope this was clear!

package.json for reference:

{
  "name": "vue31vtu",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@vue/compat": "^3.1.0",
    "core-js": "^3.6.5",
    "vue": "^3.1.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-unit-jest": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.1.0",
    "@vue/test-utils": "^2.0.0-rc.10",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^7.0.0",
    "typescript": "~3.9.3",
    "vue-jest": "^5.0.0-0"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {},
    "overrides": [
      {
        "files": [
          "**/__tests__/*.{j,t}s?(x)",
          "**/tests/unit/**/*.spec.{j,t}s?(x)"
        ],
        "env": {
          "jest": true
        }
      }
    ]
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}
@xanf
Copy link
Collaborator

xanf commented Aug 26, 2021

@marina-mosti thank you for reporting this!
The reason for "duplicating" events is pretty simple, and it's not 100% a VTU issue. Actually this is because in compat mode Vue "emits" vue copy of event for DOM, while VTU is listening for both :)

This is how I'm working around this in yet-unreleased package vue-test-utils-next-compat which will be targetting compatibility of old VTU tests with vue-test-utils-next:

  const VTU = require('@vue/test-utils')
  VTU.VueWrapper.prototype.attachNativeEventListener = () => {}

@marina-mosti
Copy link
Contributor Author

marina-mosti commented Aug 26, 2021

Hey @xanf awesome!! Thanks for taking a look and the hack 😄
Looking forward to the package

@lmiller1990
Copy link
Member

@xanf beat me to it with the double click explanation.

Is there any obvious explanation for the first problem? "... The event for the keyboard event never fires ...".

Also, I wonder if we can just do trigger('keyup.enter')? We have some tests around this behavior.

@marina-mosti
Copy link
Contributor Author

Reopening because even with @xanf 's fix, the keyboard event is still not working with:

it('should fire the enter key', () => {
        const wrapper = shallowMount(TestInput)

        wrapper.find('input').element.dispatchEvent(
            new KeyboardEvent('keyup', { keyCode: 13 })
        )

        console.log(wrapper.emitted())
        expect(wrapper.emitted().enter).toHaveLength(1)
    })
    ```

@lmiller1990
Copy link
Member

We can just do like this: https://github.com/vuejs/test-utils/pull/1441/files.

Using dispatchEvent isn't documented, I'm not sure exactly on how we can make your test pass, but considering this isn't documented or officially supported, I'm going to go and and recommend we test like I've proposed in the PR.

If there's a case not covered by the example in the PR, we can re-open or make a new issue. For now I don't see any obvious actionable here, so I'll close this as inactive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants