smastrom / react-rating

⭐ Zero-dependency, highly customizable rating component for React.
https://reactrating.netlify.app
MIT License
346 stars 6 forks source link

Component error when using react testing library #15

Closed jebbard closed 1 year ago

jebbard commented 1 year ago

I currently cannot use the Rating component with the react testing library. Here is a minimal example:

import { Rating } from "@smastrom/react-rating";
import { render } from '@testing-library/react';

describe('Rating', () => {
    test('Fails', async () => {
        render(
            <Rating data-testid={'X'} isDisabled={false} style={{ maxWidth: 100 }} items={5}
                value={0} />
        );
    }, 10000);
});

If I run it with yarn test Rating.test.tsx, I get following error:

TypeError: h.current.getBBox is not a function

       5 | describe('Rating', () => {
       6 |     test('Fails', async () => {
    >  7 |         render(
         |               ^
       8 |             <Rating data-testid={'X'} isDisabled={false} style={{ maxWidth: 100 }} items={5}
       9 |                 value={0} />
      10 |         );

      at node_modules/@smastrom/react-rating/dist/index.js:1:1735
      at commitHookEffectListMount (node_modules/react-dom/cjs/react-dom.development.js:23150:26)
      at commitLayoutEffectOnFiber (node_modules/react-dom/cjs/react-dom.development.js:23273:15)
      at commitLayoutMountEffects_complete (node_modules/react-dom/cjs/react-dom.development.js:24688:9)
      at commitLayoutEffects_begin (node_modules/react-dom/cjs/react-dom.development.js:24674:7)
      at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:24612:3)
      at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:26823:5)
      at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:26682:5)
      at finishConcurrentRender (node_modules/react-dom/cjs/react-dom.development.js:25981:9)
      at performConcurrentWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:25809:7)
      at flushActQueue (node_modules/react/cjs/react.development.js:2667:24)
      at act (node_modules/react/cjs/react.development.js:2582:11)
      at node_modules/@testing-library/react/dist/act-compat.js:63:25
      at renderRoot (node_modules/@testing-library/react/dist/pure.js:159:26)
      at render (node_modules/@testing-library/react/dist/pure.js:246:10)
      at Object.<anonymous> (src/test/org/mycollection/games/client/widgets/commonviews/Rating.test.tsx:7:15)
      at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
      at runJest (node_modules/@jest/core/build/runJest.js:404:19)
      at _run10000 (node_modules/@jest/core/build/cli/index.js:320:7)
      at runCLI (node_modules/@jest/core/build/cli/index.js:173:3)

What do I need to do to use it with react testing library?

smastrom commented 1 year ago

Hi Jans, this is expected. getBBox is the Web API this package uses to compute the final bounding box of each rating item.

Such Web API isn't supported in Node environments like jest-dom or happy-dom and needs to be stubbed unless you prefer to run the tests in a real browser (using Cypress, Playwright, etc.).

I've used react-testing-library as well, and that's the mock implementation:

beforeEach(() => {
   window.SVGElement.prototype.getBBox = () => ({
      x: 0,
      y: 0,
      width: 0,
      height: 0,
   })
})

afterEach(() => {
   delete window.SVGElement.prototype.getBBox
})

https://github.com/smastrom/react-rating/blob/main/tests/dom/setupTests.ts

Also, the data-test-id you added to the Rating component won't be added to the root element so you might want to select it using this class: .rr--group.