@git.zone/tstest 1.5.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/index.js +9 -2
- package/dist_ts/tstest.classes.tap.parser.d.ts +4 -0
- package/dist_ts/tstest.classes.tap.parser.js +114 -24
- package/dist_ts/tstest.classes.testdirectory.d.ts +10 -0
- package/dist_ts/tstest.classes.testdirectory.js +31 -1
- package/dist_ts/tstest.classes.tstest.d.ts +3 -1
- package/dist_ts/tstest.classes.tstest.js +52 -27
- package/dist_ts_tapbundle/index.d.ts +1 -0
- package/dist_ts_tapbundle/index.js +2 -1
- package/dist_ts_tapbundle/tapbundle.classes.tap.d.ts +54 -1
- package/dist_ts_tapbundle/tapbundle.classes.tap.js +288 -24
- package/dist_ts_tapbundle/tapbundle.classes.taptest.d.ts +7 -1
- package/dist_ts_tapbundle/tapbundle.classes.taptest.js +75 -27
- package/dist_ts_tapbundle/tapbundle.classes.taptools.d.ts +81 -1
- package/dist_ts_tapbundle/tapbundle.classes.taptools.js +180 -2
- package/dist_ts_tapbundle/ts_tapbundle/00_commitinfo_data.d.ts +8 -0
- package/dist_ts_tapbundle/ts_tapbundle/00_commitinfo_data.js +9 -0
- package/dist_ts_tapbundle/ts_tapbundle/index.d.ts +6 -0
- package/dist_ts_tapbundle/ts_tapbundle/index.js +7 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.pretask.d.ts +10 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.pretask.js +13 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.tap.d.ts +104 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.tap.js +401 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.taptest.d.ts +38 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.taptest.js +110 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.taptools.d.ts +109 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.taptools.js +241 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.tapwrap.d.ts +8 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.tapwrap.js +7 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.plugins.d.ts +8 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.plugins.js +10 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.tapcreator.d.ts +3 -0
- package/dist_ts_tapbundle/ts_tapbundle/tapbundle.tapcreator.js +5 -0
- package/dist_ts_tapbundle/ts_tapbundle/webhelpers.d.ts +7 -0
- package/dist_ts_tapbundle/ts_tapbundle/webhelpers.js +35 -0
- package/dist_ts_tapbundle/ts_tapbundle_node/classes.pathinject.d.ts +5 -0
- package/dist_ts_tapbundle/ts_tapbundle_node/classes.pathinject.js +13 -0
- package/dist_ts_tapbundle/ts_tapbundle_node/plugins.d.ts +11 -0
- package/dist_ts_tapbundle/ts_tapbundle_node/plugins.js +14 -0
- package/dist_ts_tapbundle_node/ts_tapbundle/tapbundle.classes.taptest.d.ts +38 -0
- package/dist_ts_tapbundle_node/ts_tapbundle/tapbundle.classes.taptest.js +110 -0
- package/dist_ts_tapbundle_node/ts_tapbundle/tapbundle.classes.taptools.d.ts +109 -0
- package/dist_ts_tapbundle_node/ts_tapbundle/tapbundle.classes.taptools.js +241 -0
- package/dist_ts_tapbundle_node/ts_tapbundle/tapbundle.plugins.d.ts +8 -0
- package/dist_ts_tapbundle_node/ts_tapbundle/tapbundle.plugins.js +10 -0
- package/dist_ts_tapbundle_node/ts_tapbundle/tapbundle.tapcreator.d.ts +3 -0
- package/dist_ts_tapbundle_node/ts_tapbundle/tapbundle.tapcreator.js +5 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/classes.pathinject.d.ts +5 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/classes.pathinject.js +13 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/classes.tapnodetools.d.ts +25 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/classes.tapnodetools.js +81 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/classes.testfileprovider.d.ts +6 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/classes.testfileprovider.js +16 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/index.d.ts +2 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/index.js +3 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/paths.d.ts +2 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/paths.js +4 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/plugins.d.ts +11 -0
- package/dist_ts_tapbundle_node/ts_tapbundle_node/plugins.js +14 -0
- package/package.json +11 -8
- package/readme.md +141 -0
- package/readme.plan.md +253 -30
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +8 -1
- package/ts/tstest.classes.tap.parser.ts +111 -25
- package/ts/tstest.classes.testdirectory.ts +39 -0
- package/ts/tstest.classes.tstest.ts +61 -27
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import * as paths from './paths.js';
|
|
3
|
+
export const fileUrls = {
|
|
4
|
+
dockerAlpineImage: 'https://code.foss.global/testassets/docker/raw/branch/main/alpine.tar',
|
|
5
|
+
};
|
|
6
|
+
export class TestFileProvider {
|
|
7
|
+
async getDockerAlpineImageAsLocalTarball() {
|
|
8
|
+
const filePath = plugins.path.join(paths.testFilesDir, 'alpine.tar');
|
|
9
|
+
// fetch the docker alpine image
|
|
10
|
+
const response = await plugins.smartrequest.getBinary(fileUrls.dockerAlpineImage);
|
|
11
|
+
await plugins.smartfile.fs.ensureDir(paths.testFilesDir);
|
|
12
|
+
await plugins.smartfile.memory.toFs(response.body, filePath);
|
|
13
|
+
return filePath;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50ZXN0ZmlsZXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfdGFwYnVuZGxlX25vZGUvY2xhc3Nlcy50ZXN0ZmlsZXByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBRXBDLE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRztJQUN0QixpQkFBaUIsRUFBRSx1RUFBdUU7Q0FDM0YsQ0FBQTtBQUVELE1BQU0sT0FBTyxnQkFBZ0I7SUFDcEIsS0FBSyxDQUFDLGtDQUFrQztRQUM3QyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFBO1FBQ3BFLGdDQUFnQztRQUNoQyxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ2xGLE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN6RCxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzdELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7Q0FDRiJ9
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export * from './classes.tapnodetools.js';
|
|
2
|
+
export * from './classes.pathinject.js';
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c190YXBidW5kbGVfbm9kZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMseUJBQXlCLENBQUMifQ==
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
export const cwd = process.cwd();
|
|
3
|
+
export const testFilesDir = plugins.path.join(cwd, './.nogit/testfiles/');
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c190YXBidW5kbGVfbm9kZS9wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxNQUFNLENBQUMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUscUJBQXFCLENBQUMsQ0FBQyJ9
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as crypto from 'crypto';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
export { crypto, fs, path, };
|
|
5
|
+
import * as qenv from '@push.rocks/qenv';
|
|
6
|
+
import * as smartcrypto from '@push.rocks/smartcrypto';
|
|
7
|
+
import * as smartfile from '@push.rocks/smartfile';
|
|
8
|
+
import * as smartpath from '@push.rocks/smartpath';
|
|
9
|
+
import * as smartrequest from '@push.rocks/smartrequest';
|
|
10
|
+
import * as smartshell from '@push.rocks/smartshell';
|
|
11
|
+
export { qenv, smartcrypto, smartfile, smartpath, smartrequest, smartshell, };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// node native
|
|
2
|
+
import * as crypto from 'crypto';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
export { crypto, fs, path, };
|
|
6
|
+
// @push.rocks scope
|
|
7
|
+
import * as qenv from '@push.rocks/qenv';
|
|
8
|
+
import * as smartcrypto from '@push.rocks/smartcrypto';
|
|
9
|
+
import * as smartfile from '@push.rocks/smartfile';
|
|
10
|
+
import * as smartpath from '@push.rocks/smartpath';
|
|
11
|
+
import * as smartrequest from '@push.rocks/smartrequest';
|
|
12
|
+
import * as smartshell from '@push.rocks/smartshell';
|
|
13
|
+
export { qenv, smartcrypto, smartfile, smartpath, smartrequest, smartshell, };
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3RhcGJ1bmRsZV9ub2RlL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYztBQUNkLE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQ2pDLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBRTdCLE9BQU8sRUFBRSxNQUFNLEVBQUMsRUFBRSxFQUFFLElBQUksR0FBRyxDQUFDO0FBRTVCLG9CQUFvQjtBQUNwQixPQUFPLEtBQUssSUFBSSxNQUFNLGtCQUFrQixDQUFDO0FBQ3pDLE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFNBQVMsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRCxPQUFPLEtBQUssU0FBUyxNQUFNLHVCQUF1QixDQUFDO0FBQ25ELE9BQU8sS0FBSyxZQUFZLE1BQU0sMEJBQTBCLENBQUM7QUFDekQsT0FBTyxLQUFLLFVBQVUsTUFBTSx3QkFBd0IsQ0FBQztBQUVyRCxPQUFPLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxVQUFVLEdBQUcsQ0FBQyJ9
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@git.zone/tstest",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "a test utility to run tests that match test/**/*.ts",
|
|
6
|
-
"
|
|
7
|
-
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./dist_ts/index.js",
|
|
8
|
+
"./tapbundle": "./dist_ts_tapbundle/index.js",
|
|
9
|
+
"./tapbundle_node": "./dist_ts_tapbundle_node/index.js"
|
|
10
|
+
},
|
|
8
11
|
"type": "module",
|
|
9
12
|
"author": "Lossless GmbH",
|
|
10
13
|
"license": "MIT",
|
|
@@ -56,11 +59,11 @@
|
|
|
56
59
|
"last 1 chrome versions"
|
|
57
60
|
],
|
|
58
61
|
"scripts": {
|
|
59
|
-
"test": "pnpm run build && pnpm run test:tapbundle && pnpm run test:tstest",
|
|
60
|
-
"test:tapbundle": "tsx ./cli.child.ts test/tapbundle/**/*.ts",
|
|
61
|
-
"test:tapbundle:verbose": "tsx ./cli.child.ts test/tapbundle/**/*.ts --verbose",
|
|
62
|
-
"test:tstest": "tsx ./cli.child.ts test/tstest/**/*.ts",
|
|
63
|
-
"test:tstest:verbose": "tsx ./cli.child.ts test/tstest/**/*.ts --verbose",
|
|
62
|
+
"test": "pnpm run build && pnpm run test:tapbundle:verbose && pnpm run test:tstest:verbose",
|
|
63
|
+
"test:tapbundle": "tsx ./cli.child.ts \"test/tapbundle/**/*.ts\"",
|
|
64
|
+
"test:tapbundle:verbose": "tsx ./cli.child.ts \"test/tapbundle/**/*.ts\" --verbose",
|
|
65
|
+
"test:tstest": "tsx ./cli.child.ts \"test/tstest/**/*.ts\"",
|
|
66
|
+
"test:tstest:verbose": "tsx ./cli.child.ts \"test/tstest/**/*.ts\" --verbose",
|
|
64
67
|
"build": "(tsbuild tsfolders)",
|
|
65
68
|
"buildDocs": "tsdoc"
|
|
66
69
|
}
|
package/readme.md
CHANGED
|
@@ -19,6 +19,14 @@
|
|
|
19
19
|
- 📝 **Detailed Logging** - Optional file logging for debugging
|
|
20
20
|
- ⚡ **Performance Metrics** - See which tests are slow
|
|
21
21
|
- 🤖 **CI/CD Ready** - JSON output mode for automation
|
|
22
|
+
- 🏷️ **Tag-based Filtering** - Run only tests with specific tags
|
|
23
|
+
- 🎯 **Parallel Test Execution** - Run tests in parallel groups
|
|
24
|
+
- 🔧 **Test Lifecycle Hooks** - beforeEach/afterEach support
|
|
25
|
+
- 📸 **Snapshot Testing** - Compare test outputs with saved snapshots
|
|
26
|
+
- ⏳ **Timeout Control** - Set custom timeouts for tests
|
|
27
|
+
- 🔁 **Retry Logic** - Automatically retry failing tests
|
|
28
|
+
- 🛠️ **Test Fixtures** - Create reusable test data
|
|
29
|
+
- 📦 **Browser-Compatible** - Full browser support for tapbundle
|
|
22
30
|
|
|
23
31
|
## Installation
|
|
24
32
|
|
|
@@ -61,6 +69,7 @@ tstest "test/unit/*.ts"
|
|
|
61
69
|
| `--no-color` | Disable colored output |
|
|
62
70
|
| `--json` | Output results as JSON |
|
|
63
71
|
| `--logfile` | Save detailed logs to `.nogit/testlogs/[testname].log` |
|
|
72
|
+
| `--tags <tags>` | Run only tests with specific tags (comma-separated) |
|
|
64
73
|
|
|
65
74
|
### Example Outputs
|
|
66
75
|
|
|
@@ -147,6 +156,103 @@ tap.test('my awesome test', async () => {
|
|
|
147
156
|
tap.start();
|
|
148
157
|
```
|
|
149
158
|
|
|
159
|
+
#### Test Features
|
|
160
|
+
|
|
161
|
+
**Tag-based Test Filtering**
|
|
162
|
+
```typescript
|
|
163
|
+
tap.tags('unit', 'api')
|
|
164
|
+
.test('should handle API requests', async () => {
|
|
165
|
+
// Test code
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Run with: tstest test/ --tags unit,api
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Test Lifecycle Hooks**
|
|
172
|
+
```typescript
|
|
173
|
+
tap.describe('User API Tests', () => {
|
|
174
|
+
let testUser;
|
|
175
|
+
|
|
176
|
+
tap.beforeEach(async () => {
|
|
177
|
+
testUser = await createTestUser();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
tap.afterEach(async () => {
|
|
181
|
+
await deleteTestUser(testUser.id);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
tap.test('should update user profile', async () => {
|
|
185
|
+
// Test code using testUser
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Parallel Test Execution**
|
|
191
|
+
```typescript
|
|
192
|
+
// Files with matching parallel group names run concurrently
|
|
193
|
+
// test.auth.para__1.ts
|
|
194
|
+
tap.test('authentication test', async () => { /* ... */ });
|
|
195
|
+
|
|
196
|
+
// test.user.para__1.ts
|
|
197
|
+
tap.test('user operations test', async () => { /* ... */ });
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Test Timeouts and Retries**
|
|
201
|
+
```typescript
|
|
202
|
+
tap.timeout(5000)
|
|
203
|
+
.retry(3)
|
|
204
|
+
.test('flaky network test', async (tools) => {
|
|
205
|
+
// This test has 5 seconds to complete and will retry up to 3 times
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Snapshot Testing**
|
|
210
|
+
```typescript
|
|
211
|
+
tap.test('should match snapshot', async (tools) => {
|
|
212
|
+
const result = await generateReport();
|
|
213
|
+
await tools.matchSnapshot(result);
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Test Fixtures**
|
|
218
|
+
```typescript
|
|
219
|
+
// Define a reusable fixture
|
|
220
|
+
tap.defineFixture('testUser', async () => ({
|
|
221
|
+
id: 1,
|
|
222
|
+
name: 'Test User',
|
|
223
|
+
email: 'test@example.com'
|
|
224
|
+
}));
|
|
225
|
+
|
|
226
|
+
tap.test('user test', async (tools) => {
|
|
227
|
+
const user = tools.fixture('testUser');
|
|
228
|
+
expect(user.name).toEqual('Test User');
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Skipping and Todo Tests**
|
|
233
|
+
```typescript
|
|
234
|
+
tap.skip.test('work in progress', async () => {
|
|
235
|
+
// This test will be skipped
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
tap.todo('implement user deletion', async () => {
|
|
239
|
+
// This marks a test as todo
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Browser Testing**
|
|
244
|
+
```typescript
|
|
245
|
+
// test.browser.ts
|
|
246
|
+
import { tap, webhelpers } from '@push.rocks/tapbundle';
|
|
247
|
+
|
|
248
|
+
tap.test('DOM manipulation', async () => {
|
|
249
|
+
const element = await webhelpers.fixture(webhelpers.html`
|
|
250
|
+
<div>Hello World</div>
|
|
251
|
+
`);
|
|
252
|
+
expect(element).toBeInstanceOf(HTMLElement);
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
150
256
|
## Advanced Features
|
|
151
257
|
|
|
152
258
|
### Glob Pattern Support
|
|
@@ -163,6 +269,8 @@ tstest "test/integration/*.test.ts"
|
|
|
163
269
|
tstest "test/**/*.spec.ts" "test/**/*.test.ts"
|
|
164
270
|
```
|
|
165
271
|
|
|
272
|
+
**Important**: Always quote glob patterns to prevent shell expansion. Without quotes, the shell will expand the pattern and only pass the first matching file to tstest.
|
|
273
|
+
|
|
166
274
|
### Automatic Logging
|
|
167
275
|
|
|
168
276
|
Use `--logfile` to automatically save test output:
|
|
@@ -181,6 +289,26 @@ In verbose mode, see performance metrics:
|
|
|
181
289
|
Slowest test: api integration test (486ms)
|
|
182
290
|
```
|
|
183
291
|
|
|
292
|
+
### Parallel Test Groups
|
|
293
|
+
|
|
294
|
+
Tests can be organized into parallel groups for concurrent execution:
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
━━━ Parallel Group: para__1 ━━━
|
|
298
|
+
▶️ test/auth.para__1.ts
|
|
299
|
+
▶️ test/user.para__1.ts
|
|
300
|
+
... tests run concurrently ...
|
|
301
|
+
──────────────────────────────────
|
|
302
|
+
|
|
303
|
+
━━━ Parallel Group: para__2 ━━━
|
|
304
|
+
▶️ test/db.para__2.ts
|
|
305
|
+
▶️ test/api.para__2.ts
|
|
306
|
+
... tests run concurrently ...
|
|
307
|
+
──────────────────────────────────
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Files with the same parallel group suffix (e.g., `para__1`) run simultaneously, while different groups run sequentially.
|
|
311
|
+
|
|
184
312
|
### CI/CD Integration
|
|
185
313
|
|
|
186
314
|
For continuous integration, combine quiet and JSON modes:
|
|
@@ -192,6 +320,19 @@ tstest test/ --json > test-results.json
|
|
|
192
320
|
tstest test/ --quiet
|
|
193
321
|
```
|
|
194
322
|
|
|
323
|
+
## Changelog
|
|
324
|
+
|
|
325
|
+
### Version 1.7.0
|
|
326
|
+
- 🎉 Made `@push.rocks/tapbundle` fully browser-compatible
|
|
327
|
+
- 📸 Added snapshot testing with base64-encoded communication protocol
|
|
328
|
+
- 🏷️ Introduced tag-based test filtering
|
|
329
|
+
- 🔧 Enhanced test lifecycle hooks (beforeEach/afterEach)
|
|
330
|
+
- 🎯 Fixed parallel test execution and grouping
|
|
331
|
+
- ⏳ Improved timeout and retry mechanisms
|
|
332
|
+
- 🛠️ Added test fixtures for reusable test data
|
|
333
|
+
- 📊 Enhanced TAP parser for better test reporting
|
|
334
|
+
- 🐛 Fixed glob pattern handling in shell scripts
|
|
335
|
+
|
|
195
336
|
## Contribution
|
|
196
337
|
|
|
197
338
|
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
package/readme.plan.md
CHANGED
|
@@ -1,41 +1,264 @@
|
|
|
1
|
-
# Plan for
|
|
1
|
+
# Improvement Plan for tstest and tapbundle
|
|
2
2
|
|
|
3
3
|
!! FIRST: Reread /home/philkunz/.claude/CLAUDE.md to ensure following all guidelines !!
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
When a test fails, we want to display all the console logs from that failed test in the terminal, even without the --verbose flag. This makes debugging failed tests much easier.
|
|
5
|
+
## 1. Enhanced Communication Between tapbundle and tstest
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
7
|
+
### 1.1 Real-time Test Progress API
|
|
8
|
+
- Create a bidirectional communication channel between tapbundle and tstest
|
|
9
|
+
- Emit events for test lifecycle stages (start, progress, completion)
|
|
10
|
+
- Allow tstest to subscribe to tapbundle events for better progress reporting
|
|
11
|
+
- Implement a standardized message format for test metadata
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
13
|
+
### 1.2 Rich Error Reporting
|
|
14
|
+
- Pass structured error objects from tapbundle to tstest
|
|
15
|
+
- Include stack traces, code snippets, and contextual information
|
|
16
|
+
- Support for error categorization (assertion failures, timeouts, uncaught exceptions)
|
|
17
|
+
- Visual diff output for failed assertions
|
|
17
18
|
|
|
18
|
-
##
|
|
19
|
+
## 2. Enhanced toolsArg Functionality
|
|
19
20
|
|
|
20
|
-
### 1
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
### 2.1 Test Flow Control ✅
|
|
22
|
+
```typescript
|
|
23
|
+
tap.test('conditional test', async (toolsArg) => {
|
|
24
|
+
const result = await someOperation();
|
|
25
|
+
|
|
26
|
+
// Skip the rest of the test
|
|
27
|
+
if (!result) {
|
|
28
|
+
return toolsArg.skip('Precondition not met');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Conditional skipping
|
|
32
|
+
await toolsArg.skipIf(condition, 'Reason for skipping');
|
|
33
|
+
|
|
34
|
+
// Mark test as todo
|
|
35
|
+
await toolsArg.todo('Not implemented yet');
|
|
36
|
+
});
|
|
37
|
+
```
|
|
23
38
|
|
|
24
|
-
### 2.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
39
|
+
### 2.2 Test Metadata and Configuration ✅
|
|
40
|
+
```typescript
|
|
41
|
+
// Fluent syntax ✅
|
|
42
|
+
tap.tags('slow', 'integration')
|
|
43
|
+
.priority('high')
|
|
44
|
+
.timeout(5000)
|
|
45
|
+
.retry(3)
|
|
46
|
+
.test('configurable test', async (toolsArg) => {
|
|
47
|
+
// Test implementation
|
|
48
|
+
});
|
|
49
|
+
```
|
|
28
50
|
|
|
29
|
-
### 3
|
|
30
|
-
|
|
31
|
-
-
|
|
51
|
+
### 2.3 Test Data and Context Sharing ✅
|
|
52
|
+
```typescript
|
|
53
|
+
tap.test('data-driven test', async (toolsArg) => {
|
|
54
|
+
// Access shared context ✅
|
|
55
|
+
const sharedData = toolsArg.context.get('sharedData');
|
|
56
|
+
|
|
57
|
+
// Set data for other tests ✅
|
|
58
|
+
toolsArg.context.set('resultData', computedValue);
|
|
59
|
+
|
|
60
|
+
// Parameterized test data (not yet implemented)
|
|
61
|
+
const testData = toolsArg.data<TestInput>();
|
|
62
|
+
expect(processData(testData)).toEqual(expected);
|
|
63
|
+
});
|
|
64
|
+
```
|
|
32
65
|
|
|
33
|
-
##
|
|
34
|
-
1. Add log buffering to TapParser
|
|
35
|
-
2. Update TsTestLogger to handle failed test logs
|
|
36
|
-
3. Modify test result processing to show logs on failure
|
|
66
|
+
## 3. Nested Tests and Test Suites
|
|
37
67
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
68
|
+
### 3.1 Test Grouping with describe() ✅
|
|
69
|
+
```typescript
|
|
70
|
+
tap.describe('User Authentication', () => {
|
|
71
|
+
tap.beforeEach(async (toolsArg) => {
|
|
72
|
+
// Setup for each test in this suite
|
|
73
|
+
await toolsArg.context.set('db', await createTestDatabase());
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
tap.afterEach(async (toolsArg) => {
|
|
77
|
+
// Cleanup after each test
|
|
78
|
+
await toolsArg.context.get('db').cleanup();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
tap.test('should login with valid credentials', async (toolsArg) => {
|
|
82
|
+
// Test implementation
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
tap.describe('Password Reset', () => {
|
|
86
|
+
tap.test('should send reset email', async (toolsArg) => {
|
|
87
|
+
// Nested test
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3.2 Hierarchical Test Organization
|
|
94
|
+
- Support for multiple levels of nesting
|
|
95
|
+
- Inherited context and configuration from parent suites
|
|
96
|
+
- Aggregated reporting for test suites
|
|
97
|
+
- Suite-level lifecycle hooks
|
|
98
|
+
|
|
99
|
+
## 4. Advanced Test Features
|
|
100
|
+
|
|
101
|
+
### 4.1 Snapshot Testing
|
|
102
|
+
```typescript
|
|
103
|
+
tap.test('component render', async (toolsArg) => {
|
|
104
|
+
const output = renderComponent(props);
|
|
105
|
+
|
|
106
|
+
// Compare with stored snapshot
|
|
107
|
+
await toolsArg.matchSnapshot(output, 'component-output');
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 4.2 Performance Benchmarking
|
|
112
|
+
```typescript
|
|
113
|
+
tap.test('performance test', async (toolsArg) => {
|
|
114
|
+
const benchmark = toolsArg.benchmark();
|
|
115
|
+
|
|
116
|
+
// Run operation
|
|
117
|
+
await expensiveOperation();
|
|
118
|
+
|
|
119
|
+
// Assert performance constraints
|
|
120
|
+
benchmark.expect({
|
|
121
|
+
maxDuration: 1000,
|
|
122
|
+
maxMemory: '100MB'
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 4.3 Test Fixtures and Factories ✅
|
|
128
|
+
```typescript
|
|
129
|
+
tap.test('with fixtures', async (toolsArg) => {
|
|
130
|
+
// Create test fixtures
|
|
131
|
+
const user = await toolsArg.fixture('user', { name: 'Test User' });
|
|
132
|
+
const post = await toolsArg.fixture('post', { author: user });
|
|
133
|
+
|
|
134
|
+
// Use factory functions
|
|
135
|
+
const users = await toolsArg.factory('user').createMany(5);
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 5. Test Execution Improvements
|
|
140
|
+
|
|
141
|
+
### 5.1 Parallel Test Execution ✅
|
|
142
|
+
- Run independent tests concurrently ✅
|
|
143
|
+
- Configurable concurrency limits (via file naming convention)
|
|
144
|
+
- Resource pooling for shared resources
|
|
145
|
+
- Proper isolation between parallel tests ✅
|
|
146
|
+
|
|
147
|
+
Implementation:
|
|
148
|
+
- Tests with `para__<groupNumber>` in filename run in parallel
|
|
149
|
+
- Different groups run sequentially
|
|
150
|
+
- Tests without `para__` run serially
|
|
151
|
+
|
|
152
|
+
### 5.2 Watch Mode
|
|
153
|
+
- Automatically re-run tests on file changes
|
|
154
|
+
- Intelligent test selection based on changed files
|
|
155
|
+
- Fast feedback loop for development
|
|
156
|
+
- Integration with IDE/editor plugins
|
|
157
|
+
|
|
158
|
+
### 5.3 Advanced Test Filtering ✅ (partially)
|
|
159
|
+
```typescript
|
|
160
|
+
// Run tests by tags ✅
|
|
161
|
+
tstest --tags "unit,fast"
|
|
162
|
+
|
|
163
|
+
// Exclude tests by pattern (not yet implemented)
|
|
164
|
+
tstest --exclude "**/slow/**"
|
|
165
|
+
|
|
166
|
+
// Run only failed tests from last run (not yet implemented)
|
|
167
|
+
tstest --failed
|
|
168
|
+
|
|
169
|
+
// Run tests modified in git (not yet implemented)
|
|
170
|
+
tstest --changed
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 6. Reporting and Analytics
|
|
174
|
+
|
|
175
|
+
### 6.1 Custom Reporters
|
|
176
|
+
- Plugin architecture for custom reporters
|
|
177
|
+
- Built-in reporters: JSON, JUnit, HTML, Markdown
|
|
178
|
+
- Real-time streaming reporters
|
|
179
|
+
- Aggregated test metrics and trends
|
|
180
|
+
|
|
181
|
+
### 6.2 Coverage Integration
|
|
182
|
+
- Built-in code coverage collection
|
|
183
|
+
- Coverage thresholds and enforcement
|
|
184
|
+
- Coverage trending over time
|
|
185
|
+
- Integration with CI/CD pipelines
|
|
186
|
+
|
|
187
|
+
### 6.3 Test Analytics Dashboard
|
|
188
|
+
- Web-based dashboard for test results
|
|
189
|
+
- Historical test performance data
|
|
190
|
+
- Flaky test detection
|
|
191
|
+
- Test impact analysis
|
|
192
|
+
|
|
193
|
+
## 7. Developer Experience
|
|
194
|
+
|
|
195
|
+
### 7.1 Better Error Messages
|
|
196
|
+
- Clear, actionable error messages
|
|
197
|
+
- Suggestions for common issues
|
|
198
|
+
- Links to documentation
|
|
199
|
+
- Code examples in error output
|
|
200
|
+
|
|
201
|
+
### 7.2 Interactive Mode (Needs Detailed Specification)
|
|
202
|
+
- REPL for exploring test failures
|
|
203
|
+
- Need to define: How to enter interactive mode? When tests fail?
|
|
204
|
+
- What commands/features should be available in the REPL?
|
|
205
|
+
- Debugging integration
|
|
206
|
+
- Node.js inspector protocol integration?
|
|
207
|
+
- Breakpoint support?
|
|
208
|
+
- Step-through test execution
|
|
209
|
+
- Pause between tests?
|
|
210
|
+
- Step into/over/out functionality?
|
|
211
|
+
- Interactive test data manipulation
|
|
212
|
+
- Modify test inputs on the fly?
|
|
213
|
+
- Inspect intermediate values?
|
|
214
|
+
|
|
215
|
+
### 7.3 ~~VS Code Extension~~ (Scratched)
|
|
216
|
+
- ~~Test explorer integration~~
|
|
217
|
+
- ~~Inline test results~~
|
|
218
|
+
- ~~CodeLens for running individual tests~~
|
|
219
|
+
- ~~Debugging support~~
|
|
220
|
+
|
|
221
|
+
## Implementation Phases
|
|
222
|
+
|
|
223
|
+
### Phase 1: Core Enhancements (Priority: High) ✅
|
|
224
|
+
1. Implement enhanced toolsArg methods (skip, skipIf, timeout, retry) ✅
|
|
225
|
+
2. Add basic test grouping with describe() ✅
|
|
226
|
+
3. Improve error reporting between tapbundle and tstest ✅
|
|
227
|
+
|
|
228
|
+
### Phase 2: Advanced Features (Priority: Medium)
|
|
229
|
+
1. Implement nested test suites ✅ (basic describe support)
|
|
230
|
+
2. Add snapshot testing ✅
|
|
231
|
+
3. Create test fixture system ✅
|
|
232
|
+
4. Implement parallel test execution ✅
|
|
233
|
+
|
|
234
|
+
### Phase 3: Developer Experience (Priority: Medium)
|
|
235
|
+
1. Add watch mode
|
|
236
|
+
2. Implement custom reporters
|
|
237
|
+
3. ~~Create VS Code extension~~ (Scratched)
|
|
238
|
+
4. Add interactive debugging (Needs detailed spec first)
|
|
239
|
+
|
|
240
|
+
### Phase 4: Analytics and Performance (Priority: Low)
|
|
241
|
+
1. Build test analytics dashboard
|
|
242
|
+
2. Add performance benchmarking
|
|
243
|
+
3. Implement coverage integration
|
|
244
|
+
4. Create trend analysis tools
|
|
245
|
+
|
|
246
|
+
## Technical Considerations
|
|
247
|
+
|
|
248
|
+
### API Design Principles
|
|
249
|
+
- Maintain backward compatibility
|
|
250
|
+
- Progressive enhancement approach
|
|
251
|
+
- Opt-in features to avoid breaking changes
|
|
252
|
+
- Clear migration paths for new features
|
|
253
|
+
|
|
254
|
+
### Performance Goals
|
|
255
|
+
- Minimal overhead for test execution
|
|
256
|
+
- Efficient parallel execution
|
|
257
|
+
- Fast test discovery
|
|
258
|
+
- Optimized browser test bundling
|
|
259
|
+
|
|
260
|
+
### Integration Points
|
|
261
|
+
- Clean interfaces between tstest and tapbundle
|
|
262
|
+
- Extensible plugin architecture
|
|
263
|
+
- Standard test result format
|
|
264
|
+
- Compatible with existing CI/CD tools
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ export const runCli = async () => {
|
|
|
12
12
|
const args = process.argv.slice(2);
|
|
13
13
|
const logOptions: LogOptions = {};
|
|
14
14
|
let testPath: string | null = null;
|
|
15
|
+
let tags: string[] = [];
|
|
15
16
|
|
|
16
17
|
// Parse options
|
|
17
18
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -36,6 +37,11 @@ export const runCli = async () => {
|
|
|
36
37
|
case '--logfile':
|
|
37
38
|
logOptions.logFile = true; // Set this as a flag, not a value
|
|
38
39
|
break;
|
|
40
|
+
case '--tags':
|
|
41
|
+
if (i + 1 < args.length) {
|
|
42
|
+
tags = args[++i].split(',');
|
|
43
|
+
}
|
|
44
|
+
break;
|
|
39
45
|
default:
|
|
40
46
|
if (!arg.startsWith('-')) {
|
|
41
47
|
testPath = arg;
|
|
@@ -52,6 +58,7 @@ export const runCli = async () => {
|
|
|
52
58
|
console.error(' --no-color Disable colored output');
|
|
53
59
|
console.error(' --json Output results as JSON');
|
|
54
60
|
console.error(' --logfile Write logs to .nogit/testlogs/[testfile].log');
|
|
61
|
+
console.error(' --tags Run only tests with specified tags (comma-separated)');
|
|
55
62
|
process.exit(1);
|
|
56
63
|
}
|
|
57
64
|
|
|
@@ -66,6 +73,6 @@ export const runCli = async () => {
|
|
|
66
73
|
executionMode = TestExecutionMode.DIRECTORY;
|
|
67
74
|
}
|
|
68
75
|
|
|
69
|
-
const tsTestInstance = new TsTest(process.cwd(), testPath, executionMode, logOptions);
|
|
76
|
+
const tsTestInstance = new TsTest(process.cwd(), testPath, executionMode, logOptions, tags);
|
|
70
77
|
await tsTestInstance.run();
|
|
71
78
|
};
|