🔥

Vueのテストでfocusイベントを拾う方法

2021/06/12に公開

始めに

vue-test-utilsを使ってテストする際に、明示的にfocus命令を送ってもfocusイベントが発火しなくて解決するのにかなり時間がかかったので備忘録として残します。

describe('test case', () => {
  const createWrapper = () => {
    return mount(MyComponent)
  };
  let wrapper: ReturnType<typeof createWrapper>
  beforeEach(() => {
    wrapper = createWrapper()
  })
  
  it('test', await () => {
    const elTextarea = wrapper.find('textarea').element
    // focus命令を強制的に出してもイベントが拾えない
    elTextarea.focus()
  })
});

結論

結論を言うと、document.bodyにattachされた状態で動かす必要がありました。attach後はdetachするためにwrapper自体を破棄する必要があるそうです。

 describe('test case', () => {
   const createWrapper = () => {
+    return mount(MyComponent, {
+      attachTo: document.body
+    })
   };
   let wrapper: ReturnType<typeof createWrapper>
   beforeEach(() => {
     wrapper = createWrapper()
   })
+  afterEach(() = {
+    // detachするためにwrapperを破棄する
+    wrapper.destory()
+  })
  
   it('test', await () => {
     const elTextarea = wrapper.find('textarea').element
     // focusイベントが拾えるようになる
     elTextarea.focus()
   })
 });

終わりに

以上がVueのテストでfocusイベントが送られるようにする方法でした。確かにJSでダウンロードするためにメモリ上でaタグを生成してクリックする方法があるので、その状況でfocusできたら確かに変と言えば変でしたね。とは言えそんなこと普通は分からないですし、見えない状況で動かしているのでDOMのテストは中々難しいものですね。。

参考記事

https://stackoverflow.com/questions/53041818/how-can-you-test-if-an-input-is-focused-with-vue-test-utils
https://vue-test-utils.vuejs.org/ja/api/options.html#attachtodocument

Discussion