Vue-test-utils: Rendered dom not being removed from document after each test when attachToDocument is true

Created on 13 Mar 2019  路  5Comments  路  Source: vuejs/vue-test-utils

Version

1.0.0-beta.29

Reproduction link

https://codesandbox.io/s/y006o3zxqz

Steps to reproduce

Run the sanbox, and view the test results.

The second test fails, as it finds two buttons in the DOM.

What is expected?

The previous test's DOM to be removed from the document.

What is actually happening?

the old test DOM persists in the document.


When using document.querySelectorAll(...) inside an app, and testing various scenarios, the old APPs DOM is not being removed from the JSDOM document when mountToDocument: true is set during mount, causing unexpected results in the tests.

feature request

Most helpful comment

@eddyerburgh One side note....

wrapper.destroy() assumes a non-functional component, and will only remove the DOM if the wrapper root is a non-functional component.

Hence for testing functional components, there is no way to remove the DOM generated by a functional component.

wrapper.destroy() should first check to see if the root element is a functional component or a Vue instance, and if functional, just remove the elements from DOM, and if Vue instance destroy the VM as well as the DOM (as it currently does).

All 5 comments

We've been able to work around this temporarily by doing similar to the following:

const App = Vue.extend({
  template: '<div><button>Button</button></div>',
  destroyed() {
    // Hack to remove DOM from document as vue-test-utils leaves
    // the rendered DOM in document after each test, when
    // mounting option `attachToDocument` is true.
    // Requires each test to call wrapper.vm.$destroy() when done
    if (this.$el && this.$el.parentNode && this.$el.parentNode.removeChild) {
      this.$el.parentNode.removeChild(this.$el)
    }
  }
})

and then calling wrapper.vm.$destroy() at the end of each test.

You need to use the wrapper.destroy method on the root wrapper:

const wrapper = mount(TestComponent, { 
  attachToDocument: true
})

wrapper.destroy()

We should add destroy to the docs on attachToDocument, but we won't update vue test utils to do this automatically

Yeah, I did't know about the destroy() wrapper method (although after looking at the source code, I do see it in there).

Docs update would be a great help... and maybe mentioning that the DOM+vm sticks around if not destroyed, which would over time - during a test suite - waste memory footprint.

@eddyerburgh One side note....

wrapper.destroy() assumes a non-functional component, and will only remove the DOM if the wrapper root is a non-functional component.

Hence for testing functional components, there is no way to remove the DOM generated by a functional component.

wrapper.destroy() should first check to see if the root element is a functional component or a Vue instance, and if functional, just remove the elements from DOM, and if Vue instance destroy the VM as well as the DOM (as it currently does).

I am just now using .destroy() on a wrapper with attachToDocument: true, and when I check for a DOM elemen it's still there. @eddyerburgh any clue?
The component is a classic OPTIONS API component.

Was this page helpful?
0 / 5 - 0 ratings