From 1964161fd3e461e7d645e580d441101ee91e096e Mon Sep 17 00:00:00 2001 From: Donald Labaj Date: Sun, 1 Feb 2026 09:50:39 -0500 Subject: [PATCH 1/2] fix: Removes vitest since it can not be used with webpack. --- jest.config.cjs | 20 ++++++++++++++++++++ package.json | 17 +++++++++-------- src/app/app.test.tsx | 1 - src/test/mocks/fileMock.cjs | 1 + src/test/mocks/styleMock.cjs | 1 + src/test/setup.ts | 34 +++++++++++++++++++--------------- vitest.config.ts | 24 ------------------------ 7 files changed, 50 insertions(+), 48 deletions(-) create mode 100644 jest.config.cjs create mode 100644 src/test/mocks/fileMock.cjs create mode 100644 src/test/mocks/styleMock.cjs delete mode 100644 vitest.config.ts diff --git a/jest.config.cjs b/jest.config.cjs new file mode 100644 index 00000000..7aba2500 --- /dev/null +++ b/jest.config.cjs @@ -0,0 +1,20 @@ +/** @type {import('jest').Config} */ +module.exports = { + testEnvironment: 'jest-environment-jsdom', + setupFilesAfterEnv: ['/src/test/setup.ts'], + moduleNameMapper: { + '\\.(css|less|scss|sass)$': '/src/test/mocks/styleMock.cjs', + '\\.(svg|png|jpg|jpeg|gif|ico|webp)$': '/src/test/mocks/fileMock.cjs', + '^@app/(.*)$': '/src/app/$1', + 'monaco-editor': '/src/test/mocks/monaco-editor.ts', + }, + transform: { + '^.+\\.(ts|tsx|js|jsx)$': ['ts-jest', { useESM: false }], + }, + transformIgnorePatterns: [ + '/node_modules/(?!(@patternfly|react-router)/)', + ], + testMatch: ['**/__tests__/**/*.(ts|tsx|js)', '**/*.test.(ts|tsx|js)'], + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], + collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/**/*.d.ts', '!src/test/**'], +}; diff --git a/package.json b/package.json index 860ff56d..7fbbd92f 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,9 @@ "build": "NODE_OPTIONS='--max-old-space-size=4096' webpack --config webpack.prod.js", "start": "sirv dist --cors --single --host --port 8080", "start:dev": "webpack serve --color --progress --config webpack.dev.js", - "test": "vitest run", - "test:watch": "vitest", - "test:coverage": "vitest run --coverage", + "test": "jest", + "test:watch": "jest --watch", + "test:coverage": "jest --coverage", "eslint": "eslint --ext .tsx,.js ./src/", "lint": "npm run eslint", "format": "prettier --check --write ./src/**/*.{tsx,ts}", @@ -25,14 +25,14 @@ }, "devDependencies": { "@eslint/js": "^9.29.0", + "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^14.6.1", "@types/react-router-dom": "^5.3.3", "@typescript-eslint/eslint-plugin": "^8.34.0", "@typescript-eslint/parser": "^8.34.0", - "@vitejs/plugin-react": "^4.3.3", - "@vitest/coverage-v8": "^4.0.10", + "@types/jest": "^29.5.14", "copy-webpack-plugin": "^13.0.0", "css-loader": "^7.1.2", "css-minimizer-webpack-plugin": "^7.0.2", @@ -43,7 +43,9 @@ "eslint-plugin-react-hooks": "^5.2.0", "html-webpack-plugin": "^5.6.3", "imagemin": "^9.0.0", - "jsdom": "^25.0.1", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-fixed-jsdom": "^0.0.9", "mini-css-extract-plugin": "^2.9.2", "postcss": "^8.4.49", "prettier": "^3.5.3", @@ -56,14 +58,13 @@ "style-loader": "^4.0.0", "svg-url-loader": "^8.0.0", "terser-webpack-plugin": "^5.3.14", + "ts-jest": "^29.2.5", "ts-loader": "^9.5.2", "tsconfig-paths-webpack-plugin": "^4.2.0", "tslib": "^2.8.1", "typescript": "^5.8.3", "typescript-eslint": "^8.34.0", "url-loader": "^4.1.1", - "vite": "^6.4.1", - "vitest": "^4.0.5", "webpack": "^5.97.0", "webpack-bundle-analyzer": "^4.10.2", "webpack-cli": "^5.1.4", diff --git a/src/app/app.test.tsx b/src/app/app.test.tsx index 811a27ed..ac8e410e 100644 --- a/src/app/app.test.tsx +++ b/src/app/app.test.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import App from '@app/index'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { describe, expect, it, test } from 'vitest'; describe('App tests', () => { test('should render default App component', () => { diff --git a/src/test/mocks/fileMock.cjs b/src/test/mocks/fileMock.cjs new file mode 100644 index 00000000..86059f36 --- /dev/null +++ b/src/test/mocks/fileMock.cjs @@ -0,0 +1 @@ +module.exports = 'test-file-stub'; diff --git a/src/test/mocks/styleMock.cjs b/src/test/mocks/styleMock.cjs new file mode 100644 index 00000000..f053ebf7 --- /dev/null +++ b/src/test/mocks/styleMock.cjs @@ -0,0 +1 @@ +module.exports = {}; diff --git a/src/test/setup.ts b/src/test/setup.ts index 58d85159..95e73f3e 100644 --- a/src/test/setup.ts +++ b/src/test/setup.ts @@ -1,36 +1,40 @@ +import { TextEncoder, TextDecoder } from 'util'; import '@testing-library/jest-dom'; -import { vi } from 'vitest'; + +// Polyfill for jsdom (react-router etc. may use these) +global.TextEncoder = TextEncoder; +global.TextDecoder = TextDecoder as typeof global.TextDecoder; // Mock PatternFly Chatbot MessageBar to avoid monaco-editor dependency -vi.mock('@patternfly/chatbot/dist/dynamic/MessageBar', () => ({ - MessageBar: vi.fn(() => null), +jest.mock('@patternfly/chatbot/dist/dynamic/MessageBar', () => ({ + MessageBar: jest.fn(() => null), })); // Mock CSS imports Object.defineProperty(window, 'matchMedia', { writable: true, - value: vi.fn().mockImplementation(query => ({ + value: jest.fn().mockImplementation((query: string) => ({ matches: false, media: query, onchange: null, - addListener: vi.fn(), // deprecated - removeListener: vi.fn(), // deprecated - addEventListener: vi.fn(), - removeEventListener: vi.fn(), - dispatchEvent: vi.fn(), + addListener: jest.fn(), + removeListener: jest.fn(), + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), })), }); // Mock ResizeObserver global.ResizeObserver = class ResizeObserver { - observe = vi.fn(); - unobserve = vi.fn(); - disconnect = vi.fn(); + observe = jest.fn(); + unobserve = jest.fn(); + disconnect = jest.fn(); }; // Mock IntersectionObserver global.IntersectionObserver = class IntersectionObserver { - observe = vi.fn(); - unobserve = vi.fn(); - disconnect = vi.fn(); + observe = jest.fn(); + unobserve = jest.fn(); + disconnect = jest.fn(); } as any; diff --git a/vitest.config.ts b/vitest.config.ts deleted file mode 100644 index 1aeadad5..00000000 --- a/vitest.config.ts +++ /dev/null @@ -1,24 +0,0 @@ -/// -import { defineConfig } from 'vitest/config'; -import react from '@vitejs/plugin-react'; -import path from 'path'; - -export default defineConfig({ - plugins: [react()], - test: { - environment: 'jsdom', - setupFiles: ['./src/test/setup.ts'], - globals: true, - css: true, - }, - resolve: { - alias: { - '@app': path.resolve(__dirname, './src/app'), - // Mock monaco-editor to avoid bundling it in tests - 'monaco-editor': path.resolve(__dirname, './src/test/mocks/monaco-editor.ts'), - }, - }, - ssr: { - noExternal: [/@patternfly\/.*/], - }, -}); From bd78c767a095787473795db85252f4ca1aa24e47 Mon Sep 17 00:00:00 2001 From: Donald Labaj Date: Wed, 4 Feb 2026 10:15:42 -0500 Subject: [PATCH 2/2] chore: updated to fix lint issue. --- src/test/setup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/setup.ts b/src/test/setup.ts index 95e73f3e..ae4d42b9 100644 --- a/src/test/setup.ts +++ b/src/test/setup.ts @@ -1,4 +1,4 @@ -import { TextEncoder, TextDecoder } from 'util'; +import { TextDecoder, TextEncoder } from 'util'; import '@testing-library/jest-dom'; // Polyfill for jsdom (react-router etc. may use these)