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/@jest/fake-timers/LICENSE
generated
vendored
Normal file
22
frontend/node_modules/@jest/fake-timers/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.
|
||||
107
frontend/node_modules/@jest/fake-timers/build/index.d.mts
generated
vendored
Normal file
107
frontend/node_modules/@jest/fake-timers/build/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
import { StackTraceConfig } from "jest-message-util";
|
||||
import { ModuleMocker } from "jest-mock";
|
||||
import { Config } from "@jest/types";
|
||||
|
||||
//#region src/legacyFakeTimers.d.ts
|
||||
|
||||
type Callback = (...args: Array<unknown>) => void;
|
||||
type TimerConfig<Ref> = {
|
||||
idToRef: (id: number) => Ref;
|
||||
refToId: (ref: Ref) => number | void;
|
||||
};
|
||||
declare class FakeTimers<TimerRef = unknown> {
|
||||
#private;
|
||||
private _cancelledTicks;
|
||||
private readonly _config;
|
||||
private _disposed;
|
||||
private _fakeTimerAPIs;
|
||||
private _fakingTime;
|
||||
private readonly _global;
|
||||
private _immediates;
|
||||
private readonly _maxLoops;
|
||||
private readonly _moduleMocker;
|
||||
private _now;
|
||||
private _ticks;
|
||||
private readonly _timerAPIs;
|
||||
private _timers;
|
||||
private _uuidCounter;
|
||||
private readonly _timerConfig;
|
||||
constructor({
|
||||
global,
|
||||
moduleMocker,
|
||||
timerConfig,
|
||||
config,
|
||||
maxLoops
|
||||
}: {
|
||||
global: typeof globalThis;
|
||||
moduleMocker: ModuleMocker;
|
||||
timerConfig: TimerConfig<TimerRef>;
|
||||
config: StackTraceConfig;
|
||||
maxLoops?: number;
|
||||
});
|
||||
clearAllTimers(): void;
|
||||
dispose(): void;
|
||||
reset(): void;
|
||||
now(): number;
|
||||
runAllTicks(): void;
|
||||
runAllImmediates(): void;
|
||||
private _runImmediate;
|
||||
runAllTimers(): void;
|
||||
runOnlyPendingTimers(): void;
|
||||
advanceTimersToNextTimer(steps?: number): void;
|
||||
advanceTimersByTime(msToRun: number): void;
|
||||
runWithRealTimers(cb: Callback): void;
|
||||
useRealTimers(): void;
|
||||
useFakeTimers(): void;
|
||||
getTimerCount(): number;
|
||||
private _checkFakeTimers;
|
||||
private _createMocks;
|
||||
private _fakeClearTimer;
|
||||
private _fakeClearImmediate;
|
||||
private _fakeNextTick;
|
||||
private _fakeRequestAnimationFrame;
|
||||
private _fakeSetImmediate;
|
||||
private _fakeSetInterval;
|
||||
private _fakeSetTimeout;
|
||||
private _getNextTimerHandleAndExpiry;
|
||||
private _runTimerHandle;
|
||||
}
|
||||
//#endregion
|
||||
//#region src/modernFakeTimers.d.ts
|
||||
declare class FakeTimers$1 {
|
||||
private _clock;
|
||||
private readonly _config;
|
||||
private _fakingTime;
|
||||
private readonly _global;
|
||||
private readonly _fakeTimers;
|
||||
constructor({
|
||||
global,
|
||||
config
|
||||
}: {
|
||||
global: typeof globalThis;
|
||||
config: Config.ProjectConfig;
|
||||
});
|
||||
clearAllTimers(): void;
|
||||
dispose(): void;
|
||||
runAllTimers(): void;
|
||||
runAllTimersAsync(): Promise<void>;
|
||||
runOnlyPendingTimers(): void;
|
||||
runOnlyPendingTimersAsync(): Promise<void>;
|
||||
advanceTimersToNextTimer(steps?: number): void;
|
||||
advanceTimersToNextTimerAsync(steps?: number): Promise<void>;
|
||||
advanceTimersByTime(msToRun: number): void;
|
||||
advanceTimersByTimeAsync(msToRun: number): Promise<void>;
|
||||
advanceTimersToNextFrame(): void;
|
||||
runAllTicks(): void;
|
||||
useRealTimers(): void;
|
||||
useFakeTimers(fakeTimersConfig?: Config.FakeTimersConfig): void;
|
||||
reset(): void;
|
||||
setSystemTime(now?: number | Date): void;
|
||||
getRealSystemTime(): number;
|
||||
now(): number;
|
||||
getTimerCount(): number;
|
||||
private _checkFakeTimers;
|
||||
private _toSinonFakeTimersConfig;
|
||||
}
|
||||
//#endregion
|
||||
export { FakeTimers as LegacyFakeTimers, FakeTimers$1 as ModernFakeTimers };
|
||||
113
frontend/node_modules/@jest/fake-timers/build/index.d.ts
generated
vendored
Normal file
113
frontend/node_modules/@jest/fake-timers/build/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* 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 {Config} from '@jest/types';
|
||||
import {StackTraceConfig} from 'jest-message-util';
|
||||
import {ModuleMocker} from 'jest-mock';
|
||||
|
||||
declare type Callback = (...args: Array<unknown>) => void;
|
||||
|
||||
export declare class LegacyFakeTimers<TimerRef = unknown> {
|
||||
#private;
|
||||
private _cancelledTicks;
|
||||
private readonly _config;
|
||||
private _disposed;
|
||||
private _fakeTimerAPIs;
|
||||
private _fakingTime;
|
||||
private readonly _global;
|
||||
private _immediates;
|
||||
private readonly _maxLoops;
|
||||
private readonly _moduleMocker;
|
||||
private _now;
|
||||
private _ticks;
|
||||
private readonly _timerAPIs;
|
||||
private _timers;
|
||||
private _uuidCounter;
|
||||
private readonly _timerConfig;
|
||||
constructor({
|
||||
global,
|
||||
moduleMocker,
|
||||
timerConfig,
|
||||
config,
|
||||
maxLoops,
|
||||
}: {
|
||||
global: typeof globalThis;
|
||||
moduleMocker: ModuleMocker;
|
||||
timerConfig: TimerConfig<TimerRef>;
|
||||
config: StackTraceConfig;
|
||||
maxLoops?: number;
|
||||
});
|
||||
clearAllTimers(): void;
|
||||
dispose(): void;
|
||||
reset(): void;
|
||||
now(): number;
|
||||
runAllTicks(): void;
|
||||
runAllImmediates(): void;
|
||||
private _runImmediate;
|
||||
runAllTimers(): void;
|
||||
runOnlyPendingTimers(): void;
|
||||
advanceTimersToNextTimer(steps?: number): void;
|
||||
advanceTimersByTime(msToRun: number): void;
|
||||
runWithRealTimers(cb: Callback): void;
|
||||
useRealTimers(): void;
|
||||
useFakeTimers(): void;
|
||||
getTimerCount(): number;
|
||||
private _checkFakeTimers;
|
||||
private _createMocks;
|
||||
private _fakeClearTimer;
|
||||
private _fakeClearImmediate;
|
||||
private _fakeNextTick;
|
||||
private _fakeRequestAnimationFrame;
|
||||
private _fakeSetImmediate;
|
||||
private _fakeSetInterval;
|
||||
private _fakeSetTimeout;
|
||||
private _getNextTimerHandleAndExpiry;
|
||||
private _runTimerHandle;
|
||||
}
|
||||
|
||||
export declare class ModernFakeTimers {
|
||||
private _clock;
|
||||
private readonly _config;
|
||||
private _fakingTime;
|
||||
private readonly _global;
|
||||
private readonly _fakeTimers;
|
||||
constructor({
|
||||
global,
|
||||
config,
|
||||
}: {
|
||||
global: typeof globalThis;
|
||||
config: Config.ProjectConfig;
|
||||
});
|
||||
clearAllTimers(): void;
|
||||
dispose(): void;
|
||||
runAllTimers(): void;
|
||||
runAllTimersAsync(): Promise<void>;
|
||||
runOnlyPendingTimers(): void;
|
||||
runOnlyPendingTimersAsync(): Promise<void>;
|
||||
advanceTimersToNextTimer(steps?: number): void;
|
||||
advanceTimersToNextTimerAsync(steps?: number): Promise<void>;
|
||||
advanceTimersByTime(msToRun: number): void;
|
||||
advanceTimersByTimeAsync(msToRun: number): Promise<void>;
|
||||
advanceTimersToNextFrame(): void;
|
||||
runAllTicks(): void;
|
||||
useRealTimers(): void;
|
||||
useFakeTimers(fakeTimersConfig?: Config.FakeTimersConfig): void;
|
||||
reset(): void;
|
||||
setSystemTime(now?: number | Date): void;
|
||||
getRealSystemTime(): number;
|
||||
now(): number;
|
||||
getTimerCount(): number;
|
||||
private _checkFakeTimers;
|
||||
private _toSinonFakeTimersConfig;
|
||||
}
|
||||
|
||||
declare type TimerConfig<Ref> = {
|
||||
idToRef: (id: number) => Ref;
|
||||
refToId: (ref: Ref) => number | void;
|
||||
};
|
||||
|
||||
export {};
|
||||
726
frontend/node_modules/@jest/fake-timers/build/index.js
generated
vendored
Normal file
726
frontend/node_modules/@jest/fake-timers/build/index.js
generated
vendored
Normal file
@@ -0,0 +1,726 @@
|
||||
/*!
|
||||
* /**
|
||||
* * 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/legacyFakeTimers.ts":
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
function _util() {
|
||||
const data = require("util");
|
||||
_util = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
function _jestMessageUtil() {
|
||||
const data = require("jest-message-util");
|
||||
_jestMessageUtil = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
function _jestUtil() {
|
||||
const data = require("jest-util");
|
||||
_jestUtil = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* eslint-disable local/prefer-spread-eventually */
|
||||
|
||||
const MS_IN_A_YEAR = 31_536_000_000;
|
||||
class FakeTimers {
|
||||
_cancelledTicks;
|
||||
_config;
|
||||
_disposed;
|
||||
_fakeTimerAPIs;
|
||||
_fakingTime = false;
|
||||
_global;
|
||||
_immediates;
|
||||
_maxLoops;
|
||||
_moduleMocker;
|
||||
_now;
|
||||
_ticks;
|
||||
_timerAPIs;
|
||||
_timers;
|
||||
_uuidCounter;
|
||||
_timerConfig;
|
||||
constructor({
|
||||
global,
|
||||
moduleMocker,
|
||||
timerConfig,
|
||||
config,
|
||||
maxLoops
|
||||
}) {
|
||||
this._global = global;
|
||||
this._timerConfig = timerConfig;
|
||||
this._config = config;
|
||||
this._maxLoops = maxLoops || 100_000;
|
||||
this._uuidCounter = 1;
|
||||
this._moduleMocker = moduleMocker;
|
||||
|
||||
// Store original timer APIs for future reference
|
||||
this._timerAPIs = {
|
||||
cancelAnimationFrame: global.cancelAnimationFrame,
|
||||
clearImmediate: global.clearImmediate,
|
||||
clearInterval: global.clearInterval,
|
||||
clearTimeout: global.clearTimeout,
|
||||
nextTick: global.process && global.process.nextTick,
|
||||
requestAnimationFrame: global.requestAnimationFrame,
|
||||
setImmediate: global.setImmediate,
|
||||
setInterval: global.setInterval,
|
||||
setTimeout: global.setTimeout
|
||||
};
|
||||
this._disposed = false;
|
||||
this.reset();
|
||||
}
|
||||
clearAllTimers() {
|
||||
this._immediates = [];
|
||||
this._timers.clear();
|
||||
}
|
||||
dispose() {
|
||||
this._disposed = true;
|
||||
this.clearAllTimers();
|
||||
}
|
||||
reset() {
|
||||
this._cancelledTicks = {};
|
||||
this._now = 0;
|
||||
this._ticks = [];
|
||||
this._immediates = [];
|
||||
this._timers = new Map();
|
||||
}
|
||||
now() {
|
||||
if (this._fakingTime) {
|
||||
return this._now;
|
||||
}
|
||||
return Date.now();
|
||||
}
|
||||
runAllTicks() {
|
||||
this._checkFakeTimers();
|
||||
// Only run a generous number of ticks and then bail.
|
||||
// This is just to help avoid recursive loops
|
||||
let i;
|
||||
for (i = 0; i < this._maxLoops; i++) {
|
||||
const tick = this._ticks.shift();
|
||||
if (tick === undefined) {
|
||||
break;
|
||||
}
|
||||
if (!Object.prototype.hasOwnProperty.call(this._cancelledTicks, tick.uuid)) {
|
||||
// Callback may throw, so update the map prior calling.
|
||||
this._cancelledTicks[tick.uuid] = true;
|
||||
tick.callback();
|
||||
}
|
||||
}
|
||||
if (i === this._maxLoops) {
|
||||
throw new Error(`Ran ${this._maxLoops} ticks, and there are still more! ` + "Assuming we've hit an infinite recursion and bailing out...");
|
||||
}
|
||||
}
|
||||
runAllImmediates() {
|
||||
this._checkFakeTimers();
|
||||
// Only run a generous number of immediates and then bail.
|
||||
let i;
|
||||
for (i = 0; i < this._maxLoops; i++) {
|
||||
const immediate = this._immediates.shift();
|
||||
if (immediate === undefined) {
|
||||
break;
|
||||
}
|
||||
this._runImmediate(immediate);
|
||||
}
|
||||
if (i === this._maxLoops) {
|
||||
throw new Error(`Ran ${this._maxLoops} immediates, and there are still more! Assuming ` + "we've hit an infinite recursion and bailing out...");
|
||||
}
|
||||
}
|
||||
_runImmediate(immediate) {
|
||||
try {
|
||||
immediate.callback();
|
||||
} finally {
|
||||
this._fakeClearImmediate(immediate.uuid);
|
||||
}
|
||||
}
|
||||
runAllTimers() {
|
||||
this._checkFakeTimers();
|
||||
this.runAllTicks();
|
||||
this.runAllImmediates();
|
||||
|
||||
// Only run a generous number of timers and then bail.
|
||||
// This is just to help avoid recursive loops
|
||||
let i;
|
||||
for (i = 0; i < this._maxLoops; i++) {
|
||||
const nextTimerHandleAndExpiry = this._getNextTimerHandleAndExpiry();
|
||||
|
||||
// If there are no more timer handles, stop!
|
||||
if (nextTimerHandleAndExpiry === null) {
|
||||
break;
|
||||
}
|
||||
const [nextTimerHandle, expiry] = nextTimerHandleAndExpiry;
|
||||
this._now = expiry;
|
||||
this._runTimerHandle(nextTimerHandle);
|
||||
|
||||
// Some of the immediate calls could be enqueued
|
||||
// during the previous handling of the timers, we should
|
||||
// run them as well.
|
||||
if (this._immediates.length > 0) {
|
||||
this.runAllImmediates();
|
||||
}
|
||||
if (this._ticks.length > 0) {
|
||||
this.runAllTicks();
|
||||
}
|
||||
}
|
||||
if (i === this._maxLoops) {
|
||||
throw new Error(`Ran ${this._maxLoops} timers, and there are still more! ` + "Assuming we've hit an infinite recursion and bailing out...");
|
||||
}
|
||||
}
|
||||
runOnlyPendingTimers() {
|
||||
// We need to hold the current shape of `this._timers` because existing
|
||||
// timers can add new ones to the map and hence would run more than necessary.
|
||||
// See https://github.com/jestjs/jest/pull/4608 for details
|
||||
const timerEntries = [...this._timers.entries()];
|
||||
this._checkFakeTimers();
|
||||
for (const _immediate of this._immediates) this._runImmediate(_immediate);
|
||||
for (const [timerHandle, timer] of timerEntries.sort(([, left], [, right]) => left.expiry - right.expiry)) {
|
||||
this._now = timer.expiry;
|
||||
this._runTimerHandle(timerHandle);
|
||||
}
|
||||
}
|
||||
advanceTimersToNextTimer(steps = 1) {
|
||||
if (steps < 1) {
|
||||
return;
|
||||
}
|
||||
const nextExpiry = [...this._timers.values()].reduce((minExpiry, timer) => {
|
||||
if (minExpiry === null || timer.expiry < minExpiry) return timer.expiry;
|
||||
return minExpiry;
|
||||
}, null);
|
||||
if (nextExpiry !== null) {
|
||||
this.advanceTimersByTime(nextExpiry - this._now);
|
||||
this.advanceTimersToNextTimer(steps - 1);
|
||||
}
|
||||
}
|
||||
advanceTimersByTime(msToRun) {
|
||||
this._checkFakeTimers();
|
||||
// Only run a generous number of timers and then bail.
|
||||
// This is just to help avoid recursive loops
|
||||
let i;
|
||||
for (i = 0; i < this._maxLoops; i++) {
|
||||
const timerHandleAndExpiry = this._getNextTimerHandleAndExpiry();
|
||||
|
||||
// If there are no more timer handles, stop!
|
||||
if (timerHandleAndExpiry === null) {
|
||||
break;
|
||||
}
|
||||
const [timerHandle, nextTimerExpiry] = timerHandleAndExpiry;
|
||||
if (this._now + msToRun < nextTimerExpiry) {
|
||||
// There are no timers between now and the target we're running to
|
||||
break;
|
||||
} else {
|
||||
msToRun -= nextTimerExpiry - this._now;
|
||||
this._now = nextTimerExpiry;
|
||||
this._runTimerHandle(timerHandle);
|
||||
}
|
||||
}
|
||||
|
||||
// Advance the clock by whatever time we still have left to run
|
||||
this._now += msToRun;
|
||||
if (i === this._maxLoops) {
|
||||
throw new Error(`Ran ${this._maxLoops} timers, and there are still more! ` + "Assuming we've hit an infinite recursion and bailing out...");
|
||||
}
|
||||
}
|
||||
runWithRealTimers(cb) {
|
||||
const prevClearImmediate = this._global.clearImmediate;
|
||||
const prevClearInterval = this._global.clearInterval;
|
||||
const prevClearTimeout = this._global.clearTimeout;
|
||||
const prevNextTick = this._global.process.nextTick;
|
||||
const prevSetImmediate = this._global.setImmediate;
|
||||
const prevSetInterval = this._global.setInterval;
|
||||
const prevSetTimeout = this._global.setTimeout;
|
||||
this.useRealTimers();
|
||||
let cbErr = null;
|
||||
let errThrown = false;
|
||||
try {
|
||||
cb();
|
||||
} catch (error) {
|
||||
errThrown = true;
|
||||
cbErr = error;
|
||||
}
|
||||
this._global.clearImmediate = prevClearImmediate;
|
||||
this._global.clearInterval = prevClearInterval;
|
||||
this._global.clearTimeout = prevClearTimeout;
|
||||
this._global.process.nextTick = prevNextTick;
|
||||
this._global.setImmediate = prevSetImmediate;
|
||||
this._global.setInterval = prevSetInterval;
|
||||
this._global.setTimeout = prevSetTimeout;
|
||||
if (errThrown) {
|
||||
throw cbErr;
|
||||
}
|
||||
}
|
||||
useRealTimers() {
|
||||
const global = this._global;
|
||||
if (typeof global.cancelAnimationFrame === 'function') {
|
||||
(0, _jestUtil().setGlobal)(global, 'cancelAnimationFrame', this._timerAPIs.cancelAnimationFrame);
|
||||
}
|
||||
if (typeof global.clearImmediate === 'function') {
|
||||
(0, _jestUtil().setGlobal)(global, 'clearImmediate', this._timerAPIs.clearImmediate);
|
||||
}
|
||||
(0, _jestUtil().setGlobal)(global, 'clearInterval', this._timerAPIs.clearInterval);
|
||||
(0, _jestUtil().setGlobal)(global, 'clearTimeout', this._timerAPIs.clearTimeout);
|
||||
if (typeof global.requestAnimationFrame === 'function') {
|
||||
(0, _jestUtil().setGlobal)(global, 'requestAnimationFrame', this._timerAPIs.requestAnimationFrame);
|
||||
}
|
||||
if (typeof global.setImmediate === 'function') {
|
||||
(0, _jestUtil().setGlobal)(global, 'setImmediate', this._timerAPIs.setImmediate);
|
||||
}
|
||||
(0, _jestUtil().setGlobal)(global, 'setInterval', this._timerAPIs.setInterval);
|
||||
(0, _jestUtil().setGlobal)(global, 'setTimeout', this._timerAPIs.setTimeout);
|
||||
global.process.nextTick = this._timerAPIs.nextTick;
|
||||
this._fakingTime = false;
|
||||
}
|
||||
useFakeTimers() {
|
||||
this._createMocks();
|
||||
const global = this._global;
|
||||
if (typeof global.cancelAnimationFrame === 'function') {
|
||||
(0, _jestUtil().setGlobal)(global, 'cancelAnimationFrame', this._fakeTimerAPIs.cancelAnimationFrame);
|
||||
}
|
||||
if (typeof global.clearImmediate === 'function') {
|
||||
(0, _jestUtil().setGlobal)(global, 'clearImmediate', this._fakeTimerAPIs.clearImmediate);
|
||||
}
|
||||
(0, _jestUtil().setGlobal)(global, 'clearInterval', this._fakeTimerAPIs.clearInterval);
|
||||
(0, _jestUtil().setGlobal)(global, 'clearTimeout', this._fakeTimerAPIs.clearTimeout);
|
||||
if (typeof global.requestAnimationFrame === 'function') {
|
||||
(0, _jestUtil().setGlobal)(global, 'requestAnimationFrame', this._fakeTimerAPIs.requestAnimationFrame);
|
||||
}
|
||||
if (typeof global.setImmediate === 'function') {
|
||||
(0, _jestUtil().setGlobal)(global, 'setImmediate', this._fakeTimerAPIs.setImmediate);
|
||||
}
|
||||
(0, _jestUtil().setGlobal)(global, 'setInterval', this._fakeTimerAPIs.setInterval);
|
||||
(0, _jestUtil().setGlobal)(global, 'setTimeout', this._fakeTimerAPIs.setTimeout);
|
||||
global.process.nextTick = this._fakeTimerAPIs.nextTick;
|
||||
this._fakingTime = true;
|
||||
}
|
||||
getTimerCount() {
|
||||
this._checkFakeTimers();
|
||||
return this._timers.size + this._immediates.length + this._ticks.length;
|
||||
}
|
||||
_checkFakeTimers() {
|
||||
if (!this._fakingTime) {
|
||||
this._global.console.warn('A function to advance timers was called but the timers APIs are not mocked ' + 'with fake timers. Call `jest.useFakeTimers({legacyFakeTimers: true})` ' + 'in this test file or enable fake timers for all tests by setting ' + "{'enableGlobally': true, 'legacyFakeTimers': true} in " + `Jest configuration file.\nStack Trace:\n${(0, _jestMessageUtil().formatStackTrace)(
|
||||
// eslint-disable-next-line unicorn/error-message
|
||||
new Error().stack, this._config, {
|
||||
noStackTrace: false
|
||||
})}`);
|
||||
}
|
||||
}
|
||||
#createMockFunction(implementation) {
|
||||
return this._moduleMocker.fn(implementation.bind(this));
|
||||
}
|
||||
_createMocks() {
|
||||
const promisifiableFakeSetTimeout = this.#createMockFunction(this._fakeSetTimeout);
|
||||
// @ts-expect-error: no index
|
||||
promisifiableFakeSetTimeout[_util().promisify.custom] = (delay, arg) => new Promise(resolve => promisifiableFakeSetTimeout(resolve, delay, arg));
|
||||
this._fakeTimerAPIs = {
|
||||
cancelAnimationFrame: this.#createMockFunction(this._fakeClearTimer),
|
||||
clearImmediate: this.#createMockFunction(this._fakeClearImmediate),
|
||||
clearInterval: this.#createMockFunction(this._fakeClearTimer),
|
||||
clearTimeout: this.#createMockFunction(this._fakeClearTimer),
|
||||
nextTick: this.#createMockFunction(this._fakeNextTick),
|
||||
requestAnimationFrame: this.#createMockFunction(this._fakeRequestAnimationFrame),
|
||||
setImmediate: this.#createMockFunction(this._fakeSetImmediate),
|
||||
setInterval: this.#createMockFunction(this._fakeSetInterval),
|
||||
setTimeout: promisifiableFakeSetTimeout
|
||||
};
|
||||
}
|
||||
_fakeClearTimer(timerRef) {
|
||||
const uuid = this._timerConfig.refToId(timerRef);
|
||||
if (uuid) {
|
||||
this._timers.delete(String(uuid));
|
||||
}
|
||||
}
|
||||
_fakeClearImmediate(uuid) {
|
||||
this._immediates = this._immediates.filter(immediate => immediate.uuid !== uuid);
|
||||
}
|
||||
_fakeNextTick(callback, ...args) {
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
const uuid = String(this._uuidCounter++);
|
||||
this._ticks.push({
|
||||
callback: () => callback.apply(null, args),
|
||||
uuid
|
||||
});
|
||||
const cancelledTicks = this._cancelledTicks;
|
||||
this._timerAPIs.nextTick(() => {
|
||||
if (!Object.prototype.hasOwnProperty.call(cancelledTicks, uuid)) {
|
||||
// Callback may throw, so update the map prior calling.
|
||||
cancelledTicks[uuid] = true;
|
||||
callback.apply(null, args);
|
||||
}
|
||||
});
|
||||
}
|
||||
_fakeRequestAnimationFrame(callback) {
|
||||
return this._fakeSetTimeout(() => {
|
||||
// TODO: Use performance.now() once it's mocked
|
||||
callback(this._now);
|
||||
}, 1000 / 60);
|
||||
}
|
||||
_fakeSetImmediate(callback, ...args) {
|
||||
if (this._disposed) {
|
||||
return null;
|
||||
}
|
||||
const uuid = String(this._uuidCounter++);
|
||||
this._immediates.push({
|
||||
callback: () => callback.apply(null, args),
|
||||
uuid
|
||||
});
|
||||
this._timerAPIs.setImmediate(() => {
|
||||
if (!this._disposed) {
|
||||
if (this._immediates.some(x => x.uuid === uuid)) {
|
||||
try {
|
||||
callback.apply(null, args);
|
||||
} finally {
|
||||
this._fakeClearImmediate(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return uuid;
|
||||
}
|
||||
_fakeSetInterval(callback, intervalDelay, ...args) {
|
||||
if (this._disposed) {
|
||||
return null;
|
||||
}
|
||||
if (intervalDelay == null) {
|
||||
intervalDelay = 0;
|
||||
}
|
||||
const uuid = this._uuidCounter++;
|
||||
this._timers.set(String(uuid), {
|
||||
callback: () => callback.apply(null, args),
|
||||
expiry: this._now + intervalDelay,
|
||||
interval: intervalDelay,
|
||||
type: 'interval'
|
||||
});
|
||||
return this._timerConfig.idToRef(uuid);
|
||||
}
|
||||
_fakeSetTimeout(callback, delay, ...args) {
|
||||
if (this._disposed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-bitwise,unicorn/prefer-math-trunc
|
||||
delay = Number(delay) | 0;
|
||||
const uuid = this._uuidCounter++;
|
||||
this._timers.set(String(uuid), {
|
||||
callback: () => callback.apply(null, args),
|
||||
expiry: this._now + delay,
|
||||
interval: undefined,
|
||||
type: 'timeout'
|
||||
});
|
||||
return this._timerConfig.idToRef(uuid);
|
||||
}
|
||||
_getNextTimerHandleAndExpiry() {
|
||||
let nextTimerHandle = null;
|
||||
let soonestTime = MS_IN_A_YEAR;
|
||||
for (const [uuid, timer] of this._timers.entries()) {
|
||||
if (timer.expiry < soonestTime) {
|
||||
soonestTime = timer.expiry;
|
||||
nextTimerHandle = uuid;
|
||||
}
|
||||
}
|
||||
if (nextTimerHandle === null) {
|
||||
return null;
|
||||
}
|
||||
return [nextTimerHandle, soonestTime];
|
||||
}
|
||||
_runTimerHandle(timerHandle) {
|
||||
const timer = this._timers.get(timerHandle);
|
||||
if (!timer) {
|
||||
// Timer has been cleared - we'll hit this when a timer is cleared within
|
||||
// another timer in runOnlyPendingTimers
|
||||
return;
|
||||
}
|
||||
switch (timer.type) {
|
||||
case 'timeout':
|
||||
this._timers.delete(timerHandle);
|
||||
timer.callback();
|
||||
break;
|
||||
case 'interval':
|
||||
timer.expiry = this._now + (timer.interval || 0);
|
||||
timer.callback();
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unexpected timer type: ${timer.type}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports["default"] = FakeTimers;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./src/modernFakeTimers.ts":
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
function _fakeTimers() {
|
||||
const data = require("@sinonjs/fake-timers");
|
||||
_fakeTimers = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
function _jestMessageUtil() {
|
||||
const data = require("jest-message-util");
|
||||
_jestMessageUtil = function () {
|
||||
return data;
|
||||
};
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class FakeTimers {
|
||||
_clock;
|
||||
_config;
|
||||
_fakingTime;
|
||||
_global;
|
||||
_fakeTimers;
|
||||
constructor({
|
||||
global,
|
||||
config
|
||||
}) {
|
||||
this._global = global;
|
||||
this._config = config;
|
||||
this._fakingTime = false;
|
||||
this._fakeTimers = (0, _fakeTimers().withGlobal)(global);
|
||||
}
|
||||
clearAllTimers() {
|
||||
if (this._fakingTime) {
|
||||
this._clock.reset();
|
||||
}
|
||||
}
|
||||
dispose() {
|
||||
this.useRealTimers();
|
||||
}
|
||||
runAllTimers() {
|
||||
if (this._checkFakeTimers()) {
|
||||
this._clock.runAll();
|
||||
}
|
||||
}
|
||||
async runAllTimersAsync() {
|
||||
if (this._checkFakeTimers()) {
|
||||
await this._clock.runAllAsync();
|
||||
}
|
||||
}
|
||||
runOnlyPendingTimers() {
|
||||
if (this._checkFakeTimers()) {
|
||||
this._clock.runToLast();
|
||||
}
|
||||
}
|
||||
async runOnlyPendingTimersAsync() {
|
||||
if (this._checkFakeTimers()) {
|
||||
await this._clock.runToLastAsync();
|
||||
}
|
||||
}
|
||||
advanceTimersToNextTimer(steps = 1) {
|
||||
if (this._checkFakeTimers()) {
|
||||
for (let i = steps; i > 0; i--) {
|
||||
this._clock.next();
|
||||
// Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250
|
||||
this._clock.tick(0);
|
||||
if (this._clock.countTimers() === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async advanceTimersToNextTimerAsync(steps = 1) {
|
||||
if (this._checkFakeTimers()) {
|
||||
for (let i = steps; i > 0; i--) {
|
||||
await this._clock.nextAsync();
|
||||
// Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250
|
||||
await this._clock.tickAsync(0);
|
||||
if (this._clock.countTimers() === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
advanceTimersByTime(msToRun) {
|
||||
if (this._checkFakeTimers()) {
|
||||
this._clock.tick(msToRun);
|
||||
}
|
||||
}
|
||||
async advanceTimersByTimeAsync(msToRun) {
|
||||
if (this._checkFakeTimers()) {
|
||||
await this._clock.tickAsync(msToRun);
|
||||
}
|
||||
}
|
||||
advanceTimersToNextFrame() {
|
||||
if (this._checkFakeTimers()) {
|
||||
this._clock.runToFrame();
|
||||
}
|
||||
}
|
||||
runAllTicks() {
|
||||
if (this._checkFakeTimers()) {
|
||||
// @ts-expect-error - doesn't exist?
|
||||
this._clock.runMicrotasks();
|
||||
}
|
||||
}
|
||||
useRealTimers() {
|
||||
if (this._fakingTime) {
|
||||
this._clock.uninstall();
|
||||
this._fakingTime = false;
|
||||
}
|
||||
}
|
||||
useFakeTimers(fakeTimersConfig) {
|
||||
if (this._fakingTime) {
|
||||
this._clock.uninstall();
|
||||
}
|
||||
this._clock = this._fakeTimers.install(this._toSinonFakeTimersConfig(fakeTimersConfig));
|
||||
this._fakingTime = true;
|
||||
}
|
||||
reset() {
|
||||
if (this._checkFakeTimers()) {
|
||||
const {
|
||||
now
|
||||
} = this._clock;
|
||||
this._clock.reset();
|
||||
this._clock.setSystemTime(now);
|
||||
}
|
||||
}
|
||||
setSystemTime(now) {
|
||||
if (this._checkFakeTimers()) {
|
||||
this._clock.setSystemTime(now);
|
||||
}
|
||||
}
|
||||
getRealSystemTime() {
|
||||
return Date.now();
|
||||
}
|
||||
now() {
|
||||
if (this._fakingTime) {
|
||||
return this._clock.now;
|
||||
}
|
||||
return Date.now();
|
||||
}
|
||||
getTimerCount() {
|
||||
if (this._checkFakeTimers()) {
|
||||
return this._clock.countTimers();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
_checkFakeTimers() {
|
||||
if (!this._fakingTime) {
|
||||
this._global.console.warn('A function to advance timers was called but the timers APIs are not replaced ' + 'with fake timers. Call `jest.useFakeTimers()` in this test file or enable ' + "fake timers for all tests by setting 'fakeTimers': {'enableGlobally': true} " + `in Jest configuration file.\nStack Trace:\n${(0, _jestMessageUtil().formatStackTrace)(
|
||||
// eslint-disable-next-line unicorn/error-message
|
||||
new Error().stack, this._config, {
|
||||
noStackTrace: false
|
||||
})}`);
|
||||
}
|
||||
return this._fakingTime;
|
||||
}
|
||||
_toSinonFakeTimersConfig(fakeTimersConfig = {}) {
|
||||
fakeTimersConfig = {
|
||||
...this._config.fakeTimers,
|
||||
...fakeTimersConfig
|
||||
};
|
||||
const advanceTimeDelta = typeof fakeTimersConfig.advanceTimers === 'number' ? fakeTimersConfig.advanceTimers : undefined;
|
||||
const toFake = new Set(Object.keys(this._fakeTimers.timers));
|
||||
if (fakeTimersConfig.doNotFake) for (const nameOfFakeableAPI of fakeTimersConfig.doNotFake) {
|
||||
toFake.delete(nameOfFakeableAPI);
|
||||
}
|
||||
return {
|
||||
advanceTimeDelta,
|
||||
loopLimit: fakeTimersConfig.timerLimit || 100_000,
|
||||
now: fakeTimersConfig.now ?? Date.now(),
|
||||
shouldAdvanceTime: Boolean(fakeTimersConfig.advanceTimers),
|
||||
shouldClearNativeTimers: true,
|
||||
toFake: [...toFake]
|
||||
};
|
||||
}
|
||||
}
|
||||
exports["default"] = FakeTimers;
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // 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
|
||||
}));
|
||||
Object.defineProperty(exports, "LegacyFakeTimers", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _legacyFakeTimers.default;
|
||||
}
|
||||
}));
|
||||
Object.defineProperty(exports, "ModernFakeTimers", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _modernFakeTimers.default;
|
||||
}
|
||||
}));
|
||||
var _legacyFakeTimers = _interopRequireDefault(__webpack_require__("./src/legacyFakeTimers.ts"));
|
||||
var _modernFakeTimers = _interopRequireDefault(__webpack_require__("./src/modernFakeTimers.ts"));
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
||||
})();
|
||||
|
||||
module.exports = __webpack_exports__;
|
||||
/******/ })()
|
||||
;
|
||||
4
frontend/node_modules/@jest/fake-timers/build/index.mjs
generated
vendored
Normal file
4
frontend/node_modules/@jest/fake-timers/build/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import cjsModule from './index.js';
|
||||
|
||||
export const LegacyFakeTimers = cjsModule.LegacyFakeTimers;
|
||||
export const ModernFakeTimers = cjsModule.ModernFakeTimers;
|
||||
40
frontend/node_modules/@jest/fake-timers/package.json
generated
vendored
Normal file
40
frontend/node_modules/@jest/fake-timers/package.json
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@jest/fake-timers",
|
||||
"version": "30.0.4",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jestjs/jest.git",
|
||||
"directory": "packages/jest-fake-timers"
|
||||
},
|
||||
"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/types": "30.0.1",
|
||||
"@sinonjs/fake-timers": "^13.0.0",
|
||||
"@types/node": "*",
|
||||
"jest-message-util": "30.0.2",
|
||||
"jest-mock": "30.0.2",
|
||||
"jest-util": "30.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/test-utils": "30.0.4",
|
||||
"@types/sinonjs__fake-timers": "^8.1.5"
|
||||
},
|
||||
"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