React-testing-library: TypeError: MutationObserver is not a constructor

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

I have a test like

import React from "react";
import { render, screen } from "@testing-library/react";
import Countdown from "./Countdown";
describe('Countdown', () => {
    test("renders Countdown without crashing", async () => {
        const { container, getByText } = render(<Countdown timeTillDate="07 08 2020, 6:00 am" timeFormat="MM DD YYYY, h:mm a" />);
        await screen.findByText('Countdown');
        // render should show the title
        expect(getByText(/Countdown/)).toBeInTheDocument();
        expect(container).toContainElement(document.querySelector('h1'));
    });
});

This test fails with an exception

TypeError: MutationObserver is not a constructor

This same issue was raised and closed because a polyfill solved the problem. But it was also mentioned that with the latest code a polyfill was not needed. The web application that I am using was originally started with Create-React-App. Here is a snippet of my package.json to get an idea of the versions I am using:

    "@testing-library/dom": "^7.20.0",
    "@testing-library/jest-dom": "^5.11.0",
    "@testing-library/react": "^10.4.3",
    "@testing-library/user-event": "^12.0.11",
...
    "cross-env": "6.0.3",
...
    "ts-jest": "^26.1.1",
    "typescript": "3.9.6"

With these versions I shouldn't need a polyfill right?

Thank you.

Most helpful comment

For other people facing the "MutationObserver is not a constructor" issue, It took me some time to figure out what's the basic solution, so I'm posting this because it might save you some time.

go to this part in the documentation: https://testing-library.com/docs/react-testing-library/setup#jest-24-or-lower-and-defaults

react-scripts includes a dependency called jest-environment-jsdom-fourteen.

All I had to do to get rid of the MutationObserver problem, is to run the test using a jest option: --env jest-environment-jsdom-fourteen

All 24 comments

Is this the issue you were referring to? https://github.com/testing-library/react-testing-library/issues/730

For #730, the issue was that two different dependencies both specified different versions of jsdom. It seems like that's a possibilty here as well. If you'd like to troubleshoot this hypothesis, you can poke around your package-lock.json/yarn.lock and try to figure out what versions of jsdom are being specified.

As for polyfilling... 🤔 I suspect your application/dev env is polyfilling MutationObserver appropriately, but it's plausible that polyfilling is not applied in the same way (or at all!) to your test environment. That's another avenue you could explore!

This issue seems pretty common, it might be worth a dedicated spot in the docs (or even a custom error message?)

Also it's easier to check duplicate versions with npm ls jsdom or yarn why jsdom. Make sure you're using the same package manager you install the project with or the result may be incorrect.

Thank for the tip. Here is what I found out. Unfortunately it seems you
know more about this than I. There are indeed more than one version of
jsdom but I am not sure what to do to fix it: Here is the output:

PS> yarn why jsdom
yarn why v1.22.4
[1/4] Why do we have the module "jsdom"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "[email protected]"
info Reasons this module exists

  • "jest-environment-jsdom-sixteen" depends on it
  • Hoisted from "jest-environment-jsdom-sixteen#jsdom"
    info Disk size without dependencies: "5.17MB"
    info Disk size with unique dependencies: "10.4MB"
    info Disk size with transitive dependencies: "22.16MB"
    info Number of shared dependencies: 49
    => Found "jest-environment-jsdom-fourteen#[email protected]"
    info This module exists because
    "react-scripts#jest-environment-jsdom-fourteen" depends on it.
    info Disk size without dependencies: "3.01MB"
    info Disk size with unique dependencies: "7.97MB"
    info Disk size with transitive dependencies: "19.73MB"
    info Number of shared dependencies: 49
    => Found "jest-environment-jsdom#[email protected]"
    info This module exists because
    "react-scripts#jest#jest-cli#jest-config#jest-environment-jsdom" depends on
    it.
    info Disk size without dependencies: "2.93MB"
    info Disk size with unique dependencies: "7.8MB"
    info Disk size with transitive dependencies: "19.46MB"
    info Number of shared dependencies: 48

The polyfill problem was resolved for me with
"test": "cross-env CI=true react-scripts test
--env=jest-environment-jsdom-sixteen --coverage"

But apparently it doesn't work in all cases.

On Sat, Jul 4, 2020 at 5:00 PM Nick McCurdy notifications@github.com
wrote:

Also it's easier to check duplicate versions with npm ls jsdom or yarn
why jsdom. Make sure you're using the same package manager you install
the project with or the result may be incorrect.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/testing-library/react-testing-library/issues/731#issuecomment-653817081,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3TXR5X7YRZPJNF5D6LRZ6RBBANCNFSM4OQJYFQA
.

There are three versions of jsdom (starting with => Found), all installed as dependencies within react-scripts. Try upgrading the package.

Nick,,

From package.json I am using version 3.4.1 and that is that latest version
of react-scripts. It doesn't look like I can upgrade react-scripts.

Kevin

On Sat, Jul 4, 2020 at 11:22 PM Nick McCurdy notifications@github.com
wrote:

There are three versions of jsdom (starting with => Found), all installed
as dependencies within react-scripts. Try upgrading the package.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/testing-library/react-testing-library/issues/731#issuecomment-653840352,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3T2IXSQHCW6HHV7KEDRZ75ZLANCNFSM4OQJYFQA
.

You might be able to upgrade the other dependencies with yarn upgrade. If that doesn't work, it would be helpful to have a Code Sandbox of this issue. https://codesandbox.io/s/new

Could you please try to update jest-config to @^26.1.0 ?

I don't see jest-config in in the list of dependencies. Should it be added?

This is curious. When I have a node server the addition of
"jest-environment-jsdom-sixteen" is required to make this error go away.
But with the same app translated to a Gatsby environment the error no
longer occurs so there is no need to install this package.

On Tue, Jul 14, 2020 at 12:25 AM Andon notifications@github.com wrote:

Kevin try this:
https://stackoverflow.com/questions/61036156/react-typescript-testing-typeerror-mutationobserver-is-not-a-constructor

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/testing-library/react-testing-library/issues/731#issuecomment-657974544,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3WWLSSZDJ5RTOCSME3R3PT5VANCNFSM4OQJYFQA
.

temp solution but I've added the MutationObserver package to the devDependencies and adding it to the global scope like this before running tests:

import MutationObserver from "mutation-observer";
global.MutationObserver = MutationObserver;

For other people facing the "MutationObserver is not a constructor" issue, It took me some time to figure out what's the basic solution, so I'm posting this because it might save you some time.

go to this part in the documentation: https://testing-library.com/docs/react-testing-library/setup#jest-24-or-lower-and-defaults

react-scripts includes a dependency called jest-environment-jsdom-fourteen.

All I had to do to get rid of the MutationObserver problem, is to run the test using a jest option: --env jest-environment-jsdom-fourteen

Having the same problem having latest packages installed, none of the solutions seem to work.

Having the same problem having latest packages installed, none of the solutions seem to work.

@rmnbod can you please show us your test scripts and package.json? We'll be able to have a look..

Having the same problem having latest packages installed, none of the solutions seem to work.

@rmnbod can you please show us your test scripts and package.json? We'll be able to have a look..

...
"react-scripts": "^3.4.3",`
"@testing-library/jest-dom": "^5.11.3",  
"@testing-library/react": "^10.4.8",  
"@testing-library/user-event": "^12.1.1",  
"ts-jest": "^26.2.0",  
"typescript": "^3.9.7"  
...
````

```javascript
import React from "react";
import { Provider } from "react-redux";
import { BrowserRouter } from "react-router-dom";
import Dashboard from "../index";
import store from '../../../app/store'
import { screen, render } from "@testing-library/react";

jest.mock("../../../services/api/api-client-ts")

it('updates user data', async () => {
    render(
        <Provider store={store}>
            <BrowserRouter>
                <Dashboard/>
            </BrowserRouter>
        </Provider>
    )

    expect(await screen.findByText('fn ln'))
})

Fails with TypeError: MutationObserver is not a constructor exception.

At the end though managed it to work with MutationObserver polyfill, react-scripts test --env=jest-environment-jsdom-sixteen is of no avail.

At the end though managed it to work with MutationObserver polyfill, react-scripts test --env=jest-environment-jsdom-sixteen is of no avail.

Sorry, I didn't understand that, you're saying it doesn't work?

As you can see in @kentcdodds's comment here, you can either shim it yourself our use jest-environment-jsdom-sixteen..

Also react-scripts v4 is in alpha right now and it works without any extra effort FYI. It's awesome.

Can this be closed? It seems like the known issues in this thread have been solved.

Yes. Thank you.

On Mon, Aug 24, 2020 at 4:31 AM Nick McCurdy notifications@github.com
wrote:

>
>

Can this be closed? It seems like the known issues in this thread have
been solved.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/testing-library/react-testing-library/issues/731#issuecomment-679018261,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3VVK2CDZMUA6NUL2VTSCIXQRANCNFSM4OQJYFQA
.

The solution of "test": "react-scripts test --env=jest-environment-jsdom-sixteen", works fine for Mutation Observer error but if we use it with --coverage flag as
"test": "react-scripts test --env=jest-environment-jsdom-sixteen --coverage",
it gives errors as

 console.error node_modules/jest-environment-jsdom-sixteen/node_modules/jsdom/lib/jsdom/virtual-console.js:29
      Error: Uncaught [Error: App(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.]

@paramsinghvc does this happen for the same test that passed without the --coverage flag? The error doesn't seem coverage related to me..
If it does, can you please try and upgrade react-scripts to next and let us know if this still reproduces?

Without the --coverage flag, it works fine. I figured out a fix, by using react-scripts test --env=jsdom-fourteen --coverage instead of sixteen.

Its October.
Fix according to developer and seems to work fine in my latest CRA project
npm install react-scripts@next

"MutationObserver need jsdom 16

in v4 of react-scripts uses that by default"

You can also update testing library with npm-check-updates (works for yarn too )

npm install -g npm-check-updates
ncu ( see what deps can be updated )
ncu -u ( update said deps in package.json )
yarn or npm install 

https://github.com/raineorshine/npm-check-updates

As this one doesn't seem to be mentioned here yet, I took my fix from an answer on this issue:
https://github.com/testing-library/dom-testing-library/issues/477#issuecomment-629183432

Install jest-environment-jsdom:

npm i -D jest-environment-jsdom

Add to package.json:

"resolutions": {
  "jest-environment-jsdom": "^26.0.1"
}
Was this page helpful?
0 / 5 - 0 ratings