feat(scenario): add context.assert() API for script assertions

- Add context.assert(fn, description) for function assertions
- Logs outcome on success/failure, throws on assertion failure
- Bump package version from 1.8.0 to 1.9.0
This commit is contained in:
Andrii Arsenin
2026-09-15 12:35:17 +03:00
parent 622dfdbfb0
commit 715afd2151
4 changed files with 45 additions and 1 deletions
@@ -42,6 +42,15 @@ export interface ScriptContext {
log: (...args: unknown[]) => void;
warn: (...args: unknown[]) => void;
error: (...args: unknown[]) => void;
/**
* Runs `fn` and requires it to return `true`. Logs the outcome under
* `description`, then throws if `fn` returned anything other than `true`
* or threw an exception.
*/
assert: (
fn: () => boolean | Promise<boolean>,
description: string,
) => Promise<void>;
/** Runs a named snippet with the same context, plus any extra positional args. */
runSnippet: (alias: string, ...args: unknown[]) => Promise<unknown>;
/** Returns metadata + absolute disk path for files attached to the current scenario. */
@@ -141,6 +150,28 @@ export class CodeExecutorService {
log: (...args: unknown[]) => scriptLog("log", toStr(args)),
warn: (...args: unknown[]) => scriptLog("warn", toStr(args)),
error: (...args: unknown[]) => scriptLog("error", toStr(args)),
assert: async (
fn: () => boolean | Promise<boolean>,
description: string,
): Promise<void> => {
let passed: boolean;
let failureReason: string | undefined;
try {
passed = (await fn()) === true;
} catch (err) {
passed = false;
failureReason = (err as Error).message;
}
if (passed) {
scriptLog("log", `Assertion passed: ${description}`);
return;
}
const message = failureReason
? `Assertion failed: ${description} (${failureReason})`
: `Assertion failed: ${description}`;
scriptLog("error", message);
throw new Error(message);
},
getStepOutput: getStepOutput ?? (() => Promise.resolve(null)),
getCredential: (alias: string): unknown => {
if (!(alias in credMap)) {