Skip to content

Commit

Permalink
feat: remove mutationobserver shim (#457)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Kent C. Dodds authored and kentcdodds committed Mar 12, 2020
1 parent 4c0193c commit ab3e691
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 63 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
27 changes: 1 addition & 26 deletions src/__tests__/helpers.js
Original file line number Diff line number Diff line change
@@ -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
}
})
}
})
20 changes: 1 addition & 19 deletions src/events.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {getWindowFromNode} from './helpers'
const eventMap = {
// Clipboard Events
copy: {
Expand Down Expand Up @@ -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) {
Expand Down
32 changes: 19 additions & 13 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -41,27 +39,35 @@ 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') {
throw new Error('Could not find default container')
}
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,
Expand Down
5 changes: 3 additions & 2 deletions src/wait-for-dom-change.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
newMutationObserver,
getWindowFromNode,
getDocument,
setImmediate,
setTimeout,
Expand Down Expand Up @@ -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),
)
Expand Down
5 changes: 3 additions & 2 deletions src/wait-for.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
newMutationObserver,
getWindowFromNode,
getDocument,
setImmediate,
setTimeout,
Expand Down Expand Up @@ -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),
)
Expand Down

0 comments on commit ab3e691

Please sign in to comment.