React-testing-library: asFragment throws "TypeError: document.createRange(...).createContextualFragment is not a function"

Created on 1 Jul 2020  ·  4Comments  ·  Source: testing-library/react-testing-library

Relevant code or config:

import React from 'react';
import {render} from '@testing-library/react';

describe('asFragment', () => {
  it('returns a fragment without throwing', () => {
    const {asFragment} = render(<div>I should not throw</div>);
    expect(asFragment()).toMatchSnapshot();
  });
});
❯ npx jest createcontextualfragment
 FAIL  src/app/createContextualFragment.test.js
  ● asFragment › returns a fragment without throwing

    TypeError: document.createRange(...).createContextualFragment is not a function

       5 |   it('returns a fragment without throwing', () => {
       6 |     const {asFragment} = render(<div>I should not throw</div>);
    >  7 |     expect(asFragment()).toMatchSnapshot();
         |            ^
       8 |   });
       9 | });
      10 |

      at asFragment (node_modules/@testing-library/react/dist/pure.js:120:39)
      at Object.<anonymous> (src/app/createContextualFragment.test.js:7:12)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.846 s, estimated 2 s
Ran all test suites matching /createcontextualfragment/i.

What you did:

I'm trying to use snapshot matching with a react component.

What happened:

asFragment throws TypeError: document.createRange(...).createContextualFragment is not a function as seen in the sample test and jest execution above.

Reproduction:

I attempted to recreate the issue in the provided Codesandbox, but it appears that snapshots aren't working the same way in that environment. Here's the fork in case it helps: https://codesandbox.io/s/react-testing-library-demo-xpj4u?file=/src/__tests__/hello.js

Problem description:

I'd like to use snapshot matching for my react components, but asFragment throws and prevents tests from executing and passing.

Suggested solution:

As discovered below, my jest config overrides document.createRange with an outdated polyfill that doesn't provide createContextualFragment. Removing this polyfill fixed this error and allowed asFragment to work as expected.

Most helpful comment

Oh no! When you asked to see my config, I hesitated because I didn't want to introduce any red herrings from all of the other config cruft that has built up in this app. I figured it was worth another look, though.

Lo and behold I found that we are overriding document.createRange with an outdated polyfill that doesn't have createContextualFragment in jest.setup.js. Removing this polyfill allowed asFragment to work as expected. Apologies for the false alarm, and thanks again for taking the time to investigate.

All 4 comments

Hi @tupton, I've tried to reproduce this in my local env but without any success.
What jest-environment-jsdom are you using? can you please attach your jest config? Are you using CRA or something else?

@tupton Can you check the extension of your files? If it's exactly like in the codesandbox, you need to change them.

hello.js > hello.jsx
__tests__/hello.js > __tests__/hello.test.jsx

Thanks for taking a look. I see this in my large, non-CRA web app in which I'm trying to introduce testing-library. I'll try to get a repo set up with the exact versions of other dependencies that I'm using and see if I can reproduce there.

Requested versions and config follows.

❯ npm ls jest-environment-jsdom
[email protected] /Users/tupton/code/frontend-web
└─┬ [email protected]
  └─┬ @jest/[email protected]
    └─┬ [email protected]
      └── [email protected]
❯ npm ls jest-environment-jsdom-sixteen
[email protected] /Users/tupton/code/frontend-web
└── [email protected]
  "jest": {
    "verbose": false,
    "testURL": "http://localhost/",
    "setupFiles": [
      "<rootDir>/jest.setup.js"
    ],
    "setupFilesAfterEnv": [
      "<rootDir>/jest.setupAfterEnv.js"
    ],
    "transformIgnorePatterns": [
      "<rootDir>/node_modules/(?!lodash)",
      "/build/"
    ],
    "moduleFileExtensions": [
      "js",
      "json",
      "es6"
    ],
    "modulePaths": [
      "test/config"
    ],
    "moduleNameMapper": {
      "App/([^\\.]*)$": "<rootDir>/src/app/$1",
      "(^[a-zA-Z]+\\.mock\\.json)$": "<rootDir>/__mocks__/data/$1",
      "\\.(css|scss)$": "<rootDir>/test/config/styleMock.js",
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/config/fileMock.js",
      "mocks/data/(.*\\.json)$": "<rootDir>/__mocks__/data/$1"
    },
    "snapshotSerializers": [
      "enzyme-to-json/serializer"
    ],
    "testEnvironment": "jest-environment-jsdom-sixteen"
  },

Can you check the extension of your files?

We only use .js files in this app – I don't think using .jsx is a path we want to go down, and I think things are configured so that .js files will work just fine.

It's probably also worth noting that I worked around this for now by taking a snapshot of container as returned by render. I'm unsure if that's against best practices or not, but it seems to work as expected.

Oh no! When you asked to see my config, I hesitated because I didn't want to introduce any red herrings from all of the other config cruft that has built up in this app. I figured it was worth another look, though.

Lo and behold I found that we are overriding document.createRange with an outdated polyfill that doesn't have createContextualFragment in jest.setup.js. Removing this polyfill allowed asFragment to work as expected. Apologies for the false alarm, and thanks again for taking the time to investigate.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bdauria picture bdauria  ·  4Comments

alejandronanez picture alejandronanez  ·  4Comments

albert-olive picture albert-olive  ·  3Comments

nagacoder picture nagacoder  ·  3Comments

good-idea picture good-idea  ·  4Comments