Jest errors with solutions

kkazala

Kinga

Posted on July 20, 2023

Jest errors with solutions

You may find example SPFx solution on GitHub

1. Parsing error: "parserOptions.project"

Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: test\components\HelloWorld.test.tsx.
The file must be included in at least one of the projects provided.
Enter fullscreen mode Exit fullscreen mode

Solution

Add .eslintignore file to the root of your project:

.eslintignore

.eslintrc.js

**/test/*.ts
**/test/*.tsx

*.test.ts
*.test.tsx
Enter fullscreen mode Exit fullscreen mode

2. Property 'toBeInTheDocument' does not exist...

error TS2339: Property 'toBeInTheDocument' does not exist on type 'JestMatchers<HTMLElement>'.
Enter fullscreen mode Exit fullscreen mode

Solution

Add import '@testing-library/jest-dom';

HelloWorld.test.tsx

import '@testing-library/jest-dom';
import { RenderResult, render } from '@testing-library/react';
import React from "react";
import HelloWorld from "../../src/webparts/helloWorld/components/HelloWorld";

describe("HelloWorld.tsx", () => {
    it("should render correctly", async () => {

        let helloWorld: RenderResult =  render(<HelloWorld  description="" isDarkTheme={false} environmentMessage="" hasTeamsContext={false} userDisplayName="" />);
        expect(helloWorld.getByTestId('helloWorld')).toBeInTheDocument();

    });
});
Enter fullscreen mode Exit fullscreen mode

3. Cannot read properties of undefined (reading 'createElement')

    TypeError: Cannot read properties of undefined (reading 'createElement')

       7 |     it("should render correctly", async () => {
       8 |
    >  9 |         let helloWorld: RenderResult =  render(<HelloWorld  description="" isDarkTheme={false} environmentMessage="" hasTeamsContext={false} userDisplayName="" />);
         |                                                ^
      10 |         expect(helloWorld.getByTestId('helloWorld')).toBeInTheDocument();
      11 |
      12 |     });
Enter fullscreen mode Exit fullscreen mode

Solution

Add "esModuleInterop": true, to compilerOptions in tsconfig.json

tsconfig.json

{
  "extends": "./node_modules/@microsoft/rush-stack-compiler-4.5/includes/tsconfig-web.json",
  "compilerOptions": {
    "target": "es5",
    "esModuleInterop": true,
    //...
}
Enter fullscreen mode Exit fullscreen mode

4. SyntaxError: Invalid or unexpected token

    Details:

C:\GitHub\Archive\spfx1.17.4_pnpm\src\webparts\helloWorld\components\HelloWorld.module.scss:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){@import '~@fluentui/react/dist/sass/References.scss';
                                                                                      ^
    SyntaxError: Invalid or unexpected token

      1 | import { escape } from '@microsoft/sp-lodash-subset';
      2 | import * as React from 'react';
    > 3 | import styles from './HelloWorld.module.scss';
Enter fullscreen mode Exit fullscreen mode

Solution

Add "\\.(css|scss)": "identity-obj-proxy" to moduleNameMapper in package.json

package.json

{
  //...
  "jest": {
    "moduleNameMapper": {
      "\\.(css|scss)": "identity-obj-proxy"
    }
}
Enter fullscreen mode Exit fullscreen mode

5. SyntaxError: Invalid or unexpected token


    Details:

    C:\GitHub\Archive\spfx1.17.4_pnpm\src\webparts\helloWorld\assets\welcome-light.png:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){PNG


    SyntaxError: Invalid or unexpected token

      18 |       <section className={`${styles.helloWorld} ${hasTeamsContext ? styles.teams : ''}`} data-testid="helloWorld" >
      19 |         <div className={styles.welcome}>
    > 20 |           <img alt="" src={isDarkTheme ? require('../assets/welcome-dark.png') : require('../assets/welcome-light.png')} className={styles.welcomeImage} />
Enter fullscreen mode Exit fullscreen mode

Solution

Media files aren't being mocked.

Create assetsTransformer.js in the root of your project.

assetsTransformer.js

const path = require('path');

module.exports = {
  process(src, filename, config, options) {
    return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
  },
};
Enter fullscreen mode Exit fullscreen mode

Add "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/assetsTransformer.js" to moduleNameMapper in package.json

package.json

{
  //...
  "jest": {
    "moduleNameMapper": {
      //...
      "\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)": "<rootDir>/assetsTransformer.js"
    }
}
Enter fullscreen mode Exit fullscreen mode

Credit where credit is due: github issue#2663

6. Cannot find module 'HelloWorldWebPartStrings' from 'src/webparts/helloWorld/components/HelloWorld.tsx'

Cannot find module 'HelloWorldWebPartStrings' from 'src/webparts/helloWorld/components/HelloWorld.tsx'

    Require stack:
      src/webparts/helloWorld/components/HelloWorld.tsx
      test/components/HelloWorld.test.tsx

      1 | import { escape } from '@microsoft/sp-lodash-subset';
    > 2 | import strings from 'HelloWorldWebPartStrings';
Enter fullscreen mode Exit fullscreen mode

Solution

Add "HelloWorldWebPartStrings": "<rootDir>/src/webparts/helloWorld/loc/myStrings.d.ts" to moduleNameMapper in package.json

package.json

{
  //...
  "jest": {
    "moduleNameMapper": {
      //...
      "HelloWorldWebPartStrings": "identity-obj-proxy"
    }
}
Enter fullscreen mode Exit fullscreen mode

And mock your strings as a constant:

HelloWorld.test.tsx

jest.mock('HelloWorldWebPartStrings', () => {
    return {
        PropertyPaneDescription: "Description",
        //...
    }
    { virtual: true }
})
Enter fullscreen mode Exit fullscreen mode

Source: surajit09's answer

7. The icon "info" was used but not registered.

This is just a warning you may see when testing react components using fluent ui icons. Annoying nevertheless.

Solution

In your test.tsx file add the following:

import { setIconOptions } from '@fluentui/react/lib/Styling';

// Suppress icon warnings.
setIconOptions({
  disableWarnings: true
});
Enter fullscreen mode Exit fullscreen mode

Source: Disabling warnings/test scenarios

You may find example SPFx solution on GitHub

8. Cannot use import statement outside a module

If you are getting errors similar to

 \node_modules\@pnp\azidjsclient\index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { PnPClientStorage, getHashCode } from "@pnp/core/index.js";
                                                                                      ^^^^^^
    SyntaxError: Cannot use import statement outside a module

      2 | import { DefaultAzureCredential } from "@azure/identity";
      3 | import { setLogLevel } from "@azure/logger";
    > 4 | import { AzureIdentity } from "@pnp/azidjsclient";
Enter fullscreen mode Exit fullscreen mode

you need to enable support for ECMAScript Modules (ESM), as described here

Solution

  1. On Windows, install cross-env: npm i cross-env --save-dev
  2. Update your test script in package.json. Replace "test": "jest" with "test": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest"
"scripts": {
  "test": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest"
},
Enter fullscreen mode Exit fullscreen mode

9. Must use import to load ES Module

After completing the step above, you may now see another error:

Err: Must use import to load ES Module: \node_modules\@pnp\azidjsclient\index.js

      2 | import { DefaultAzureCredential } from "@azure/identity";
      3 | import { setLogLevel } from "@azure/logger";
    > 4 | import { AzureIdentity } from "@pnp/azidjsclient";
Enter fullscreen mode Exit fullscreen mode

Solution

Add additional configuration to your package.json:

"jest": {
  "transform": {
    "^.+\\.(ts|tsx)?$": ["ts-jest", { "useESM": true }]
  },
  "extensionsToTreatAsEsm": [
    ".ts"
  ]
}
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
kkazala
Kinga

Posted on July 20, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Jest errors with solutions
jest Jest errors with solutions

July 20, 2023