# Architecture Overview ## Project Structure This project integrates tstest with tapbundle through a modular architecture: 1. **tstest** (`/ts/`) - The test runner that discovers and executes test files 2. **tapbundle** (`/ts_tapbundle/`) - The TAP testing framework for writing tests 3. **tapbundle_node** (`/ts_tapbundle_node/`) - Node.js-specific testing utilities ## How Components Work Together ### Test Execution Flow 1. **CLI Entry Point** (`cli.js` � `cli.ts.js` � `cli.child.ts`) - The CLI uses tsx to run TypeScript files directly - Accepts glob patterns to find test files - Supports options like `--verbose`, `--quiet`, `--web` 2. **Test Discovery** - tstest scans for test files matching the provided pattern - Defaults to `test/**/*.ts` when no pattern is specified - Supports both file and directory modes 3. **Test Runner** - Each test file imports `tap` and `expect` from tapbundle - Tests are written using `tap.test()` with async functions - Browser tests are compiled with esbuild and run in Chromium via Puppeteer ### Key Integration Points 1. **Import Structure** - Test files import from local tapbundle: `import { tap, expect } from '../../ts_tapbundle/index.js'` - Node-specific tests also import from tapbundle_node: `import { tapNodeTools } from '../../ts_tapbundle_node/index.js'` 2. **WebHelpers** - Browser tests can use webhelpers for DOM manipulation - `webhelpers.html` - Template literal for creating HTML strings - `webhelpers.fixture` - Creates DOM elements from HTML strings - Automatically detects browser environment and only enables in browser context 3. **Build System** - Uses `tsbuild tsfolders` to compile TypeScript - Maintains separate output directories: `/dist_ts/`, `/dist_ts_tapbundle/`, `/dist_ts_tapbundle_node/` - Compilation order is resolved automatically based on dependencies ### Test Scripts The package.json defines several test scripts: - `test` - Builds and runs all tests (tapbundle and tstest) - `test:tapbundle` - Runs tapbundle framework tests - `test:tstest` - Runs tstest's own tests - Both support `:verbose` variants for detailed output ### Environment Detection The framework automatically detects the runtime environment: - Node.js tests run directly via tsx - Browser tests are compiled and served via a local server - WebHelpers are only enabled in browser environment This architecture allows for seamless testing across both Node.js and browser environments while maintaining a clean separation of concerns. ## Logging System ### Log File Naming (Fixed in v1.9.1) When using the `--logfile` flag, tstest creates log files in `.nogit/testlogs/`. The log file naming was updated to preserve directory structure and prevent collisions: - **Old behavior**: `test/tapbundle/test.ts` → `.nogit/testlogs/test.log` - **New behavior**: `test/tapbundle/test.ts` → `.nogit/testlogs/test__tapbundle__test.log` This fix ensures that test files with the same basename in different directories don't overwrite each other's logs. The implementation: 1. Takes the relative path from the current working directory 2. Replaces path separators (`/`) with double underscores (`__`) 3. Removes the `.ts` extension 4. Creates a flat filename that preserves the directory structure ### Test Timing Display (Fixed in v1.9.2) Fixed an issue where test timing was displayed incorrectly with duplicate values like: - Before: `✅ test name # time=133ms (0ms)` - After: `✅ test name (133ms)` The issue was in the TAP parser regex which was greedily capturing the entire line including the TAP timing comment. Changed the regex from `(.*)` to `(.*?)` to make it non-greedy, properly separating the test name from the timing metadata. ## Protocol Limitations and Improvements ### Current TAP Protocol Issues The current implementation uses standard TAP format with metadata in comments: ``` ok 1 - test name # time=123ms ``` This has several limitations: 1. **Delimiter Conflict**: Test descriptions containing `#` can break parsing 2. **Regex Fragility**: Complex regex patterns that are hard to maintain 3. **Limited Metadata**: Difficult to add rich error information or custom data ### Planned Protocol V2 A new internal protocol is being designed that will: - Use Unicode delimiters `⟦TSTEST:⟧` that won't conflict with test content - Support structured JSON metadata - Allow rich error reporting with stack traces and diffs - Maintain backwards compatibility during migration See `readme.protocol.md` for the full specification and `tapbundle.protocols.ts` for the implementation utilities.