testing-library / vue-testing-library

🦎 Simple and complete Vue.js testing utilities that encourage good testing practices.
http://testing-library.com/vue
MIT License
1.08k stars 110 forks source link

document.activeElement state lost after rendering #317

Open kristiankostadinov opened 3 months ago

kristiankostadinov commented 3 months ago

Describe the bug

A component focuses an element in the onMounted hook and the focus is lost after the render function.

In the Codesandbox there is a TestButton component that sets the focus in onMounted. In the respective test there are two test cases - one using @testing-library/vue and one using @vue/test-utils directly. The behavior of document.activeElement differs between the two. @testing-library/vue loses the state of document.activeElement

To Reproduce Steps to reproduce the behavior:

Codesandbox

Expected behavior

document.activeElement should be the button that was focused in the onMounted hook

Screenshots

image

Related information:

Relevant code or config (if any)

TestButton.vue

<template>
  <div>
    <button ref="button">Test</button>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref } from "vue";

const button = ref<HTMLButtonElement | null>(null);

onMounted(() => {
  console.info(document.activeElement?.nodeName); // <- body
  button.value?.focus();
  console.info(document.activeElement?.nodeName); // <- button
});
</script>
import { render } from "@testing-library/vue";
import { mount } from "@vue/test-utils";
import TestButton from "./TestButton.vue";

describe("TestButton", () => {
  it("test @vue/test-utils", () => {
    const wrapper = mount(TestButton, { attachTo: document.body });

    console.info(document.activeElement?.nodeName); // <- button
    expect(document.activeElement?.nodeName).toBe("BUTTON");

    wrapper.unmount();
  });

  it("test @testing-library/vue", () => {
    const { unmount } = render(TestButton, { container: document.body });

    console.info(document.activeElement?.nodeName); // <- (!) body
    expect(document.activeElement?.nodeName).toBe("BUTTON");

    unmount();
  });
});