Mocking document.createRange for jest

Kyle Kelley picture Kyle Kelley · Feb 13, 2017 · Viewed 7.6k times · Source

Jest, through JSDom I imagine, does not have document.createRange defined. How can I overwrite or provide this behavior?

The version we wrote for our custom JSDom + mocha setup (ran before all tests) looks like this:

global.Range = function Range() {};

const createContextualFragment = (html) => {
  const div = document.createElement('div');
  div.innerHTML = html;
  return div.children[0]; // so hokey it's not even funny
};

Range.prototype.createContextualFragment = (html) => createContextualFragment(html);

// HACK: Polyfil that allows codemirror to render in a JSDOM env.
global.window.document.createRange = function createRange() {
  return {
    setEnd: () => {},
    setStart: () => {},
    getBoundingClientRect: () => {
      return { right: 0 };
    },
    getClientRects: () => [],
    createContextualFragment,
  };
};

Is there a way to provide this to jest?

Answer

jjbskir picture jjbskir · Sep 10, 2019

I added the polyfill in setupTests.js as described in this thread.

if (window.document) {
    window.document.createRange = () => ({
        setStart: () => {},
        setEnd: () => {},
        commonAncestorContainer: {
            nodeName: 'BODY',
            ownerDocument: document,
        },
    });
}

For it to work with TypeScript I had to add // @ts-ignore above commonAncestorContainer.