hotwired / stimulus

A modest JavaScript framework for the HTML you already have
https://stimulus.hotwired.dev/
MIT License
12.74k stars 427 forks source link

ReferenceError: MutationObserver is not defined #130

Closed chocnut closed 6 years ago

chocnut commented 6 years ago

I'm creating a test for a controller. But got this error when I do Application.start(). I'm using jest for testing.

Here's the code

import {Application} from 'stimulus'
import SomeController from '../controllers/some_controller'

describe('SomeController', () => {
  beforeEach(() => {
    const stimulusApp = Application.start()
    stimulusApp.register('some', SomeController)
  })
})
skyksandr commented 6 years ago

I would suggest to have a look here: https://github.com/stimulusjs/stimulus/tree/master/packages/%40stimulus/mutation-observers

javan commented 6 years ago

You'll need to run your tests in a browser or a simulated environment with MutationObserver support. I believe jest uses jsdom by default, which doesn't appear to support it: https://github.com/jsdom/jsdom/issues/639.

chocnut commented 6 years ago

thanks @javan make sense.

damonbauer commented 5 years ago

For anyone who comes across this:

Add mutationobserver-shim to your project:

yarn add mutationobserver-shim --dev

Include it in Jest setup. In your jest.config.js, update setupFilesAfterEnv array to include a setup file, like so:

// jest.config.js

setupFilesAfterEnv: [
  '<rootDir>/setup-jest.js'
],

Then, in the setup file, import the shim:

// setup-jest.js

import 'mutationobserver-shim';
Matt-Yorkley commented 2 years ago

In case anyone lands here looking for test setup tips with StimulusJS and Jest; you don't need that MutationObserver shim anymore, newer versions of JSDOM support it by default.

tf-matak commented 1 year ago

Works in my locale :

import SubmissionController from './submission_controller';
import { Application } from '@hotwired/stimulus';
import window from '@testing-library/jest-dom'

describe('SubmissionController', () => {

  beforeEach(() => {
    document.body.innerHTML = '<div data-controller="submission"/>';
  });

  beforeAll(() => {
    window.Stimulus = Application.start();
    window.Stimulus.register('submission', SubmissionController);
  });

  it('Should be empty', () => {
    const el = document.querySelector('[data-controller="submission"]');
    expect(el).toHaveTextContent('');
    expect(el.innerHTML).toMatch('');
  });
});