From ab3e69163ddcb55b3fb74e93a7beb9d2b50e106d 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-for.js | 5 +++-- 6 files changed, 27 insertions(+), 63 deletions(-) diff --git a/package.json b/package.json index 162ea74b..b559eab6 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 048e462e..1766937d 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-for.js b/src/wait-for.js index c2b51adc..7829b817 100644 --- a/src/wait-for.js +++ b/src/wait-for.js @@ -1,5 +1,5 @@ import { - newMutationObserver, + getWindowFromNode, getDocument, setImmediate, setTimeout, @@ -28,7 +28,8 @@ function waitFor( 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), )