16

Is there a way to actually trigger the submission of a form by clicking on a submit button in a Vue Unit Test?

Let's take this simple component:

<template>
    <form @submit.prevent="$emit('submitEventTriggered')">
        <button type="submit">Submit Form</button>
    </form>
</template>

<script>
    export default {}
</script>

You can find a similar component as an example here.

I want to test that submit.prevent gets triggered when the button is clicked and therefore the submitEventTriggered is emitted. When I run this in a browser everything works as expected, but the following test fails:

import {shallowMount} from '@vue/test-utils'
import {assert} from 'chai'
import Form from '@/components/Form.vue'

describe.only('Form', () => {

    it('button click triggers submit event', () => {
        const wrapper = shallowMount(Form)

        wrapper.find('[type=\'submit\']').trigger('click')

        assert.exists(wrapper.emitted('submitEventTriggered'), 'Form submit not triggered')
    })
})

With this output:

AssertionError: Form submit not triggered: expected undefined to exist

If I change the action to trigger submit.prevent on the form directly everything works fine, but then there is actually no test coverage for the submitting via button.

wrapper.find('form').trigger('submit.prevent')

It seems like the trigger function doesn't actually click the button.

Why is this and is there a way to fix it?

3
  • 1
    This seems to me like a bug. I reported it here: github.com/vuejs/vue-test-utils/issues/1030 Commented Nov 19, 2018 at 21:30
  • 2
    Would like to know why/who downvoted you Commented Nov 19, 2018 at 22:00
  • 1
    Having the same issue - commented on the github issue - hopefully it can be resolved. Commented Nov 21, 2018 at 4:50

1 Answer 1

23

Note: The previous method used attachToDocument, which has been deprecated,


The issue is that Vue Test Utils does not attach DOM nodes to the document by default. This is to avoid enforcing cleanup. You can solve this by setting attachTo to an HTML element when you mount the component:

const div = document.createElement('div')
div.id = 'root'
document.body.appendChild(div)

it('button click triggers submit event', () => {
  const wrapper = shallowMount(Form, {
    attachTo: '#root'
  })

  wrapper.find("[type='submit']").trigger('click')

  assert.exists(
    wrapper.emitted('submitEventTriggered'),
    'Form submit not triggered'
  )
})

You should remove the DOM node from the document to avoid a memory leak. You can do this by calling destroy on the wrapper:

wrapper.destroy()
Sign up to request clarification or add additional context in comments.

6 Comments

Where is the documentation of Vue Test Utils does not attach DOM nodes to the document by default?
this isn't working for me, and the attachTo example on the Vue Test Utils site doesn't either, is there some config that needs to be added for attachTo to work with mount/shallowMount?
the example in the vue test utils website has an error (a PR was submitted to fix it so it might be corrected soon) expect(wrapper.vm.$el.parentNode).to.not.be.null should be expect(wrapper.vm.$el.parentNode).not.toBeNull()
I got the error Error: Not implemented: HTMLFormElement.prototype.submit. So instead of triggering the submit via the button, I did like below: wrapper.findComponent('form').trigger('submit') and I could remove the attachTo and others. May be useful in case one does not need to test DOM features, but only the submit event of the form
|

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.