feat(tstest): add support for package.json before scripts during test execution

This commit is contained in:
2026-03-19 15:38:02 +00:00
parent bc39793682
commit cf4e5c33e8
5 changed files with 197 additions and 2 deletions

View File

@@ -27,6 +27,9 @@ import {
hasDirectives,
} from './tstest.classes.testfile.directives.js';
// Before-script support
import { loadBeforeScripts, runBeforeScript, type IBeforeScripts } from './tstest.classes.beforescripts.js';
export class TsTest {
public testDir: TestDirectory;
public executionMode: TestExecutionMode;
@@ -48,6 +51,8 @@ export class TsTest {
public runtimeRegistry = new RuntimeAdapterRegistry();
public dockerAdapter: DockerRuntimeAdapter | null = null;
private beforeScripts: IBeforeScripts | null = null;
constructor(cwdArg: string, testPathArg: string, executionModeArg: TestExecutionMode, logOptions: LogOptions = {}, tags: string[] = [], startFromFile: number | null = null, stopAtFile: number | null = null, timeoutSeconds: number | null = null) {
this.executionMode = executionModeArg;
this.testDir = new TestDirectory(cwdArg, testPathArg, executionModeArg);
@@ -97,7 +102,22 @@ export class TsTest {
if (this.logger.options.logFile) {
await this.movePreviousLogFiles();
}
// Load and execute test:before script (runs once per test run)
this.beforeScripts = loadBeforeScripts(this.testDir.cwd);
if (this.beforeScripts.beforeOnce) {
const success = await runBeforeScript(
this.smartshellInstance,
this.beforeScripts.beforeOnce,
'test:before',
this.logger,
);
if (!success) {
this.logger.error('test:before script failed. Aborting test run.');
process.exit(1);
}
}
const testGroups = await this.testDir.getTestFileGroups();
const allFiles = [...testGroups.serial, ...Object.values(testGroups.parallelGroups).flat()];
@@ -280,6 +300,22 @@ export class TsTest {
if (adapters.length === 1) {
// Single runtime - no sections needed
const adapter = adapters[0];
// Run test:before:testfile if defined
if (this.beforeScripts?.beforeTestfile) {
const success = await runBeforeScript(
this.smartshellInstance,
this.beforeScripts.beforeTestfile,
`test:before:testfile (${fileName})`,
this.logger,
{ TSTEST_FILE: fileNameArg, TSTEST_RUNTIME: adapter.id },
);
if (!success) {
this.logger.error(`test:before:testfile failed for ${fileName}. Skipping test file.`);
return;
}
}
const options = hasDirectives(directives) ? directivesToRuntimeOptions(directives, adapter.id) : undefined;
const tapParser = await adapter.run(fileNameArg, fileIndex, totalFiles, options);
tapCombinator.addTapParser(tapParser);
@@ -288,6 +324,23 @@ export class TsTest {
for (let i = 0; i < adapters.length; i++) {
const adapter = adapters[i];
this.logger.sectionStart(`Part ${i + 1}: ${adapter.displayName}`);
// Run test:before:testfile if defined (runs before each runtime)
if (this.beforeScripts?.beforeTestfile) {
const success = await runBeforeScript(
this.smartshellInstance,
this.beforeScripts.beforeTestfile,
`test:before:testfile (${fileName} on ${adapter.displayName})`,
this.logger,
{ TSTEST_FILE: fileNameArg, TSTEST_RUNTIME: adapter.id },
);
if (!success) {
this.logger.error(`test:before:testfile failed for ${fileName} on ${adapter.displayName}. Skipping.`);
this.logger.sectionEnd();
continue;
}
}
const options = hasDirectives(directives) ? directivesToRuntimeOptions(directives, adapter.id) : undefined;
const tapParser = await adapter.run(fileNameArg, fileIndex, totalFiles, options);
tapCombinator.addTapParser(tapParser);
@@ -310,6 +363,21 @@ export class TsTest {
return;
}
// Run test:before:testfile if defined
if (this.beforeScripts?.beforeTestfile) {
const success = await runBeforeScript(
this.smartshellInstance,
this.beforeScripts.beforeTestfile,
`test:before:testfile (${fileNameArg} on Docker)`,
this.logger,
{ TSTEST_FILE: fileNameArg, TSTEST_RUNTIME: 'docker' },
);
if (!success) {
this.logger.error(`test:before:testfile failed for ${fileNameArg}. Skipping.`);
return;
}
}
try {
const tapParser = await this.dockerAdapter.run(fileNameArg, fileIndex, totalFiles);
tapCombinator.addTapParser(tapParser);