tape-six 1.7.11 → 1.7.12

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/README.md CHANGED
@@ -37,7 +37,7 @@ with existing unit test libraries:
37
37
  - The [DX](https://en.wikipedia.org/wiki/User_experience#Developer_experience) in browsers are usually abysmal.
38
38
  - Both console-based debugging and a UI to navigate results are properly supported.
39
39
  - Integration with browser automation tools is supported for automated testing.
40
- - Examples for [Playwright](https://playwright.dev/) and [Puppeteer](https://pptr.dev/) are provided.
40
+ - Automated testing with [Puppeteer](https://pptr.dev/) and [Playwright](https://playwright.dev/) via dedicated packages (see [Related packages](#related-packages)).
41
41
 
42
42
  ## How it looks
43
43
 
@@ -415,10 +415,17 @@ See [set-up tests](https://github.com/uhop/tape-six/wiki/Set-up-tests) for detai
415
415
 
416
416
  Test output can be controlled by flags. See [Supported flags](https://github.com/uhop/tape-six/wiki/Supported-flags) for details.
417
417
 
418
+ ### Related packages
419
+
420
+ - [tape-six-proc](https://www.npmjs.com/package/tape-six-proc) — runs test files in separate processes instead of worker threads.
421
+ - [tape-six-puppeteer](https://www.npmjs.com/package/tape-six-puppeteer) — automates browser testing with Puppeteer.
422
+ - [tape-six-playwright](https://www.npmjs.com/package/tape-six-playwright) — automates browser testing with Playwright.
423
+
418
424
  ## Release notes
419
425
 
420
426
  The most recent releases:
421
427
 
428
+ - 1.7.12 _Added `--help`/`-h` and `--version`/`-v` options to all CLI utilities. Added flag documentation to help output._
422
429
  - 1.7.11 _Documentation consistency: added missing sequential test commands to AI docs, fixed test glob references._
423
430
  - 1.7.10 _Switched from workflows to Agent Skills (agentskills.io) for consumer integration. Improved CJS import docs._
424
431
  - 1.7.9 _Merged test directories, fixed `.d.ts` typings, added `ts-check` to CI._
package/TESTING.md CHANGED
@@ -552,10 +552,11 @@ Example with environment-specific tests:
552
552
  ```json
553
553
  {
554
554
  "tape6": {
555
+ "tests": ["/tests/test-*.*js"],
556
+ "cli": ["/tests/test-*.cjs"],
555
557
  "node": ["/tests/node/test-*.js"],
556
558
  "deno": ["/tests/deno/test-*.js"],
557
- "browser": ["/tests/web/test-*.html"],
558
- "tests": ["/tests/test-*.*js"],
559
+ "browser": ["/tests/browser/test-*.html"],
559
560
  "importmap": {
560
561
  "imports": {
561
562
  "tape-six": "/node_modules/tape-six/index.js",
@@ -566,7 +567,7 @@ Example with environment-specific tests:
566
567
  }
567
568
  ```
568
569
 
569
- In this example, running `tape6` on Node will execute tests matching `/tests/node/test-*.js` + `/tests/test-*.*js`. Running in a browser will execute `/tests/web/test-*.html` + `/tests/test-*.*js`.
570
+ In this example, running `tape6` on Node will execute tests matching `/tests/node/test-*.js` + `/tests/test-*.cjs` (cli) + `/tests/test-*.*js` (tests). Running in a browser will execute `/tests/browser/test-*.html` + `/tests/test-*.*js` (tests) — `cli` patterns are skipped.
570
571
 
571
572
  ## Browser testing
572
573
 
@@ -580,7 +581,7 @@ Browser tests use `tape6-server`, a static file server bundled with `tape-six` t
580
581
  {
581
582
  "tape6": {
582
583
  "tests": ["/tests/test-*.*js"],
583
- "browser": ["/tests/web/test-*.html"],
584
+ "browser": ["/tests/browser/test-*.html"],
584
585
  "importmap": {
585
586
  "imports": {
586
587
  "tape-six": "/node_modules/tape-six/index.js",
@@ -653,7 +654,7 @@ Create an HTML file that loads test scripts directly with an inline import map:
653
654
  </html>
654
655
  ```
655
656
 
656
- Navigate to the HTML file directly (e.g., `http://localhost:3000/tests/web/test-simple.html`). Results appear in the browser console. This approach does not use the web UI.
657
+ Navigate to the HTML file directly (e.g., `http://localhost:3000/tests/browser/test-simple.html`). Results appear in the browser console. This approach does not use the web UI.
657
658
 
658
659
  ### Flags and parallel execution in the browser
659
660
 
@@ -665,19 +666,12 @@ http://localhost:3000/?flags=FO&par=3
665
666
 
666
667
  ### Browser automation
667
668
 
668
- Use Puppeteer or Playwright to run browser tests from the command line:
669
+ For automated headless browser testing, use the dedicated packages:
669
670
 
670
- ```js
671
- import puppeteer from 'puppeteer';
672
- const browser = await puppeteer.launch({headless: true});
673
- const page = await browser.newPage();
674
- page.on('console', msg => console.log(msg.text()));
675
- await page.exposeFunction('__tape6_reportResults', async text => {
676
- await browser.close();
677
- process.exit(text === 'success' ? 0 : 1);
678
- });
679
- await page.goto('http://localhost:3000/?flags=M');
680
- ```
671
+ - [tape-six-puppeteer](https://www.npmjs.com/package/tape-six-puppeteer) — runs configured browser tests with Puppeteer.
672
+ - [tape-six-playwright](https://www.npmjs.com/package/tape-six-playwright) runs configured browser tests with Playwright.
673
+
674
+ Both integrate with `tape6-server` and the `__tape6_reportResults` callback to report pass/fail from the command line.
681
675
 
682
676
  ### Browser limitations
683
677
 
@@ -749,6 +743,8 @@ test('MyClass', async t => {
749
743
 
750
744
  ### Writing a CommonJS test
751
745
 
746
+ Always use `require()` — it is the correct and idiomatic CJS pattern:
747
+
752
748
  ```cjs
753
749
  const {test} = require('tape-six');
754
750
  const {myFunction} = require('my-package');
@@ -758,7 +754,9 @@ test('myFunction from CJS', t => {
758
754
  });
759
755
  ```
760
756
 
761
- If the module under test uses top-level `await`, `require()` cannot load it. Use `await import()` inside async tests instead:
757
+ > **IMPORTANT:** Do NOT use `await import()` as a substitute for `require()`. It is only needed when the module under test uses top-level `await` (which is rare). For local project modules, verify first — e.g., grep for `^await` at the top level of the source file. If it has no top-level `await`, use `require()`.
758
+
759
+ Rare fallback for modules with top-level `await`:
762
760
 
763
761
  ```cjs
764
762
  const {test} = require('tape-six');
@@ -776,6 +774,12 @@ node tests/test-<name>.js # run your new test file directly
776
774
  npm test # run full suite to check for regressions
777
775
  ```
778
776
 
777
+ ## Related packages
778
+
779
+ - [tape-six-proc](https://www.npmjs.com/package/tape-six-proc) — runs test files in separate processes instead of worker threads. Useful when tests need full process isolation.
780
+ - [tape-six-puppeteer](https://www.npmjs.com/package/tape-six-puppeteer) — automates browser testing with Puppeteer. Runs configured browser tests headlessly from the command line.
781
+ - [tape-six-playwright](https://www.npmjs.com/package/tape-six-playwright) — automates browser testing with Playwright. Same as above but using Playwright.
782
+
779
783
  ## Links
780
784
 
781
785
  - Full API reference: https://github.com/uhop/tape-six/wiki/Tester
package/bin/tape6-bun.js CHANGED
@@ -2,7 +2,15 @@
2
2
 
3
3
  import {fileURLToPath} from 'node:url';
4
4
 
5
- import {getOptions, initFiles, initReporter, showInfo} from '../src/utils/config.js';
5
+ import {
6
+ getOptions,
7
+ initFiles,
8
+ initReporter,
9
+ showInfo,
10
+ printVersion,
11
+ printHelp,
12
+ printFlagOptions
13
+ } from '../src/utils/config.js';
6
14
 
7
15
  import {getReporter, setReporter} from '../src/test.js';
8
16
  import {selectTimer} from '../src/utils/timer.js';
@@ -21,10 +29,30 @@ const showSelf = () => {
21
29
  process.exit(0);
22
30
  };
23
31
 
32
+ const showVersion = () => {
33
+ printVersion('tape6-bun');
34
+ process.exit(0);
35
+ };
36
+
37
+ const showHelp = () => {
38
+ printHelp('tape6-bun', 'Tape6 test runner for Bun', 'tape6-bun [options] [files...]', [
39
+ ['--flags, -f <flags>', 'Set reporter flags (env: TAPE6_FLAGS)'],
40
+ ['--par, -p <n>', 'Set parallelism level (env: TAPE6_PAR)'],
41
+ ['--info', 'Show configuration info and exit'],
42
+ ['--self', 'Print the path to this script and exit'],
43
+ ['--help, -h', 'Show this help message and exit'],
44
+ ['--version, -v', 'Show version and exit']
45
+ ]);
46
+ printFlagOptions();
47
+ process.exit(0);
48
+ };
49
+
24
50
  const main = async () => {
25
51
  const currentOptions = getOptions({
26
- '--self': showSelf,
27
- '--info': {isValueRequired: false}
52
+ '--self': {fn: showSelf, isValueRequired: false},
53
+ '--info': {isValueRequired: false},
54
+ '--help': {aliases: ['-h'], fn: showHelp, isValueRequired: false},
55
+ '--version': {aliases: ['-v'], fn: showVersion, isValueRequired: false}
28
56
  });
29
57
 
30
58
  const [files] = await Promise.all([
package/bin/tape6-deno.js CHANGED
@@ -3,7 +3,15 @@
3
3
  import process from 'node:process';
4
4
  import {fileURLToPath} from 'node:url';
5
5
 
6
- import {getOptions, initFiles, initReporter, showInfo} from '../src/utils/config.js';
6
+ import {
7
+ getOptions,
8
+ initFiles,
9
+ initReporter,
10
+ showInfo,
11
+ printVersion,
12
+ printHelp,
13
+ printFlagOptions
14
+ } from '../src/utils/config.js';
7
15
 
8
16
  import {getReporter, setReporter} from '../src/test.js';
9
17
  import {selectTimer} from '../src/utils/timer.js';
@@ -22,10 +30,30 @@ const showSelf = () => {
22
30
  Deno.exit(0);
23
31
  };
24
32
 
33
+ const showVersion = () => {
34
+ printVersion('tape6-deno');
35
+ Deno.exit(0);
36
+ };
37
+
38
+ const showHelp = () => {
39
+ printHelp('tape6-deno', 'Tape6 test runner for Deno', 'tape6-deno [options] [files...]', [
40
+ ['--flags, -f <flags>', 'Set reporter flags (env: TAPE6_FLAGS)'],
41
+ ['--par, -p <n>', 'Set parallelism level (env: TAPE6_PAR)'],
42
+ ['--info', 'Show configuration info and exit'],
43
+ ['--self', 'Print the path to this script and exit'],
44
+ ['--help, -h', 'Show this help message and exit'],
45
+ ['--version, -v', 'Show version and exit']
46
+ ]);
47
+ printFlagOptions();
48
+ Deno.exit(0);
49
+ };
50
+
25
51
  const main = async () => {
26
52
  const currentOptions = getOptions({
27
- '--self': showSelf,
28
- '--info': {isValueRequired: false}
53
+ '--self': {fn: showSelf, isValueRequired: false},
54
+ '--info': {isValueRequired: false},
55
+ '--help': {aliases: ['-h'], fn: showHelp, isValueRequired: false},
56
+ '--version': {aliases: ['-v'], fn: showVersion, isValueRequired: false}
29
57
  });
30
58
 
31
59
  const [files] = await Promise.all([
package/bin/tape6-node.js CHANGED
@@ -3,7 +3,15 @@
3
3
  import process from 'node:process';
4
4
  import {fileURLToPath} from 'node:url';
5
5
 
6
- import {getOptions, initFiles, initReporter, showInfo} from '../src/utils/config.js';
6
+ import {
7
+ getOptions,
8
+ initFiles,
9
+ initReporter,
10
+ showInfo,
11
+ printVersion,
12
+ printHelp,
13
+ printFlagOptions
14
+ } from '../src/utils/config.js';
7
15
 
8
16
  import {getReporter, setReporter} from '../src/test.js';
9
17
  import {selectTimer} from '../src/utils/timer.js';
@@ -22,10 +30,30 @@ const showSelf = () => {
22
30
  process.exit(0);
23
31
  };
24
32
 
33
+ const showVersion = () => {
34
+ printVersion('tape6-node');
35
+ process.exit(0);
36
+ };
37
+
38
+ const showHelp = () => {
39
+ printHelp('tape6-node', 'Tape6 test runner for Node.js', 'tape6-node [options] [files...]', [
40
+ ['--flags, -f <flags>', 'Set reporter flags (env: TAPE6_FLAGS)'],
41
+ ['--par, -p <n>', 'Set parallelism level (env: TAPE6_PAR)'],
42
+ ['--info', 'Show configuration info and exit'],
43
+ ['--self', 'Print the path to this script and exit'],
44
+ ['--help, -h', 'Show this help message and exit'],
45
+ ['--version, -v', 'Show version and exit']
46
+ ]);
47
+ printFlagOptions();
48
+ process.exit(0);
49
+ };
50
+
25
51
  const main = async () => {
26
52
  const currentOptions = getOptions({
27
- '--self': showSelf,
28
- '--info': {isValueRequired: false}
53
+ '--self': {fn: showSelf, isValueRequired: false},
54
+ '--info': {isValueRequired: false},
55
+ '--help': {aliases: ['-h'], fn: showHelp, isValueRequired: false},
56
+ '--version': {aliases: ['-v'], fn: showVersion, isValueRequired: false}
29
57
  });
30
58
 
31
59
  const [files] = await Promise.all([
@@ -3,6 +3,26 @@
3
3
  import process from 'node:process';
4
4
  import {fileURLToPath} from 'node:url';
5
5
 
6
+ import {printVersion, printHelp} from '../src/utils/config.js';
7
+
8
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
9
+ printHelp(
10
+ 'tape6-runner',
11
+ 'Print the path to a tape6 CLI script',
12
+ 'tape6-runner [options] [runtime]',
13
+ [
14
+ ['--help, -h', 'Show this help message and exit'],
15
+ ['--version, -v', 'Show version and exit']
16
+ ]
17
+ );
18
+ console.log('\nRuntimes: node, deno, bun, seq, server, runner, main (default)');
19
+ process.exit(0);
20
+ }
21
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
22
+ printVersion('tape6-runner');
23
+ process.exit(0);
24
+ }
25
+
6
26
  const runtimeFiles = {
7
27
  node: 'tape6-node.js',
8
28
  deno: 'tape6-deno.js',
package/bin/tape6-seq.js CHANGED
@@ -3,7 +3,15 @@
3
3
  import process from 'node:process';
4
4
  import {fileURLToPath} from 'node:url';
5
5
 
6
- import {getOptions, initFiles, initReporter, showInfo} from '../src/utils/config.js';
6
+ import {
7
+ getOptions,
8
+ initFiles,
9
+ initReporter,
10
+ showInfo,
11
+ printVersion,
12
+ printHelp,
13
+ printFlagOptions
14
+ } from '../src/utils/config.js';
7
15
 
8
16
  import {getReporter, setReporter, setConfiguredFlag, testRunner} from '../src/test.js';
9
17
  import {selectTimer} from '../src/utils/timer.js';
@@ -24,10 +32,35 @@ const showSelf = () => {
24
32
  process.exit(0);
25
33
  };
26
34
 
35
+ const showVersion = () => {
36
+ printVersion('tape6-seq');
37
+ process.exit(0);
38
+ };
39
+
40
+ const showHelp = () => {
41
+ printHelp(
42
+ 'tape6-seq',
43
+ 'Tape6 test runner (sequential, in-process)',
44
+ 'tape6-seq [options] [files...]',
45
+ [
46
+ ['--flags, -f <flags>', 'Set reporter flags (env: TAPE6_FLAGS)'],
47
+ ['--par, -p <n>', 'Set parallelism level (env: TAPE6_PAR)'],
48
+ ['--info', 'Show configuration info and exit'],
49
+ ['--self', 'Print the path to this script and exit'],
50
+ ['--help, -h', 'Show this help message and exit'],
51
+ ['--version, -v', 'Show version and exit']
52
+ ]
53
+ );
54
+ printFlagOptions();
55
+ process.exit(0);
56
+ };
57
+
27
58
  const main = async () => {
28
59
  const currentOptions = getOptions({
29
- '--self': showSelf,
30
- '--info': {isValueRequired: false}
60
+ '--self': {fn: showSelf, isValueRequired: false},
61
+ '--info': {isValueRequired: false},
62
+ '--help': {aliases: ['-h'], fn: showHelp, isValueRequired: false},
63
+ '--version': {aliases: ['-v'], fn: showVersion, isValueRequired: false}
31
64
  });
32
65
 
33
66
  const [files] = await Promise.all([
@@ -6,7 +6,13 @@ import path from 'node:path';
6
6
  import process from 'node:process';
7
7
  import {fileURLToPath} from 'node:url';
8
8
 
9
- import {getConfig, resolveTests, resolvePatterns} from '../src/utils/config.js';
9
+ import {
10
+ getConfig,
11
+ resolveTests,
12
+ resolvePatterns,
13
+ printVersion,
14
+ printHelp
15
+ } from '../src/utils/config.js';
10
16
 
11
17
  const fsp = fs.promises;
12
18
 
@@ -26,6 +32,24 @@ const showSelf = () => {
26
32
  }
27
33
  process.exit(0);
28
34
  };
35
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
36
+ printHelp('tape6-server', 'Static file server for browser testing', 'tape6-server [options]', [
37
+ ['--trace', 'Enable request trace logging'],
38
+ ['--self', 'Print the path to this script and exit'],
39
+ ['--help, -h', 'Show this help message and exit'],
40
+ ['--version, -v', 'Show version and exit']
41
+ ]);
42
+ console.log('\nEnvironment:');
43
+ console.log(' HOST Server hostname (default: localhost)');
44
+ console.log(' PORT Server port (default: 3000)');
45
+ console.log(' SERVER_ROOT Root directory for serving files (default: cwd)');
46
+ console.log(' WEBAPP_PATH Path to the web app directory');
47
+ process.exit(0);
48
+ }
49
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
50
+ printVersion('tape6-server');
51
+ process.exit(0);
52
+ }
29
53
  if (process.argv.includes('--self')) showSelf();
30
54
 
31
55
  // MIME source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
package/bin/tape6.js CHANGED
@@ -3,7 +3,23 @@
3
3
  import process from 'node:process';
4
4
  import {fileURLToPath} from 'node:url';
5
5
 
6
- if (process.argv.includes('--self')) {
6
+ import {printVersion, printHelp, printFlagOptions} from '../src/utils/config.js';
7
+
8
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
9
+ printHelp('tape6', 'Tape6 test runner (auto-detects runtime)', 'tape6 [options] [files...]', [
10
+ ['--flags, -f <flags>', 'Set reporter flags (env: TAPE6_FLAGS)'],
11
+ ['--par, -p <n>', 'Set parallelism level (env: TAPE6_PAR)'],
12
+ ['--info', 'Show configuration info and exit'],
13
+ ['--self', 'Print the path to this script and exit'],
14
+ ['--help, -h', 'Show this help message and exit'],
15
+ ['--version, -v', 'Show version and exit']
16
+ ]);
17
+ printFlagOptions();
18
+ process.exit(0);
19
+ } else if (process.argv.includes('--version') || process.argv.includes('-v')) {
20
+ printVersion('tape6');
21
+ process.exit(0);
22
+ } else if (process.argv.includes('--self')) {
7
23
  const self = new URL(import.meta.url);
8
24
  if (self.protocol === 'file:') {
9
25
  console.log(fileURLToPath(self));
package/llms-full.txt CHANGED
@@ -6,7 +6,7 @@
6
6
  - Test files are directly executable: `node test.js`, `bun run test.js`, `deno run -A test.js`
7
7
  - Parallel test execution via worker threads
8
8
  - TAP, TTY (colored), and JSONL output formats
9
- - Browser testing with built-in web UI and automation support (Puppeteer, Playwright)
9
+ - Browser testing with built-in web UI; headless automation via tape-six-puppeteer / tape-six-playwright
10
10
  - Before/after hooks: `beforeAll`, `afterAll`, `beforeEach`, `afterEach`
11
11
  - `test()` is aliased as `suite()`, `describe()`, and `it()` for easy migration
12
12
  - When called inside a test body, top-level functions auto-delegate to the current tester
@@ -266,7 +266,7 @@ Configuration is read from `tape6.json` or the `"tape6"` section of `package.jso
266
266
  "tape6": {
267
267
  "tests": ["/tests/test-*.*js"],
268
268
  "cli": ["/tests/test-*.cjs"],
269
- "browser": ["/tests/web/test-*.html"],
269
+ "browser": ["/tests/browser/test-*.html"],
270
270
  "importmap": {
271
271
  "imports": {
272
272
  "tape-six": "/node_modules/tape-six/index.js",
@@ -277,7 +277,7 @@ Configuration is read from `tape6.json` or the `"tape6"` section of `package.jso
277
277
  }
278
278
  ```
279
279
 
280
- Environment-specific subsections: `node`, `deno`, `bun`, `browser`.
280
+ Environment-specific subsections: `cli` (CLI-only: Node, Bun, Deno), `node`, `deno`, `bun`, `browser`.
281
281
 
282
282
  ## Command-line utilities
283
283
 
@@ -286,12 +286,15 @@ Environment-specific subsections: `node`, `deno`, `bun`, `browser`.
286
286
  Runs test files in parallel using worker threads.
287
287
 
288
288
  ```bash
289
- tape6 [--flags FLAGS] [--par N] [--info] [tests...]
289
+ tape6 [options...] [tests...]
290
290
  ```
291
291
 
292
- - `--flags FLAGS` — output control flags (see below).
293
- - `--par N` — number of parallel workers (default: all CPU cores).
292
+ - `--flags FLAGS`, `-f FLAGS` — output control flags (see below).
293
+ - `--par N`, `-p N` — number of parallel workers (default: all CPU cores).
294
294
  - `--info` — print current configuration and exit without running tests.
295
+ - `--self` — print the path to this script and exit.
296
+ - `--help`, `-h` — show help message and exit.
297
+ - `--version`, `-v` — show version and exit.
295
298
  - No arguments: runs tests from configuration.
296
299
  - Options accept `--flags FO` or `--flags=FO`. The `=` form does not support quoting.
297
300
 
@@ -304,10 +307,17 @@ Sequential in-process runner. Same options as `tape6` but no threads.
304
307
  Web server for browser testing:
305
308
 
306
309
  ```bash
307
- tape6-server [--trace] [--port N]
310
+ tape6-server [options...]
308
311
  ```
309
312
 
310
- Default port: 3000. Navigate to `http://localhost:3000` for the web UI.
313
+ - `--trace` enable request trace logging.
314
+ - `--self` — print the path to this script and exit.
315
+ - `--help`, `-h` — show help message and exit.
316
+ - `--version`, `-v` — show version and exit.
317
+
318
+ Configured via environment variables: `HOST` (default: localhost), `PORT` (default: 3000),
319
+ `SERVER_ROOT` (default: cwd), `WEBAPP_PATH`.
320
+ Navigate to `http://localhost:3000` for the web UI.
311
321
 
312
322
  ### Runtime-specific runners
313
323
 
@@ -351,33 +361,15 @@ Browser: `http://localhost:3000/?flags=FO`
351
361
 
352
362
  1. Start the server: `npm start` (runs `tape6-server --trace`).
353
363
  2. Open `http://localhost:3000` for the web UI.
354
- 3. Or automate with Puppeteer/Playwright:
364
+ 3. For automated headless testing use dedicated packages:
365
+ - tape-six-puppeteer (https://www.npmjs.com/package/tape-six-puppeteer)
366
+ - tape-six-playwright (https://www.npmjs.com/package/tape-six-playwright)
355
367
 
356
- ```js
357
- // Puppeteer example
358
- import puppeteer from 'puppeteer';
359
- const browser = await puppeteer.launch({headless: true});
360
- const page = await browser.newPage();
361
- page.on('console', msg => console.log(msg.text()));
362
- await page.exposeFunction('__tape6_reportResults', async text => {
363
- await browser.close();
364
- process.exit(text === 'success' ? 0 : 1);
365
- });
366
- await page.goto('http://localhost:3000/tests/web/test-simple.html?flags=M');
367
- ```
368
+ ## Related packages
368
369
 
369
- ```js
370
- // Playwright example
371
- import {chromium} from 'playwright';
372
- const browser = await chromium.launch({headless: true});
373
- const page = await browser.newPage();
374
- page.on('console', msg => console.log(msg.text()));
375
- await page.exposeFunction('__tape6_reportResults', async text => {
376
- await browser.close();
377
- process.exit(text === 'success' ? 0 : 1);
378
- });
379
- await page.goto('http://localhost:3000/tests/web/test-simple.html?flags=M');
380
- ```
370
+ - tape-six-proc (https://www.npmjs.com/package/tape-six-proc) — runs test files in separate processes instead of worker threads.
371
+ - tape-six-puppeteer (https://www.npmjs.com/package/tape-six-puppeteer) — automates browser testing with Puppeteer.
372
+ - tape-six-playwright (https://www.npmjs.com/package/tape-six-playwright) — automates browser testing with Playwright.
381
373
 
382
374
  ## 3rd-party assertion libraries
383
375
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tape-six",
3
- "version": "1.7.11",
4
- "description": "TAP-based unit test library for Node, Deno, Bun, and browsers. ES modules, TypeScript, zero dependencies.",
3
+ "version": "1.7.12",
4
+ "description": "TAP-inspired unit test library for Node, Deno, Bun, and browsers. ES modules, TypeScript, zero dependencies.",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "module": "index.js",
@@ -33,8 +33,6 @@
33
33
  "test:seq": "node ./bin/tape6-seq.js --flags FO",
34
34
  "test:seq:bun": "bun run ./bin/tape6-seq.js --flags FO",
35
35
  "test:seq:deno": "deno run -A ./bin/tape6-seq.js --flags FO",
36
- "test:puppeteer": "node tests/puppeteer-chrome.js",
37
- "test:playwright": "node tests/playwright-chrome.js",
38
36
  "ts-test": "node ./bin/tape6.js --flags FO 'tests/test-*.*ts'",
39
37
  "ts-test:bun": "bun run ./bin/tape6-bun.js --flags FO 'tests/test-*.*ts'",
40
38
  "ts-test:deno": "deno run -A ./bin/tape6-deno.js --flags FO 'tests/test-*.*ts'",
@@ -92,7 +90,7 @@
92
90
  "/tests/test-*.cjs"
93
91
  ],
94
92
  "browser": [
95
- "/tests/web/test-*.html"
93
+ "/tests/browser/test-*.html"
96
94
  ],
97
95
  "importmap": {
98
96
  "imports": {
@@ -104,10 +102,8 @@
104
102
  },
105
103
  "devDependencies": {
106
104
  "@types/chai": "^5.2.3",
107
- "@types/node": "^25.3.5",
105
+ "@types/node": "^25.5.0",
108
106
  "chai": "^6.2.2",
109
- "playwright": "^1.58.2",
110
- "puppeteer": "^24.38.0",
111
107
  "typescript": "^5.9.3"
112
108
  }
113
109
  }
@@ -19,15 +19,22 @@ Write or update tests using the tape-six testing library.
19
19
  2. Identify the module or feature to test. Read its source code to understand the public API.
20
20
  3. Create or update the test file in `tests/test-<name>.js` (or `.ts` for TypeScript, `.cjs` for CommonJS):
21
21
  - **ESM** (`.js`): `import test from 'tape-six'` and import the module under test using the project's package name.
22
- - **CJS** (`.cjs`): `const {test} = require('tape-six')` and `const {...} = require('my-package')`. If the module under test uses top-level `await`, `require()` cannot load it use `await import('my-package')` inside async tests instead.
22
+ - **CJS** (`.cjs`): `const {test} = require('tape-six')` and `const {...} = require('my-package')`. Always use `require()` — it is the correct CJS pattern. **Do NOT use `await import()` unless you have confirmed** (e.g., grep for `^await` at the top level) that the module under test uses top-level `await`, which is rare.
23
23
  - Write one top-level `test()` per logical group.
24
24
  - Use embedded `await t.test()` for sub-cases.
25
25
  - Use `t.beforeEach`/`t.afterEach` for shared setup/teardown.
26
26
  - Cover: normal operation, edge cases, error conditions.
27
27
  - Use `t.equal` for primitives, `t.deepEqual` for objects/arrays, `t.throws` for errors, `await t.rejects` for async errors.
28
28
  - All `msg` arguments are optional but recommended for clarity.
29
- 4. Run the new test file directly to verify: `node tests/test-<name>.js`
30
- 5. Run the full test suite to check for regressions: `npm test`
29
+ 4. **Browser-specific tests** — if the project uses browser testing with `tape6-server`. See the "Browser testing" section in `TESTING.md` for full details.
30
+ - Browsers run `.js` and `.mjs` only no TypeScript, no CommonJS.
31
+ - Browsers can also run `.html` shim files (with inline importmap and `<script type="module">`).
32
+ - Place browser-only files in a subdirectory (e.g., `tests/browser/`) and add patterns to `"browser"` in the `tape6` config.
33
+ - Run: `npx tape6-server --trace`, then open `http://localhost:3000`.
34
+ 5. **Environment-specific tests** — the `tape6` config in `package.json` supports per-environment patterns (`tests`, `cli`, `node`, `bun`, `deno`, `browser`). All are additive. See "Configuring test discovery" in `TESTING.md`.
35
+ 6. **Verify (CLI):** run the new test file directly: `node tests/test-<name>.js`
36
+ - Run the full suite to check for regressions: `npm test`
31
37
  - If debugging, use `npm run test:seq` (runs sequentially, easier to trace issues).
32
38
  - To see which files are being run, add `--flags fo` (overrides the default `--flags FO`).
33
- 6. Report results and any failures.
39
+ 7. **Verify (browser):** start `npx tape6-server --trace`, then open `http://localhost:3000/?q=/tests/test-<name>.js` to run a specific file. Use multiple `?q=` parameters to run several files. Open `http://localhost:3000/` to run all configured tests.
40
+ 8. Report results and any failures.
@@ -1,9 +1,58 @@
1
- import {promises as fsp} from 'node:fs';
1
+ import {promises as fsp, readFileSync} from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import os from 'node:os';
4
+ import {fileURLToPath} from 'node:url';
4
5
 
5
6
  import {listing, wildToRe} from './listing.js';
6
7
 
8
+ export const printVersion = commandName => {
9
+ const pkgJsonPath = path.resolve(
10
+ path.dirname(fileURLToPath(import.meta.url)),
11
+ '../../package.json'
12
+ ),
13
+ version = JSON.parse(readFileSync(pkgJsonPath, 'utf8')).version;
14
+ console.log(commandName + ' ' + version);
15
+ };
16
+
17
+ export const printHelp = (commandName, description, usage, options) => {
18
+ const pkgJsonPath = path.resolve(
19
+ path.dirname(fileURLToPath(import.meta.url)),
20
+ '../../package.json'
21
+ ),
22
+ version = JSON.parse(readFileSync(pkgJsonPath, 'utf8')).version;
23
+ console.log(commandName + ' ' + version + ' \u2014 ' + description + '\n');
24
+ console.log('Usage: ' + usage + '\n');
25
+ if (options) {
26
+ console.log('Options:');
27
+ const width = options.reduce((max, [flag]) => Math.max(max, flag.length), 0) + 2;
28
+ for (const [flag, desc] of options) {
29
+ console.log(' ' + flag.padEnd(width) + desc);
30
+ }
31
+ }
32
+ };
33
+
34
+ const flagDefs = {
35
+ f: {name: 'failureOnly', description: 'Show failed tests only'},
36
+ t: {name: 'showTime', description: 'Show test execution time'},
37
+ b: {name: 'showBanner', description: 'Show the banner'},
38
+ d: {name: 'showData', description: 'Show test data'},
39
+ o: {name: 'failOnce', description: 'Stop after first failure'},
40
+ s: {name: 'showStack', description: 'Show stack traces'},
41
+ l: {name: 'showLog', description: 'Show console log output'},
42
+ n: {name: 'showAssertNumber', description: 'Show assertion numbers'},
43
+ m: {name: 'monochrome', description: 'Disable colors (monochrome)'},
44
+ j: {name: 'useJsonL', description: 'Use JSONL reporter'},
45
+ c: {name: 'noConsoleCapture', description: 'Disable console capture'},
46
+ h: {name: 'hideStreams', description: 'Hide streams'}
47
+ };
48
+
49
+ export const printFlagOptions = () => {
50
+ console.log('\nFlags (uppercase = on, lowercase = off):');
51
+ for (const [flag, {description}] of Object.entries(flagDefs)) {
52
+ console.log(' ' + flag.toUpperCase() + ' ' + description);
53
+ }
54
+ };
55
+
7
56
  const exclude = (files, pattern) => {
8
57
  const excluded = new Set();
9
58
  for (const file of files) {
@@ -136,20 +185,9 @@ export const getTimeoutValue = () => {
136
185
 
137
186
  // parsing options
138
187
 
139
- export const flagNames = {
140
- f: 'failureOnly',
141
- t: 'showTime',
142
- b: 'showBanner',
143
- d: 'showData',
144
- o: 'failOnce',
145
- s: 'showStack',
146
- l: 'showLog',
147
- n: 'showAssertNumber',
148
- m: 'monochrome',
149
- j: 'useJsonL',
150
- c: 'noConsoleCapture',
151
- h: 'hideStreams'
152
- };
188
+ export const flagNames = Object.fromEntries(
189
+ Object.entries(flagDefs).map(([k, {name}]) => [k, name])
190
+ );
153
191
 
154
192
  export const processArgs = argOptions => {
155
193
  const result = {files: [], flags: {}};
@@ -247,7 +285,7 @@ export const getOptions = extraOptions => {
247
285
 
248
286
  for (let i = 0; i < flags.length; ++i) {
249
287
  const flag = flags[i].toLowerCase(),
250
- name = flagNames[flag];
288
+ name = flagDefs[flag]?.name;
251
289
  if (typeof name == 'string') options.flags[name] = flag !== flags[i];
252
290
  }
253
291