Skip to content

Commit e7eb64c

Browse files
authored
jest-environment-jsdom: stop setting document to null on teardown (#13972)
1 parent 7cf5006 commit e7eb64c

File tree

3 files changed

+43
-15
lines changed

3 files changed

+43
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- `[jest-circus]` Send test case results for `todo` tests ([#13915](https://github.com/facebook/jest/pull/13915))
1919
- `[jest-circus]` Update message printed on test timeout ([#13830](https://github.com/facebook/jest/pull/13830))
2020
- `[jest-circus]` Avoid creating the word "testfalse" when `takesDoneCallback` is `false` in the message printed on test timeout AND updated timeouts test ([#13954](https://github.com/facebook/jest/pull/13954))
21+
- `[jest-environment-jsdom]` Stop setting `document` to `null` on teardown ([#13972](https://github.com/facebook/jest/pull/13972))
2122
- `[@jest/test-result]` Allow `TestResultsProcessor` type to return a Promise ([#13950](https://github.com/facebook/jest/pull/13950))
2223

2324
### Chore & Maintenance

packages/jest-environment-jsdom/src/__tests__/jsdom_environment.test.ts

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ describe('JSDomEnvironment', () => {
8484

8585
/**
8686
* When used in conjunction with Custom Elements (part of the WebComponents standard)
87-
* setting the global.document to null too early is problematic because:
87+
* setting the `global` and `global.document` to null too early is problematic because:
8888
*
8989
* CustomElement's disconnectedCallback method is called when a custom element
9090
* is removed from the DOM. The disconnectedCallback could need the document
@@ -94,7 +94,7 @@ describe('JSDomEnvironment', () => {
9494
* The custom element will be removed from the DOM at this point, therefore disconnectedCallback
9595
* will be called, so please make sure the global.document is still available at this point.
9696
*/
97-
it('should not set the global.document to null too early', () => {
97+
it('should call CE disconnectedCallback with valid globals on teardown', () => {
9898
const env = new JSDomEnvironment(
9999
{
100100
globalConfig: makeGlobalConfig(),
@@ -103,12 +103,46 @@ describe('JSDomEnvironment', () => {
103103
{console, docblockPragmas: {}, testPath: __filename},
104104
);
105105

106-
const originalCloseFn = env.global.close.bind(env.global);
107-
env.global.close = () => {
108-
originalCloseFn();
109-
expect(env.global.document).not.toBeNull();
110-
};
106+
let hasDisconnected = false;
107+
let documentWhenDisconnected = null;
111108

112-
return env.teardown();
109+
// define a custom element
110+
const {HTMLElement} = env.global;
111+
class MyCustomElement extends HTMLElement {
112+
disconnectedCallback() {
113+
hasDisconnected = true;
114+
documentWhenDisconnected = env.global.document;
115+
}
116+
}
117+
118+
// append an instance of the custom element
119+
env.global.customElements.define('my-custom-element', MyCustomElement);
120+
const instance = env.global.document.createElement('my-custom-element');
121+
env.global.document.body.appendChild(instance);
122+
123+
// teardown will disconnect the custom elements
124+
env.teardown();
125+
126+
expect(hasDisconnected).toBe(true);
127+
expect(documentWhenDisconnected).not.toBeNull();
128+
});
129+
130+
it('should not fire load event after the environment was teared down', async () => {
131+
const env = new JSDomEnvironment(
132+
{
133+
globalConfig: makeGlobalConfig(),
134+
projectConfig: makeProjectConfig(),
135+
},
136+
{console, docblockPragmas: {}, testPath: __filename},
137+
);
138+
139+
const loadHandler = jest.fn();
140+
env.global.document.addEventListener('load', loadHandler);
141+
env.teardown();
142+
143+
// The `load` event is fired in microtasks, wait until the microtask queue is reliably flushed
144+
await new Promise(resolve => setTimeout(resolve, 0));
145+
146+
expect(loadHandler).not.toHaveBeenCalled();
113147
});
114148
});

packages/jest-environment-jsdom/src/index.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,6 @@ export default class JSDOMEnvironment implements JestEnvironment<number> {
160160
this.global.removeEventListener('error', this.errorEventListener);
161161
}
162162
this.global.close();
163-
164-
// Dispose "document" to prevent "load" event from triggering.
165-
166-
// Note that this.global.close() will trigger the CustomElement::disconnectedCallback
167-
// Do not reset the document before CustomElement disconnectedCallback function has finished running,
168-
// document should be accessible within disconnectedCallback.
169-
Object.defineProperty(this.global, 'document', {value: null});
170163
}
171164
this.errorEventListener = null;
172165
// @ts-expect-error: this.global not allowed to be `null`

0 commit comments

Comments
 (0)