You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3+Vitest组合API测试中,input触发焦点后activeElement为HTMLBodyElement问题

解决Vue测试中document.activeElement指向body而非input的问题

问题重现

Vue组件代码

<template>
  <input id="input" type="text" @focus="handleOnFocus($event)" />
</template>
<script setup type="ts">
const handleOnFocus = () => {
  console.log('Component document.activeElement:', document.activeElement)
}
</script>

测试代码

import { mount } from '@vue/test-utils'
import { expect } from 'vitest'
import AarghOmg from './AarghOmg.vue'

describe('AarghOmg', () => {
  let wrapper: any

  beforeEach(() => {
    wrapper = mount<typeof AarghOmg>(AarghOmg, {
      attachTo: document.body
    })
  })

  it('outputs activeElement', () => {
    wrapper.find('#input').trigger('focus')

    console.log('Test document.body.innerHTML:', document.body.innerHTML)
    expect(true).toBe(true)
  })
})

控制台输出

Component document.activeElement: HTMLBodyElement {}
Test document.body.innerHTML: <div data-v-app=""><input id="input" type="text"></div>

问题:浏览器中触发input焦点时,document.activeElement正常指向input,但测试环境中却指向body。


解决方案

1. 直接调用DOM元素的focus()方法

@vue/test-utils的trigger('focus')仅模拟事件派发,不会真正让元素获得焦点。改用DOM原生的focus()方法:

// 替换原有的trigger('focus')
wrapper.find('#input').element.focus()

2. 配置测试环境支持视觉模拟

若使用jsdom(vitest默认环境),需开启pretendToBeVisual选项以支持焦点操作。在vitest.config.ts中添加:

export default defineConfig({
  test: {
    environmentOptions: {
      jsdom: {
        pretendToBeVisual: true
      }
    }
  }
})

3. 异步等待焦点状态更新

焦点操作可能涉及异步DOM更新,需用await配合nextTick确保状态生效:

it('outputs activeElement as input', async () => {
  const input = wrapper.find('#input')
  input.element.focus()
  await wrapper.vm.$nextTick()

  expect(document.activeElement).toBe(input.element)
})

原理说明

trigger('focus')仅触发组件的focus事件回调,但不会修改浏览器(或测试环境)的实际焦点状态。而直接调用DOM元素的focus()方法会触发环境的焦点行为,同步更新document.activeElement的值。

内容的提问来源于stack exchange,提问作者mummybot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:33:23