@alejandrojca/elmulo-reporter 2.0.0-beta.6 → 2.0.0-beta.8

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/VERSION.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Elmulo Reporter",
3
- "version": "2.0.0-beta.6",
3
+ "version": "2.0.0-beta.8",
4
4
  "schemaVersion": 3,
5
5
  "source": "elmulo-reporter",
6
6
  "results": "elmulo-results",
package/assets/app.css CHANGED
@@ -27,9 +27,12 @@
27
27
  box-sizing: border-box;
28
28
  }
29
29
 
30
- body {
31
- margin: 0;
32
- }
30
+ html,
31
+ body {
32
+ height: 100%;
33
+ margin: 0;
34
+ overflow: hidden;
35
+ }
33
36
 
34
37
  html[data-theme="dark"],
35
38
  html[data-theme="dark"] * {
@@ -258,10 +261,54 @@ button {
258
261
  .metricCard.passed { --metric-color: var(--pw-success); }
259
262
  .metricCard.failed { --metric-color: var(--pw-danger); }
260
263
  .metricCard.skipped { --metric-color: var(--pw-gray-300); }
261
- .metricCard.flaky { --metric-color: var(--pw-warning); }
262
- .metricCard.otherErrors { --metric-color: #d18a00; }
263
-
264
- .metricCard.activeFilter {
264
+ .metricCard.flaky { --metric-color: var(--pw-warning); }
265
+ .metricCard.otherErrors { --metric-color: #d18a00; }
266
+
267
+ .metricCard.failedBreakdown {
268
+ display: grid;
269
+ gap: 0.9rem;
270
+ grid-column: span 2;
271
+ grid-template-columns: minmax(90px, 0.7fr) minmax(210px, 1.3fr);
272
+ }
273
+
274
+ .failureMetricTotal {
275
+ align-self: center;
276
+ }
277
+
278
+ .failureMetricBreakdown {
279
+ align-content: center;
280
+ display: grid;
281
+ gap: 0.35rem;
282
+ margin: 0;
283
+ }
284
+
285
+ .failureMetricBreakdown > div {
286
+ --breakdown-color: var(--pw-danger);
287
+ align-items: center;
288
+ border: 1px solid color-mix(in srgb, var(--breakdown-color) 62%, var(--pw-gray-200));
289
+ border-radius: 999px;
290
+ display: flex;
291
+ justify-content: space-between;
292
+ padding: 0.25rem 0.55rem;
293
+ }
294
+
295
+ .failureMetricBreakdown .reported { --breakdown-color: var(--pw-blue-600); }
296
+ .failureMetricBreakdown .otherErrors { --breakdown-color: var(--pw-warning); }
297
+
298
+ .failureMetricBreakdown dt,
299
+ .failureMetricBreakdown dd {
300
+ color: var(--pw-gray-700);
301
+ font-size: 0.68rem;
302
+ font-weight: 800;
303
+ margin: 0;
304
+ }
305
+
306
+ .failureMetricBreakdown dd {
307
+ color: var(--breakdown-color);
308
+ font-size: 0.82rem;
309
+ }
310
+
311
+ .metricCard.activeFilter {
265
312
  border-color: var(--metric-color, var(--pw-blue-700));
266
313
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--metric-color, var(--pw-blue-700)) 18%, transparent);
267
314
  }
@@ -363,10 +410,15 @@ button {
363
410
  padding: 0.55rem 0.65rem;
364
411
  }
365
412
 
366
- .statusLegendItem.empty {
367
- opacity: 0.56;
368
- }
369
-
413
+ .statusLegendItem.empty {
414
+ opacity: 0.56;
415
+ }
416
+
417
+ .statusLegendItem:not(.empty) {
418
+ border-color: var(--status-color);
419
+ box-shadow: 0 0 0 1px color-mix(in srgb, var(--status-color) 24%, transparent);
420
+ }
421
+
370
422
  .statusLegendDot {
371
423
  background: var(--status-color);
372
424
  border-radius: 50%;
@@ -2228,18 +2280,35 @@ html[data-theme="dark"] .exportPdfButton {
2228
2280
  grid-template-columns: repeat(5, 1fr);
2229
2281
  }
2230
2282
 
2231
- .attentionCard {
2232
- background: var(--pw-blue-050);
2233
- border: 1px solid var(--pw-gray-200);
2234
- border-left: 4px solid var(--attention-color, var(--pw-blue-700));
2283
+ .attentionCard {
2284
+ background: var(--pw-blue-050);
2285
+ border: 1px solid var(--pw-gray-200);
2286
+ border-left: 4px solid var(--attention-color, var(--pw-blue-700));
2235
2287
  border-radius: 14px;
2236
2288
  color: var(--pw-gray-900);
2237
2289
  display: grid;
2238
- gap: 0.25rem;
2239
- padding: 0.8rem;
2240
- text-align: left;
2241
- }
2242
-
2290
+ gap: 0.25rem;
2291
+ padding: 0.8rem;
2292
+ text-align: left;
2293
+ transition:
2294
+ border-color 160ms ease,
2295
+ box-shadow 160ms ease,
2296
+ transform 160ms ease;
2297
+ }
2298
+
2299
+ .attentionCard:not(:disabled):hover,
2300
+ .attentionCard:not(:disabled):focus-visible {
2301
+ border-color: var(--attention-color, var(--pw-blue-700));
2302
+ box-shadow:
2303
+ 0 0 0 2px color-mix(in srgb, var(--attention-color, var(--pw-blue-700)) 24%, transparent),
2304
+ 0 12px 24px color-mix(in srgb, var(--attention-color, var(--pw-blue-700)) 14%, transparent);
2305
+ transform: translateY(-2px);
2306
+ }
2307
+
2308
+ .attentionCard:not(:disabled):focus-visible {
2309
+ outline: none;
2310
+ }
2311
+
2243
2312
  .attentionCard.failed,
2244
2313
  .attentionCard.no_comment,
2245
2314
  .attentionCard.no_ticket {
@@ -3938,15 +4007,23 @@ pre {
3938
4007
 
3939
4008
  /* Elmulo V2 application navigation */
3940
4009
 
3941
- .appFrame {
3942
- display: grid;
3943
- grid-template-columns: auto minmax(0, 1fr);
3944
- min-height: 100vh;
3945
- }
3946
-
3947
- .workspaceShell {
3948
- min-width: 0;
3949
- }
4010
+ .appFrame {
4011
+ display: grid;
4012
+ grid-template-columns: auto minmax(0, 1fr);
4013
+ height: 100vh;
4014
+ height: 100dvh;
4015
+ min-height: 0;
4016
+ overflow: hidden;
4017
+ }
4018
+
4019
+ .workspaceShell {
4020
+ display: grid;
4021
+ grid-template-rows: auto minmax(0, 1fr);
4022
+ height: 100vh;
4023
+ height: 100dvh;
4024
+ min-width: 0;
4025
+ overflow: hidden;
4026
+ }
3950
4027
 
3951
4028
  .sidebar {
3952
4029
  background:
@@ -4074,23 +4151,40 @@ pre {
4074
4151
  position: relative;
4075
4152
  }
4076
4153
 
4077
- .sidebarIcon {
4078
- align-items: center;
4079
- background: rgb(255 255 255 / 7%);
4080
- border-radius: 9px;
4081
- display: inline-flex;
4082
- font-size: 1rem;
4083
- font-weight: 800;
4084
- height: 34px;
4085
- justify-content: center;
4086
- width: 34px;
4087
- }
4088
-
4089
- .sidebarLink.active .sidebarIcon {
4090
- background: #dff8f8;
4091
- color: #075f76;
4092
- }
4093
-
4154
+ .sidebarIcon {
4155
+ align-items: center;
4156
+ background: rgb(255 255 255 / 7%);
4157
+ border-radius: 9px;
4158
+ display: inline-flex;
4159
+ height: 34px;
4160
+ justify-content: center;
4161
+ width: 34px;
4162
+ }
4163
+
4164
+ .sidebarIconImage {
4165
+ filter: brightness(0) invert(1);
4166
+ height: 21px;
4167
+ object-fit: contain;
4168
+ opacity: 0.82;
4169
+ transition: filter 140ms ease, opacity 140ms ease, transform 140ms ease;
4170
+ width: 21px;
4171
+ }
4172
+
4173
+ .sidebarLink:hover .sidebarIconImage {
4174
+ opacity: 1;
4175
+ transform: scale(1.06);
4176
+ }
4177
+
4178
+ .sidebarLink.active .sidebarIcon {
4179
+ background: #dff8f8;
4180
+ color: #075f76;
4181
+ }
4182
+
4183
+ .sidebarLink.active .sidebarIconImage {
4184
+ filter: brightness(0) saturate(100%) invert(29%) sepia(43%) saturate(1271%) hue-rotate(147deg) brightness(91%) contrast(96%);
4185
+ opacity: 1;
4186
+ }
4187
+
4094
4188
  .sidebarLabel {
4095
4189
  font-size: 0.85rem;
4096
4190
  font-weight: 700;
@@ -4196,11 +4290,16 @@ pre {
4196
4290
  width: 38px;
4197
4291
  }
4198
4292
 
4199
- .appShell {
4200
- margin: 0 auto;
4201
- max-width: 1600px;
4202
- padding: 1.5rem 2rem 4rem;
4203
- }
4293
+ .appShell {
4294
+ height: 100%;
4295
+ margin: 0 auto;
4296
+ max-width: 1600px;
4297
+ min-height: 0;
4298
+ overflow-y: auto;
4299
+ overscroll-behavior-y: contain;
4300
+ padding: 1.5rem 2rem 4rem;
4301
+ width: 100%;
4302
+ }
4204
4303
 
4205
4304
  .workspaceView[hidden] {
4206
4305
  display: none !important;
@@ -4311,11 +4410,12 @@ pre {
4311
4410
  transform: translateY(-1px);
4312
4411
  }
4313
4412
 
4314
- .overviewLaunchGrid button > span {
4315
- color: var(--pw-teal);
4316
- font-size: 1.15rem;
4317
- font-weight: 800;
4318
- }
4413
+ .overviewLaunchIcon {
4414
+ filter: brightness(0) saturate(100%) invert(61%) sepia(78%) saturate(623%) hue-rotate(132deg) brightness(87%) contrast(82%);
4415
+ height: 24px;
4416
+ object-fit: contain;
4417
+ width: 24px;
4418
+ }
4319
4419
 
4320
4420
  .overviewLaunchGrid small {
4321
4421
  color: var(--pw-gray-700);
package/assets/app.js CHANGED
@@ -42,13 +42,13 @@
42
42
  const pdfSections = [
43
43
  ["summary", "Resumen ejecutivo", "Indicadores principales y evaluación general.", true],
44
44
  ["statusDistribution", "Distribución por estado", "Resultados automáticos y clasificaciones manuales.", true],
45
- ["runContext", "Contexto de la corrida", "Ambiente, fecha, navegador, tags, rama y pipeline.", true],
45
+ ["runContext", "Contexto de la corrida", "Ambiente, fecha, navegador, tags, rama y pipeline.", false],
46
46
  ["features", "Resultados por Feature", "Totales y estados agrupados por Feature.", true],
47
47
  ["issues", "Problemas que requieren seguimiento", "Fallos, Jira, comentarios y tickets asociados.", true],
48
- ["previousComparison", "Comparación con la corrida anterior", "Variaciones de resultados y duración.", true],
49
- ["recentHistory", "Historial reciente", "Últimas ejecuciones del mismo ambiente.", true],
50
- ["flaky", "Pruebas inestables", "Casos que pasaron después de uno o más reintentos.", true],
51
- ["recurrentFailures", "Fallos recurrentes", "Pruebas con fallos repetidos en el historial.", true],
48
+ ["previousComparison", "Comparación con la corrida anterior", "Variaciones de resultados y duración.", false],
49
+ ["recentHistory", "Historial reciente", "Últimas ejecuciones del mismo ambiente.", false],
50
+ ["flaky", "Pruebas inestables", "Casos que pasaron después de uno o más reintentos.", false],
51
+ ["recurrentFailures", "Fallos recurrentes", "Pruebas con fallos repetidos en el historial.", false],
52
52
  ["slowTests", "Pruebas más lentas", "Ranking histórico de pruebas por duración.", false],
53
53
  ["recommendation", "Recomendación y pendientes", "Evaluación final, fallos sin comentario y sin ticket.", true],
54
54
  ];
@@ -705,19 +705,32 @@
705
705
  dialog.showModal();
706
706
  }
707
707
 
708
- function metric(label, value, className = "") {
709
- return `<article class="metricCard ${className}">
710
- <span>${escapeHtml(label)}</span>
711
- <strong>${value}</strong>
712
- </article>`;
713
- }
714
-
715
- function summaryMarkup() {
716
- const effectiveStatuses = run.tests.map(effectiveTestStatus);
717
- const statusCount = (status) =>
718
- effectiveStatuses.filter((value) => value === status).length;
719
- const otherErrorsCount = effectiveStatuses.filter((status) =>
720
- otherErrorStatuses.has(status)).length;
708
+ function metric(label, value, className = "") {
709
+ return `<article class="metricCard ${className}">
710
+ <span>${escapeHtml(label)}</span>
711
+ <strong>${value}</strong>
712
+ </article>`;
713
+ }
714
+
715
+ function failureMetric(total, deltaMarkup, breakdown, className = "") {
716
+ return `<article class="metricCard failed failedBreakdown ${className}">
717
+ <div class="failureMetricTotal">
718
+ <span>Fallidas</span>
719
+ <strong>${escapeHtml(total)}${deltaMarkup}</strong>
720
+ </div>
721
+ <dl class="failureMetricBreakdown" aria-label="Desglose de pruebas fallidas">
722
+ ${breakdown.map(([label, value, status]) => `<div class="${escapeHtml(status)}">
723
+ <dt>${escapeHtml(label)}</dt>
724
+ <dd>${escapeHtml(value)}</dd>
725
+ </div>`).join("")}
726
+ </dl>
727
+ </article>`;
728
+ }
729
+
730
+ function summaryMarkup() {
731
+ const effectiveStatuses = run.tests.map(effectiveTestStatus);
732
+ const statusCount = (status) =>
733
+ effectiveStatuses.filter((value) => value === status).length;
721
734
  const activeClass = (status, baseClass = status) =>
722
735
  `${baseClass} ${state.status === status ? "activeFilter" : ""}`.trim();
723
736
  const previousRun = [...(run.trends?.runs || [])]
@@ -728,26 +741,33 @@
728
741
  const difference = Number(current) - Number(previous || 0);
729
742
  if (!difference) return '<small class="metricDelta neutral">Sin cambios</small>';
730
743
  return `<small class="metricDelta ${difference > 0 ? "up" : "down"}">${difference > 0 ? "+" : ""}${difference} vs. anterior</small>`;
731
- };
732
- const passedCount = statusCount("passed");
733
- const failedCount = statusCount("failed");
734
- const previousOtherErrors = previousRun
735
- ? Number(previousRun.environment_error || 0) +
736
- Number(previousRun.precondition_error || 0) +
737
- Number(previousRun.outdated_test || 0) +
738
- Number(previousRun.reported || 0)
739
- : null;
744
+ };
745
+ const passedCount = statusCount("passed");
746
+ const automaticFailures = run.tests.filter((test) => test.status === "failed");
747
+ const failedCount = automaticFailures.length;
748
+ const pendingFailures = automaticFailures.filter((test) =>
749
+ effectiveTestStatus(test) === "failed").length;
750
+ const reportedFailures = automaticFailures.filter((test) =>
751
+ effectiveTestStatus(test) === "reported").length;
752
+ const otherFailures = automaticFailures.filter((test) => {
753
+ const status = effectiveTestStatus(test);
754
+ return otherErrorStatuses.has(status) && status !== "reported";
755
+ }).length;
740
756
 
741
757
  return `
742
758
  ${metric("Casos", groupTestsByCase(run.tests).length)}
743
759
  ${metric("Ejecuciones", run.tests.length)}
744
760
  ${metric("Exitosas", `${passedCount}${delta(passedCount, previousRun?.passed)}`, activeClass("passed"))}
745
- ${metric("Fallidas", `${failedCount}${delta(failedCount, previousRun?.failed)}`, activeClass("failed"))}
746
- ${metric(
747
- "Otros errores",
748
- `${otherErrorsCount}${delta(otherErrorsCount, previousOtherErrors)}`,
749
- activeClass("other_errors", "otherErrors"),
750
- )}
761
+ ${failureMetric(
762
+ failedCount,
763
+ delta(failedCount, previousRun?.failed),
764
+ [
765
+ ["Pendientes", pendingFailures, "pending"],
766
+ ["Reportadas", reportedFailures, "reported"],
767
+ ["Otros errores", otherFailures, "otherErrors"],
768
+ ],
769
+ activeClass("failed"),
770
+ )}
751
771
  ${metric("Inestables", run.tests.filter((test) => test.flaky).length, "flaky")}
752
772
  `;
753
773
  }
@@ -2559,35 +2579,35 @@
2559
2579
  }
2560
2580
 
2561
2581
  const viewMetadata = {
2562
- overview: {
2563
- label: "Resumen",
2564
- description: "Estado de la corrida y señales que requieren atención.",
2565
- icon: "",
2566
- },
2582
+ overview: {
2583
+ label: "Resumen",
2584
+ description: "Estado de la corrida y señales que requieren atención.",
2585
+ icon: "summary.png",
2586
+ },
2567
2587
  executions: {
2568
2588
  label: "Ejecuciones",
2569
2589
  description: "Tendencias, historial y comparación entre corridas.",
2570
- icon: "",
2590
+ icon: "executions.png",
2571
2591
  },
2572
2592
  quality: {
2573
2593
  label: "Calidad",
2574
2594
  description: "Estabilidad, fallos recurrentes y rendimiento histórico.",
2575
- icon: "",
2595
+ icon: "quality.png",
2576
2596
  },
2577
2597
  analysis: {
2578
2598
  label: "Análisis",
2579
2599
  description: "Bandeja de trabajo para investigar y clasificar fallos.",
2580
- icon: "!",
2600
+ icon: "analysis.png",
2581
2601
  },
2582
2602
  tests: {
2583
2603
  label: "Pruebas",
2584
2604
  description: "Explorador de casos, pasos, evidencias e historial por Jira.",
2585
- icon: "",
2605
+ icon: "tests.png",
2586
2606
  },
2587
2607
  preferences: {
2588
2608
  label: "Preferencias",
2589
2609
  description: "Apariencia y configuración local del espacio de trabajo.",
2590
- icon: "",
2610
+ icon: "preferences.png",
2591
2611
  },
2592
2612
  };
2593
2613
 
@@ -2747,7 +2767,9 @@
2747
2767
  aria-current="${state.view === key ? "page" : "false"}"
2748
2768
  title="${escapeHtml(item.label)}"
2749
2769
  >
2750
- <span class="sidebarIcon" aria-hidden="true">${item.icon}</span>
2770
+ <span class="sidebarIcon" aria-hidden="true">
2771
+ <img class="sidebarIconImage" src="assets/menu-icons/${escapeHtml(item.icon)}" alt="">
2772
+ </span>
2751
2773
  <span class="sidebarLabel">${escapeHtml(item.label)}</span>
2752
2774
  ${badges[key] ? `<span class="sidebarBadge">${escapeHtml(badges[key])}</span>` : ""}
2753
2775
  </button>`).join("")}
@@ -2759,20 +2781,22 @@
2759
2781
  </aside>`;
2760
2782
  }
2761
2783
 
2762
- function overviewLaunchpadMarkup() {
2763
- const failed = run.tests.filter((test) => effectiveTestStatus(test) === "failed");
2764
- const withoutComment = failed.filter((test) => !annotationFor(test).comment).length;
2765
- return `<section class="overviewLaunchpad" aria-labelledby="overview-next-title">
2784
+ function overviewLaunchpadMarkup() {
2785
+ const failed = run.tests.filter((test) => effectiveTestStatus(test) === "failed");
2786
+ const withoutComment = failed.filter((test) => !annotationFor(test).comment).length;
2787
+ const launchIcon = (view) =>
2788
+ `<img class="overviewLaunchIcon" src="assets/menu-icons/${escapeHtml(viewMetadata[view].icon)}" alt="">`;
2789
+ return `<section class="overviewLaunchpad" aria-labelledby="overview-next-title">
2766
2790
  <header>
2767
2791
  <div><p class="eyebrow">Explorar</p><h2 id="overview-next-title">Continuá el análisis</h2></div>
2768
2792
  <span>Cada área conserva el ambiente, los filtros y la prueba seleccionada.</span>
2769
- </header>
2770
- <div class="overviewLaunchGrid">
2771
- <button type="button" data-nav-view="executions"><span>▶</span><strong>Ejecuciones</strong><small>${escapeHtml(run.trends?.totalRuns || 0)} corridas disponibles</small></button>
2772
- <button type="button" data-nav-view="quality"><span>◇</span><strong>Calidad histórica</strong><small>Estabilidad, recurrencia y tiempos</small></button>
2773
- <button type="button" data-nav-view="analysis"><span>!</span><strong>Análisis pendiente</strong><small>${withoutComment} fallos sin comentario</small></button>
2774
- <button type="button" data-nav-view="tests"><span>☑</span><strong>Explorar pruebas</strong><small>${run.tests.length} ejecuciones en la corrida</small></button>
2775
- </div>
2793
+ </header>
2794
+ <div class="overviewLaunchGrid">
2795
+ <button type="button" data-nav-view="executions">${launchIcon("executions")}<strong>Ejecuciones</strong><small>${escapeHtml(run.trends?.totalRuns || 0)} corridas disponibles</small></button>
2796
+ <button type="button" data-nav-view="quality">${launchIcon("quality")}<strong>Calidad histórica</strong><small>Estabilidad, recurrencia y tiempos</small></button>
2797
+ <button type="button" data-nav-view="analysis">${launchIcon("analysis")}<strong>Análisis pendiente</strong><small>${withoutComment} fallos sin comentario</small></button>
2798
+ <button type="button" data-nav-view="tests">${launchIcon("tests")}<strong>Explorar pruebas</strong><small>${run.tests.length} ejecuciones en la corrida</small></button>
2799
+ </div>
2776
2800
  </section>`;
2777
2801
  }
2778
2802
 
Binary file
Binary file
Binary file
Binary file
Binary file
package/finalize.cjs CHANGED
@@ -435,7 +435,7 @@ function persistRun(database, run) {
435
435
  system: run.system || {},
436
436
  source: run.source || {},
437
437
  execution: run.execution || null,
438
- reporterVersion: "2.0.0-beta.6",
438
+ reporterVersion: "2.0.0-beta.8",
439
439
  }),
440
440
  ],
441
441
  );
@@ -873,19 +873,27 @@ function buildHtml(run) {
873
873
  `;
874
874
  }
875
875
 
876
- function copyStaticAssets(reportDir) {
877
- // Assets belong to the reporter package, not to the consuming Cypress project.
878
- const sourceDir = path.join(__dirname, "assets");
879
- const destinationDir = path.join(reportDir, "assets");
880
- ensureDir(destinationDir);
881
- for (const filename of fs.readdirSync(sourceDir)) {
882
- fs.copyFileSync(
883
- path.join(sourceDir, filename),
884
- path.join(destinationDir, filename),
885
- );
886
- }
887
- }
888
-
876
+ function copyDirectoryContents(sourceDir, destinationDir) {
877
+ ensureDir(destinationDir);
878
+ for (const entry of fs.readdirSync(sourceDir, { withFileTypes: true })) {
879
+ const sourcePath = path.join(sourceDir, entry.name);
880
+ const destinationPath = path.join(destinationDir, entry.name);
881
+ if (entry.isDirectory()) {
882
+ copyDirectoryContents(sourcePath, destinationPath);
883
+ } else if (entry.isFile()) {
884
+ fs.copyFileSync(sourcePath, destinationPath);
885
+ }
886
+ }
887
+ }
888
+
889
+ function copyStaticAssets(reportDir) {
890
+ // Assets belong to the reporter package, not to the consuming Cypress project.
891
+ copyDirectoryContents(
892
+ path.join(__dirname, "assets"),
893
+ path.join(reportDir, "assets"),
894
+ );
895
+ }
896
+
889
897
  function mergeHttpManifest(run, runDir) {
890
898
  const manifest = readJson(path.join(runDir, "http", "manifest.json"), []);
891
899
  if (!Array.isArray(manifest) || !manifest.length) return;
@@ -924,7 +932,7 @@ async function finalizeRun(options = {}) {
924
932
  if (!run) throw new Error(`No se encontró ${rawPath}`);
925
933
 
926
934
  run.schemaVersion = DATABASE_SCHEMA_VERSION;
927
- run.reporterVersion = "2.0.0-beta.6";
935
+ run.reporterVersion = "2.0.0-beta.8";
928
936
  run.lifecycle = run.lifecycle || "completed";
929
937
  run.source = run.source || {
930
938
  branch: process.env.CI_COMMIT_REF_NAME || "",
@@ -966,7 +974,9 @@ module.exports = {
966
974
  buildTrends,
967
975
  buildQualityAnalytics,
968
976
  canonicalTestIdentity,
969
- compareRuns,
977
+ compareRuns,
978
+ copyDirectoryContents,
979
+ copyStaticAssets,
970
980
  enrichRunTests,
971
981
  finalizeRun,
972
982
  loadAnnotations,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alejandrojca/elmulo-reporter",
3
- "version": "2.0.0-beta.6",
3
+ "version": "2.0.0-beta.8",
4
4
  "description": "Reporter independiente para ejecuciones de Cypress con dashboard, historial SQLite y evidencias.",
5
5
  "type": "commonjs",
6
6
  "main": "plugin.cjs",
package/plugin.cjs CHANGED
@@ -57,7 +57,7 @@ function registerElmuloReporter(on, config, options = {}) {
57
57
  "unknown",
58
58
  tagExpression: config.env?.TAGS || process.env.CYPRESS_TAGS || "",
59
59
  lifecycle: "running",
60
- reporterVersion: "2.0.0-beta.6",
60
+ reporterVersion: "2.0.0-beta.8",
61
61
  execution: executionScript
62
62
  ? { runner: "npm", script: executionScript, args: executionArgs }
63
63
  : null,
package/server.cjs CHANGED
@@ -182,7 +182,7 @@ async function serveReport(options = {}) {
182
182
  if (request.method === "GET" && url.pathname === "/api/health") {
183
183
  sendJson(response, 200, {
184
184
  ok: true,
185
- version: "2.0.0-beta.6",
185
+ version: "2.0.0-beta.8",
186
186
  schemaVersion: 3,
187
187
  });
188
188
  return;