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:
anthonyrawlins
2025-07-11 14:06:34 +10:00
parent c6d69695a8
commit aacb45156b
6109 changed files with 777927 additions and 1 deletions

3
frontend/node_modules/@pkgr/core/index.d.cts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import * as core from './lib/index.js'
export = core

8
frontend/node_modules/@pkgr/core/lib/constants.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
/// <reference types="node" preserve="true" />
export declare const CWD: string;
export interface CjsRequire extends NodeJS.Require {
<T>(id: string): T;
}
export declare const cjsRequire: CjsRequire;
export declare const EVAL_FILENAMES: Set<string>;
export declare const EXTENSIONS: string[];

9
frontend/node_modules/@pkgr/core/lib/constants.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
import { createRequire } from 'node:module';
export const CWD = process.cwd();
const importMetaUrl = import.meta.url;
export const cjsRequire = importMetaUrl
? createRequire(importMetaUrl)
: require;
export const EVAL_FILENAMES = new Set(['[eval]', '[worker eval]']);
export const EXTENSIONS = ['.ts', '.tsx', ...Object.keys(cjsRequire.extensions)];
//# sourceMappingURL=constants.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,CAAC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;AAMhC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAA;AAErC,MAAM,CAAC,MAAM,UAAU,GAAe,aAAa;IACjD,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC;IAC9B,CAAC,CAAC,OAAO,CAAA;AAEX,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAA;AAGlE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA"}

5
frontend/node_modules/@pkgr/core/lib/helpers.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
export declare const tryPkg: (pkg: string) => string | undefined;
export declare const isPkgAvailable: (pkg: string) => boolean;
export declare const tryFile: (filename?: string[] | string, includeDir?: boolean, base?: string) => string;
export declare const tryExtensions: (filepath: string, extensions?: string[]) => string;
export declare const findUp: (searchEntry: string, searchFileOrIncludeDir?: boolean | string, includeDir?: boolean) => string;

45
frontend/node_modules/@pkgr/core/lib/helpers.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
import fs from 'node:fs';
import path from 'node:path';
import { CWD, EXTENSIONS, cjsRequire } from './constants.js';
export const tryPkg = (pkg) => {
try {
return cjsRequire.resolve(pkg);
}
catch { }
};
export const isPkgAvailable = (pkg) => !!tryPkg(pkg);
export const tryFile = (filename, includeDir = false, base = CWD) => {
if (typeof filename === 'string') {
const filepath = path.resolve(base, filename);
return fs.existsSync(filepath) &&
(includeDir || fs.statSync(filepath).isFile())
? filepath
: '';
}
for (const file of filename ?? []) {
const filepath = tryFile(file, includeDir, base);
if (filepath) {
return filepath;
}
}
return '';
};
export const tryExtensions = (filepath, extensions = EXTENSIONS) => {
const ext = [...extensions, ''].find(ext => tryFile(filepath + ext));
return ext == null ? '' : filepath + ext;
};
export const findUp = (searchEntry, searchFileOrIncludeDir, includeDir) => {
const isSearchFile = typeof searchFileOrIncludeDir === 'string';
const searchFile = isSearchFile ? searchFileOrIncludeDir : 'package.json';
let lastSearchEntry;
do {
const searched = tryFile(searchFile, isSearchFile && includeDir, searchEntry);
if (searched) {
return searched;
}
lastSearchEntry = searchEntry;
searchEntry = path.dirname(searchEntry);
} while (!lastSearchEntry || lastSearchEntry !== searchEntry);
return '';
};
//# sourceMappingURL=helpers.js.map

1
frontend/node_modules/@pkgr/core/lib/helpers.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE5D,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,EAAE;IACpC,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAChC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;AAE5D,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,QAA4B,EAC5B,UAAU,GAAG,KAAK,EAClB,IAAI,GAAG,GAAG,EACF,EAAE;IACV,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAC7C,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC5B,CAAC,UAAU,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;YAC9C,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,EAAE,CAAA;IACR,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,QAAQ,IAAI,EAAE,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAA;QAChD,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAA;QACjB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,CAAA;AACX,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAE,UAAU,GAAG,UAAU,EAAE,EAAE;IACzE,MAAM,GAAG,GAAG,CAAC,GAAG,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAA;IACpE,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,CAAA;AAC1C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,WAAmB,EACnB,sBAAyC,EACzC,UAAoB,EACpB,EAAE;IACF,MAAM,YAAY,GAAG,OAAO,sBAAsB,KAAK,QAAQ,CAAA;IAE/D,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,cAAc,CAAA;IAEzE,IAAI,eAAmC,CAAA;IAEvC,GAAG,CAAC;QACF,MAAM,QAAQ,GAAG,OAAO,CACtB,UAAU,EACV,YAAY,IAAI,UAAU,EAC1B,WAAW,CACZ,CAAA;QACD,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAA;QACjB,CAAC;QACD,eAAe,GAAG,WAAW,CAAA;QAC7B,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IACzC,CAAC,QAAQ,CAAC,eAAe,IAAI,eAAe,KAAK,WAAW,EAAC;IAE7D,OAAO,EAAE,CAAA;AACX,CAAC,CAAA"}

65
frontend/node_modules/@pkgr/core/lib/index.cjs generated vendored Normal file
View File

@@ -0,0 +1,65 @@
'use strict';
var node_module = require('node:module');
var fs = require('node:fs');
var path = require('node:path');
const import_meta = {};
const CWD = process.cwd();
const importMetaUrl = import_meta.url;
const cjsRequire = importMetaUrl ? node_module.createRequire(importMetaUrl) : require;
const EVAL_FILENAMES = /* @__PURE__ */ new Set(["[eval]", "[worker eval]"]);
const EXTENSIONS = [".ts", ".tsx", ...Object.keys(cjsRequire.extensions)];
const tryPkg = (pkg) => {
try {
return cjsRequire.resolve(pkg);
} catch (e) {
}
};
const isPkgAvailable = (pkg) => !!tryPkg(pkg);
const tryFile = (filename, includeDir = false, base = CWD) => {
if (typeof filename === "string") {
const filepath = path.resolve(base, filename);
return fs.existsSync(filepath) && (includeDir || fs.statSync(filepath).isFile()) ? filepath : "";
}
for (const file of filename != null ? filename : []) {
const filepath = tryFile(file, includeDir, base);
if (filepath) {
return filepath;
}
}
return "";
};
const tryExtensions = (filepath, extensions = EXTENSIONS) => {
const ext = [...extensions, ""].find((ext2) => tryFile(filepath + ext2));
return ext == null ? "" : filepath + ext;
};
const findUp = (searchEntry, searchFileOrIncludeDir, includeDir) => {
const isSearchFile = typeof searchFileOrIncludeDir === "string";
const searchFile = isSearchFile ? searchFileOrIncludeDir : "package.json";
let lastSearchEntry;
do {
const searched = tryFile(
searchFile,
isSearchFile && includeDir,
searchEntry
);
if (searched) {
return searched;
}
lastSearchEntry = searchEntry;
searchEntry = path.dirname(searchEntry);
} while (!lastSearchEntry || lastSearchEntry !== searchEntry);
return "";
};
exports.CWD = CWD;
exports.EVAL_FILENAMES = EVAL_FILENAMES;
exports.EXTENSIONS = EXTENSIONS;
exports.cjsRequire = cjsRequire;
exports.findUp = findUp;
exports.isPkgAvailable = isPkgAvailable;
exports.tryExtensions = tryExtensions;
exports.tryFile = tryFile;
exports.tryPkg = tryPkg;

2
frontend/node_modules/@pkgr/core/lib/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export * from './constants.js';
export * from './helpers.js';

3
frontend/node_modules/@pkgr/core/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export * from './constants.js';
export * from './helpers.js';
//# sourceMappingURL=index.js.map

1
frontend/node_modules/@pkgr/core/lib/index.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA"}

38
frontend/node_modules/@pkgr/core/package.json generated vendored Normal file
View File

@@ -0,0 +1,38 @@
{
"name": "@pkgr/core",
"version": "0.2.7",
"type": "module",
"description": "Shared core module for `@pkgr` packages or any package else",
"repository": "git+https://github.com/un-ts/pkgr.git",
"homepage": "https://github.com/un-ts/pkgr/blob/master/packages/core",
"author": "JounQin <admin@1stg.me> (https://www.1stG.me)",
"funding": "https://opencollective.com/pkgr",
"license": "MIT",
"engines": {
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
},
"main": "./lib/index.cjs",
"types": "./index.d.cts",
"module": "./lib/index.js",
"exports": {
".": {
"import": {
"types": "./lib/index.d.ts",
"default": "./lib/index.js"
},
"require": {
"types": "./index.d.cts",
"default": "./lib/index.cjs"
}
},
"./package.json": "./package.json"
},
"files": [
"index.d.cts",
"lib"
],
"publishConfig": {
"access": "public"
},
"sideEffects": false
}