fix(tstest): Add timeout warning for long-running tests and introduce local settings configuration

This commit is contained in:
Philipp Kunz 2025-05-24 10:52:15 +00:00
parent 13b11ab1bf
commit 33f705d961
3 changed files with 26 additions and 4 deletions

View File

@ -1,5 +1,13 @@
# Changelog # Changelog
## 2025-05-24 - 1.11.3 - fix(tstest)
Add timeout warning for long-running tests and introduce local settings configuration
- Add .claude/settings.local.json with permission configuration for local development
- Implement a timeout warning timer that notifies when tests run longer than 1 minute without an explicit timeout
- Clear the timeout warning timer upon test completion
- Remove unused import of logPrefixes in tstest.classes.tstest.ts
## 2025-05-24 - 1.11.2 - fix(tstest) ## 2025-05-24 - 1.11.2 - fix(tstest)
Improve timeout and error handling in test execution along with TAP parser timeout logic improvements. Improve timeout and error handling in test execution along with TAP parser timeout logic improvements.

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@git.zone/tstest', name: '@git.zone/tstest',
version: '1.11.2', version: '1.11.3',
description: 'a test utility to run tests that match test/**/*.ts' description: 'a test utility to run tests that match test/**/*.ts'
} }

View File

@ -1,6 +1,5 @@
import * as plugins from './tstest.plugins.js'; import * as plugins from './tstest.plugins.js';
import * as paths from './tstest.paths.js'; import * as paths from './tstest.paths.js';
import * as logPrefixes from './tstest.logprefixes.js';
import { coloredString as cs } from '@push.rocks/consolecolor'; import { coloredString as cs } from '@push.rocks/consolecolor';
@ -19,6 +18,7 @@ export class TsTest {
public startFromFile: number | null; public startFromFile: number | null;
public stopAtFile: number | null; public stopAtFile: number | null;
public timeoutSeconds: number | null; public timeoutSeconds: number | null;
private timeoutWarningTimer: NodeJS.Timeout | null = null;
public smartshellInstance = new plugins.smartshell.Smartshell({ public smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash', executor: 'bash',
@ -45,6 +45,16 @@ export class TsTest {
await this.movePreviousLogFiles(); await this.movePreviousLogFiles();
} }
// Start timeout warning timer if no timeout was specified
if (this.timeoutSeconds === null) {
this.timeoutWarningTimer = setTimeout(() => {
// Use the logger instead of console.error to ensure the warning is visible
this.logger.error('Warning: Test is running for more than 1 minute.');
this.logger.error('Consider using --timeout option to set a timeout for test files.');
this.logger.error('Example: tstest test --timeout=300 (for 5 minutes)');
}, 60000); // 1 minute
}
const testGroups = await this.testDir.getTestFileGroups(); const testGroups = await this.testDir.getTestFileGroups();
const allFiles = [...testGroups.serial, ...Object.values(testGroups.parallelGroups).flat()]; const allFiles = [...testGroups.serial, ...Object.values(testGroups.parallelGroups).flat()];
@ -83,6 +93,12 @@ export class TsTest {
} }
} }
// Clear the timeout warning timer if it was set
if (this.timeoutWarningTimer) {
clearTimeout(this.timeoutWarningTimer);
this.timeoutWarningTimer = null;
}
tapCombinator.evaluate(); tapCombinator.evaluate();
} }
@ -303,7 +319,6 @@ export class TsTest {
); );
// Handle timeout if specified // Handle timeout if specified
let hasTimedOut = false;
if (this.timeoutSeconds !== null) { if (this.timeoutSeconds !== null) {
const timeoutMs = this.timeoutSeconds * 1000; const timeoutMs = this.timeoutSeconds * 1000;
let timeoutId: NodeJS.Timeout; let timeoutId: NodeJS.Timeout;
@ -323,7 +338,6 @@ export class TsTest {
clearTimeout(timeoutId); clearTimeout(timeoutId);
} catch (error) { } catch (error) {
// Handle timeout error // Handle timeout error
hasTimedOut = true;
tapParser.handleTimeout(this.timeoutSeconds); tapParser.handleTimeout(this.timeoutSeconds);
} }
} else { } else {