Skip to content

Commit a8b7aa0

Browse files
committed
[chore] use afterEach to cleanup modals automatically.
1 parent ba2fe90 commit a8b7aa0

File tree

2 files changed

+16
-43
lines changed

2 files changed

+16
-43
lines changed

specs/Modal.spec.js

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,25 @@ import expect from 'expect';
1212
import ReactDOM from 'react-dom';
1313
import Modal from '../lib/components/Modal';
1414
import * as ariaAppHider from '../lib/helpers/ariaAppHider';
15-
import { renderModal, unmountModal } from './helper';
15+
import { renderModal, unmountModal, emptyDOM } from './helper';
1616

1717
const Simulate = TestUtils.Simulate;
1818

1919

2020
describe('Modal', () => {
21-
afterEach('check if test cleaned up rendered modals', () => {
22-
const overlay = document.querySelectorAll('.ReactModal__Overlay');
23-
const content = document.querySelectorAll('.ReactModal__Content');
24-
expect(overlay.length).toBe(0);
25-
expect(content.length).toBe(0);
26-
});
21+
afterEach('check if test cleaned up rendered modals', emptyDOM);
2722

2823
it('scopes tab navigation to the modal');
2924
it('focuses the last focused element when tabbing in from browser chrome');
3025

3126
it('can be open initially', () => {
3227
const component = renderModal({ isOpen: true }, 'hello');
3328
expect(component.portal.content.innerHTML.trim()).toEqual('hello');
34-
unmountModal();
3529
});
3630

3731
it('can be closed initially', () => {
3832
const component = renderModal({}, 'hello');
3933
expect(ReactDOM.findDOMNode(component.portal).innerHTML.trim()).toEqual('');
40-
unmountModal();
4134
});
4235

4336
it('accepts appElement as a prop', () => {
@@ -73,21 +66,18 @@ describe('Modal', () => {
7366
const child = 'I am a child of Modal, and he has sent me here...';
7467
const component = renderModal({ isOpen: true }, child);
7568
expect(component.portal.content.innerHTML).toEqual(child);
76-
unmountModal();
7769
});
7870

7971
it('renders the modal content with a dialog aria role when provided ', () => {
8072
const child = 'I am a child of Modal, and he has sent me here...';
8173
const component = renderModal({ isOpen: true, role: 'dialog' }, child);
8274
expect(component.portal.content.getAttribute('role')).toEqual('dialog');
83-
unmountModal();
8475
});
8576

8677
it('renders the modal with a aria-label based on the contentLabel prop', () => {
8778
const child = 'I am a child of Modal, and he has sent me here...';
8879
const component = renderModal({ isOpen: true, contentLabel: 'Special Modal' }, child);
8980
expect(component.portal.content.getAttribute('aria-label')).toEqual('Special Modal');
90-
unmountModal();
9181
});
9282

9383
it('has default props', () => {
@@ -114,16 +104,13 @@ describe('Modal', () => {
114104
it('focuses the modal content', () => {
115105
renderModal({ isOpen: true }, null, function checkModalContentFocus () {
116106
expect(document.activeElement).toEqual(this.portal.content);
117-
unmountModal();
118107
});
119108
});
120109

121110
it('give back focus to previous element or modal.', (done) => {
122111
const modal = renderModal({
123112
isOpen: true,
124113
onRequestClose () {
125-
unmountModal();
126-
unmountModal();
127114
done();
128115
}
129116
}, null, () => {});
@@ -160,7 +147,6 @@ describe('Modal', () => {
160147

161148
renderModal({ isOpen: true }, input, () => {
162149
expect(document.activeElement).toEqual(document.querySelector('.focus_input'));
163-
unmountModal();
164150
});
165151
});
166152

@@ -169,7 +155,6 @@ describe('Modal', () => {
169155
expect(() => {
170156
Simulate.keyDown(component.portal.content, { key: 'Tab', keyCode: 9, which: 9 });
171157
}).toNotThrow();
172-
unmountModal();
173158
});
174159

175160
it('keeps focus inside the modal when child has no tabbable elements', () => {
@@ -183,61 +168,51 @@ describe('Modal', () => {
183168
preventDefault () { tabPrevented = true; }
184169
});
185170
expect(tabPrevented).toEqual(true);
186-
unmountModal();
187171
});
188172

189173
it('supports portalClassName', () => {
190174
const modal = renderModal({ isOpen: true, portalClassName: 'myPortalClass' });
191175
expect(modal.node.className).toEqual('myPortalClass');
192-
unmountModal();
193176
});
194177

195178
it('supports custom className', () => {
196179
const modal = renderModal({ isOpen: true, className: 'myClass' });
197180
expect(modal.portal.content.className.indexOf('myClass')).toNotEqual(-1);
198-
unmountModal();
199181
});
200182

201183
it('supports overlayClassName', () => {
202184
const modal = renderModal({ isOpen: true, overlayClassName: 'myOverlayClass' });
203185
expect(modal.portal.overlay.className.indexOf('myOverlayClass')).toNotEqual(-1);
204-
unmountModal();
205186
});
206187

207188
it('overrides the default styles when a custom classname is used', () => {
208189
const modal = renderModal({ isOpen: true, className: 'myClass' });
209190
expect(modal.portal.content.style.top).toEqual('');
210-
unmountModal();
211191
});
212192

213193
it('overrides the default styles when a custom overlayClassName is used', () => {
214194
const modal = renderModal({ isOpen: true, overlayClassName: 'myOverlayClass' });
215195
expect(modal.portal.overlay.style.backgroundColor).toEqual('');
216-
unmountModal();
217196
});
218197

219198
it('supports adding style to the modal contents', () => {
220199
const modal = renderModal({ isOpen: true, style: { content: { width: '20px' } } });
221200
expect(modal.portal.content.style.width).toEqual('20px');
222-
unmountModal();
223201
});
224202

225203
it('supports overriding style on the modal contents', () => {
226204
const modal = renderModal({ isOpen: true, style: { content: { position: 'static' } } });
227205
expect(modal.portal.content.style.position).toEqual('static');
228-
unmountModal();
229206
});
230207

231208
it('supports adding style on the modal overlay', () => {
232209
const modal = renderModal({ isOpen: true, style: { overlay: { width: '75px' } } });
233210
expect(modal.portal.overlay.style.width).toEqual('75px');
234-
unmountModal();
235211
});
236212

237213
it('supports overriding style on the modal overlay', () => {
238214
const modal = renderModal({ isOpen: true, style: { overlay: { position: 'static' } } });
239215
expect(modal.portal.overlay.style.position).toEqual('static');
240-
unmountModal();
241216
});
242217

243218
it('supports overriding the default styles', () => {
@@ -248,7 +223,6 @@ describe('Modal', () => {
248223
const modal = renderModal({ isOpen: true });
249224
expect(modal.portal.content.style.position).toEqual(newStyle);
250225
Modal.defaultStyles.content.position = previousStyle;
251-
unmountModal();
252226
});
253227

254228
it('adds class to body when open', () => {
@@ -262,7 +236,6 @@ describe('Modal', () => {
262236

263237
renderModal({ isOpen: false });
264238
expect(document.body.className.indexOf('ReactModal__Body--open') !== -1).toEqual(false);
265-
unmountModal();
266239
});
267240

268241
it('removes class from body when unmounted without closing', () => {
@@ -290,19 +263,15 @@ describe('Modal', () => {
290263
const content = document.querySelector('.ReactModal__Content');
291264
expect(overlay.className.match(/ReactModal__Overlay--after-open/)).toExist();
292265
expect(content.className.match(/ReactModal__Content--after-open/)).toExist();
293-
unmountModal();
294266
});
295267

296268
it('should trigger the onAfterOpen callback', () => {
297269
const afterOpenCallback = sinon.spy();
298270
renderModal({
299271
isOpen: true,
300-
onAfterOpen () {
301-
afterOpenCallback();
302-
}
272+
onAfterOpen: afterOpenCallback
303273
});
304274
expect(afterOpenCallback.called).toBeTruthy();
305-
unmountModal();
306275
});
307276

308277
it('check the state of the modal after close with time out and reopen it', () => {
@@ -315,7 +284,6 @@ describe('Modal', () => {
315284
modal.portal.open();
316285
modal.portal.closeWithoutTimeout();
317286
expect(!modal.portal.state.isOpen).toBeTruthy();
318-
unmountModal();
319287
});
320288

321289
it('should close on Esc key event', () => {
@@ -340,15 +308,14 @@ describe('Modal', () => {
340308
expect(event).toBeTruthy();
341309
expect(event.constructor).toBeTruthy();
342310
expect(event.key).toEqual('FakeKeyToTestLater');
343-
unmountModal();
344311
});
345312

346313
describe('should close on overlay click', () => {
347-
afterEach('Unmount modal', () => {
348-
unmountModal();
349-
});
314+
afterEach('Unmount modal', emptyDOM);
350315

351316
describe('verify props', () => {
317+
afterEach('Unmount modal', emptyDOM);
318+
352319
it('verify default prop of shouldCloseOnOverlayClick', () => {
353320
const modal = renderModal({ isOpen: true });
354321
expect(modal.props.shouldCloseOnOverlayClick).toEqual(true);
@@ -361,6 +328,8 @@ describe('Modal', () => {
361328
});
362329

363330
describe('verify clicks', () => {
331+
afterEach('Unmount modal', emptyDOM);
332+
364333
it('verify overlay click when shouldCloseOnOverlayClick sets to false', () => {
365334
const requestCloseCallback = sinon.spy();
366335
const modal = renderModal({
@@ -395,9 +364,7 @@ describe('Modal', () => {
395364
const modal = renderModal({
396365
isOpen: true,
397366
shouldCloseOnOverlayClick: true,
398-
onRequestClose () {
399-
requestCloseCallback();
400-
}
367+
onRequestClose: requestCloseCallback
401368
});
402369
expect(modal.props.isOpen).toEqual(true);
403370
const overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay');
@@ -481,6 +448,7 @@ describe('Modal', () => {
481448
});
482449

483450
modal.portal.closeWithTimeout();
451+
unmountModal();
484452

485453
const overlay = TestUtils.findRenderedDOMComponentWithClass(modal.portal, 'ReactModal__Overlay');
486454
const content = TestUtils.findRenderedDOMComponentWithClass(modal.portal, 'ReactModal__Content');
@@ -489,7 +457,6 @@ describe('Modal', () => {
489457
expect(/ReactModal__Content--before-close/.test(content.className)).toBe(true);
490458

491459
modal.portal.closeWithoutTimeout();
492-
unmountModal();
493460
});
494461

495462
it('keeps the modal in the DOM until closeTimeoutMS elapses', (done) => {

specs/helper.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,9 @@ export const unmountModal = () => {
2525
ReactDOM.unmountComponentAtNode(currentDiv);
2626
document.body.removeChild(currentDiv);
2727
};
28+
29+
export const emptyDOM = () => {
30+
while (divStack.length) {
31+
unmountModal();
32+
}
33+
};

0 commit comments

Comments
 (0)