release: WRNexusJS 0.8.0
This commit is contained in:
@@ -190,3 +190,5 @@ export {
|
||||
MemoryCookieJar,
|
||||
} from "./advanced.ts";
|
||||
export type { TestRequestOptions, JsonResponse, Deferred, WaitForOptions } from "./advanced.ts";
|
||||
export { withDatabaseRollback, createFactory, captureBrowserArtifacts } from "./platform.ts";
|
||||
export type { TransactionalDatabase, BrowserArtifactPage } from "./platform.ts";
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user