diff --git a/jest.config.ts b/jest.config.ts index 93874b54..5d3129f3 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -18,7 +18,8 @@ const config: Config = { globals: { IS_REACT_ACT_ENVIRONMENT: true, }, - setupFiles: ['/jest.setup.ts'], + setupFilesAfterEnv: ['/jest.setup.ts'], + testPathIgnorePatterns: ['/src/tests/testsUtils.test.tsx'], }; export default config; diff --git a/jest.setup.ts b/jest.setup.ts index 996e17fd..df2d89b7 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import '@testing-library/jest-dom' import { TextEncoder, TextDecoder } from 'util'; // fix for ReferenceError: TextDecoder / TextEncoder is not defined diff --git a/package-lock.json b/package-lock.json index 62aa759a..dcf9c6dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,10 +40,13 @@ "@mui/lab": "5.0.0-alpha.169", "@mui/material": "^5.15.14", "@react-hook/window-size": "^3.1.1", + "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^14.5.2", "@types/autosuggest-highlight": "^3.2.3", "@types/eslint": "^8.56.7", "@types/eslint-config-prettier": "^6.11.3", + "@types/jest": "^29.5.13", "@types/json-logic-js": "^2.0.7", "@types/license-checker": "^25.0.6", "@types/localized-countries": "^2.0.3", @@ -79,6 +82,7 @@ "glob": "^10.3.12", "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", + "jest-dom": "^4.0.0", "jest-environment-jsdom": "^29.7.0", "license-checker": "^25.0.1", "notistack": "^3.0.1", @@ -136,6 +140,12 @@ "node": ">=0.10.0" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "dev": true + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -5393,6 +5403,99 @@ "node": ">=8" } }, + "node_modules/@testing-library/jest-dom": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz", + "integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==", + "dev": true, + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, + "node_modules/@testing-library/jest-dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@testing-library/react": { "version": "16.0.0", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.0.0.tgz", @@ -5420,6 +5523,19 @@ } } }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -5577,6 +5693,16 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jest": { + "version": "29.5.13", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.13.tgz", + "integrity": "sha512-wd+MVEZCHt23V0/L642O5APvspWply/rGY5BcW4SUETo2UzPU3Z26qr8jC2qxpimI2jjx9h7+2cj2FwIr01bXg==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, "node_modules/@types/jsdom": { "version": "20.0.1", "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", @@ -7564,6 +7690,12 @@ "tiny-invariant": "^1.0.6" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, "node_modules/cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", @@ -10066,6 +10198,15 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -11164,6 +11305,13 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-dom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jest-dom/-/jest-dom-4.0.0.tgz", + "integrity": "sha512-gBxYZlZB1Jgvf2gP2pRfjjUWF8woGBHj/g5rAQgFPB/0K2atGuhVcPO+BItyjWeKg9zM+dokgcMOH01vrWVMFA==", + "deprecated": "🚨 jest-dom has moved to @testing-library/jest-dom. Please uninstall jest-dom and install @testing-library/jest-dom instead, or use an older version of jest-dom. Learn more about this change here: https://github.com/testing-library/dom-testing-library/issues/260 Thanks! :)", + "dev": true + }, "node_modules/jest-each": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", @@ -12836,6 +12984,15 @@ "node": ">=6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", @@ -14206,6 +14363,19 @@ "once": "^1.3.0" } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/redux": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", @@ -15074,6 +15244,18 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", diff --git a/package.json b/package.json index a2982b6a..b2ca7d5c 100644 --- a/package.json +++ b/package.json @@ -46,18 +46,18 @@ "uuid": "^9.0.1" }, "peerDependencies": { - "@mui/system": "^5.15.15", - "@mui/x-tree-view": "^6.17.0", - "papaparse": "^5.4.1", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", "@hookform/resolvers": "^3.3.4", "@mui/icons-material": "^5.15.14", "@mui/lab": "5.0.0-alpha.169", "@mui/material": "^5.15.14", + "@mui/system": "^5.15.15", + "@mui/x-tree-view": "^6.17.0", "ag-grid-community": "^31.0.0", "ag-grid-react": "^31.2.0", "notistack": "^3.0.1", + "papaparse": "^5.4.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.51.2", @@ -80,10 +80,13 @@ "@mui/lab": "5.0.0-alpha.169", "@mui/material": "^5.15.14", "@react-hook/window-size": "^3.1.1", + "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^14.5.2", "@types/autosuggest-highlight": "^3.2.3", "@types/eslint": "^8.56.7", "@types/eslint-config-prettier": "^6.11.3", + "@types/jest": "^29.5.13", "@types/json-logic-js": "^2.0.7", "@types/license-checker": "^25.0.6", "@types/localized-countries": "^2.0.3", @@ -119,6 +122,7 @@ "glob": "^10.3.12", "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", + "jest-dom": "^4.0.0", "jest-environment-jsdom": "^29.7.0", "license-checker": "^25.0.1", "notistack": "^3.0.1", diff --git a/src/tests/testsUtils.test.tsx b/src/tests/testsUtils.test.tsx new file mode 100644 index 00000000..61ccf0ef --- /dev/null +++ b/src/tests/testsUtils.test.tsx @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +// eslint-disable-next-line import/no-extraneous-dependencies +import { render as rtlRender } from '@testing-library/react'; +import { createTheme, ThemeProvider } from '@mui/material/styles'; +import { IntlProvider } from 'react-intl'; +import { Theme } from '@mui/system'; +import { + loginEn, + reportViewerEn, + topBarEn, + tableEn, + treeviewFinderEn, + elementSearchEn, + equipmentSearchEn, + filterEn, + filterExpertEn, + descriptionEn, + equipmentsEn, + csvEn, + cardErrorBoundaryEn, + flatParametersEn, + multipleSelectionDialogEn, + commonButtonEn, + directoryItemsInputEn, +} from '../translations/en'; + +const fullTrad = { + ...reportViewerEn, + ...loginEn, + ...topBarEn, + ...tableEn, + ...treeviewFinderEn, + ...elementSearchEn, + ...equipmentSearchEn, + ...filterEn, + ...filterExpertEn, + ...descriptionEn, + ...equipmentsEn, + ...csvEn, + ...cardErrorBoundaryEn, + ...flatParametersEn, + ...multipleSelectionDialogEn, + ...commonButtonEn, + ...directoryItemsInputEn, +}; +const renderWithTranslation = (ui: React.ReactElement, trad: Record = fullTrad) => ( + + {ui} + +); + +const lightTheme = createTheme( + { + components: { + MuiTab: { + styleOverrides: { + root: { + textTransform: 'none', + }, + }, + }, + MuiButton: { + styleOverrides: { + root: { + textTransform: 'none', + }, + }, + }, + }, + palette: { + mode: 'light', + }, + }, + { + aggrid: { + theme: 'ag-theme-alpine', + overlay: { + background: '#e6e6e6', + }, + }, + } +); +const renderWithTheme = (ui: React.ReactElement, theme: Theme = lightTheme) => ( + {ui} +); + +// eslint-disable-next-line import/prefer-default-export +export class RenderBuilder { + renderWithTheme: boolean = false; + + theme: Theme = lightTheme; + + renderWithTrad: boolean = false; + + trad: Record = fullTrad; + + withTrad(trad?: Record) { + this.renderWithTrad = true; + if (trad) { + this.trad = trad; + } + return this; + } + + withTheme(theme?: Theme) { + this.renderWithTheme = true; + if (theme) { + this.theme = theme; + } + return this; + } + + render(ui: React.ReactElement) { + let newUi = this.renderWithTrad ? renderWithTranslation(ui, this.trad) : ui; + newUi = this.renderWithTheme ? renderWithTheme(newUi, this.theme) : newUi; + return rtlRender(newUi); + } +} diff --git a/tsconfig.json b/tsconfig.json index 9411442b..0febda27 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,5 +16,6 @@ "noEmit": true, "jsx": "react-jsx" }, - "include": ["src", "demo"] // we can let demo because the file generation is managed my vite and we have noEmit anyway + "types":["node","jest", "@testing-library/jest-dom"], + "include": ["src", "demo","jest.setup.ts"] // we can let demo because the file generation is managed my vite and we have noEmit anyway } diff --git a/vite.config.mts b/vite.config.mts index 323224e8..c9aa0f24 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -30,6 +30,7 @@ export default defineConfig((config) => ({ libInjectCss(), dts({ include: ['src'], + exclude: '**/*.test.{ts,tsx}', }), ], build: {