0

I have a fairly simple VueJS component called "Reveal"; it hides a message until somebody clicks on it, like so:

<template>
<div>
    <div v-show="!isShowing">
        <span v-on:click="show">ANSWER (Click to reveal)</span>
    </div>
    <div v-show="isShowing">
        <span v-on:click="hide">{{ message }} (Click to hide)</span>
    </div>
</div>
</template>

<script>
export default {
    props: ['message'],
    data() {
        return {
            isShowing: false
        };
    },
    methods: {
        show: function() {
            this.isShowing = true;
        },
        hide: function() {
            this.isShowing = false;
        }
    }
}
</script>

Now I'm trying to test it with the following Reveal.spec.js, using Mocha+Chai, like so:

import { expect } from 'chai'
import { shallowMount } from '@vue/test-utils'
import Reveal from '@/components/Reveal.vue'

describe('Reveal.vue', () => {
  it('doesn\'t reveal the message when instantiated', () => {
    const msg = 'secret message'
    const wrapper = shallowMount(Reveal, {
      propsData: { 
        message: msg
      }
    })

    const spans = wrapper.findAll('span')
    expect(spans.length).to.equal(2);

    expect(spans.at(0).text()).to.include("ANSWER");
    expect(spans.at(0).isVisible()).to.be.true;

    expect(spans.at(1).text()).to.include(msg);
    expect(spans.at(1).isVisible()).to.be.false;
  })

  it('reveals the message when clicked', () => {
    const msg = 'secret message'
    const wrapper = shallowMount(Reveal, {
      propsData: {
        message: msg 
      }
    })
    wrapper.trigger('click')

    const spans = wrapper.findAll('span')
    expect(spans.length).to.equal(2);

    expect(spans.at(0).text()).to.include("ANSWER");
    expect(spans.at(0).isVisible()).to.be.false;

    expect(spans.at(1).text()).to.include(msg);
    expect(spans.at(1).isVisible()).to.be.true;
  })
})

My problem is that the call to wrapper.trigger() doesn't seem to actually trigger the click--or, perhaps more accurately, the "v-show" doesn't seem to be accurately reflected in the resulting DOM nodes, since the first span appears to remain visible even though after the click the isShowing boolean should be flipping its value.

I'm absolutely certain I'm misunderstanding what's going on here, because something this simple should be blindingly straightforward. Where am I going wrong?

2
  • Just find the native html element and run click() on it, works every time. Commented Nov 25, 2018 at 14:47
  • For example, something along the lines of wrapper.find('button').click() should work. Commented Nov 25, 2018 at 14:48

1 Answer 1

1

trigger dispatches an Event on the root element of the wrapper. Your event listener is on a span element, so you need to use find to access a Wrapper containing the span element, before calling trigger:

const spans = wrapper.findAll('span')

spans.at(1).trigger('click')
Sign up to request clarification or add additional context in comments.

2 Comments

That did it, thanks! Wish the Vue docs were more clear about this. This is well-covered in your book, I take it? :-)
It is indeed ; )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.