ReferenceError: DOMRect is not defined

Viewed 1035
  1. jest config: testEnvironment: 'jsdom'

  2. sample code:

    it('test', async () => {
     await act(async () => {
       await asyncRender(
         <Popover isOpen position={new DOMRect(10, 10)}>
           <Button text="Child Button" />
         </Popover>
       );
     });
    
     expect(...);
    });
    
  3. Get the error information, ReferenceError: DOMRect is not defined.

Anyone has any suggestions about this issue?

1 Answers

Issue is jsdom does not implement the DOMRect class. If you check the source code you'll see it implements getClientBoundingRect by returning a plain object with properties like a DOMRect. But no class anywhere.

Solutions are

A) open a issue at jsdom repo and hope they'll add it

B) work around it by not using DOMRect at all: In your example, passing a {x:10,y:10} object may work fine

C) create a custom DOMRect class within jest environment. There are (said to be) various ways to do this. What worked for me (jest 27+) was to create a file that provides a jsdom environment + a custom DOMRect mock:

const JsDomEnv = require('jest-environment-jsdom');

class CustomEnvironment extends JsDomEnv {

  async setup() {
    await super.setup();
    this.global.DOMRect = class DOMRect {
        bottom:number=0;
        left:number=0;
        right:number=0;
        top:number=0;
        constructor (public x=0, public y=0, public width=0, public height=0) {};
        static fromRect(other?: DOMRectInit): DOMRect {
            return new DOMRect(other.x,other.y,other.width,other.height)
        }
        toJSON() {
            return JSON.stringify(this)
        }
    }
  }

}

module.exports = CustomEnvironment;

and then pass the file path to jest config: testEnvironment:'./custom-env.ts' instead of 'jsdom'.

Related