30
votes

I'm testing a couple of components that reach outside of their DOM structure when mounting and unmounting to provide specific interaction capability that wouldn't be possible otherwise.

I'm using Jest and the default JSDOM initialization to create a browser-like environment within node. I couldn't find anything in the documentation to suggest that Jest reset JSDOM after every test execution, and there's no explicit documentation on how to do that manually if that is not the case.

My question is, does Jest reset the JSDOM instance after every test, suite or does it keep a single instance of JSDOM across all test runs? If so, how can I control it?

2
More about this issue, and some ideas to deal with it: github.com/facebook/jest/issues/1224Elias Zamaria

2 Answers

59
votes

To correct the (misleading) accepted answer and explicitly underline that very important bit of information from one of the previous comments:

No. Jest does not clean the JSDOM document after each test run! It only clears the DOM after all tests inside an entire file are completed.

That means that you have to manually cleanup your resources created during a test, after every single test run. Otherwise it will cause shared state, which results in very subtle errors that can be incredibly hard to track.

The following is a very simple, yet effective method to cleanup the JSDOM after each single test inside a jest test suite:

describe('my test suite', () => {
  afterEach(() => {
    document.getElementsByTagName('html')[0].innerHTML = ''; 
  });

  // your tests here ...
});
2
votes

Rico Pfaus is right, though I found that resetting the innerHTML the way he suggests was too destructive and caused tests to fail. Instead, I found selecting a specific element (by class or id) I want to remove from the document more effective.

describe('my test suite', () => {
    afterEach(() => {
        document.querySelector(SOME CLASS OR ID).innerHTML = ''
    })
})