Set up comprehensive frontend testing infrastructure
- Install Jest for unit testing with React Testing Library - Install Playwright for end-to-end testing - Configure Jest with proper TypeScript support and module mapping - Create test setup files and utilities for both unit and e2e tests Components: * Jest configuration with coverage thresholds * Playwright configuration with browser automation * Unit tests for LoginForm, AuthContext, and useSocketIO hook * E2E tests for authentication, dashboard, and agents workflows * GitHub Actions workflow for automated testing * Mock data and API utilities for consistent testing * Test documentation with best practices Testing features: - Unit tests with 70% coverage threshold - E2E tests with API mocking and user journey testing - CI/CD integration for automated test runs - Cross-browser testing support with Playwright - Authentication system testing end-to-end 🚀 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		
							
								
								
									
										2
									
								
								frontend/node_modules/ts-jest/dist/config/index.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								frontend/node_modules/ts-jest/dist/config/index.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| export * from './paths-to-module-name-mapper'; | ||||
| export * from './types'; | ||||
							
								
								
									
										18
									
								
								frontend/node_modules/ts-jest/dist/config/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								frontend/node_modules/ts-jest/dist/config/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| "use strict"; | ||||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||||
|     if (k2 === undefined) k2 = k; | ||||
|     var desc = Object.getOwnPropertyDescriptor(m, k); | ||||
|     if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||||
|       desc = { enumerable: true, get: function() { return m[k]; } }; | ||||
|     } | ||||
|     Object.defineProperty(o, k2, desc); | ||||
| }) : (function(o, m, k, k2) { | ||||
|     if (k2 === undefined) k2 = k; | ||||
|     o[k2] = m[k]; | ||||
| })); | ||||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||||
|     for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| __exportStar(require("./paths-to-module-name-mapper"), exports); | ||||
| __exportStar(require("./types"), exports); | ||||
							
								
								
									
										9
									
								
								frontend/node_modules/ts-jest/dist/config/paths-to-module-name-mapper.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								frontend/node_modules/ts-jest/dist/config/paths-to-module-name-mapper.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| import type { Config } from '@jest/types'; | ||||
| import type { CompilerOptions } from 'typescript'; | ||||
| type TsPathMapping = Exclude<CompilerOptions['paths'], undefined>; | ||||
| type JestPathMapping = Config.InitialOptions['moduleNameMapper']; | ||||
| export declare const pathsToModuleNameMapper: (mapping: TsPathMapping, { prefix, useESM }?: { | ||||
|     prefix?: string; | ||||
|     useESM?: boolean; | ||||
| }) => JestPathMapping; | ||||
| export {}; | ||||
							
								
								
									
										52
									
								
								frontend/node_modules/ts-jest/dist/config/paths-to-module-name-mapper.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								frontend/node_modules/ts-jest/dist/config/paths-to-module-name-mapper.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| "use strict"; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.pathsToModuleNameMapper = void 0; | ||||
| const bs_logger_1 = require("bs-logger"); | ||||
| const utils_1 = require("../utils"); | ||||
| const messages_1 = require("../utils/messages"); | ||||
| // we don't need to escape all chars, so commented out is the real one | ||||
| // const escapeRegex = (str: string) => str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') | ||||
| const escapeRegex = (str) => str.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&'); | ||||
| const logger = utils_1.rootLogger.child({ [bs_logger_1.LogContexts.namespace]: 'path-mapper' }); | ||||
| const pathsToModuleNameMapper = (mapping, { prefix = '', useESM = false } = {}) => { | ||||
|     const jestMap = {}; | ||||
|     for (const fromPath of Object.keys(mapping)) { | ||||
|         const toPaths = mapping[fromPath]; | ||||
|         // check that we have only one target path | ||||
|         if (toPaths.length === 0) { | ||||
|             logger.warn((0, messages_1.interpolate)("Not mapping \"{{path}}\" because it has no target." /* Errors.NotMappingPathWithEmptyMap */, { path: fromPath })); | ||||
|             continue; | ||||
|         } | ||||
|         // split with '*' | ||||
|         const segments = fromPath.split(/\*/g); | ||||
|         if (segments.length === 1) { | ||||
|             const paths = toPaths.map((target) => { | ||||
|                 const enrichedPrefix = prefix !== '' && !prefix.endsWith('/') ? `${prefix}/` : prefix; | ||||
|                 return `${enrichedPrefix}${target}`; | ||||
|             }); | ||||
|             const cjsPattern = `^${escapeRegex(fromPath)}$`; | ||||
|             jestMap[cjsPattern] = paths.length === 1 ? paths[0] : paths; | ||||
|         } | ||||
|         else if (segments.length === 2) { | ||||
|             const paths = toPaths.map((target) => { | ||||
|                 const enrichedTarget = target.startsWith('./') && prefix !== '' ? target.substring(target.indexOf('/') + 1) : target; | ||||
|                 const enrichedPrefix = prefix !== '' && !prefix.endsWith('/') ? `${prefix}/` : prefix; | ||||
|                 return `${enrichedPrefix}${enrichedTarget.replace(/\*/g, '$1')}`; | ||||
|             }); | ||||
|             if (useESM) { | ||||
|                 const esmPattern = `^${escapeRegex(segments[0])}(.*)${escapeRegex(segments[1])}\\.js$`; | ||||
|                 jestMap[esmPattern] = paths.length === 1 ? paths[0] : paths; | ||||
|             } | ||||
|             const cjsPattern = `^${escapeRegex(segments[0])}(.*)${escapeRegex(segments[1])}$`; | ||||
|             jestMap[cjsPattern] = paths.length === 1 ? paths[0] : paths; | ||||
|         } | ||||
|         else { | ||||
|             logger.warn((0, messages_1.interpolate)("Not mapping \"{{path}}\" because it has more than one star (`*`)." /* Errors.NotMappingMultiStarPath */, { path: fromPath })); | ||||
|         } | ||||
|     } | ||||
|     if (useESM) { | ||||
|         jestMap['^(\\.{1,2}/.*)\\.js$'] = '$1'; | ||||
|     } | ||||
|     return jestMap; | ||||
| }; | ||||
| exports.pathsToModuleNameMapper = pathsToModuleNameMapper; | ||||
							
								
								
									
										2
									
								
								frontend/node_modules/ts-jest/dist/config/types.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								frontend/node_modules/ts-jest/dist/config/types.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| import type { TsConfigJson } from 'type-fest'; | ||||
| export type TsConfigCompilerOptionsJson = TsConfigJson.CompilerOptions; | ||||
							
								
								
									
										2
									
								
								frontend/node_modules/ts-jest/dist/config/types.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								frontend/node_modules/ts-jest/dist/config/types.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| "use strict"; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
		Reference in New Issue
	
	Block a user
	 anthonyrawlins
					anthonyrawlins