Skip to content

Commit

Permalink
Do not reset global.document before CustomElement:disconnectedCallbac…
Browse files Browse the repository at this point in the history
…k has finished running, document should be accessible in this callback function
  • Loading branch information
dalvarezmartinez1 committed Nov 3, 2021
1 parent d7f0975 commit 8363f1e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
Expand Up @@ -39,4 +39,28 @@ describe('JSDomEnvironment', () => {

expect(env.dom.window.navigator.userAgent).toEqual('foo');
});

/**
* When used in conjunction with Custom Elements (part of the WebComponents standard)
* setting the global.document to null too early is problematic because:
*
* CustomElement's disconnectedCallback method is called when a custom element
* is removed from the DOM. The disconnectedCallback could need the document
* in order to remove some listener for example.
*
* global.close calls jsdom's Window.js.close which does this._document.body.innerHTML = "".
* The custom element will be removed from the DOM at this point, therefore disconnectedCallback
* will be called, so please make sure the global.document is still available at this point.
*/
it('should not set the global.document to null too early', () => {
const env = new JSDomEnvironment(makeProjectConfig());

const originalCloseFn = env.global.close.bind(env.global);
env.global.close = () => {
originalCloseFn();
expect(env.global.document).not.toBeNull();
};

return env.teardown();
});
});
7 changes: 6 additions & 1 deletion packages/jest-environment-jsdom/src/index.ts
Expand Up @@ -125,9 +125,14 @@ class JSDOMEnvironment implements JestEnvironment<number> {
if (this.errorEventListener) {
this.global.removeEventListener('error', this.errorEventListener);
}
this.global.close();

// Dispose "document" to prevent "load" event from triggering.

// Note that this.global.close() will trigger the CustomElement::disconnectedCallback
// Do not reset the document before CustomElement disconnectedCallback function has finished running,
// document should be accessible within disconnectedCallback.
Object.defineProperty(this.global, 'document', {value: null});
this.global.close();
}
this.errorEventListener = null;
// @ts-expect-error
Expand Down

0 comments on commit 8363f1e

Please sign in to comment.