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:
		
							
								
								
									
										59
									
								
								frontend/node_modules/yargs/build/lib/utils/apply-extends.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								frontend/node_modules/yargs/build/lib/utils/apply-extends.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| import { YError } from '../yerror.js'; | ||||
| let previouslyVisitedConfigs = []; | ||||
| let shim; | ||||
| export function applyExtends(config, cwd, mergeExtends, _shim) { | ||||
|     shim = _shim; | ||||
|     let defaultConfig = {}; | ||||
|     if (Object.prototype.hasOwnProperty.call(config, 'extends')) { | ||||
|         if (typeof config.extends !== 'string') | ||||
|             return defaultConfig; | ||||
|         const isPath = /\.json|\..*rc$/.test(config.extends); | ||||
|         let pathToDefault = null; | ||||
|         if (!isPath) { | ||||
|             try { | ||||
|                 pathToDefault = require.resolve(config.extends); | ||||
|             } | ||||
|             catch (_err) { | ||||
|                 return config; | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             pathToDefault = getPathToDefaultConfig(cwd, config.extends); | ||||
|         } | ||||
|         checkForCircularExtends(pathToDefault); | ||||
|         previouslyVisitedConfigs.push(pathToDefault); | ||||
|         defaultConfig = isPath | ||||
|             ? JSON.parse(shim.readFileSync(pathToDefault, 'utf8')) | ||||
|             : require(config.extends); | ||||
|         delete config.extends; | ||||
|         defaultConfig = applyExtends(defaultConfig, shim.path.dirname(pathToDefault), mergeExtends, shim); | ||||
|     } | ||||
|     previouslyVisitedConfigs = []; | ||||
|     return mergeExtends | ||||
|         ? mergeDeep(defaultConfig, config) | ||||
|         : Object.assign({}, defaultConfig, config); | ||||
| } | ||||
| function checkForCircularExtends(cfgPath) { | ||||
|     if (previouslyVisitedConfigs.indexOf(cfgPath) > -1) { | ||||
|         throw new YError(`Circular extended configurations: '${cfgPath}'.`); | ||||
|     } | ||||
| } | ||||
| function getPathToDefaultConfig(cwd, pathToExtend) { | ||||
|     return shim.path.resolve(cwd, pathToExtend); | ||||
| } | ||||
| function mergeDeep(config1, config2) { | ||||
|     const target = {}; | ||||
|     function isObject(obj) { | ||||
|         return obj && typeof obj === 'object' && !Array.isArray(obj); | ||||
|     } | ||||
|     Object.assign(target, config1); | ||||
|     for (const key of Object.keys(config2)) { | ||||
|         if (isObject(config2[key]) && isObject(target[key])) { | ||||
|             target[key] = mergeDeep(config1[key], config2[key]); | ||||
|         } | ||||
|         else { | ||||
|             target[key] = config2[key]; | ||||
|         } | ||||
|     } | ||||
|     return target; | ||||
| } | ||||
							
								
								
									
										5
									
								
								frontend/node_modules/yargs/build/lib/utils/is-promise.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								frontend/node_modules/yargs/build/lib/utils/is-promise.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| export function isPromise(maybePromise) { | ||||
|     return (!!maybePromise && | ||||
|         !!maybePromise.then && | ||||
|         typeof maybePromise.then === 'function'); | ||||
| } | ||||
							
								
								
									
										34
									
								
								frontend/node_modules/yargs/build/lib/utils/levenshtein.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								frontend/node_modules/yargs/build/lib/utils/levenshtein.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| export function levenshtein(a, b) { | ||||
|     if (a.length === 0) | ||||
|         return b.length; | ||||
|     if (b.length === 0) | ||||
|         return a.length; | ||||
|     const matrix = []; | ||||
|     let i; | ||||
|     for (i = 0; i <= b.length; i++) { | ||||
|         matrix[i] = [i]; | ||||
|     } | ||||
|     let j; | ||||
|     for (j = 0; j <= a.length; j++) { | ||||
|         matrix[0][j] = j; | ||||
|     } | ||||
|     for (i = 1; i <= b.length; i++) { | ||||
|         for (j = 1; j <= a.length; j++) { | ||||
|             if (b.charAt(i - 1) === a.charAt(j - 1)) { | ||||
|                 matrix[i][j] = matrix[i - 1][j - 1]; | ||||
|             } | ||||
|             else { | ||||
|                 if (i > 1 && | ||||
|                     j > 1 && | ||||
|                     b.charAt(i - 2) === a.charAt(j - 1) && | ||||
|                     b.charAt(i - 1) === a.charAt(j - 2)) { | ||||
|                     matrix[i][j] = matrix[i - 2][j - 2] + 1; | ||||
|                 } | ||||
|                 else { | ||||
|                     matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, Math.min(matrix[i][j - 1] + 1, matrix[i - 1][j] + 1)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return matrix[b.length][a.length]; | ||||
| } | ||||
							
								
								
									
										17
									
								
								frontend/node_modules/yargs/build/lib/utils/maybe-async-result.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								frontend/node_modules/yargs/build/lib/utils/maybe-async-result.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| import { isPromise } from './is-promise.js'; | ||||
| export function maybeAsyncResult(getResult, resultHandler, errorHandler = (err) => { | ||||
|     throw err; | ||||
| }) { | ||||
|     try { | ||||
|         const result = isFunction(getResult) ? getResult() : getResult; | ||||
|         return isPromise(result) | ||||
|             ? result.then((result) => resultHandler(result)) | ||||
|             : resultHandler(result); | ||||
|     } | ||||
|     catch (err) { | ||||
|         return errorHandler(err); | ||||
|     } | ||||
| } | ||||
| function isFunction(arg) { | ||||
|     return typeof arg === 'function'; | ||||
| } | ||||
							
								
								
									
										10
									
								
								frontend/node_modules/yargs/build/lib/utils/obj-filter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								frontend/node_modules/yargs/build/lib/utils/obj-filter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| import { objectKeys } from '../typings/common-types.js'; | ||||
| export function objFilter(original = {}, filter = () => true) { | ||||
|     const obj = {}; | ||||
|     objectKeys(original).forEach(key => { | ||||
|         if (filter(key, original[key])) { | ||||
|             obj[key] = original[key]; | ||||
|         } | ||||
|     }); | ||||
|     return obj; | ||||
| } | ||||
							
								
								
									
										17
									
								
								frontend/node_modules/yargs/build/lib/utils/process-argv.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								frontend/node_modules/yargs/build/lib/utils/process-argv.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| function getProcessArgvBinIndex() { | ||||
|     if (isBundledElectronApp()) | ||||
|         return 0; | ||||
|     return 1; | ||||
| } | ||||
| function isBundledElectronApp() { | ||||
|     return isElectronApp() && !process.defaultApp; | ||||
| } | ||||
| function isElectronApp() { | ||||
|     return !!process.versions.electron; | ||||
| } | ||||
| export function hideBin(argv) { | ||||
|     return argv.slice(getProcessArgvBinIndex() + 1); | ||||
| } | ||||
| export function getProcessArgvBin() { | ||||
|     return process.argv[getProcessArgvBinIndex()]; | ||||
| } | ||||
							
								
								
									
										12
									
								
								frontend/node_modules/yargs/build/lib/utils/set-blocking.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								frontend/node_modules/yargs/build/lib/utils/set-blocking.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| export default function setBlocking(blocking) { | ||||
|     if (typeof process === 'undefined') | ||||
|         return; | ||||
|     [process.stdout, process.stderr].forEach(_stream => { | ||||
|         const stream = _stream; | ||||
|         if (stream._handle && | ||||
|             stream.isTTY && | ||||
|             typeof stream._handle.setBlocking === 'function') { | ||||
|             stream._handle.setBlocking(blocking); | ||||
|         } | ||||
|     }); | ||||
| } | ||||
							
								
								
									
										10
									
								
								frontend/node_modules/yargs/build/lib/utils/which-module.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								frontend/node_modules/yargs/build/lib/utils/which-module.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| export default function whichModule(exported) { | ||||
|     if (typeof require === 'undefined') | ||||
|         return null; | ||||
|     for (let i = 0, files = Object.keys(require.cache), mod; i < files.length; i++) { | ||||
|         mod = require.cache[files[i]]; | ||||
|         if (mod.exports === exported) | ||||
|             return mod; | ||||
|     } | ||||
|     return null; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 anthonyrawlins
					anthonyrawlins