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:
22
frontend/node_modules/babel-jest/LICENSE
generated
vendored
Normal file
22
frontend/node_modules/babel-jest/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
Copyright Contributors to the Jest project.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
43
frontend/node_modules/babel-jest/README.md
generated
vendored
Normal file
43
frontend/node_modules/babel-jest/README.md
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# babel-jest
|
||||
|
||||
[Babel](https://github.com/babel/babel) [jest](https://github.com/jestjs/jest) plugin
|
||||
|
||||
## Usage
|
||||
|
||||
If you are already using `jest-cli`, add `babel-jest` and it will automatically compile JavaScript code using Babel.
|
||||
|
||||
```bash
|
||||
yarn add --dev babel-jest @babel/core
|
||||
```
|
||||
|
||||
If you would like to write your own preprocessor, uninstall and delete babel-jest and set the [config.transform](https://jestjs.io/docs/configuration#transform-object-string-string) option to your preprocessor.
|
||||
|
||||
## Setup
|
||||
|
||||
_Note: this step is only required if you are using `babel-jest` with additional code preprocessors._
|
||||
|
||||
To explicitly define `babel-jest` as a transformer for your JavaScript code, map _.js_ files to the `babel-jest` module. Typescript files are also supported.
|
||||
|
||||
By default, it loads your existing Babel configuration (if any)
|
||||
|
||||
```json
|
||||
"transform": {
|
||||
"\\.[jt]sx?$": "babel-jest"
|
||||
},
|
||||
```
|
||||
|
||||
You can also pass further [babel options](https://babeljs.io/docs/options)
|
||||
|
||||
```json
|
||||
"transform": {
|
||||
"\\.[jt]sx?$": ["babel-jest", { "extends": "./babel.config.js", "plugins": ["babel-plugin-transform-import-meta"] }]
|
||||
},
|
||||
```
|
||||
|
||||
By default, `babel-jest` includes `babel-preset-jest`. In addition to the babel options, we introduce a new option, `excludeJestPreset`, which allows you to disable this behavior. Note that this will break `jest.mock` hoisting.
|
||||
|
||||
```json
|
||||
"transform": {
|
||||
"\\.[jt]sx?$": ["babel-jest", { "excludeJestPreset": true }],
|
||||
}
|
||||
```
|
||||
14
frontend/node_modules/babel-jest/build/index.d.mts
generated
vendored
Normal file
14
frontend/node_modules/babel-jest/build/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import { TransformOptions } from "@babel/core";
|
||||
import { SyncTransformer, TransformerCreator } from "@jest/transform";
|
||||
|
||||
//#region src/index.d.ts
|
||||
|
||||
interface TransformerConfig extends TransformOptions {
|
||||
excludeJestPreset?: boolean;
|
||||
}
|
||||
declare const createTransformer: TransformerCreator<SyncTransformer<TransformerConfig>, TransformerConfig>;
|
||||
declare const transformerFactory: {
|
||||
createTransformer: TransformerCreator<SyncTransformer<TransformerConfig>, TransformerConfig>;
|
||||
};
|
||||
//#endregion
|
||||
export { createTransformer, transformerFactory as default };
|
||||
28
frontend/node_modules/babel-jest/build/index.d.ts
generated
vendored
Normal file
28
frontend/node_modules/babel-jest/build/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {TransformOptions} from '@babel/core';
|
||||
import {SyncTransformer, TransformerCreator} from '@jest/transform';
|
||||
|
||||
export declare const createTransformer: TransformerCreator<
|
||||
SyncTransformer<TransformerConfig>,
|
||||
TransformerConfig
|
||||
>;
|
||||
|
||||
declare interface TransformerConfig extends TransformOptions {
|
||||
excludeJestPreset?: boolean;
|
||||
}
|
||||
|
||||
declare const transformerFactory: {
|
||||
createTransformer: TransformerCreator<
|
||||
SyncTransformer<TransformerConfig>,
|
||||
TransformerConfig
|
||||
>;
|
||||
};
|
||||
export default transformerFactory;
|
||||
|
||||
export {};
|
||||
288
frontend/node_modules/babel-jest/build/index.js
generated
vendored
Normal file
288
frontend/node_modules/babel-jest/build/index.js
generated
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
/*!
|
||||
* /**
|
||||
* * Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* *
|
||||
* * This source code is licensed under the MIT license found in the
|
||||
* * LICENSE file in the root directory of this source tree.
|
||||
* * /
|
||||
*/
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ "./src/loadBabelConfig.ts":
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
Object.defineProperty(exports, "loadPartialConfig", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _core().loadPartialConfig;
|
||||
}
|
||||
}));
|
||||
Object.defineProperty(exports, "loadPartialConfigAsync", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _core().loadPartialConfigAsync;
|
||||
}
|
||||
}));
|
||||
function _core() {
|
||||
const data = require("@babel/core");
|
||||
_core = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // The module cache
|
||||
/******/ var __webpack_module_cache__ = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/ // Check if module is in cache
|
||||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||
/******/ if (cachedModule !== undefined) {
|
||||
/******/ return cachedModule.exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||
/******/ // no module.id needed
|
||||
/******/ // no module.loaded needed
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/************************************************************************/
|
||||
var __webpack_exports__ = {};
|
||||
// This entry needs to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
|
||||
(() => {
|
||||
var exports = __webpack_exports__;
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = exports.createTransformer = void 0;
|
||||
function _crypto() {
|
||||
const data = require("crypto");
|
||||
_crypto = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
function path() {
|
||||
const data = _interopRequireWildcard(require("path"));
|
||||
path = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
function _core() {
|
||||
const data = require("@babel/core");
|
||||
_core = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
function _chalk() {
|
||||
const data = _interopRequireDefault(require("chalk"));
|
||||
_chalk = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
function fs() {
|
||||
const data = _interopRequireWildcard(require("graceful-fs"));
|
||||
fs = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
function _slash() {
|
||||
const data = _interopRequireDefault(require("slash"));
|
||||
_slash = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
var _loadBabelConfig = __webpack_require__("./src/loadBabelConfig.ts");
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
||||
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const THIS_FILE = fs().readFileSync(__filename);
|
||||
const jestPresetPath = require.resolve('babel-preset-jest');
|
||||
const babelIstanbulPlugin = require.resolve('babel-plugin-istanbul');
|
||||
function assertLoadedBabelConfig(babelConfig, cwd, filename) {
|
||||
if (!babelConfig) {
|
||||
throw new Error(`babel-jest: Babel ignores ${_chalk().default.bold((0, _slash().default)(path().relative(cwd, filename)))} - make sure to include the file in Jest's ${_chalk().default.bold('transformIgnorePatterns')} as well.`);
|
||||
}
|
||||
}
|
||||
function addIstanbulInstrumentation(babelOptions, transformOptions) {
|
||||
if (transformOptions.instrument) {
|
||||
const copiedBabelOptions = {
|
||||
...babelOptions
|
||||
};
|
||||
copiedBabelOptions.auxiliaryCommentBefore = ' istanbul ignore next ';
|
||||
// Copied from jest-runtime transform.js
|
||||
copiedBabelOptions.plugins = [...(copiedBabelOptions.plugins ?? []), [babelIstanbulPlugin, {
|
||||
// files outside `cwd` will not be instrumented
|
||||
cwd: transformOptions.config.cwd,
|
||||
exclude: []
|
||||
}]];
|
||||
return copiedBabelOptions;
|
||||
}
|
||||
return babelOptions;
|
||||
}
|
||||
function getCacheKeyFromConfig(sourceText, sourcePath, babelOptions, transformOptions) {
|
||||
const {
|
||||
config,
|
||||
configString,
|
||||
instrument
|
||||
} = transformOptions;
|
||||
const configPath = [babelOptions.config ?? '', babelOptions.babelrc ?? ''];
|
||||
return (0, _crypto().createHash)('sha1').update(THIS_FILE).update('\0', 'utf8').update(JSON.stringify(babelOptions.options)).update('\0', 'utf8').update(sourceText).update('\0', 'utf8').update(path().relative(config.rootDir, sourcePath)).update('\0', 'utf8').update(configString).update('\0', 'utf8').update(configPath.join('')).update('\0', 'utf8').update(instrument ? 'instrument' : '').update('\0', 'utf8').update("production" ?? 0).update('\0', 'utf8').update(process.env.BABEL_ENV ?? '').update('\0', 'utf8').update(process.version).digest('hex').slice(0, 32);
|
||||
}
|
||||
function loadBabelConfig(cwd, filename, transformOptions) {
|
||||
const babelConfig = (0, _loadBabelConfig.loadPartialConfig)(transformOptions);
|
||||
assertLoadedBabelConfig(babelConfig, cwd, filename);
|
||||
return babelConfig;
|
||||
}
|
||||
async function loadBabelConfigAsync(cwd, filename, transformOptions) {
|
||||
const babelConfig = await (0, _loadBabelConfig.loadPartialConfigAsync)(transformOptions);
|
||||
assertLoadedBabelConfig(babelConfig, cwd, filename);
|
||||
return babelConfig;
|
||||
}
|
||||
function loadBabelOptions(cwd, filename, transformOptions, jestTransformOptions) {
|
||||
const {
|
||||
options
|
||||
} = loadBabelConfig(cwd, filename, transformOptions);
|
||||
return addIstanbulInstrumentation(options, jestTransformOptions);
|
||||
}
|
||||
async function loadBabelOptionsAsync(cwd, filename, transformOptions, jestTransformOptions) {
|
||||
const {
|
||||
options
|
||||
} = await loadBabelConfigAsync(cwd, filename, transformOptions);
|
||||
return addIstanbulInstrumentation(options, jestTransformOptions);
|
||||
}
|
||||
const createTransformer = transformerConfig => {
|
||||
const {
|
||||
excludeJestPreset,
|
||||
...inputOptions
|
||||
} = transformerConfig ?? {};
|
||||
const options = {
|
||||
...inputOptions,
|
||||
caller: {
|
||||
name: 'babel-jest',
|
||||
supportsDynamicImport: false,
|
||||
supportsExportNamespaceFrom: false,
|
||||
supportsStaticESM: false,
|
||||
supportsTopLevelAwait: false,
|
||||
...inputOptions.caller
|
||||
},
|
||||
compact: false,
|
||||
plugins: inputOptions.plugins ?? [],
|
||||
presets: [...(inputOptions.presets ?? []), ...(excludeJestPreset === true ? [] : [jestPresetPath])],
|
||||
sourceMaps: 'both'
|
||||
};
|
||||
function mergeBabelTransformOptions(filename, transformOptions) {
|
||||
const {
|
||||
cwd,
|
||||
rootDir
|
||||
} = transformOptions.config;
|
||||
// `cwd` and `root` first to allow incoming options to override it
|
||||
return {
|
||||
cwd,
|
||||
root: rootDir,
|
||||
...options,
|
||||
caller: {
|
||||
...options.caller,
|
||||
supportsDynamicImport: transformOptions.supportsDynamicImport ?? options.caller.supportsDynamicImport,
|
||||
supportsExportNamespaceFrom: transformOptions.supportsExportNamespaceFrom ?? options.caller.supportsExportNamespaceFrom,
|
||||
supportsStaticESM: transformOptions.supportsStaticESM ?? options.caller.supportsStaticESM,
|
||||
supportsTopLevelAwait: transformOptions.supportsTopLevelAwait ?? options.caller.supportsTopLevelAwait
|
||||
},
|
||||
filename
|
||||
};
|
||||
}
|
||||
return {
|
||||
canInstrument: true,
|
||||
getCacheKey(sourceText, sourcePath, transformOptions) {
|
||||
const babelOptions = loadBabelConfig(transformOptions.config.cwd, sourcePath, mergeBabelTransformOptions(sourcePath, transformOptions));
|
||||
return getCacheKeyFromConfig(sourceText, sourcePath, babelOptions, transformOptions);
|
||||
},
|
||||
async getCacheKeyAsync(sourceText, sourcePath, transformOptions) {
|
||||
const babelOptions = await loadBabelConfigAsync(transformOptions.config.cwd, sourcePath, mergeBabelTransformOptions(sourcePath, transformOptions));
|
||||
return getCacheKeyFromConfig(sourceText, sourcePath, babelOptions, transformOptions);
|
||||
},
|
||||
process(sourceText, sourcePath, transformOptions) {
|
||||
const babelOptions = loadBabelOptions(transformOptions.config.cwd, sourcePath, mergeBabelTransformOptions(sourcePath, transformOptions), transformOptions);
|
||||
const transformResult = (0, _core().transformSync)(sourceText, babelOptions);
|
||||
if (transformResult) {
|
||||
const {
|
||||
code,
|
||||
map
|
||||
} = transformResult;
|
||||
if (typeof code === 'string') {
|
||||
return {
|
||||
code,
|
||||
map
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
code: sourceText
|
||||
};
|
||||
},
|
||||
async processAsync(sourceText, sourcePath, transformOptions) {
|
||||
const babelOptions = await loadBabelOptionsAsync(transformOptions.config.cwd, sourcePath, mergeBabelTransformOptions(sourcePath, transformOptions), transformOptions);
|
||||
const transformResult = await (0, _core().transformAsync)(sourceText, babelOptions);
|
||||
if (transformResult) {
|
||||
const {
|
||||
code,
|
||||
map
|
||||
} = transformResult;
|
||||
if (typeof code === 'string') {
|
||||
return {
|
||||
code,
|
||||
map
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
code: sourceText
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
exports.createTransformer = createTransformer;
|
||||
const transformerFactory = {
|
||||
// Assigned here, instead of as a separate export, due to limitations in Jest's
|
||||
// requireOrImportModule, requiring all exports to be on the `default` export
|
||||
createTransformer
|
||||
};
|
||||
var _default = exports["default"] = transformerFactory;
|
||||
})();
|
||||
|
||||
module.exports = __webpack_exports__;
|
||||
/******/ })()
|
||||
;
|
||||
4
frontend/node_modules/babel-jest/build/index.mjs
generated
vendored
Normal file
4
frontend/node_modules/babel-jest/build/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import cjsModule from './index.js';
|
||||
|
||||
export const createTransformer = cjsModule.createTransformer;
|
||||
export default cjsModule.default;
|
||||
46
frontend/node_modules/babel-jest/package.json
generated
vendored
Normal file
46
frontend/node_modules/babel-jest/package.json
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "babel-jest",
|
||||
"description": "Jest plugin to use babel for transformation.",
|
||||
"version": "30.0.4",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jestjs/jest.git",
|
||||
"directory": "packages/babel-jest"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"require": "./build/index.js",
|
||||
"import": "./build/index.mjs",
|
||||
"default": "./build/index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jest/transform": "30.0.4",
|
||||
"@types/babel__core": "^7.20.5",
|
||||
"babel-plugin-istanbul": "^7.0.0",
|
||||
"babel-preset-jest": "30.0.1",
|
||||
"chalk": "^4.1.2",
|
||||
"graceful-fs": "^4.2.11",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.27.4",
|
||||
"@jest/test-utils": "30.0.4",
|
||||
"@types/graceful-fs": "^4.1.9"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"gitHead": "f4296d2bc85c1405f84ddf613a25d0bc3766b7e5"
|
||||
}
|
||||
Reference in New Issue
Block a user