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?
Jest actually ships with jsdom and the environment already configured. You can override it with the testEnvironment setting. If you need to set up more aspects of the environment though, you can use the setupTestFrameworkScriptFile setting to point to a file that executes before all of your tests run.
jsdom is a pure JavaScript implementation of the DOM and browser APIs that runs in node. If you're not using Jest and you would like to run your tests in Node, then you must install jsdom yourself. There's also a package called global-jsdom which can be used to setup the global environment to simulate the browser APIs.
afterEach(() => { jest. clearAllMocks(); }); to call jest. clearAllMocks to clear all mocks after each test.
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 ... });
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 = '' }) })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With