Skip to content

Javascript hooks on transition components do not get called during unit tests #890

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

Closed
benm-eras opened this issue Aug 2, 2018 · 4 comments
Labels

Comments

@benm-eras
Copy link

Version

1.0.0-beta.22

Reproduction link

https://github.com/benm-eras/VueDemo/tree/transition-tests

Steps to reproduce

I have used the latest version of Vue CLI to scaffold an app, and added a simple component to demonstrate my issue. Just clone my repo and switch to the transition-tests branch. Then run yarn run serve to see it working as intended, or yarn run test to see the tests failing.

It is a minimal reproduction of a component that will form the basis for modal dialogs. Ultimately I am using Animate.css to add nice transitions, and I want different transitions for the backdrop (fade) and content (zoom). The only way I have found of making this work is to have one transition component inside the other, and use the javascript hooks to show/hide each other.

It works great in the browser, but the javascript hooks don't seem to run during unit tests, even when introducing delays before assertion.

What is expected?

The javascript hooks on the transition components should run just like they do in the browser.

What is actually happening?

The javascript hooks are not running during unit tests.


Having read through some previous issues, I understand that the transition and transition group components are automatically stubbed, so I wouldn't be surprised if I have missed some setup or configuration needed to make this work. If that is the case I would greatly appreciate any advice.

@eddyerburgh
Copy link
Member

eddyerburgh commented Aug 4, 2018

Yes Transition components and TransitionGroup components are stubbed automatically, and the stubs don't fully implement hooks.

A quick fix is to use the unstubbed versions by setting stubs to false:

const wrapper = mountingMethod(testComponent, {
  stubs: {
    transition: false
  }
}) 

But really we should improve the stubs to behave as expected.

@eddyerburgh eddyerburgh added the bug label Aug 4, 2018
@benm-eras
Copy link
Author

Thanks @eddyerburgh! That gets me to the point where the Javascript hooks are running as expected (with a $nextTick(...) to wait on the transition), but now I get "TypeError: Cannot read property 'split' of undefined" error mentioned in #839, which the monkey patch you suggested there gets around, but causes a load of "[Vue warn]: Error in callback for watcher "page": "TypeError: computed.getPropertyValue is not a function" warnings in subsequent tests.

That said I am only having this problem in my production code, not the reproduction I posted here! I'll be damned if I can work out what the difference is though!

@380Z
Copy link

380Z commented Aug 14, 2018

I had the same problem with the JavaScript hooks but solved it in a different manner. I created a wrapper component which extends the TransisionStub and used it in my tests. This wrapper adds two methods which allow you to manually fire hooks at the moment you need it (after the show / hide).

ExtendedTransistionStub.js

import { TransitionStub } from 'vue-test-utils'

export default {
  name: 'ExtendedTransitionStub',
  extends: TransitionStub,
  methods: {
    triggerEnterHooks () {
      this.$emit('beforeEnter')
      this.$emit('enter')
      this.$emit('afterEnter')
    },
    triggerLeaveHooks () {
      this.$emit('beforeLeave')
      this.$emit('leave')
      this.$emit('afterLeave')
    },
  },
}

And in your tests:

import { shallowMount } from "@vue/test-utils";
import MyComponent from "@/components/MyComponent.vue";
import ExtendedTransitionStub from './stubs/ExtendedTransitionStub';

config.stubs.transition = ExtendedTransitionStub;

describe('TransisionComponent.vue', () => {
  it('fire hooks', () => {
      const wrapper = shallowMount(MyComponent, {});

      const transition = wrapper.find({name: 'ExtendedTransitionStub'});
      transition.vm.triggerEnterHooks();
      transition.vm.triggerLeaveHooks();
 })
})

@eddyerburgh Can these methods be implemented in the TransitionStub of vue-test-utils?
And is it possible to trigger these methods automatically?


"TypeError: computed.getPropertyValue is not a function" can be fixed by

const { getComputedStyle } = window
window.getComputedStyle = (node) => {
 return Object.assign(getComputedStyle(node), {
   transitionDelay: '',
   animationDelay: '',
   transitionDuration: '',
   animationDuration: '',
 })
}

@RALGIE
Copy link

RALGIE commented Mar 29, 2022

@eddyerburgh,You said:

Yes Transition components and TransitionGroup components are stubbed automatically, and the stubs don't fully implement hooks.

Because

const wrapper = mountingMethod(testComponent, {
  stubs: {
    transition: false
  }
}) 

the above option isn't an option for me because I use expect(cmp.vm.$el).toMatchSnapshot(); and an attribute from the element is changed every time it runs. Are the hooks all implemented? I think it isn't because the leave from the transition isn't triggered. Can you verify this?

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

No branches or pull requests

4 participants