Vue Academy · Lesson

Testing User Interactions and Events

wrapper.trigger('click'), setValue(), wrapper.vm.$emit(), async flushPromises().

Lesson 3 of 413 steps

Testing User Interactions and Events is a free Vue Academy lesson on CoddyKit. This is lesson 3 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, and your progress syncs across the web and the CoddyKit app. The Vue Academy course includes 4 lessons in total.

Simulating User Behavior

Beyond rendering, tests should mimic what a user does: clicking buttons, typing into inputs, submitting forms. @vue/test-utils wrappers expose methods to dispatch DOM events and update Vue afterward.

trigger for Click Events

wrapper.trigger("click") fires a click on the element. Because it updates the DOM, it returns a promise — await it so assertions see the result.

const button = wrapper.get("button")
await button.trigger("click")
expect(wrapper.text()).toContain("Clicked once")

Why Tests Are Async

Vue updates the DOM asynchronously. After an interaction the new state is not visible until the next tick. Awaiting the trigger promise lets the DOM settle before you assert.

it("increments on click", async () => {
  const wrapper = mount(Counter)
  await wrapper.get("button").trigger("click")
  expect(wrapper.get(".count").text()).toBe("1")
})

setValue for Inputs

To type into a field, use wrapper.setValue(value) on the input wrapper. It sets the value and dispatches an input event so v-model updates.

const input = wrapper.get("input")
await input.setValue("hello@example.com")
expect(input.element.value).toBe("hello@example.com")

Checkboxes and Selects

setValue adapts to the element: pass a boolean for checkboxes and the option value for a select.

await wrapper.get("input[type=checkbox]").setValue(true)
await wrapper.get("select").setValue("tr")

Asserting Emitted Events

Components communicate up via emitted events. wrapper.emitted() returns a record of every event the component emitted, keyed by name.

await wrapper.get("button").trigger("click")
expect(wrapper.emitted()).toHaveProperty("submit")

Inspecting Emitted Payloads

wrapper.emitted("name") returns an array of emission argument-arrays. The first emission’s first argument is emitted("name")[0][0].

await wrapper.get("button").trigger("click")
const events = wrapper.emitted("submit")
expect(events).toHaveLength(1)
expect(events[0][0]).toEqual({ email: "a@b.com" })

A Form Submit Test

Combine the pieces: fill a field, submit the form, then assert the emitted payload.

it("emits submit with the email", async () => {
  const wrapper = mount(LoginForm)
  await wrapper.get("input").setValue("a@b.com")
  await wrapper.get("form").trigger("submit.prevent")
  expect(wrapper.emitted("submit")[0][0]).toEqual({ email: "a@b.com" })
})

Async Operations in Components

Many handlers call APIs and update state when the promise resolves. The microtask may not have run by the time your assertion executes, so you must wait.

async function load() {
  loading.value = true
  data.value = await fetchData()
  loading.value = false
}

flushPromises

flushPromises from Test Utils resolves all pending microtasks (then-callbacks). Await it after triggering an async action so resolved promises and the resulting DOM updates are applied.

import { flushPromises } from "@vue/test-utils"

await wrapper.get("button").trigger("click")
await flushPromises()
expect(wrapper.text()).toContain("Loaded")

Putting Async Tests Together

The pattern: mount, interact, await flushPromises(), assert. Mark the test function async so you can use await throughout.

it("shows results after fetch", async () => {
  const wrapper = mount(SearchBox)
  await wrapper.get("input").setValue("vue")
  await wrapper.get("form").trigger("submit.prevent")
  await flushPromises()
  expect(wrapper.findAll("li")).toHaveLength(2)
})

Quick Check

Check your understanding of interaction testing.

Recap

You learned to test interactions and events:

  • trigger("click") fires events; await it because Vue updates async.
  • setValue sets input/checkbox/select values and fires input events for v-model.
  • wrapper.emitted() records emitted events; emitted("name")[0][0] reads the first payload.
  • For async handlers, await flushPromises() before asserting.
  • Mark tests async to use await.
Free to start

Learn HTML with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
42
Lessons
156

Frequently Asked Questions

Is the “Testing User Interactions and Events” lesson free?

Yes — any 3 lessons of the Vue Academy learning path, including “Testing User Interactions and Events”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Vue Academy course includes 4 lessons in total.

What will I learn in “Testing User Interactions and Events”?

wrapper.trigger('click'), setValue(), wrapper.vm.$emit(), async flushPromises(). You practise Vue Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Vue Academy?

No prior experience is required. Vue Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.

How long does the “Testing User Interactions and Events” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Vue Academy lesson?

Yes. Every Vue Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Vitest Setup for Vue Projects
  2. Mounting and Querying Components
  3. Testing User Interactions and Events
  4. Mocking Composables, Stores, and APIs
← Back to Vue Academy