Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"ResizeObserver is not defined" error when running Jest #40

Closed
remidej opened this issue May 8, 2020 · 22 comments
Closed

"ResizeObserver is not defined" error when running Jest #40

remidej opened this issue May 8, 2020 · 22 comments

Comments

@remidej
Copy link

remidej commented May 8, 2020

Hello 👋

Using useResizeObserver crashes my app's tests. Jest uses JSDom, which apparently doesn't support the ResizeObserver API.

I know we can detect when Jest is running, but React doesn't support conditionally calling hooks, so I don't know how to prevent Jest from crashing. I think the fix has to be done inside the hook.

@ZeeCoder
Copy link
Owner

ZeeCoder commented May 8, 2020

Hey 👋

There must be some way to patch the test environment.
I'm quite certain that the answer won't lie in detecting the test environment within the hook. 😅

@seloner
Copy link

seloner commented Jun 12, 2020

I am having the same issue with jest.

@ZeeCoder
Copy link
Owner

I'll be happy to add a section to the Readme if someone comments a solution.

@2gnc
Copy link

2gnc commented Jun 15, 2020

I used polyfilled version, import useResizeObserver from "use-resize-observer/polyfilled"; because of issues in IOs 12. Maybe this will help.

@seloner
Copy link

seloner commented Jun 16, 2020

I managed to bypass the issue like that.

import React from 'react';

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

import { AuthProvider } from '../context/AuthProvider';
import LoginPage from './LoginPage';

const pass = 'pass';
const user = 'user';
class ResizeObserver {
  observe() {}
  unobserve() {}
}
describe('loginpage ', () => {
  window.ResizeObserver = ResizeObserver;
  test('should update username and password', async () => {
    const { findByPlaceholderText } = render(
      <AuthProvider>
        <LoginPage />
      </AuthProvider>,
    );
    const username = await findByPlaceholderText('Your username...');
    const password = await findByPlaceholderText('Password...');
    fireEvent.change(username, { target: { value: user } });
    fireEvent.change(password, { target: { value: pass } });
    expect(username.value).toBe(user);
    expect(password.value).toBe(pass);
  });
});

@tay1orjones
Copy link

tay1orjones commented Jul 21, 2020

I work on a component library where we use the hook to enhance component functionality behind a prop. So if hasResize=false, we don't use the values provided from the hook. The library does not provide a polyfill for the same reasons you list in the readme.

The hook can't be placed behind a browser support conditional - so even when hasResize=false is false, the hook throws an error in environments where RO is not supported. This effectively requires our consumers to provide an RO polyfill when they may not even have configured props to use the hook.

The only solution for us is to have two components, Component and ComponentWithResize. Render one or the other depending on prop and support.

A check for RO support in the hook would be very inexpensive and fix these issues.

@ZeeCoder
Copy link
Owner

@tay1orjones that sounds to me like a different issue.
For that I think the hook could be smart enough not to create a ResizeObserver instance when there's nothing to observe.
So then when hasResize=false in your case, you would simply not pass in anything to the hook to observe, and it would do nothing.

@GreenGremlin
Copy link

I ran into the same problem, in that I'd like to use this hook with graceful degradation for IE. I put up #42 which does just this, though it still needs some tests added.

@GreenGremlin
Copy link

GreenGremlin commented Jul 22, 2020

I added a test to #42, it should be ready to go.

@tay1orjones
Copy link

@ZeeCoder yep, thats fair. #42 will solve that for us, thanks @GreenGremlin!

@aricallen
Copy link

In case it helps someone, I found that you can mock module to use polyfilled when in tests with a few lines. This will at least get around the undefined error. It won't add any functionality tho.

jest.mock('use-resize-observer', () => {
  return jest.requireActual('use-resize-observer/polyfilled');
});

@ZeeCoder
Copy link
Owner

@tay1orjones the latest alpha release (https://github.com/ZeeCoder/use-resize-observer/releases/tag/v6.2.0-alpha.1) will not instantiate the ResizeObserver, until there's an actual element it receives, so it should handle your case.

I still think the original issue with Jest reported here is not something the library needs to adapt to, but rather the environment needs to be mocked or polyfilled.
Also see the documentation for other options to opt out of RO instantiation altogether if needed.:
https://github.com/ZeeCoder/use-resize-observer#opting-out-of-or-delaying-resizeobserver-instantiation

@peterkrieg
Copy link

peterkrieg commented Oct 19, 2020

Another possible mock solution - create a minimal mock of useResizeObserver which at least returns an object with width

// JSDom (which is used by jest) does not implement layout/rendering.
// we create this mock to simply simulate a desktop view with a width of 1000
function useResizeObserverMock() {
  return {
    width: 1000,
  };
}

jest.mock('use-resize-observer', () => useResizeObserverMock);

@sawsanCS
Copy link

adding this line of code in the testing file fixed the error for me
global.ResizeObserver = require('resize-observer-polyfill')

@Francois-Esquire
Copy link

For those looking for a more configurable solution, the below worked for me:

jest.config.js

module.exports = {
  moduleNameMapper: {
    'use-resize-observer': 'use-resize-observer/polyfilled'
  }
};

@VladislavVB
Copy link

Solution for vitest
write in the file with the test at the highest level of nesting

const ResizeObserverMock = vi.fn(() => ({
  observe: vi.fn(),
  unobserve: vi.fn(),
  disconnect: vi.fn()
}))

vi.stubGlobal('ResizeObserver', ResizeObserverMock)

@BhagyashreeCH
Copy link

BhagyashreeCH commented Apr 27, 2023

I managed to bypass the issue like that.

import React from 'react';

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

import { AuthProvider } from '../context/AuthProvider';
import LoginPage from './LoginPage';

const pass = 'pass';
const user = 'user';
class ResizeObserver {
  observe() {}
  unobserve() {}
}
describe('loginpage ', () => {
  window.ResizeObserver = ResizeObserver;
  test('should update username and password', async () => {
    const { findByPlaceholderText } = render(
      <AuthProvider>
        <LoginPage />
      </AuthProvider>,
    );
    const username = await findByPlaceholderText('Your username...');
    const password = await findByPlaceholderText('Password...');
    fireEvent.change(username, { target: { value: user } });
    fireEvent.change(password, { target: { value: pass } });
    expect(username.value).toBe(user);
    expect(password.value).toBe(pass);
  });
});

Hi,
I was getting "please install a polyfill for ResizeObserver" after migrating jest26 to jest28 version in angular application. We are not using ResizeObserver in our application but I am not sure whether any dependency with NGXCHARTS, So I was getting this error suddenly.

I have tried above solution of bypassing, it worked thank you.

class ResizeObserver {
observe() {}
unobserve() {}
disconnect() {}
}

describe('Component', () => {
window.ResizeObserver = ResizeObserver;
})

@rodentskie
Copy link

adding this line of code in the testing file fixed the error for me global.ResizeObserver = require('resize-observer-polyfill')

import ResizeObserver from 'resize-observer-polyfill';
global.ResizeObserver = ResizeObserver;

@kiranlpatil
Copy link

adding this line of code in the testing file fixed the error for me global.ResizeObserver = require('resize-observer-polyfill')

import ResizeObserver from 'resize-observer-polyfill';
global.ResizeObserver = ResizeObserver;

Thanks, It really works. I am rendering ReactFlow in JEST. Surprisingly it works.

@abuzain432432
Copy link

global.ResizeObserver = class {
observe() {}
unobserve() {}
disconnect() {}
};
This code solved my issue

@lohnsonok
Copy link

lohnsonok commented Apr 28, 2024

adding this line of code in the testing file fixed the error for me global.ResizeObserver = require('resize-observer-polyfill')

import ResizeObserver from 'resize-observer-polyfill';
global.ResizeObserver = ResizeObserver;

directy in jest.setup.ts works well 👍

@sanchitos
Copy link

sanchitos commented Jun 13, 2024

npm i -D resize-observer-polyfill

In setupTests.ts

import ResizeObserver from 'resize-observer-polyfill';
global.ResizeObserver = ResizeObserver;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests