How do I disable vue.js transitions for tests?

Viewed 7220

I have a vue.js component that uses the <transition> element to animate hide/show.

To speed up tests I would like to disable the animation. How can I do that?

* { transition: none !important } is suggested here: https://github.com/vuejs/vue/issues/463 but it doesnt's seem to make a difference.

I've created a fiddle here: https://jsfiddle.net/z11fe07p/2268/

Running the "test" the last output is "3. Display should be "none", it is: block". If I increase the timeout to 100, or remove the <transition> element, I get the expected output of "3. Display should be "none", it is: none"

So how can I disable the animation so that I can get rid of the setTimeout calls?

EDIT:

I tried removing all css styling, but still have the same problem. So the problem is triggered by simply just having the <transition> element.

EDIT 2:

Updated the fiddle to have no styling, just the <transition> element. Also included calls to $nextTick() to make sure that wasn't the reason it was behaving weirdly.

Change the call to wait100 to wait10 instead and you'll see the test start failing

https://jsfiddle.net/z11fe07p/2270/

EDIT 3:

Putting the example code here so it's easier for everyone to play around with :)

new Vue({
  el: '#app',
  template: `
    <span>
      <button @click="test()">Run test</button>
      <transition>
        <p v-show="show">Hello, world!</p>
      </transition>
    </span>
  `,
  data() {
    return {
      show: false,
    };
  },
  methods: {
    test() {
      const wait10 = _ => new Promise(resolve => setTimeout(resolve, 10));
      const wait100 = _ => new Promise(resolve => setTimeout(resolve, 100));
      const showParagraph = _ => this.show = true;
      const hideParagraph = _ => this.show = false;
      const p = document.querySelector('p');

      showParagraph();

      this.$nextTick()
        .then(wait10)
        .then(() => {
          const display = getComputedStyle(p).display;
          assertEqual(display, 'block');
        })
        .then(hideParagraph)
        .then(this.$nextTick)
        .then(wait100)
        .then(() => {
          const display = getComputedStyle(p).display;
          assertEqual(display, 'none');
        });
    }
  }
});

function assertEqual(a, b) { 
  if (a !== b) {
    console.error('Expected "' + a + '" to equal "' + b + '"');
  }
};
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app"></div>

5 Answers

I essentially change all my transition and transition-groups into a div with render functions when env is testing.

if (process.env.NODE_ENV === 'testing') {
  const div = {
    functional: true,
    render: (h, { data, children }) => h('div', data, children),
  }

  Vue.component('transition', div)
  Vue.component('transition-group', div)
}

My use case was slightly different, but the requirement the same: I wanted to disable certain transition effects for mobile screens.

My solution was to just wrap into a component. This would also work for testing (if 'disable' was set with e.g. process.env.NODE_ENV === 'testing').

<template>
  <transition v-if="!disable" :name="name" :mode="mode">
    <slot></slot>
  </transition>
  <div v-else>
    <slot></slot>
  </div>
</template>

<script>
export default {
  props: {
    disable: Boolean,
    name: String,
    mode: String,
  },
};
</script>

Purely for testing, I think Bill Criswell's answer is probably the cleanest.

Related