Files
WRNexusJS/packages/test/src/platform.ts
T
Clintchiz 586a6db8ff
Quality / quality (ubuntu-latest) (push) Failing after 21s
Quality / quality (windows-latest) (push) Canceled after 0s
release: WRNexusJS 0.8.0
2026-08-02 23:18:51 +05:30

68 lines
2.3 KiB
TypeScript

import { mkdirSync } from "node:fs";
import { join, resolve } from "node:path";
export interface TransactionalDatabase {
tx<T>(callback: (transaction: TransactionalDatabase) => Promise<T>): Promise<T>;
}
const ROLLBACK = Symbol("wrnexus-test-rollback");
/** Run test work in a real transaction and always force rollback. */
export async function withDatabaseRollback<T>(
db: TransactionalDatabase,
run: (transaction: TransactionalDatabase) => T | Promise<T>,
): Promise<T> {
let output!: T;
try {
await db.tx(async (transaction) => {
output = await run(transaction);
throw ROLLBACK;
});
} catch (error) {
if (error !== ROLLBACK) throw error;
}
return output;
}
export function createFactory<T extends Record<string, unknown>>(build: (sequence: number) => T) {
let sequence = 0;
return {
build(overrides: Partial<T> = {}): T {
return { ...build(++sequence), ...overrides };
},
buildMany(count: number, overrides: Partial<T> = {}): T[] {
if (!Number.isInteger(count) || count < 0 || count > 10_000)
throw new RangeError("Factory count must be between 0 and 10000");
return Array.from({ length: count }, () => ({ ...build(++sequence), ...overrides }));
},
reset(): void {
sequence = 0;
},
};
}
export interface BrowserArtifactPage {
screenshot(options: { path: string; fullPage?: boolean }): Promise<unknown>;
context(): { tracing?: { stop(options: { path: string }): Promise<unknown> } };
}
export async function captureBrowserArtifacts(
page: BrowserArtifactPage,
testName: string,
options: { root?: string; screenshot?: boolean; trace?: boolean } = {},
): Promise<{ screenshot?: string; trace?: string }> {
const safe = testName.replace(/[^A-Za-z0-9_.-]+/g, "-").slice(0, 120) || "test";
const root = resolve(options.root ?? join("test-results", "wrnexus"));
mkdirSync(root, { recursive: true });
const output: { screenshot?: string; trace?: string } = {};
if (options.screenshot !== false) {
output.screenshot = join(root, `${safe}.png`);
await page.screenshot({ path: output.screenshot, fullPage: true });
}
if (options.trace && page.context().tracing) {
output.trace = join(root, `${safe}.zip`);
await page.context().tracing!.stop({ path: output.trace });
}
return output;
}