/** * Zenith Silver E2E Test Runner & Assertion Library * High-performance, zero-dependency async test framework for Receipt Scanner to Excel */ // ANSI Color Codes const RESET = "\x1b[0m"; const BOLD = "\x1b[1m"; const DIM = "\x1b[2m"; const RED = "\x1b[31m"; const GREEN = "\x1b[32m"; const YELLOW = "\x1b[33m"; const BLUE = "\x1b[34m"; const MAGENTA = "\x1b[35m"; const CYAN = "\x1b[36m"; const WHITE = "\x1b[37m"; const BG_RED = "\x1b[41m"; const BG_GREEN = "\x1b[42m"; export type TestFn = () => void | Promise; export type HookFn = () => void | Promise; export interface TestCase { name: string; fn: TestFn; durationMs?: number; error?: Error; passed?: boolean; } export interface TestSuite { name: string; tests: TestCase[]; beforeAllHooks: HookFn[]; afterAllHooks: HookFn[]; beforeEachHooks: HookFn[]; afterEachHooks: HookFn[]; parent?: TestSuite; children: TestSuite[]; } class TestRegistry { suites: TestSuite[] = []; currentSuite: TestSuite | null = null; createSuite(name: string, parent?: TestSuite): TestSuite { return { name, tests: [], beforeAllHooks: [], afterAllHooks: [], beforeEachHooks: [], afterEachHooks: [], parent, children: [], }; } } const registry = new TestRegistry(); export function describe(name: string, fn: () => void) { const suite = registry.createSuite(name, registry.currentSuite || undefined); if (registry.currentSuite) { registry.currentSuite.children.push(suite); } else { registry.suites.push(suite); } const previousSuite = registry.currentSuite; registry.currentSuite = suite; try { fn(); } finally { registry.currentSuite = previousSuite; } } export function test(name: string, fn: TestFn) { if (!registry.currentSuite) { const rootSuite = registry.createSuite("Root Suite"); registry.suites.push(rootSuite); registry.currentSuite = rootSuite; } registry.currentSuite.tests.push({ name, fn }); } export const it = test; export function beforeAll(fn: HookFn) { if (registry.currentSuite) { registry.currentSuite.beforeAllHooks.push(fn); } } export function afterAll(fn: HookFn) { if (registry.currentSuite) { registry.currentSuite.afterAllHooks.push(fn); } } export function beforeEach(fn: HookFn) { if (registry.currentSuite) { registry.currentSuite.beforeEachHooks.push(fn); } } export function afterEach(fn: HookFn) { if (registry.currentSuite) { registry.currentSuite.afterEachHooks.push(fn); } } // ============================================================================ // ASSERTION LIBRARY (expect) // ============================================================================ export class AssertionError extends Error { constructor(message: string, public actual?: any, public expected?: any) { super(message); this.name = "AssertionError"; } } function deepEqual(a: any, b: any): boolean { if (a === b) return true; if (a == null || b == null) return false; if (typeof a !== "object" || typeof b !== "object") return false; if (Array.isArray(a) !== Array.isArray(b)) return false; if (Array.isArray(a)) { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { if (!deepEqual(a[i], b[i])) return false; } return true; } if (a instanceof Date && b instanceof Date) { return a.getTime() === b.getTime(); } if (a instanceof RegExp && b instanceof RegExp) { return a.toString() === b.toString(); } const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; for (const key of keysA) { if (!Object.prototype.hasOwnProperty.call(b, key)) return false; if (!deepEqual(a[key], b[key])) return false; } return true; } export interface Matchers { toBe(expected: any): void; toEqual(expected: any): void; toStrictEqual(expected: any): void; toBeCloseTo(expected: number, deltaOrDigits?: number): void; toBeGreaterThan(expected: number): void; toBeGreaterThanOrEqual(expected: number): void; toBeLessThan(expected: number): void; toBeLessThanOrEqual(expected: number): void; toBeTruthy(): void; toBeFalsy(): void; toBeNull(): void; toBeUndefined(): void; toBeDefined(): void; toContain(expected: any): void; toHaveLength(expected: number): void; toMatch(regex: RegExp | string): void; toBeInstanceOf(expected: any): void; toThrow(expectedError?: string | RegExp | Function): void; not: Matchers; } export function expect(actual: T): Matchers { const createMatcher = (isNot: boolean): Matchers => { return { toBe(expected: any) { const pass = Object.is(actual, expected); if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${JSON.stringify(actual)} ${isNot ? "NOT to be" : "to be"} ${JSON.stringify(expected)}`, actual, expected ); } }, toEqual(expected: any) { const pass = deepEqual(actual, expected); if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${JSON.stringify(actual)} ${isNot ? "NOT to equal" : "to equal"} ${JSON.stringify(expected)}`, actual, expected ); } }, toStrictEqual(expected: any) { const pass = deepEqual(actual, expected); if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${JSON.stringify(actual)} ${isNot ? "NOT to strictly equal" : "to strictly equal"} ${JSON.stringify(expected)}`, actual, expected ); } }, toBeCloseTo(expected: number, deltaOrDigits: number = 2) { if (typeof actual !== "number") { throw new AssertionError(`Actual value ${actual} is not a number`); } // If deltaOrDigits <= 0.1, treat as delta, otherwise decimal digits const delta = deltaOrDigits < 1 ? deltaOrDigits : Math.pow(10, -deltaOrDigits) / 2; const diff = Math.abs(actual - expected); const pass = diff <= delta; if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${actual} ${isNot ? "NOT to be close to" : "to be close to"} ${expected} (diff: ${diff.toFixed(4)}, max allowed: ${delta})`, actual, expected ); } }, toBeGreaterThan(expected: number) { const pass = (actual as any) > expected; if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${actual} ${isNot ? "NOT to be >" : "to be >"} ${expected}`, actual, expected ); } }, toBeGreaterThanOrEqual(expected: number) { const pass = (actual as any) >= expected; if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${actual} ${isNot ? "NOT to be >=" : "to be >="} ${expected}`, actual, expected ); } }, toBeLessThan(expected: number) { const pass = (actual as any) < expected; if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${actual} ${isNot ? "NOT to be <" : "to be <"} ${expected}`, actual, expected ); } }, toBeLessThanOrEqual(expected: number) { const pass = (actual as any) <= expected; if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${actual} ${isNot ? "NOT to be <=" : "to be <="} ${expected}`, actual, expected ); } }, toBeTruthy() { const pass = Boolean(actual); if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${JSON.stringify(actual)} ${isNot ? "to be falsy" : "to be truthy"}`, actual, !isNot ); } }, toBeFalsy() { const pass = !Boolean(actual); if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${JSON.stringify(actual)} ${isNot ? "to be truthy" : "to be falsy"}`, actual, isNot ); } }, toBeNull() { const pass = actual === null; if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${JSON.stringify(actual)} ${isNot ? "NOT to be null" : "to be null"}`, actual, null ); } }, toBeUndefined() { const pass = actual === undefined; if (isNot ? pass : !pass) { throw new AssertionError( `Expected ${actual} ${isNot ? "NOT to be undefined" : "to be undefined"}`, actual, undefined ); } }, toBeDefined() { const pass = actual !== undefined; if (isNot ? pass : !pass) { throw new AssertionError( `Expected value ${isNot ? "to be undefined" : "to be defined"}`, actual, "defined" ); } }, toContain(expected: any) { let pass = false; if (typeof actual === "string") { pass = actual.includes(String(expected)); } else if (Array.isArray(actual)) { pass = actual.some((item) => deepEqual(item, expected)); } else if (actual instanceof Set || actual instanceof Map) { pass = (actual as any).has(expected); } if (isNot ? pass : !pass) { throw new AssertionError( `Expected container ${isNot ? "NOT to contain" : "to contain"} ${JSON.stringify(expected)}`, actual, expected ); } }, toHaveLength(expected: number) { const len = (actual as any)?.length ?? (actual as any)?.size; const pass = len === expected; if (isNot ? pass : !pass) { throw new AssertionError( `Expected length ${isNot ? "NOT to be" : "to be"} ${expected}, but received ${len}`, len, expected ); } }, toMatch(regex: RegExp | string) { const str = String(actual); const re = typeof regex === "string" ? new RegExp(regex) : regex; const pass = re.test(str); if (isNot ? pass : !pass) { throw new AssertionError( `Expected string "${str}" ${isNot ? "NOT to match" : "to match"} pattern ${re}`, actual, regex ); } }, toBeInstanceOf(expected: any) { const pass = actual instanceof expected; if (isNot ? pass : !pass) { throw new AssertionError( `Expected object ${isNot ? "NOT to be instance of" : "to be instance of"} ${expected?.name || expected}`, actual, expected ); } }, toThrow(expectedError?: string | RegExp | Function) { if (typeof actual !== "function") { throw new AssertionError(`Actual target is not a function: ${typeof actual}`); } let threw = false; let caughtError: any = null; try { (actual as any)(); } catch (err) { threw = true; caughtError = err; } if (isNot) { if (threw) { throw new AssertionError( `Expected function NOT to throw, but it threw: ${caughtError?.message || caughtError}` ); } return; } if (!threw) { throw new AssertionError(`Expected function to throw an error, but it returned cleanly`); } if (expectedError) { const msg = caughtError?.message || String(caughtError); if (typeof expectedError === "string" && !msg.includes(expectedError)) { throw new AssertionError( `Expected thrown error message to contain "${expectedError}", received: "${msg}"` ); } else if (expectedError instanceof RegExp && !expectedError.test(msg)) { throw new AssertionError( `Expected thrown error message to match ${expectedError}, received: "${msg}"` ); } else if (typeof expectedError === "function" && !(caughtError instanceof expectedError)) { throw new AssertionError( `Expected thrown error to be instance of ${expectedError.name}, received: ${caughtError?.name}` ); } } }, get not() { return createMatcher(!isNot); }, }; }; return createMatcher(false); } // ============================================================================ // SUITE EXECUTION ENGINE // ============================================================================ export interface RunResults { totalSuites: number; totalTests: number; passedCount: number; failedCount: number; durationMs: number; failures: { suiteName: string; testName: string; error: Error }[]; } async function runSuite( suite: TestSuite, results: RunResults, indent = "" ): Promise { results.totalSuites++; console.log(`\n${indent}${BOLD}${CYAN}▸ ${suite.name}${RESET}`); // Run beforeAll hooks for (const hook of suite.beforeAllHooks) { try { await hook(); } catch (err: any) { console.error(`${indent} ${RED}✖ [beforeAll Hook Failed]${RESET}`, err.message); throw err; } } // Run suite tests for (const testCase of suite.tests) { results.totalTests++; // Run beforeEach hooks for (const hook of suite.beforeEachHooks) { await hook(); } const startTime = performance.now(); try { await testCase.fn(); testCase.durationMs = performance.now() - startTime; testCase.passed = true; results.passedCount++; const timeStr = testCase.durationMs > 100 ? `${YELLOW}(${testCase.durationMs.toFixed(1)}ms)${RESET}` : `${DIM}(${testCase.durationMs.toFixed(1)}ms)${RESET}`; console.log(`${indent} ${GREEN}✓${RESET} ${testCase.name} ${timeStr}`); } catch (err: any) { testCase.durationMs = performance.now() - startTime; testCase.passed = false; testCase.error = err; results.failedCount++; results.failures.push({ suiteName: suite.name, testName: testCase.name, error: err, }); console.log(`${indent} ${RED}✖ ${testCase.name}${RESET} ${RED}(${testCase.durationMs.toFixed(1)}ms)${RESET}`); console.log(`${indent} ${RED}${err.name}: ${err.message}${RESET}`); if (err.stack) { const stackLines = err.stack.split("\n").slice(1, 4).map((l: string) => `${indent} ${DIM}${l.trim()}${RESET}`); console.log(stackLines.join("\n")); } } // Run afterEach hooks for (const hook of suite.afterEachHooks) { await hook(); } } // Run nested suites for (const childSuite of suite.children) { await runSuite(childSuite, results, indent + " "); } // Run afterAll hooks for (const hook of suite.afterAllHooks) { try { await hook(); } catch (err: any) { console.error(`${indent} ${RED}✖ [afterAll Hook Failed]${RESET}`, err.message); } } } export async function runAllTests(filterPattern?: string): Promise { const globalStartTime = performance.now(); console.log(`\n${BOLD}${WHITE}================================================================================${RESET}`); console.log(`${BOLD}${CYAN} ZENITH SILVER RECEIPT SCANNER — END-TO-END VERIFICATION SUITE ${RESET}`); console.log(`${BOLD}${WHITE}================================================================================${RESET}`); console.log(`${DIM}Runner: Native Async TypeScript • Date: ${new Date().toISOString()}${RESET}\n`); const results: RunResults = { totalSuites: 0, totalTests: 0, passedCount: 0, failedCount: 0, durationMs: 0, failures: [], }; const suitesToRun = filterPattern ? registry.suites.filter((s) => s.name.toLowerCase().includes(filterPattern.toLowerCase())) : registry.suites; for (const suite of suitesToRun) { await runSuite(suite, results); } results.durationMs = performance.now() - globalStartTime; console.log(`\n${BOLD}${WHITE}================================================================================${RESET}`); console.log(`${BOLD}TEST RUN SUMMARY${RESET}`); console.log(`${BOLD}${WHITE}================================================================================${RESET}`); console.log(`Total Suites : ${results.totalSuites}`); console.log(`Total Tests : ${results.totalTests}`); console.log(`Passed Tests : ${GREEN}${BOLD}${results.passedCount} ✓${RESET}`); console.log(`Failed Tests : ${results.failedCount > 0 ? `${RED}${BOLD}${results.failedCount} ✖${RESET}` : `${GREEN}0${RESET}`}`); console.log(`Total Time : ${(results.durationMs / 1000).toFixed(2)}s (${results.durationMs.toFixed(1)} ms)`); if (results.failures.length > 0) { console.log(`\n${BOLD}${RED}FAILED TESTS SUMMARY (${results.failures.length}):${RESET}`); results.failures.forEach((f, idx) => { console.log(`\n ${RED}${idx + 1}) [${f.suiteName}] ${f.testName}${RESET}`); console.log(` ${RED}${f.error.name}: ${f.error.message}${RESET}`); }); } const allPassed = results.failedCount === 0 && results.totalTests > 0; if (allPassed) { console.log(`\n${BG_GREEN}${BOLD}${WHITE} ALL ${results.totalTests} TESTS PASSED CLEANLY (100% VERIFIED) ${RESET}\n`); } else { console.log(`\n${BG_RED}${BOLD}${WHITE} TEST SUITE FAILED WITH ${results.failedCount} ERRORS ${RESET}\n`); } return allPassed; } // Automatically execute if run directly async function main() { const args = process.argv.slice(2); const filter = args[0]; // Import test suites dynamically if this is the entry point try { await import("./tier1_features.test"); await import("./tier2_boundaries.test"); await import("./tier3_interactions.test"); await import("./tier4_workloads.test"); await import("../../src/components/dashboard/__tests__/batchUpload.test"); await import("./m1_adversarial.test"); await import("./challenger2_stress.test"); await import("../../src/components/dashboard/__tests__/inspectorModal.test"); await import("./m2_adversarial.test"); await import("../../src/components/dashboard/__tests__/liveTable.test"); await import("./m3_adversarial.test"); await import("./challenger_m3_stress"); await import("./m3_challenger_deep_stress.test"); await import("../../src/components/dashboard/__tests__/responsiveShell.test"); await import("./m4_adversarial.test"); await import("./challenger_m4_stress"); await import("./challenger_m4_2_stress"); await import("./challenger_m4_1_deep_stress"); await import("./extraction_quality.test"); await import("./export_localization.test"); await import("./export_pdf.test"); await import("./challenger_excel_adversarial.test"); await import("./auth_security.test"); await import("./security_headers.test"); await import("./csrf_tokens.test"); await import("./subdomain_routing.test"); await import("./seo_slugs.test"); await import("./user_enumeration.test"); await import("./upload_whitelist.test"); await import("./sprint_a_scanner.test"); await import("./sprint_b_speed.test"); await import("./sprint_c_image.test"); await import("./sprint_e.test"); await import("./server_pricing.test"); await import("./webhook_verification.test"); } catch (err) { console.error("Failed to load test suite modules:", err); process.exit(1); } const success = await runAllTests(filter); if (!success) { process.exit(1); } } // Check if current file is the main entry point if (typeof require !== "undefined" && require.main === module) { main().catch((err) => { console.error("Fatal runner crash:", err); process.exit(1); }); } else if (typeof process !== "undefined" && process.argv && process.argv[1]?.includes("runner.ts")) { main().catch((err) => { console.error("Fatal runner crash:", err); process.exit(1); }); }