@reportforge/playwright-pdf 0.20.1 → 0.20.2

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/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
+ ## [0.20.2] - 2026-07-12
7
+
8
+ ### Fixed
9
+
10
+ - **A run that executed zero tests (e.g. a `--grep` that matched nothing) no longer renders "APPROVED TO SHIP".** The release gate now shows a neutral "NO TESTS RAN" card explaining that there is nothing to assess, and the reporter prints a warning pointing at test filters. Previously an empty run produced an approval verdict over "0 of 0 tests passed · 0%".
11
+ - Sub-second durations are rounded — a near-empty run prints `36ms`, not `36.343000000000075ms`.
12
+
13
+ ---
14
+
6
15
  ## [0.20.1] - 2026-07-12
7
16
 
8
17
  ### Fixed
package/dist/cli/index.js CHANGED
@@ -6369,7 +6369,8 @@ var init_defaults = __esm({
6369
6369
 
6370
6370
  // src/utils/duration.ts
6371
6371
  function formatDuration(ms) {
6372
- if (ms < 1e3) return `${ms}ms`;
6372
+ const rounded = Math.round(ms);
6373
+ if (rounded < 1e3) return `${rounded}ms`;
6373
6374
  const totalSeconds = ms / 1e3;
6374
6375
  if (totalSeconds < 60) return `${totalSeconds.toFixed(2)}s`;
6375
6376
  const minutes = Math.floor(totalSeconds / 60);
package/dist/index.js CHANGED
@@ -12611,7 +12611,8 @@ var import_path3 = __toESM(require("path"));
12611
12611
  // src/utils/duration.ts
12612
12612
  init_cjs_shims();
12613
12613
  function formatDuration(ms) {
12614
- if (ms < 1e3) return `${ms}ms`;
12614
+ const rounded = Math.round(ms);
12615
+ if (rounded < 1e3) return `${rounded}ms`;
12615
12616
  const totalSeconds = ms / 1e3;
12616
12617
  if (totalSeconds < 60) return `${totalSeconds.toFixed(2)}s`;
12617
12618
  const minutes = Math.floor(totalSeconds / 60);
@@ -14355,7 +14356,7 @@ var PdfReporter = class {
14355
14356
  this.options = parseOptions(rawOptions);
14356
14357
  setLogLevel(this.options.logLevel);
14357
14358
  this.dataCollector = new DataCollector(this.options.capture);
14358
- this.version = true ? "0.20.1" : "0.x";
14359
+ this.version = true ? "0.20.2" : "0.x";
14359
14360
  logger.info(`@reportforge/playwright-pdf v${this.version} initialised`);
14360
14361
  this.licenseClient = new LicenseClient({
14361
14362
  licenseKey: this.options.licenseKey,
@@ -14433,6 +14434,9 @@ var PdfReporter = class {
14433
14434
  maybePrintUpdateNotice(licenseInfo, this.version);
14434
14435
  return;
14435
14436
  }
14437
+ if (collected.stats.total === 0) {
14438
+ logger.warn("No tests were executed \u2014 check your --grep / project filters. The report has nothing to assess.");
14439
+ }
14436
14440
  if (this.options.showTrend && collected.stats.total > 0) {
14437
14441
  try {
14438
14442
  this._appendTrend(collected);
package/dist/index.mjs CHANGED
@@ -12612,7 +12612,8 @@ import path9 from "path";
12612
12612
  // src/utils/duration.ts
12613
12613
  init_esm_shims();
12614
12614
  function formatDuration(ms) {
12615
- if (ms < 1e3) return `${ms}ms`;
12615
+ const rounded = Math.round(ms);
12616
+ if (rounded < 1e3) return `${rounded}ms`;
12616
12617
  const totalSeconds = ms / 1e3;
12617
12618
  if (totalSeconds < 60) return `${totalSeconds.toFixed(2)}s`;
12618
12619
  const minutes = Math.floor(totalSeconds / 60);
@@ -14356,7 +14357,7 @@ var PdfReporter = class {
14356
14357
  this.options = parseOptions(rawOptions);
14357
14358
  setLogLevel(this.options.logLevel);
14358
14359
  this.dataCollector = new DataCollector(this.options.capture);
14359
- this.version = true ? "0.20.1" : "0.x";
14360
+ this.version = true ? "0.20.2" : "0.x";
14360
14361
  logger.info(`@reportforge/playwright-pdf v${this.version} initialised`);
14361
14362
  this.licenseClient = new LicenseClient({
14362
14363
  licenseKey: this.options.licenseKey,
@@ -14434,6 +14435,9 @@ var PdfReporter = class {
14434
14435
  maybePrintUpdateNotice(licenseInfo, this.version);
14435
14436
  return;
14436
14437
  }
14438
+ if (collected.stats.total === 0) {
14439
+ logger.warn("No tests were executed \u2014 check your --grep / project filters. The report has nothing to assess.");
14440
+ }
14437
14441
  if (this.options.showTrend && collected.stats.total > 0) {
14438
14442
  try {
14439
14443
  this._appendTrend(collected);
@@ -1,3 +1,23 @@
1
+ {{#unless (gt stats.total 0)}}
2
+ {{!-- Zero tests executed (e.g. a --grep that matched nothing): there is nothing
3
+ to assess, so the gate must be NEUTRAL — never "APPROVED TO SHIP" over an
4
+ empty run. --}}
5
+ <div class="release-gate release-gate--neutral">
6
+ <div class="release-gate__icon">&#x25CB;</div>
7
+ <div class="release-gate__body">
8
+ <div class="release-gate__label">Release Recommendation</div>
9
+ <div class="release-gate__verdict release-gate__verdict--neutral">NO TESTS RAN</div>
10
+ <div class="release-gate__detail">
11
+ 0 tests were executed &mdash; nothing to assess. Check your test filters
12
+ (e.g. --grep), project selection, or test discovery before relying on this report.
13
+ </div>
14
+ </div>
15
+ <div class="release-gate__meta">
16
+ {{#unless (isUnknown environment.branch)}}<span>{{environment.branch}}</span>{{/unless}}
17
+ {{#unless (isUnknown environment.commit)}}<span>{{environment.commit}}</span>{{/unless}}
18
+ </div>
19
+ </div>
20
+ {{else}}
1
21
  {{#if (gt stats.failed 0)}}
2
22
  <div class="release-gate release-gate--fail">
3
23
  <div class="release-gate__icon">&#x2715;</div>
@@ -61,3 +81,4 @@
61
81
  </div>
62
82
  {{/if}}
63
83
  {{/if}}
84
+ {{/unless}}
@@ -289,12 +289,17 @@ code {
289
289
  .release-gate--fail {
290
290
  background: var(--fail-dim); border-color: #E5C9BD;
291
291
  }
292
+ /* Zero tests executed — neutral, neither approval nor hold. */
293
+ .release-gate--neutral {
294
+ background: #F5F4F2; border-color: #D8D5D0;
295
+ }
292
296
  .release-gate__icon {
293
297
  font-size: 22px; font-weight: 700; flex-shrink: 0; width: 32px;
294
298
  text-align: center; line-height: 1;
295
299
  }
296
300
  .release-gate--pass .release-gate__icon { color: var(--pass); }
297
301
  .release-gate--fail .release-gate__icon { color: var(--fail); }
302
+ .release-gate--neutral .release-gate__icon { color: var(--text-3); }
298
303
  .release-gate__body { flex: 1; }
299
304
  .release-gate__label {
300
305
  font-family: 'Inter', system-ui, sans-serif; font-size: 8px;
@@ -307,6 +312,7 @@ code {
307
312
  }
308
313
  .release-gate__verdict--pass { color: var(--pass); }
309
314
  .release-gate__verdict--fail { color: var(--fail); }
315
+ .release-gate__verdict--neutral { color: var(--text-2); }
310
316
  .release-gate__detail {
311
317
  font-family: 'Inter', system-ui, sans-serif; font-size: 10px;
312
318
  color: var(--text-2); margin-top: 4px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reportforge/playwright-pdf",
3
- "version": "0.20.1",
3
+ "version": "0.20.2",
4
4
  "description": "Playwright Test reporter that generates designed PDF reports: minimal, detailed, and executive templates with CI/CD integrations",
5
5
  "license": "Elastic-2.0",
6
6
  "author": "ReportForge",