headlamp 0.1.8 → 0.1.9

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
@@ -52,6 +52,23 @@ npx headlamp --coverage
52
52
  npx headlamp --coverage src/services/user.ts src/components/UserCard.tsx
53
53
  ```
54
54
 
55
+ ## Output flags
56
+
57
+ - `--onlyFailures[=true|false]`:
58
+ - When enabled, the CLI prints only failing tests during execution across all views, while still printing the final test summary (files/tests/time) at the end.
59
+ - Supported forms: `--onlyFailures`, `--onlyFailures=true`, `--onlyFailures=false`.
60
+ - Works with other selection flags (e.g., `-t`, `--changed`).
61
+
62
+ Examples:
63
+
64
+ ```bash
65
+ # Show only failures during the run, but still print the final summary
66
+ npx headlamp --onlyFailures
67
+
68
+ # Combine with changed-file selection
69
+ npx headlamp --changed --onlyFailures
70
+ ```
71
+
55
72
  ## Coverage flags
56
73
 
57
74
  - `--coverage`: enables coverage collection and prints merged coverage output after test execution. Uses your project's Jest/Vitest setup and reads coverage JSON from Jest.
package/dist/cli.cjs CHANGED
@@ -248,6 +248,7 @@ var init_args = __esm({
248
248
  coverage: (coverageValue) => ({ type: "coverage", coverageValue }),
249
249
  coverageUi: (value) => ({ type: "coverageUi", value }),
250
250
  coverageAbortOnFailure: (value) => ({ type: "coverageAbortOnFailure", value }),
251
+ onlyFailures: (value) => ({ type: "onlyFailures", value }),
251
252
  jestArg: (value) => ({ type: "jestArg", value }),
252
253
  jestArgs: (values) => ({ type: "jestArgs", values }),
253
254
  vitestArg: (value) => ({ type: "vitestArg", value }),
@@ -401,6 +402,18 @@ var init_args = __esm({
401
402
  "--coverage.pageFit",
402
403
  (_flag, lookahead) => step([ActionBuilders.coveragePageFit(isTruthy(String(lookahead)))], true)
403
404
  ),
405
+ // --onlyFailures flag (boolean)
406
+ rule.eq("--onlyFailures", () => step([ActionBuilders.onlyFailures(true)])),
407
+ rule.startsWith(
408
+ "--onlyFailures=",
409
+ (value) => step([
410
+ ActionBuilders.onlyFailures(isTruthy((value.split("=")[1] ?? "").trim().toLowerCase()))
411
+ ])
412
+ ),
413
+ rule.withLookahead(
414
+ "--onlyFailures",
415
+ (_flag, lookahead) => step([ActionBuilders.onlyFailures(isTruthy(String(lookahead)))], true)
416
+ ),
404
417
  rule.withLookahead(
405
418
  "--testPathPattern",
406
419
  (flag, lookahead) => step([ActionBuilders.jestArgs([flag, lookahead])], true)
@@ -547,6 +560,8 @@ var init_args = __esm({
547
560
  return { vitest: [], jest: [], coverage: false, coverageUi: action.value };
548
561
  case "coverageAbortOnFailure":
549
562
  return { vitest: [], jest: [], coverage: false, coverageAbortOnFailure: action.value };
563
+ case "onlyFailures":
564
+ return { vitest: [], jest: [], coverage: false, onlyFailures: action.value };
550
565
  case "jestArgs":
551
566
  return { vitest: [], jest: action.values, coverage: false };
552
567
  case "selectionHint":
@@ -618,6 +633,7 @@ var init_args = __esm({
618
633
  ...next,
619
634
  ...right.changed !== void 0 || left.changed !== void 0 ? { changed: right.changed ?? left.changed } : {},
620
635
  ...right.coverageAbortOnFailure !== void 0 || left.coverageAbortOnFailure !== void 0 ? { coverageAbortOnFailure: right.coverageAbortOnFailure ?? left.coverageAbortOnFailure } : {},
636
+ ...right.onlyFailures !== void 0 || left.onlyFailures !== void 0 ? { onlyFailures: right.onlyFailures ?? left.onlyFailures } : {},
621
637
  ...right.coverageDetail !== void 0 || left.coverageDetail !== void 0 ? { coverageDetail: right.coverageDetail ?? left.coverageDetail } : {},
622
638
  ...right.coverageShowCode !== void 0 || left.coverageShowCode !== void 0 ? { coverageShowCode: right.coverageShowCode ?? left.coverageShowCode } : {},
623
639
  ...right.coverageMode !== void 0 || left.coverageMode !== void 0 ? { coverageMode: right.coverageMode ?? left.coverageMode } : {},
@@ -641,6 +657,7 @@ var init_args = __esm({
641
657
  let collectCoverage = false;
642
658
  let coverageUi = "both";
643
659
  let coverageAbortOnFailure = false;
660
+ let onlyFailures = false;
644
661
  let coverageShowCode = Boolean(process.stdout.isTTY);
645
662
  let coverageMode = "auto";
646
663
  const coverageMaxFilesLocalInit = void 0;
@@ -658,6 +675,7 @@ var init_args = __esm({
658
675
  collectCoverage ||= contrib.coverage;
659
676
  coverageUi = contrib.coverageUi ?? coverageUi;
660
677
  coverageAbortOnFailure = contrib.coverageAbortOnFailure ?? coverageAbortOnFailure;
678
+ onlyFailures = contrib.onlyFailures ?? onlyFailures;
661
679
  coverageShowCode = contrib.coverageShowCode ?? coverageShowCode;
662
680
  const coverageDetailComputed = contrib.coverageDetail ?? (contrib.selection ? "auto" : void 0);
663
681
  coverageMode = contrib.coverageMode ?? (contrib.selection ? "compact" : "auto");
@@ -691,6 +709,7 @@ var init_args = __esm({
691
709
  collectCoverage,
692
710
  coverageUi,
693
711
  coverageAbortOnFailure,
712
+ onlyFailures,
694
713
  selectionSpecified: Boolean(contrib.selection),
695
714
  selectionPaths: [...contrib.selectionPaths ?? []],
696
715
  includeGlobs,
@@ -4694,6 +4713,7 @@ var formatJestOutputVitest = (raw, opts) => {
4694
4713
  const projectHint = new RegExp(
4695
4714
  `(${cwd.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&")})|(/gigworx-node/)`
4696
4715
  );
4716
+ const onlyFailures = Boolean(opts?.onlyFailures);
4697
4717
  const lines = raw.split(/\r?\n/);
4698
4718
  const out = [];
4699
4719
  const seenFailures = /* @__PURE__ */ new Set();
@@ -4781,8 +4801,10 @@ var formatJestOutputVitest = (raw, opts) => {
4781
4801
  continue;
4782
4802
  }
4783
4803
  seenFiles.add(rel);
4784
- const pill = badge === "PASS" ? colorTokens.passPill("PASS") : colorTokens.failPill("FAIL");
4785
- out.push(`${pill} ${ansi.white(rel)}`);
4804
+ if (!(onlyFailures && badge === "PASS")) {
4805
+ const pill = badge === "PASS" ? colorTokens.passPill("PASS") : colorTokens.failPill("FAIL");
4806
+ out.push(`${pill} ${ansi.white(rel)}`);
4807
+ }
4786
4808
  lineIndex += 1;
4787
4809
  continue;
4788
4810
  }
@@ -4895,14 +4917,21 @@ function renderVitestFromJestJSON(data, opts) {
4895
4917
  `(${cwd.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&")})|(/gigworx-node/)`
4896
4918
  );
4897
4919
  const ctx = { projectHint, editorCmd: opts?.editorCmd, showStacks: true };
4920
+ const onlyFailures = Boolean(opts?.onlyFailures);
4898
4921
  const out = [];
4899
- out.push(renderRunLine(cwd));
4900
- out.push("");
4922
+ if (!onlyFailures) {
4923
+ out.push(renderRunLine(cwd));
4924
+ out.push("");
4925
+ }
4901
4926
  for (const file of data.testResults) {
4902
4927
  const rel = file.testFilePath.replace(/\\/g, "/").replace(`${cwd}/`, "");
4903
4928
  const failed = file.testResults.filter((assertion) => assertion.status === "failed");
4904
- out.push(...buildPerFileOverview(rel, file.testResults));
4905
- out.push(buildFileBadgeLine(rel, failed.length));
4929
+ if (!onlyFailures) {
4930
+ out.push(...buildPerFileOverview(rel, file.testResults));
4931
+ }
4932
+ if (!(onlyFailures && failed.length === 0)) {
4933
+ out.push(buildFileBadgeLine(rel, failed.length));
4934
+ }
4906
4935
  if (file.failureMessage && failed.length === 0) {
4907
4936
  const lines = file.failureMessage.split(/\r?\n/);
4908
4937
  const details = linesFromDetails(file.failureDetails);
@@ -5290,6 +5319,7 @@ var program = async () => {
5290
5319
  collectCoverage,
5291
5320
  coverageUi,
5292
5321
  coverageAbortOnFailure,
5322
+ onlyFailures,
5293
5323
  selectionSpecified,
5294
5324
  selectionPaths,
5295
5325
  includeGlobs,
@@ -5906,12 +5936,14 @@ var program = async () => {
5906
5936
  };
5907
5937
  pretty = renderVitestFromJestJSON(reordered, {
5908
5938
  cwd: repoRootForDiscovery,
5909
- ...editorCmd !== void 0 ? { editorCmd } : {}
5939
+ ...editorCmd !== void 0 ? { editorCmd } : {},
5940
+ onlyFailures
5910
5941
  });
5911
5942
  } catch {
5912
5943
  pretty = renderVitestFromJestJSON(bridge, {
5913
5944
  cwd: repoRootForDiscovery,
5914
- ...editorCmd !== void 0 ? { editorCmd } : {}
5945
+ ...editorCmd !== void 0 ? { editorCmd } : {},
5946
+ onlyFailures
5915
5947
  });
5916
5948
  }
5917
5949
  if (debug) {
@@ -5928,7 +5960,8 @@ ${preview}${pretty.includes("\n") ? "\n\u2026" : ""}`);
5928
5960
  }
5929
5961
  const renderOpts = {
5930
5962
  cwd: repoRootForDiscovery,
5931
- ...editorCmd !== void 0 ? { editorCmd } : {}
5963
+ ...editorCmd !== void 0 ? { editorCmd } : {},
5964
+ onlyFailures
5932
5965
  };
5933
5966
  pretty = formatJestOutputVitest(output, renderOpts);
5934
5967
  if (debug) {
@@ -5994,7 +6027,8 @@ ${preview}${pretty.includes("\n") ? "\n\u2026" : ""}`);
5994
6027
  }
5995
6028
  const text = renderVitestFromJestJSON(unified, {
5996
6029
  cwd: repoRootForDiscovery,
5997
- ...editorCmd !== void 0 ? { editorCmd } : {}
6030
+ ...editorCmd !== void 0 ? { editorCmd } : {},
6031
+ onlyFailures
5998
6032
  });
5999
6033
  if (text.trim().length > 0) {
6000
6034
  process.stdout.write(text.endsWith("\n") ? text : `${text}