From bd2261f90d6c62a1bd5829f11e8ae27b1192c38b Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Wed, 4 Mar 2020 11:27:37 -0700 Subject: [PATCH] feat: remove mutationobserver shim (#457) Closes #413 Closes #357 BREAKING CHANGE: MutationObserver is supported by all major browsers and recent versions of JSDOM. If you need, you can create your own shim (using @sheerun/mutationobserver-shim) and attach it to the window. --- package.json | 1 - src/__tests__/helpers.js | 27 +-------------------------- src/events.js | 20 +------------------- src/helpers.js | 32 +++++++++++++++++++------------- src/wait-for-dom-change.js | 5 +++-- src/wait.js | 5 +++-- 6 files changed, 27 insertions(+), 63 deletions(-) diff --git a/package.json b/package.json index 8f9420fb..c3c12149 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ ], "dependencies": { "@babel/runtime": "^7.8.4", - "@sheerun/mutationobserver-shim": "^0.3.2", "@types/testing-library__dom": "^6.12.1", "aria-query": "^4.0.2", "dom-accessibility-api": "^0.3.0", diff --git a/src/__tests__/helpers.js b/src/__tests__/helpers.js index cbf6e628..109fe189 100644 --- a/src/__tests__/helpers.js +++ b/src/__tests__/helpers.js @@ -1,30 +1,5 @@ -import {getDocument, newMutationObserver} from '../helpers' +import {getDocument} from '../helpers' test('returns global document if exists', () => { expect(getDocument()).toBe(document) }) - -class DummyClass { - constructor(args) { - this.args = args - } -} - -describe('newMutationObserver', () => { - if (typeof window === 'undefined') { - it('instantiates mock MutationObserver if not availble on window', () => { - expect(newMutationObserver(() => {}).observe).toBeDefined() - }) - } else { - it('instantiates from global MutationObserver if available', () => { - const oldMutationObserver = window.MutationObserver - window.MutationObserver = DummyClass - - try { - expect(newMutationObserver('foobar').args).toEqual('foobar') - } finally { - window.MutationObserver = oldMutationObserver - } - }) - } -}) diff --git a/src/events.js b/src/events.js index 1bc3c6ff..f6896c3c 100644 --- a/src/events.js +++ b/src/events.js @@ -1,3 +1,4 @@ +import {getWindowFromNode} from './helpers' const eventMap = { // Clipboard Events copy: { @@ -410,25 +411,6 @@ Object.keys(eventMap).forEach(key => { fireEvent[key] = (node, init) => fireEvent(node, createEvent[key](node, init)) }) -function getWindowFromNode(node) { - // istanbul ignore next I'm not sure what could cause the final else so we'll leave it uncovered. - if (node.defaultView) { - // node is document - return node.defaultView - } else if (node.ownerDocument && node.ownerDocument.defaultView) { - // node is a DOM node - return node.ownerDocument.defaultView - } else if (node.window) { - // node is window - return node.window - } else { - // no idea... - throw new Error( - `Unable to find the "window" object for the given node. fireEvent currently supports firing events on DOM nodes, document, and window. Please file an issue with the code that's causing you to see this error: https://github.com/testing-library/dom-testing-library/issues/new`, - ) - } -} - // function written after some investigation here: // https://github.com/facebook/react/issues/10135#issuecomment-401496776 function setNativeValue(element, value) { diff --git a/src/helpers.js b/src/helpers.js index d12e5e85..cc2321b3 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -1,5 +1,3 @@ -import MutationObserver from '@sheerun/mutationobserver-shim' - const globalObj = typeof window === 'undefined' ? global : window // Currently this fn only supports jest timers, but it could support other test runners in the future. @@ -41,16 +39,6 @@ const {clearTimeoutFn, setImmediateFn, setTimeoutFn} = runWithRealTimers( getTimeFunctions, ) -function newMutationObserver(onMutation) { - const MutationObserverConstructor = - typeof window !== 'undefined' && - typeof window.MutationObserver !== 'undefined' - ? window.MutationObserver - : MutationObserver - - return new MutationObserverConstructor(onMutation) -} - function getDocument() { /* istanbul ignore if */ if (typeof window === 'undefined') { @@ -58,10 +46,28 @@ function getDocument() { } return window.document } +function getWindowFromNode(node) { + // istanbul ignore next I'm not sure what could cause the final else so we'll leave it uncovered. + if (node.defaultView) { + // node is document + return node.defaultView + } else if (node.ownerDocument && node.ownerDocument.defaultView) { + // node is a DOM node + return node.ownerDocument.defaultView + } else if (node.window) { + // node is window + return node.window + } else { + // no idea... + throw new Error( + `Unable to find the "window" object for the given node. Please file an issue with the code that's causing you to see this error: https://github.com/testing-library/dom-testing-library/issues/new`, + ) + } +} export { + getWindowFromNode, getDocument, - newMutationObserver, clearTimeoutFn as clearTimeout, setImmediateFn as setImmediate, setTimeoutFn as setTimeout, diff --git a/src/wait-for-dom-change.js b/src/wait-for-dom-change.js index 566746e1..c3eec4cc 100644 --- a/src/wait-for-dom-change.js +++ b/src/wait-for-dom-change.js @@ -1,5 +1,5 @@ import { - newMutationObserver, + getWindowFromNode, getDocument, setImmediate, setTimeout, @@ -31,7 +31,8 @@ function waitForDomChange({ } return new Promise((resolve, reject) => { const timer = setTimeout(onTimeout, timeout) - const observer = newMutationObserver(onMutation) + const {MutationObserver} = getWindowFromNode(container) + const observer = new MutationObserver(onMutation) runWithRealTimers(() => observer.observe(container, mutationObserverOptions), ) diff --git a/src/wait.js b/src/wait.js index 86c7596d..197ee1fb 100644 --- a/src/wait.js +++ b/src/wait.js @@ -1,5 +1,5 @@ import { - newMutationObserver, + getWindowFromNode, getDocument, setImmediate, setTimeout, @@ -28,7 +28,8 @@ function wait( const overallTimeoutTimer = setTimeout(onTimeout, timeout) const intervalId = setInterval(checkCallback, interval) - const observer = newMutationObserver(checkCallback) + const {MutationObserver} = getWindowFromNode(container) + const observer = new MutationObserver(checkCallback) runWithRealTimers(() => observer.observe(container, mutationObserverOptions), )