Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit febe7f8

Browse files
committed
Remove global event listeners beforeEach
1 parent 6a5e84b commit febe7f8

File tree

1 file changed

+60
-14
lines changed

1 file changed

+60
-14
lines changed

test/config/jest.setup-tests.js

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,77 @@
11
import mock from 'xhr-mock';
22

3-
const windowKeys = JSON.parse(JSON.stringify(Object.keys(window)));
3+
const sideEffects = {
4+
document: {
5+
addEventListener: {
6+
fn: document.addEventListener,
7+
refs: [],
8+
},
9+
keys: Object.keys(document),
10+
},
11+
window: {
12+
addEventListener: {
13+
fn: window.addEventListener,
14+
refs: [],
15+
},
16+
keys: Object.keys(window),
17+
},
18+
};
419

520
// Lifecycle Hooks
621
// -----------------------------------------------------------------------------
7-
// Soft-reset jsdom. This clears the DOM and removes all attribute from the
8-
// root element, however it does not undo changes made to jsdom globals like
9-
// the window or document object. Tests requiring a full jsdom reset should be
10-
// stored in separate files, as this is the only way (?) to do a complete
11-
// reset of JSDOM with Jest.
22+
beforeAll(async () => {
23+
// Spy addEventListener
24+
['document', 'window'].forEach(obj => {
25+
const fn = sideEffects[obj].addEventListener.fn;
26+
const refs = sideEffects[obj].addEventListener.refs;
27+
28+
function addEventListenerSpy(type, listener, options) {
29+
// Store listener reference so it can be removed during reset
30+
refs.push({ type, listener, options });
31+
// Call original window.addEventListener
32+
fn(type, listener, options);
33+
}
34+
35+
// Add to default key arry to prevent removal during reset
36+
sideEffects[obj].keys.push('addEventListener');
37+
38+
// Replace addEventListener with mock
39+
global[obj].addEventListener = addEventListenerSpy;
40+
});
41+
});
42+
43+
// Reset JSDOM. This attempts to remove side effects from tests, however it does
44+
// not reset all changes made to globals like the the window and document
45+
// objects. Tests requiring a full JSDOM reset should be stored in separate
46+
// files, which is only way to do a complete reset of JSDOM with Jest.
1247
beforeEach(async () => {
1348
const rootElm = document.documentElement;
1449

50+
// Remove attributes on root element
51+
[...rootElm.attributes].forEach(attr => rootElm.removeAttribute(attr.name));
52+
1553
// Remove elements (faster the setting innerHTML)
1654
while (rootElm.firstChild) {
1755
rootElm.removeChild(rootElm.firstChild);
1856
}
1957

20-
// Remove jest/docsify side-effects
21-
Object.keys(window)
22-
.filter(key => !windowKeys.includes(key))
23-
.forEach(key => {
24-
delete window[key];
25-
});
58+
// Remove global listeners and keys
59+
['document', 'window'].forEach(obj => {
60+
const refs = sideEffects[obj].addEventListener.refs;
2661

27-
// Remove attributes
28-
[...rootElm.attributes].forEach(attr => rootElm.removeAttribute(attr.name));
62+
// Listeners
63+
while (refs.length) {
64+
const { type, listener, options } = refs.pop();
65+
global[obj].removeEventListener(type, listener, options);
66+
}
67+
68+
// Keys
69+
Object.keys(global[obj])
70+
.filter(key => !sideEffects[obj].keys.includes(key))
71+
.forEach(key => {
72+
delete global[obj][key];
73+
});
74+
});
2975

3076
// Restore base elements
3177
rootElm.innerHTML = '<html><head></head><body></body></html>';

0 commit comments

Comments
 (0)