Kinga
Posted on July 20, 2023
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.
Solution
Add .eslintignore
file to the root of your project:
.eslintignore
.eslintrc.js
**/test/*.ts
**/test/*.tsx
*.test.ts
*.test.tsx
2. Property 'toBeInTheDocument' does not exist...
error TS2339: Property 'toBeInTheDocument' does not exist on type 'JestMatchers<HTMLElement>'.
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();
});
});
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 | });
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,
//...
}
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';
Solution
Add "\\.(css|scss)": "identity-obj-proxy"
to moduleNameMapper
in package.json
package.json
{
//...
"jest": {
"moduleNameMapper": {
"\\.(css|scss)": "identity-obj-proxy"
}
}
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} />
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)) + ';';
},
};
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"
}
}
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';
Solution
Add "HelloWorldWebPartStrings": "<rootDir>/src/webparts/helloWorld/loc/myStrings.d.ts"
to moduleNameMapper
in package.json
package.json
{
//...
"jest": {
"moduleNameMapper": {
//...
"HelloWorldWebPartStrings": "identity-obj-proxy"
}
}
And mock your strings as a constant:
HelloWorld.test.tsx
jest.mock('HelloWorldWebPartStrings', () => {
return {
PropertyPaneDescription: "Description",
//...
}
{ virtual: true }
})
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
});
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";
you need to enable support for ECMAScript Modules (ESM), as described here
Solution
- On Windows, install cross-env:
npm i cross-env --save-dev
- Update your
test
script inpackage.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"
},
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";
Solution
Add additional configuration to your package.json
:
"jest": {
"transform": {
"^.+\\.(ts|tsx)?$": ["ts-jest", { "useESM": true }]
},
"extensionsToTreatAsEsm": [
".ts"
]
}
Posted on July 20, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.