qunitx-cli 0.1.2 → 0.5.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.
Files changed (44) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/.env +1 -0
  3. package/Makefile +35 -0
  4. package/README.md +120 -49
  5. package/cli.js +1 -1
  6. package/cliff.toml +23 -0
  7. package/demo/demo.gif +0 -0
  8. package/demo/demo.tape +59 -0
  9. package/demo/example-test.js +53 -0
  10. package/demo/failing-test.js +22 -0
  11. package/flake.lock +4 -4
  12. package/flake.nix +33 -4
  13. package/lib/boilerplates/default-project-config-values.js +2 -2
  14. package/lib/boilerplates/test.js +5 -4
  15. package/lib/commands/generate.js +6 -8
  16. package/lib/commands/help.js +8 -8
  17. package/lib/commands/init.js +35 -25
  18. package/lib/commands/run/tests-in-browser.js +97 -67
  19. package/lib/commands/run.js +165 -55
  20. package/lib/servers/http.js +53 -42
  21. package/lib/setup/bind-server-to-port.js +3 -12
  22. package/lib/setup/browser.js +26 -18
  23. package/lib/setup/config.js +8 -10
  24. package/lib/setup/file-watcher.js +23 -6
  25. package/lib/setup/fs-tree.js +29 -27
  26. package/lib/setup/keyboard-events.js +7 -4
  27. package/lib/setup/test-file-paths.js +25 -23
  28. package/lib/setup/web-server.js +87 -61
  29. package/lib/setup/write-output-static-files.js +4 -1
  30. package/lib/tap/display-final-result.js +2 -2
  31. package/lib/tap/display-test-result.js +32 -14
  32. package/lib/utils/find-chrome.js +16 -0
  33. package/lib/utils/find-internal-assets-from-html.js +7 -5
  34. package/lib/utils/find-project-root.js +1 -2
  35. package/lib/utils/indent-string.js +6 -6
  36. package/lib/utils/listen-to-keyboard-key.js +6 -2
  37. package/lib/utils/parse-cli-flags.js +34 -31
  38. package/lib/utils/resolve-port-number-for.js +3 -3
  39. package/lib/utils/run-user-module.js +5 -3
  40. package/lib/utils/search-in-parent-directories.js +4 -1
  41. package/lib/utils/time-counter.js +2 -2
  42. package/package.json +21 -35
  43. package/vendor/qunit.css +7 -7
  44. package/vendor/qunit.js +3772 -3324
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npm test:*)"
5
+ ]
6
+ }
7
+ }
package/.env ADDED
@@ -0,0 +1 @@
1
+ export CHROME_BIN=$(which google-chrome-stable)
package/Makefile ADDED
@@ -0,0 +1,35 @@
1
+ .PHONY: check test lint build demo release
2
+
3
+ check: lint test
4
+
5
+ lint:
6
+ npm run lint
7
+
8
+ test:
9
+ npm test
10
+
11
+ build:
12
+ npm run build
13
+
14
+ # Regenerate demo/demo.gif using VHS.
15
+ # Requires: vhs (brew install vhs | nix profile install nixpkgs#vhs)
16
+ # Chrome (google-chrome-stable or chromium)
17
+ demo:
18
+ @which vhs > /dev/null 2>&1 || (echo "vhs not found — install: brew install vhs or nix profile install nixpkgs#vhs" && exit 1)
19
+ @CHROME=$$(which google-chrome-stable 2>/dev/null || which google-chrome 2>/dev/null || which chromium 2>/dev/null); \
20
+ test -n "$$CHROME" || (echo "Chrome not found — install google-chrome-stable or chromium" && exit 1); \
21
+ CHROME_BIN=$$CHROME vhs demo/demo.tape
22
+
23
+ # Lint, bump version, update changelog, commit, tag, push, publish to npm.
24
+ # CI then pushes the versioned Docker image and creates the GitHub release.
25
+ # Usage: make release LEVEL=patch|minor|major
26
+ release:
27
+ @test -n "$(LEVEL)" || (echo "Usage: make release LEVEL=patch|minor|major" && exit 1)
28
+ npm run lint
29
+ npm version $(LEVEL) --no-git-tag-version
30
+ npm run changelog:update
31
+ git add package.json package-lock.json CHANGELOG.md
32
+ git commit -m "Release $$(node -p 'require("./package.json").version')"
33
+ git tag "v$$(node -p 'require("./package.json").version')"
34
+ git push && git push --tags
35
+ npm publish --access public
package/README.md CHANGED
@@ -1,92 +1,163 @@
1
- # QUnitX CLI
1
+ # qunitx-cli
2
2
 
3
- CI browser runner for [qunitx](https://github.com/izelnakri/qunitx)
3
+ [![CI](https://github.com/izelnakri/qunitx-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/izelnakri/qunitx-cli/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/qunitx-cli)](https://www.npmjs.com/package/qunitx-cli)
5
+ [![npm downloads](https://img.shields.io/npm/dm/qunitx-cli)](https://www.npmjs.com/package/qunitx-cli)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
4
7
 
5
- ![QunitX terminal output](https://raw.githubusercontent.com/izelnakri/qunitx/main/docs/qunitx-help-stdout.png)
8
+ Browser-based test runner for [QUnitX](https://github.com/izelnakri/qunitx) — bundles your JS/TS tests
9
+ with esbuild, runs them in headless Chrome, and streams TAP output to the terminal.
6
10
 
7
- Default test output is TAP (_Test-Anything-Protocol_) thus you can use any tap reporter of your choice to display test
8
- output in anyway you like. Example:
11
+ ![qunitx-cli demo](demo/demo.gif)
9
12
 
10
- ```zsh
11
- # using it with tap-difflet TAP reporter:
12
- qunitx tests/attachments tests/user | npx tap-difflet
13
+ ## Features
14
+
15
+ - Runs `.js` and `.ts` test files in headless Chrome (Puppeteer + esbuild)
16
+ - TypeScript works with zero configuration — esbuild handles transpilation
17
+ - Inline source maps for accurate stack traces pointing to original source files
18
+ - Streams TAP-formatted output to the terminal in real time
19
+ - Concurrent mode (default) splits test files across all CPU cores for fast parallel runs
20
+ - `--watch` mode re-runs affected tests on file change
21
+ - `--failFast` stops the run after the first failing test
22
+ - `--debug` prints the local server URL and pipes browser console to stdout
23
+ - `--before` / `--after` hook scripts for server setup and teardown
24
+ - `--timeout` controls the maximum ms to wait for the full suite to finish
25
+ - Docker image for zero-install CI usage
26
+
27
+ ## Installation
28
+
29
+ Requires Node.js >= 24.
30
+
31
+ ```sh
32
+ npm install --save-dev qunitx-cli
13
33
  ```
14
34
 
15
- #### Installation:
35
+ Or run without installing:
36
+
37
+ ```sh
38
+ npx qunitx test/**/*.js
39
+ ```
40
+
41
+ With Docker — no install needed:
42
+
43
+ ```sh
44
+ docker run --rm -v "$(pwd):/code" -w /code ghcr.io/izelnakri/qunitx-cli:latest npx qunitx test/**/*.js
45
+ ```
16
46
 
17
- ```zsh
18
- npm install -g qunitx-cli
47
+ With Nix:
19
48
 
20
- qunitx
49
+ ```sh
50
+ nix profile install github:izelnakri/qunitx-cli
21
51
  ```
22
52
 
23
- In order to use qunitx to execute existing qunit tests please change:
53
+ ## Usage
54
+
55
+ ```sh
56
+ # Single file
57
+ qunitx test/my-test.js
58
+
59
+ # Multiple files / globs
60
+ qunitx test/**/*.js test/**/*.ts
61
+
62
+ # TypeScript — no tsconfig required
63
+ qunitx test/my-test.ts
64
+
65
+ # Watch mode: re-run on file changes
66
+ qunitx test/**/*.js --watch
67
+
68
+ # Stop on the first failure
69
+ qunitx test/**/*.js --failFast
70
+
71
+ # Print the server URL and pipe Chrome console to stdout
72
+ qunitx test/**/*.js --debug
73
+
74
+ # Custom timeout (ms)
75
+ qunitx test/**/*.js --timeout=30000
76
+
77
+ # Run a setup script before tests (can be async — awaited automatically)
78
+ qunitx test/**/*.js --before=scripts/start-server.js
79
+
80
+ # Run a teardown script after tests (can be async)
81
+ qunitx test/**/*.js --after=scripts/stop-server.js
82
+ ```
83
+
84
+ ## Writing Tests
85
+
86
+ qunitx-cli runs [QUnitX](https://github.com/izelnakri/qunitx) tests — a superset of QUnit with async
87
+ hooks, concurrency control, and test metadata.
88
+
89
+ Migrating from QUnit? Change a single import:
24
90
 
25
91
  ```js
92
+ // before
26
93
  import { module, test } from 'qunit';
27
-
28
- // to:
94
+ // after
29
95
  import { module, test } from 'qunitx';
30
96
  ```
31
97
 
32
- Example:
98
+ Example test file — ES modules, npm imports, and nested modules all work out of the box:
33
99
 
34
100
  ```js
35
- // in some-test.js: (typescript is also supported for --browser mode and node.js with --loader flag)
101
+ // some-test.js (TypeScript is also supported)
36
102
  import { module, test } from 'qunitx';
37
103
  import $ from 'jquery';
38
104
 
39
- module('Basic sanity check', function (hooks) {
40
- test('it works', function (assert) {
105
+ module('Basic sanity check', (hooks) => {
106
+ test('it works', (assert) => {
41
107
  assert.equal(true, true);
42
108
  });
43
109
 
44
- module('More advanced cases', function (hooks) {
45
- test('deepEqual works', function (assert) {
110
+ module('More advanced cases', (hooks) => {
111
+ test('deepEqual works', (assert) => {
46
112
  assert.deepEqual({ username: 'izelnakri' }, { username: 'izelnakri' });
47
113
  });
48
- test('can import ES & npm modules', function (assert) {
114
+
115
+ test('can import ES & npm modules', (assert) => {
49
116
  assert.ok(Object.keys($));
50
117
  });
51
118
  });
52
119
  });
53
120
  ```
54
121
 
55
- ```zsh
56
- # you can run the test in node with ES modules package.json{ "type": "module" }
57
- $ node --test some-test.js
122
+ Run it:
58
123
 
59
- # Suggested mode: if you want to run it in CI/google chrome:
124
+ ```sh
125
+ # Headless Chrome (recommended for CI)
126
+ qunitx some-test.js
60
127
 
61
- $ qunitx some-test.js
62
-
63
- # with browser output enabled:
64
-
65
- $ qunitx some-test.js --debug
66
-
67
- # TypeScript also works, make sure on node.js mode, tsconfig.json exists with compilerOptions.module & compilerOptions.moduleResolution set to "NodeNext":
68
-
69
- $ node --loader=ts-node/esm/transpile-only --test some-test.ts
70
-
71
- $ qunitx some-test.ts --debug
128
+ # With browser console output
129
+ qunitx some-test.js --debug
72
130
 
131
+ # TypeScript — no config needed
132
+ qunitx some-test.ts
73
133
  ```
74
134
 
75
- ### Code coverage
135
+ ## CLI Reference
76
136
 
77
- Since QUnitX proxies to default node.js test runner in when executed with node, you can use any code coverage tool you like. When running the tests in `qunit`(the browser mode) code coverage support is limited.
78
137
  ```
79
- c8 node test/attachments test/user
138
+ Usage: qunitx [files/folders...] [options]
139
+
140
+ Options:
141
+ --watch Re-run tests on file changes
142
+ --failFast Stop after the first failure
143
+ --debug Print the server URL; pipe browser console to stdout
144
+ --timeout=<ms> Max ms to wait for the suite to finish [default: 20000]
145
+ --output=<dir> Directory for compiled test assets [default: ./tmp]
146
+ --before=<file> Script to run (and optionally await) before tests start
147
+ --after=<file> Script to run (and optionally await) after tests finish
148
+ --port=<n> HTTP server port (auto-selects a free port if taken)
80
149
  ```
81
150
 
82
- You can browse [c8 documentation](https://github.com/bcoe/c8) for all configuration options.
151
+ ## Development
152
+
153
+ ```sh
154
+ npm install
155
+ make check # lint + test (run before every commit)
156
+ make test # run tests only
157
+ make demo # regenerate demo output
158
+ make release LEVEL=patch # bump version, update changelog, tag, push
159
+ ```
83
160
 
84
- Implementing code coverage for the browser mode is currently not possible because we use esbuild --bundle feature to
85
- create a JS bundles for testing in the browser, this could be instrumented with `puppeteer-to-istanbul` however
86
- instrumentation includes transpiled npm imports of `qunitx` and other potential npm imports developer
87
- includes in the code, this cannot be filtered since potential filtering can only occur after the `esbuild` bundling.
88
- When chrome browser and puppeteer fully supports ES asset maps we can remove esbuild from the browser mode, run
89
- everything in deno and make instrumentation for code coverage possible with the default v8 instrumentation.
161
+ ## License
90
162
 
91
- Esbuild plugin interface is an ongoing development, we might be able to figure out a way to generate this instrumentation
92
- with esbuild in the future, which could allow code coverage for --browser mode.
163
+ MIT
package/cli.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env -S TS_NODE_COMPILER_OPTIONS='{"module":"ES2020"}' node --loader ts-node/esm/transpile-only
1
+ #!/usr/bin/env node
2
2
  import process from 'node:process';
3
3
  import displayHelpOutput from './lib/commands/help.js';
4
4
  import initializeProject from './lib/commands/init.js';
package/cliff.toml ADDED
@@ -0,0 +1,23 @@
1
+ [changelog]
2
+ header = """# Changelog
3
+
4
+ All notable changes to this project will be documented in this file.
5
+ """
6
+ body = """
7
+ {% if version %}\
8
+ ## {{ version | trim_start_matches(pat="v") }} — {{ timestamp | date(format="%Y-%m-%d") }}
9
+ {% else %}\
10
+ ## Unreleased
11
+ {% endif %}\
12
+ {% for commit in commits %}\
13
+ - {{ commit.message | split(pat="\n") | first | trim | upper_first }}
14
+ {% endfor %}
15
+ """
16
+ footer = ""
17
+ trim = true
18
+
19
+ [git]
20
+ conventional_commits = false
21
+ filter_unconventional = false
22
+ tag_pattern = "v[0-9].*"
23
+ sort_commits = "newest"
package/demo/demo.gif ADDED
Binary file
package/demo/demo.tape ADDED
@@ -0,0 +1,59 @@
1
+ # qunitx-cli demo — generates demo/demo.gif
2
+ # Run via: make demo (handles Chrome discovery automatically)
3
+
4
+ Output demo/demo.gif
5
+
6
+ Set Shell bash
7
+ Set FontSize 15
8
+ Set Width 800
9
+ Set Height 750
10
+ Set Theme "Dracula"
11
+ Set Padding 20
12
+ Set Framerate 24
13
+ Set TypingSpeed 45ms
14
+
15
+ Env PUPPETEER_SKIP_DOWNLOAD "true"
16
+ Env FORCE_COLOR "1"
17
+ Env PS1 "$ "
18
+
19
+ # ── 1. Show the test file ─────────────────────────────────────────────────────
20
+ Type "# 1/5 Inspect the test file"
21
+ Enter
22
+ Sleep 400ms
23
+ Type "cat demo/example-test.js"
24
+ Enter
25
+ Sleep 3000ms
26
+
27
+ # ── 2. Run all tests — concurrent by default, all green ──────────────────────
28
+ Type "# 2/5 Run tests — concurrent by default"
29
+ Enter
30
+ Sleep 400ms
31
+ Type "qunitx demo/example-test.js"
32
+ Enter
33
+ Sleep 7000ms
34
+
35
+ # ── 3. --debug: pipe Chrome's console.log to your terminal ───────────────────
36
+ Type "# 3/5 --debug: pipe Chrome console to your terminal"
37
+ Enter
38
+ Sleep 400ms
39
+ Type "qunitx demo/example-test.js --debug"
40
+ Enter
41
+ Sleep 7000ms
42
+
43
+ # ── 4. --failFast: stop immediately on the first failure ─────────────────────
44
+ Type "# 4/5 --failFast: stop on the first failure"
45
+ Enter
46
+ Sleep 400ms
47
+ Type "qunitx demo/failing-test.js --failFast"
48
+ Enter
49
+ Sleep 7000ms
50
+
51
+ # ── 5. --watch: stay alive and re-run on every file save ─────────────────────
52
+ Type "# 5/5 --watch: re-run on every file save"
53
+ Enter
54
+ Sleep 400ms
55
+ Type "qunitx demo/example-test.js --watch"
56
+ Enter
57
+ Sleep 6000ms
58
+ Ctrl+C
59
+ Sleep 1200ms
@@ -0,0 +1,53 @@
1
+ import { module, test } from 'qunitx';
2
+
3
+ // Tests run in real headless Chrome — not jsdom, not Node.js.
4
+
5
+ module('Browser', () => {
6
+ test('has window, document & navigator', (assert) => {
7
+ assert.ok(typeof window !== 'undefined', 'window exists');
8
+ assert.ok(document.body !== null, 'document.body exists');
9
+ assert.ok(navigator.userAgent.includes('Chrome'), 'running in Chrome');
10
+ });
11
+
12
+ test('can build and query a DOM tree', (assert) => {
13
+ const ul = document.createElement('ul');
14
+ ['Alice', 'Bob', 'Carol'].forEach((name) => {
15
+ const li = document.createElement('li');
16
+ li.textContent = name;
17
+ ul.appendChild(li);
18
+ });
19
+ assert.equal(ul.querySelectorAll('li').length, 3);
20
+ assert.equal(ul.querySelector('li').textContent, 'Alice');
21
+ });
22
+
23
+ test('crypto.randomUUID() works', (assert) => {
24
+ const id = crypto.randomUUID();
25
+ console.log('[debug] uuid:', id);
26
+ assert.ok(/^[0-9a-f-]{36}$/.test(id), 'valid UUID format');
27
+ });
28
+ });
29
+
30
+ module('Async', () => {
31
+ test('resolves a promise', async (assert) => {
32
+ const value = await Promise.resolve('hello from Chrome');
33
+ assert.equal(value, 'hello from Chrome');
34
+ });
35
+
36
+ test('rejects are caught', async (assert) => {
37
+ await assert.rejects(Promise.reject(new Error('boom')), /boom/);
38
+ });
39
+ });
40
+
41
+ module('Assertions', () => {
42
+ test('equal & deepEqual', (assert) => {
43
+ assert.equal(1 + 1, 2);
44
+ assert.deepEqual(
45
+ { user: 'alice', roles: ['admin', 'viewer'] },
46
+ { user: 'alice', roles: ['admin', 'viewer'] },
47
+ );
48
+ });
49
+
50
+ test('throws on bad input', (assert) => {
51
+ assert.throws(() => JSON.parse('{bad json}'), SyntaxError);
52
+ });
53
+ });
@@ -0,0 +1,22 @@
1
+ import { module, test } from 'qunitx';
2
+
3
+ module('Cart', () => {
4
+ test('calculates subtotal', (assert) => {
5
+ const items = [{ price: 10 }, { price: 20 }, { price: 5 }];
6
+ const total = items.reduce((sum, item) => sum + item.price, 0);
7
+ assert.equal(total, 35, 'subtotal is correct');
8
+ });
9
+
10
+ test('applies 10% discount', (assert) => {
11
+ assert.equal(Math.round(100 * 0.9), 90);
12
+ });
13
+
14
+ test('validates stock level', (assert) => {
15
+ const stock = 0;
16
+ assert.ok(stock > 0, 'expected items in stock'); // ← will fail
17
+ });
18
+
19
+ test('calculates tax', (assert) => {
20
+ assert.equal(100 * 0.2, 20); // ← never reached with --failFast
21
+ });
22
+ });
package/flake.lock CHANGED
@@ -38,16 +38,16 @@
38
38
  },
39
39
  "nixpkgs": {
40
40
  "locked": {
41
- "lastModified": 1690860117,
42
- "narHash": "sha256-srkCfjMlg777HxDVMfhkIFgRhhtuZjIOIyR2ejLYK+Y=",
41
+ "lastModified": 1772822230,
42
+ "narHash": "sha256-yf3iYLGbGVlIthlQIk5/4/EQDZNNEmuqKZkQssMljuw=",
43
43
  "owner": "NixOS",
44
44
  "repo": "nixpkgs",
45
- "rev": "96d403ee2479f2070050353b94808209f1352edb",
45
+ "rev": "71caefce12ba78d84fe618cf61644dce01cf3a96",
46
46
  "type": "github"
47
47
  },
48
48
  "original": {
49
49
  "owner": "NixOS",
50
- "ref": "nixpkgs-unstable",
50
+ "ref": "nixos-25.11",
51
51
  "repo": "nixpkgs",
52
52
  "type": "github"
53
53
  }
package/flake.nix CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  description = "A flake for napalm";
3
3
 
4
- inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
4
+ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
5
5
  inputs.napalm.url = "github:nix-community/napalm";
6
6
 
7
7
  # NOTE: This is optional, but is how to configure napalm's env
@@ -13,14 +13,43 @@
13
13
  pkgs = nixpkgs.legacyPackages."${system}";
14
14
  in {
15
15
  packages."${system}".default = napalm.legacyPackages."${system}".buildPackage ./. {
16
- nodejs = pkgs.nodejs_20;
16
+ nodejs = pkgs.nodejs_24;
17
17
  PUPPETEER_SKIP_DOWNLOAD=1;
18
18
  };
19
19
 
20
20
  devShells."${system}".default = pkgs.mkShell {
21
- nativeBuildInputs = with pkgs; [
22
- nodejs_20
21
+ nativeBuildInputs = [
22
+ pkgs.pkg-config
23
+ pkgs.deno
24
+ pkgs.nodejs_24
25
+ pkgs.git-cliff
26
+ pkgs.vhs
27
+ # self.packages.default.nativeBuildInputs
28
+ # self.packages.default.buildInputs
23
29
  ];
30
+
31
+ doCheck = false; # Disables automatically running tests for `$ nix develop` and direnv
32
+
33
+ shellHook = ''
34
+ export ZDOTDIR=$(mktemp -d)
35
+ cat > "$ZDOTDIR/.zshrc" << 'EOF'
36
+ source ~/.zshrc # Source the original ~/.zshrc, required.
37
+ function parse_git_branch {
38
+ git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\ ->\ \1/'
39
+ }
40
+ function display_jobs_count_if_needed {
41
+ local job_count=$(jobs -s | wc -l | tr -d " ")
42
+ if [ $job_count -gt 0 ]; then
43
+ echo "%B%F{yellow}%j| ";
44
+ fi
45
+ }
46
+ # NOTE: Custom prompt with a snowflake: signals we are in `$ nix develop` shell
47
+ PROMPT="%F{blue}$(date +%H:%M:%S) $(display_jobs_count_if_needed)%B%F{green}%n %F{blue}%~%F{cyan} ❄%F{yellow}$(parse_git_branch) %f%{$reset_color%}"
48
+ EOF
49
+ if [ -z "$DIRENV_IN_ENVRC" ]; then # This makes `$ nix develop` universally working with direnv without infinite loop
50
+ exec ${pkgs.zsh}/bin/zsh -i
51
+ fi
52
+ '';
24
53
  };
25
54
  };
26
55
  }
@@ -2,5 +2,5 @@ export default {
2
2
  output: 'tmp',
3
3
  timeout: 20000,
4
4
  failFast: false,
5
- port: 1234
6
- }
5
+ port: 1234,
6
+ };
@@ -1,6 +1,6 @@
1
1
  import { module, test } from 'qunitx';
2
2
 
3
- module('{{moduleName}}', function(hooks) {
3
+ module('{{moduleName}}', function (hooks) {
4
4
  test('assert true works', function (assert) {
5
5
  assert.expect(3);
6
6
  assert.ok(true);
@@ -11,9 +11,10 @@ module('{{moduleName}}', function(hooks) {
11
11
  test('async test finishes', async function (assert) {
12
12
  assert.expect(3);
13
13
 
14
- let wait = () => new Promise((resolve, reject) => {
15
- setTimeout(() => resolve(true), 50);
16
- });
14
+ let wait = () =>
15
+ new Promise((resolve, reject) => {
16
+ setTimeout(() => resolve(true), 50);
17
+ });
17
18
  let result = await wait();
18
19
 
19
20
  assert.ok(true);
@@ -7,12 +7,13 @@ import pathExists from '../utils/path-exists.js';
7
7
 
8
8
  const __dirname = dirname(fileURLToPath(import.meta.url));
9
9
 
10
- export default async function() {
10
+ export default async function () {
11
11
  let projectRoot = await findProjectRoot();
12
12
  let moduleName = process.argv[3]; // TODO: classify this maybe in future
13
- let path = process.argv[3].endsWith('.js') || process.argv[3].endsWith('.ts')
14
- ? `${projectRoot}/${process.argv[3]}`
15
- : `${projectRoot}/${process.argv[3]}.js`;
13
+ let path =
14
+ process.argv[3].endsWith('.js') || process.argv[3].endsWith('.ts')
15
+ ? `${projectRoot}/${process.argv[3]}`
16
+ : `${projectRoot}/${process.argv[3]}.js`;
16
17
 
17
18
  if (await pathExists(path)) {
18
19
  return console.log(`${path} already exists!`);
@@ -24,10 +25,7 @@ export default async function() {
24
25
  targetFolderPaths.pop();
25
26
 
26
27
  await fs.mkdir(targetFolderPaths.join('/'), { recursive: true });
27
- await fs.writeFile(
28
- path,
29
- testJSContent.toString().replace('{{moduleName}}', moduleName)
30
- );
28
+ await fs.writeFile(path, testJSContent.toString().replace('{{moduleName}}', moduleName));
31
29
 
32
30
  console.log(kleur.green(`${path} written`));
33
31
  }
@@ -7,30 +7,30 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
7
7
  const highlight = (text) => kleur.magenta().bold(text);
8
8
  const color = (text) => kleur.blue(text);
9
9
 
10
+ export default async function () {
11
+ const config = JSON.parse(await fs.readFile(`${__dirname}/../../package.json`));
10
12
 
11
- export default async function() {
12
- const config = JSON.parse((await fs.readFile(`${__dirname}/../../package.json`)));
13
+ console.log(`${highlight('[qunitx v' + config.version + '] Usage:')} qunitx ${color('[targets] --$flags')}
13
14
 
14
- console.log(`${highlight("[qunitx v" + config.version + "] Usage:")} qunitx ${color('[targets] --$flags')}
15
-
16
- ${highlight("Input options:")}
15
+ ${highlight('Input options:')}
17
16
  - File: $ ${color('qunitx test/foo.js')}
18
17
  - Folder: $ ${color('qunitx test/login')}
19
18
  - Globs: $ ${color('qunitx test/**/*-test.js')}
20
19
  - Combination: $ ${color('qunitx test/foo.js test/bar.js test/*-test.js test/logout')}
21
20
 
22
- ${highlight("Optional flags:")}
21
+ ${highlight('Optional flags:')}
23
22
  ${color('--debug')} : print console output when tests run in browser
24
23
  ${color('--watch')} : run the target file or folders, watch them for continuous run and expose http server under localhost
25
24
  ${color('--timeout')} : change default timeout per test case
26
25
  ${color('--output')} : folder to distribute built qunitx html and js that a webservers can run[default: tmp]
27
26
  ${color('--failFast')} : run the target file or folders with immediate abort if a single test fails
27
+ ${color('--port')} : HTTP server port (auto-selects a free port if the given port is taken)[default: 1234]
28
28
  ${color('--before')} : run a script before the tests(i.e start a new web server before tests)
29
29
  ${color('--after')} : run a script after the tests(i.e save test results to a file)
30
30
 
31
- ${highlight("Example:")} $ ${color('qunitx test/foo.ts app/e2e --debug --watch --before=scripts/start-new-webserver.js --after=scripts/write-test-results.js')}
31
+ ${highlight('Example:')} $ ${color('qunitx test/foo.ts app/e2e --debug --watch --before=scripts/start-new-webserver.js --after=scripts/write-test-results.js')}
32
32
 
33
- ${highlight("Commands:")}
33
+ ${highlight('Commands:')}
34
34
  ${color('$ qunitx init')} # Bootstraps qunitx base html and add qunitx config to package.json if needed
35
35
  ${color('$ qunitx new $testFileName')} # Creates a qunitx test file
36
36
  `);