@reportforge/playwright-pdf 0.10.0 → 0.10.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/README.md CHANGED
@@ -211,7 +211,9 @@ Full reference: [reportforge.org/docs/configuration](https://reportforge.org/doc
211
211
 
212
212
  ### Live Runs
213
213
 
214
- Watch a run as it happens. With `live` enabled, the reporter prints an unguessable watch link — boxed under a `Live Tracker` heading — to your CI logs at run start and streams per-test progress to a hosted dashboard while tests execute. All shards of one CI run converge on a single live view, each running test shows the step it's currently executing, and the PDF is still generated at the end, unchanged.
214
+ Watch a run as it happens. With `live` enabled, the reporter prints an unguessable watch link — boxed under a `Live Tracker` heading — to your CI logs at run start and streams per-test progress to a hosted dashboard while tests execute. All shards of one CI run converge on a single live view, each test shows its own steps and assertions as sub-lines beneath its row (Playwright's hooks, fixtures, and teardown are filtered out), and the PDF is still generated at the end, unchanged.
215
+
216
+ > The watch link is entitlement-gated. If you enable `live` but see no `Live Tracker` line, the reporter logs why (missing `RF_LICENSE_KEY`, or a cached token without the `live` entitlement — delete `~/.reportforge/license.json` to force re-activation).
215
217
 
216
218
  ```typescript
217
219
  // playwright.config.ts
package/dist/index.js CHANGED
@@ -13753,7 +13753,7 @@ var LiveStreamer = class {
13753
13753
  this.enabled = false;
13754
13754
  this.testBuffer = [];
13755
13755
  this.eventBuffer = [];
13756
- this.warn("Live streaming disabled \u2014 no active license or live entitlement.");
13756
+ logger.debug("Live streaming disabled \u2014 no active license or live entitlement.");
13757
13757
  return false;
13758
13758
  }
13759
13759
  this.jwt = info.jwt;
@@ -13816,8 +13816,8 @@ function deriveRunId(opts) {
13816
13816
  if (fromEnv) return fromEnv;
13817
13817
  return detectCiRunId() ?? (0, import_crypto9.randomUUID)();
13818
13818
  }
13819
- function computeWatchToken(runId) {
13820
- const secret = process.env.RF_LICENSE_KEY?.trim();
13819
+ function computeWatchToken(runId, key) {
13820
+ const secret = key?.trim() || process.env.RF_LICENSE_KEY?.trim();
13821
13821
  if (!secret) return null;
13822
13822
  return (0, import_crypto8.createHmac)("sha256", secret).update(`live:${runId}`).digest("hex").slice(0, WATCH_TOKEN_HEX_LEN);
13823
13823
  }
@@ -13853,17 +13853,26 @@ function mapTestBegin(test, shardKey) {
13853
13853
  function mapTestEnd(test, result, shardKey) {
13854
13854
  return {
13855
13855
  id: test.id,
13856
+ title: clampWithEllipsis(test.title ?? "", MAX_TITLE_CHARS2),
13856
13857
  status: result.status,
13857
13858
  durationMs: result.duration,
13858
13859
  retry: result.retry,
13859
13860
  shardKey
13860
13861
  };
13861
13862
  }
13863
+ function isLifecycleStep(step) {
13864
+ if (step.category === "hook" || step.category === "fixture") return true;
13865
+ for (let p = step.parent; p; p = p.parent) {
13866
+ if (p.category === "hook" || p.category === "fixture") return true;
13867
+ }
13868
+ return false;
13869
+ }
13862
13870
  function shouldEmitStep(step, mode) {
13863
13871
  if (mode === "none") return false;
13864
13872
  if (!step.title) return false;
13873
+ if (step.error && step.category !== "hook" && step.category !== "fixture") return true;
13874
+ if (isLifecycleStep(step)) return false;
13865
13875
  if (mode === "all") return true;
13866
- if (step.error) return true;
13867
13876
  return step.category === "test.step" || step.category === "expect";
13868
13877
  }
13869
13878
  function isCurrentStep(step) {
@@ -13911,7 +13920,7 @@ var PdfReporter = class {
13911
13920
  this.liveConsole = false;
13912
13921
  this.options = parseOptions(rawOptions);
13913
13922
  this.dataCollector = new DataCollector(this.options.capture);
13914
- const version = true ? "0.10.0" : "0.x";
13923
+ const version = true ? "0.10.2" : "0.x";
13915
13924
  logger.info(`@reportforge/playwright-pdf v${version} initialised`);
13916
13925
  this.licenseClient = new LicenseClient({
13917
13926
  licenseKey: this.options.licenseKey,
@@ -14125,11 +14134,17 @@ var PdfReporter = class {
14125
14134
  this.liveSteps = live.steps;
14126
14135
  this.liveConsole = live.console;
14127
14136
  void this.license();
14128
- const token = computeWatchToken(runId);
14137
+ const token = computeWatchToken(runId, this.options.licenseKey);
14129
14138
  const watchUrl = token ? buildWatchUrl(serverUrl, runId, token) : void 0;
14130
14139
  const env = detectCiEnv();
14131
- if (watchUrl) void this.announceLive(watchUrl, env, shard).catch(() => {
14132
- });
14140
+ if (watchUrl) {
14141
+ void this.announceLive(watchUrl, env, shard).catch(() => {
14142
+ });
14143
+ } else {
14144
+ logger.warn(
14145
+ "Live is enabled but no RF_LICENSE_KEY was found \u2014 cannot mint a watch link or stream. Set RF_LICENSE_KEY (or the `licenseKey` option)."
14146
+ );
14147
+ }
14133
14148
  this.liveStreamer = new LiveStreamer({
14134
14149
  serverUrl,
14135
14150
  runId,
@@ -14150,7 +14165,22 @@ var PdfReporter = class {
14150
14165
  */
14151
14166
  async announceLive(watchUrl, env, shard) {
14152
14167
  const info = await this.license();
14153
- if (!info?.jwt || !info.features?.includes("live")) return;
14168
+ if (!info) {
14169
+ logger.warn("Live is enabled but no active license resolved \u2014 no watch link or streaming.");
14170
+ return;
14171
+ }
14172
+ if (!info.jwt) {
14173
+ logger.warn(
14174
+ "Live is enabled but the license has no signed token (offline with no cached token?) \u2014 no streaming."
14175
+ );
14176
+ return;
14177
+ }
14178
+ if (!info.features?.includes("live")) {
14179
+ logger.warn(
14180
+ "Live is enabled but your license token does not include the 'live' entitlement \u2014 no watch link or streaming. This usually means a cached token predates live streaming and could not be refreshed. Ensure network access on the next run, or delete ~/.reportforge/license.json to force re-activation. If it persists on an active subscription, contact support."
14181
+ );
14182
+ return;
14183
+ }
14154
14184
  logger.info(`Live Tracker: ${watchUrl}`);
14155
14185
  console.log(formatLiveBanner(watchUrl));
14156
14186
  const isPrimaryShard = !shard || shard.current === 1;
package/dist/index.mjs CHANGED
@@ -13754,7 +13754,7 @@ var LiveStreamer = class {
13754
13754
  this.enabled = false;
13755
13755
  this.testBuffer = [];
13756
13756
  this.eventBuffer = [];
13757
- this.warn("Live streaming disabled \u2014 no active license or live entitlement.");
13757
+ logger.debug("Live streaming disabled \u2014 no active license or live entitlement.");
13758
13758
  return false;
13759
13759
  }
13760
13760
  this.jwt = info.jwt;
@@ -13817,8 +13817,8 @@ function deriveRunId(opts) {
13817
13817
  if (fromEnv) return fromEnv;
13818
13818
  return detectCiRunId() ?? randomUUID2();
13819
13819
  }
13820
- function computeWatchToken(runId) {
13821
- const secret = process.env.RF_LICENSE_KEY?.trim();
13820
+ function computeWatchToken(runId, key) {
13821
+ const secret = key?.trim() || process.env.RF_LICENSE_KEY?.trim();
13822
13822
  if (!secret) return null;
13823
13823
  return createHmac3("sha256", secret).update(`live:${runId}`).digest("hex").slice(0, WATCH_TOKEN_HEX_LEN);
13824
13824
  }
@@ -13854,17 +13854,26 @@ function mapTestBegin(test, shardKey) {
13854
13854
  function mapTestEnd(test, result, shardKey) {
13855
13855
  return {
13856
13856
  id: test.id,
13857
+ title: clampWithEllipsis(test.title ?? "", MAX_TITLE_CHARS2),
13857
13858
  status: result.status,
13858
13859
  durationMs: result.duration,
13859
13860
  retry: result.retry,
13860
13861
  shardKey
13861
13862
  };
13862
13863
  }
13864
+ function isLifecycleStep(step) {
13865
+ if (step.category === "hook" || step.category === "fixture") return true;
13866
+ for (let p = step.parent; p; p = p.parent) {
13867
+ if (p.category === "hook" || p.category === "fixture") return true;
13868
+ }
13869
+ return false;
13870
+ }
13863
13871
  function shouldEmitStep(step, mode) {
13864
13872
  if (mode === "none") return false;
13865
13873
  if (!step.title) return false;
13874
+ if (step.error && step.category !== "hook" && step.category !== "fixture") return true;
13875
+ if (isLifecycleStep(step)) return false;
13866
13876
  if (mode === "all") return true;
13867
- if (step.error) return true;
13868
13877
  return step.category === "test.step" || step.category === "expect";
13869
13878
  }
13870
13879
  function isCurrentStep(step) {
@@ -13912,7 +13921,7 @@ var PdfReporter = class {
13912
13921
  this.liveConsole = false;
13913
13922
  this.options = parseOptions(rawOptions);
13914
13923
  this.dataCollector = new DataCollector(this.options.capture);
13915
- const version = true ? "0.10.0" : "0.x";
13924
+ const version = true ? "0.10.2" : "0.x";
13916
13925
  logger.info(`@reportforge/playwright-pdf v${version} initialised`);
13917
13926
  this.licenseClient = new LicenseClient({
13918
13927
  licenseKey: this.options.licenseKey,
@@ -14126,11 +14135,17 @@ var PdfReporter = class {
14126
14135
  this.liveSteps = live.steps;
14127
14136
  this.liveConsole = live.console;
14128
14137
  void this.license();
14129
- const token = computeWatchToken(runId);
14138
+ const token = computeWatchToken(runId, this.options.licenseKey);
14130
14139
  const watchUrl = token ? buildWatchUrl(serverUrl, runId, token) : void 0;
14131
14140
  const env = detectCiEnv();
14132
- if (watchUrl) void this.announceLive(watchUrl, env, shard).catch(() => {
14133
- });
14141
+ if (watchUrl) {
14142
+ void this.announceLive(watchUrl, env, shard).catch(() => {
14143
+ });
14144
+ } else {
14145
+ logger.warn(
14146
+ "Live is enabled but no RF_LICENSE_KEY was found \u2014 cannot mint a watch link or stream. Set RF_LICENSE_KEY (or the `licenseKey` option)."
14147
+ );
14148
+ }
14134
14149
  this.liveStreamer = new LiveStreamer({
14135
14150
  serverUrl,
14136
14151
  runId,
@@ -14151,7 +14166,22 @@ var PdfReporter = class {
14151
14166
  */
14152
14167
  async announceLive(watchUrl, env, shard) {
14153
14168
  const info = await this.license();
14154
- if (!info?.jwt || !info.features?.includes("live")) return;
14169
+ if (!info) {
14170
+ logger.warn("Live is enabled but no active license resolved \u2014 no watch link or streaming.");
14171
+ return;
14172
+ }
14173
+ if (!info.jwt) {
14174
+ logger.warn(
14175
+ "Live is enabled but the license has no signed token (offline with no cached token?) \u2014 no streaming."
14176
+ );
14177
+ return;
14178
+ }
14179
+ if (!info.features?.includes("live")) {
14180
+ logger.warn(
14181
+ "Live is enabled but your license token does not include the 'live' entitlement \u2014 no watch link or streaming. This usually means a cached token predates live streaming and could not be refreshed. Ensure network access on the next run, or delete ~/.reportforge/license.json to force re-activation. If it persists on an active subscription, contact support."
14182
+ );
14183
+ return;
14184
+ }
14155
14185
  logger.info(`Live Tracker: ${watchUrl}`);
14156
14186
  console.log(formatLiveBanner(watchUrl));
14157
14187
  const isPrimaryShard = !shard || shard.current === 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reportforge/playwright-pdf",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "Enterprise-ready PDF reports for Playwright Test — minimal, detailed, and executive templates with CI/CD integrations",
5
5
  "license": "MIT",
6
6
  "author": "ReportForge",