qunitx-cli 0.11.0 → 0.15.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/README.md +7 -0
- package/dist/cli.js +60 -11
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -188,6 +188,13 @@ All CLI flags can also be set in `package.json` under the `qunitx` key, so you d
|
|
|
188
188
|
|
|
189
189
|
CLI flags always override `package.json` values when both are present.
|
|
190
190
|
|
|
191
|
+
### Environment variables
|
|
192
|
+
|
|
193
|
+
| Variable | Description |
|
|
194
|
+
|------------------|---------------------------------------------------------------------------------------------------------------|
|
|
195
|
+
| `CHROME_BIN` | Path to the Chrome/Chromium executable. Required on systems where Chrome is not on `PATH` (e.g. many CI environments). Set automatically when using `browser-actions/setup-chrome` in GitHub Actions. |
|
|
196
|
+
| `QUNITX_BROWSER` | Browser engine to use (`chromium`, `firefox`, `webkit`). Equivalent to `--browser` on the CLI. Useful in CI matrix jobs. |
|
|
197
|
+
|
|
191
198
|
If you do not provide any HTML template, qunitx falls back to its built-in `test/tests.html` boilerplate internally, so `qunitx init` is optional.
|
|
192
199
|
|
|
193
200
|
You can also pass a custom HTML file on the CLI:
|
package/dist/cli.js
CHANGED
|
@@ -682,17 +682,38 @@ function setupWebServer(config, cachedContent) {
|
|
|
682
682
|
socket.on("message", function message(data) {
|
|
683
683
|
const { event, details, abort } = JSON.parse(data);
|
|
684
684
|
if (event === "wsOpen") {
|
|
685
|
+
config._phase = "loading";
|
|
685
686
|
config._onWsOpen?.();
|
|
686
687
|
} else if (event === "connection") {
|
|
688
|
+
config._phase = "running";
|
|
687
689
|
if (!config._groupMode) console.log("TAP version 13");
|
|
690
|
+
if (config.debug && config._groupMode) {
|
|
691
|
+
const allFiles = Object.keys(config.fsTree);
|
|
692
|
+
const relFiles = allFiles.map((f) => f.replace(`${config.projectRoot}/`, ""));
|
|
693
|
+
const shown = relFiles.slice(0, 2);
|
|
694
|
+
const rest = relFiles.length - shown.length;
|
|
695
|
+
const fileList = rest > 0 ? `${shown.join(" ")} +${rest} more` : shown.join(" ");
|
|
696
|
+
console.log("#", blue(`\u2500\u2500 ${fileList} \u2500\u2500`));
|
|
697
|
+
}
|
|
688
698
|
config._resetTestTimeout?.();
|
|
689
699
|
} else if (event === "testEnd" && !abort) {
|
|
690
700
|
if (details.status === "failed") {
|
|
691
701
|
config.lastFailedTestFiles = config.lastRanTestFiles;
|
|
692
702
|
}
|
|
703
|
+
if (config.debug && details.runtime > config.timeout * 0.8) {
|
|
704
|
+
console.log(
|
|
705
|
+
`# SLOW (${details.runtime.toFixed(0)}ms / ${config.timeout}ms timeout): ${details.fullName.join(" | ")}`
|
|
706
|
+
);
|
|
707
|
+
}
|
|
693
708
|
config._resetTestTimeout?.();
|
|
694
709
|
TAPDisplayTestResult(config.COUNTER, details);
|
|
695
710
|
} else if (event === "done") {
|
|
711
|
+
config._phase = "done";
|
|
712
|
+
if (config.debug && config._groupMode) {
|
|
713
|
+
console.log(
|
|
714
|
+
`# group done: ${details.passed} passed, ${details.failed} failed (${details.runtime}ms)`
|
|
715
|
+
);
|
|
716
|
+
}
|
|
696
717
|
if (typeof config._testRunDone === "function") {
|
|
697
718
|
config._testRunDone();
|
|
698
719
|
config._testRunDone = null;
|
|
@@ -966,6 +987,7 @@ var init_web_server = __esm({
|
|
|
966
987
|
init_find_internal_assets_from_html();
|
|
967
988
|
init_html_content_marker();
|
|
968
989
|
init_display_test_result();
|
|
990
|
+
init_color();
|
|
969
991
|
init_path_exists();
|
|
970
992
|
init_http();
|
|
971
993
|
fsPromise = fs7.promises;
|
|
@@ -1122,7 +1144,7 @@ async function runUserModule(modulePath, params, scriptPosition) {
|
|
|
1122
1144
|
console.log("#", red(`QUnitX ${scriptPosition} script failed:`));
|
|
1123
1145
|
console.trace(error);
|
|
1124
1146
|
console.error(error);
|
|
1125
|
-
|
|
1147
|
+
process.stdout.write("", () => process.exit(1));
|
|
1126
1148
|
}
|
|
1127
1149
|
}
|
|
1128
1150
|
var init_run_user_module = __esm({
|
|
@@ -1470,6 +1492,7 @@ function setupFileWatchers(testFileLookupPaths, config, onEventFunc, onFinishFun
|
|
|
1470
1492
|
function handleWatchEvent(config, extensions, event, filePath, onEventFunc, onFinishFunc) {
|
|
1471
1493
|
const isFileEvent = extensions.some((ext) => filePath.endsWith(`.${ext}`));
|
|
1472
1494
|
if (!isFileEvent && event !== "unlinkDir") return;
|
|
1495
|
+
if (event === "change" && config._building && config._justAddedFiles?.has(filePath)) return;
|
|
1473
1496
|
mutateFSTree(config.fsTree, event, filePath);
|
|
1474
1497
|
console.log(
|
|
1475
1498
|
"#",
|
|
@@ -1482,6 +1505,7 @@ function handleWatchEvent(config, extensions, event, filePath, onEventFunc, onFi
|
|
|
1482
1505
|
);
|
|
1483
1506
|
if (!config._building) {
|
|
1484
1507
|
config._building = true;
|
|
1508
|
+
config._justAddedFiles = event === "add" ? /* @__PURE__ */ new Set([filePath]) : /* @__PURE__ */ new Set();
|
|
1485
1509
|
const result = onEventFunc(event, filePath);
|
|
1486
1510
|
if (!(result instanceof Promise)) {
|
|
1487
1511
|
config._building = false;
|
|
@@ -1500,6 +1524,7 @@ function handleWatchEvent(config, extensions, event, filePath, onEventFunc, onFi
|
|
|
1500
1524
|
}
|
|
1501
1525
|
});
|
|
1502
1526
|
} else {
|
|
1527
|
+
if (event === "add") config._justAddedFiles?.add(filePath);
|
|
1503
1528
|
config._pendingBuildTrigger = () => handleWatchEvent(config, extensions, event, filePath, onEventFunc, onFinishFunc);
|
|
1504
1529
|
}
|
|
1505
1530
|
}
|
|
@@ -1594,7 +1619,7 @@ function setupKeyboardEvents(config, cachedContent, connections) {
|
|
|
1594
1619
|
});
|
|
1595
1620
|
}
|
|
1596
1621
|
function abortBrowserQUnit(_config, connections) {
|
|
1597
|
-
connections.server.publish("abort"
|
|
1622
|
+
connections.server.publish("abort");
|
|
1598
1623
|
}
|
|
1599
1624
|
var init_keyboard_events = __esm({
|
|
1600
1625
|
"lib/setup/keyboard-events.ts"() {
|
|
@@ -1671,11 +1696,21 @@ async function run(config) {
|
|
|
1671
1696
|
if (["change", "unlink", "unlinkDir"].includes(event)) {
|
|
1672
1697
|
if (event === "change" && !(file in config.fsTree)) return;
|
|
1673
1698
|
cachedContent.allTestCode = null;
|
|
1699
|
+
if (config.debug) {
|
|
1700
|
+
console.log(
|
|
1701
|
+
`# Rerun triggered: ${event} \u2192 ${file.replace(`${config.projectRoot}/`, "")}`
|
|
1702
|
+
);
|
|
1703
|
+
}
|
|
1674
1704
|
return await runTestsInBrowser(config, cachedContent, connections);
|
|
1675
1705
|
}
|
|
1706
|
+
if (config.debug) {
|
|
1707
|
+
console.log(
|
|
1708
|
+
`# Rerun triggered: ${event} \u2192 ${file.replace(`${config.projectRoot}/`, "")}`
|
|
1709
|
+
);
|
|
1710
|
+
}
|
|
1676
1711
|
await runTestsInBrowser(config, cachedContent, connections, [file]);
|
|
1677
1712
|
},
|
|
1678
|
-
(_path, _event) => connections.server.publish("refresh"
|
|
1713
|
+
(_path, _event) => connections.server.publish("refresh")
|
|
1679
1714
|
);
|
|
1680
1715
|
await watcherReady;
|
|
1681
1716
|
}
|
|
@@ -1691,10 +1726,14 @@ async function run(config) {
|
|
|
1691
1726
|
fsTree: Object.fromEntries(groupFiles.map((f) => [f, config.fsTree[f]])),
|
|
1692
1727
|
// Single group keeps the root output dir for backward-compatible file paths.
|
|
1693
1728
|
output: groupCount === 1 ? config.output : `${config.output}/group-${i}`,
|
|
1694
|
-
_groupMode: true
|
|
1729
|
+
_groupMode: true,
|
|
1730
|
+
_phase: "bundling"
|
|
1695
1731
|
}));
|
|
1696
1732
|
const groupCachedContents = groups.map(() => ({ ...cachedContent }));
|
|
1697
1733
|
console.log("TAP version 13");
|
|
1734
|
+
console.log(
|
|
1735
|
+
`# Running ${allFiles.length} test file${allFiles.length === 1 ? "" : "s"} across ${groupCount} group${groupCount === 1 ? "" : "s"}`
|
|
1736
|
+
);
|
|
1698
1737
|
const [browser] = await Promise.all([
|
|
1699
1738
|
launchBrowser(config),
|
|
1700
1739
|
Promise.all(
|
|
@@ -1716,14 +1755,22 @@ async function run(config) {
|
|
|
1716
1755
|
const groupResults = await Promise.allSettled(
|
|
1717
1756
|
groupConfigs.map((groupConfig, i) => {
|
|
1718
1757
|
const groupTimeout = new Promise((_, reject) => {
|
|
1719
|
-
const t = setTimeout(
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1758
|
+
const t = setTimeout(() => {
|
|
1759
|
+
const files = Object.keys(groupConfig.fsTree).map(
|
|
1760
|
+
(f) => f.replace(`${groupConfig.projectRoot}/`, "")
|
|
1761
|
+
);
|
|
1762
|
+
reject(
|
|
1763
|
+
new Error(
|
|
1764
|
+
`Group ${i} timed out after ${GROUP_TIMEOUT_MS / 1e3}s in phase '${groupConfig._phase ?? "unknown"}'
|
|
1765
|
+
Files: ${files.join(", ")}`
|
|
1766
|
+
)
|
|
1767
|
+
);
|
|
1768
|
+
}, GROUP_TIMEOUT_MS);
|
|
1723
1769
|
t.unref();
|
|
1724
1770
|
});
|
|
1725
1771
|
return Promise.race([
|
|
1726
1772
|
(async () => {
|
|
1773
|
+
groupConfig._phase = "connecting";
|
|
1727
1774
|
const connections = await setupBrowser(groupConfig, groupCachedContents[i], browser);
|
|
1728
1775
|
groupConfig.expressApp = connections.server;
|
|
1729
1776
|
if (config.before) {
|
|
@@ -1881,7 +1928,7 @@ init_color();
|
|
|
1881
1928
|
var package_default = {
|
|
1882
1929
|
name: "qunitx-cli",
|
|
1883
1930
|
type: "module",
|
|
1884
|
-
version: "0.
|
|
1931
|
+
version: "0.15.0",
|
|
1885
1932
|
description: "Browser runner for QUnitx: run your qunitx tests in google-chrome",
|
|
1886
1933
|
author: "Izel Nakri",
|
|
1887
1934
|
license: "MIT",
|
|
@@ -1911,8 +1958,10 @@ var package_default = {
|
|
|
1911
1958
|
"changelog:preview": "git-cliff",
|
|
1912
1959
|
"changelog:update": "git-cliff --output CHANGELOG.md",
|
|
1913
1960
|
postinstall: "PLAYWRIGHT_SKIP_DOWNLOAD=true deno install --allow-scripts=npm:playwright-core || true",
|
|
1914
|
-
test:
|
|
1915
|
-
"test:
|
|
1961
|
+
test: "node --experimental-strip-types test/setup.ts && FORCE_COLOR=0 node --experimental-strip-types --test test/**/*-test.ts",
|
|
1962
|
+
"test:debug": "node --experimental-strip-types test/setup.ts && QUNITX_DEBUG=1 node --experimental-strip-types --test test/**/*-test.ts",
|
|
1963
|
+
dev: "node --experimental-strip-types test/setup.ts && node --experimental-strip-types --test --watch test/**/*-test.ts",
|
|
1964
|
+
"test:browser": "node --experimental-strip-types test/setup.ts && FORCE_COLOR=0 node --experimental-strip-types --test test/flags/*-test.ts test/inputs/*-test.ts",
|
|
1916
1965
|
"test:release": "bash scripts/test-release.sh",
|
|
1917
1966
|
"test:sanity-first": "./cli.ts test/helpers/failing-tests.js test/helpers/failing-tests.ts",
|
|
1918
1967
|
"test:sanity-second": "./cli.ts test/helpers/passing-tests.js test/helpers/passing-tests.ts"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qunitx-cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.15.0",
|
|
5
5
|
"description": "Browser runner for QUnitx: run your qunitx tests in google-chrome",
|
|
6
6
|
"author": "Izel Nakri",
|
|
7
7
|
"license": "MIT",
|
|
@@ -31,8 +31,10 @@
|
|
|
31
31
|
"changelog:preview": "git-cliff",
|
|
32
32
|
"changelog:update": "git-cliff --output CHANGELOG.md",
|
|
33
33
|
"postinstall": "PLAYWRIGHT_SKIP_DOWNLOAD=true deno install --allow-scripts=npm:playwright-core || true",
|
|
34
|
-
"test": "node --experimental-strip-types test/setup.ts && FORCE_COLOR=0 node --experimental-strip-types --test
|
|
35
|
-
"test:
|
|
34
|
+
"test": "node --experimental-strip-types test/setup.ts && FORCE_COLOR=0 node --experimental-strip-types --test test/**/*-test.ts",
|
|
35
|
+
"test:debug": "node --experimental-strip-types test/setup.ts && QUNITX_DEBUG=1 node --experimental-strip-types --test test/**/*-test.ts",
|
|
36
|
+
"dev": "node --experimental-strip-types test/setup.ts && node --experimental-strip-types --test --watch test/**/*-test.ts",
|
|
37
|
+
"test:browser": "node --experimental-strip-types test/setup.ts && FORCE_COLOR=0 node --experimental-strip-types --test test/flags/*-test.ts test/inputs/*-test.ts",
|
|
36
38
|
"test:release": "bash scripts/test-release.sh",
|
|
37
39
|
"test:sanity-first": "./cli.ts test/helpers/failing-tests.js test/helpers/failing-tests.ts",
|
|
38
40
|
"test:sanity-second": "./cli.ts test/helpers/passing-tests.js test/helpers/passing-tests.ts"
|