@alejandrojca/elmulo-reporter 2.0.0-beta.8 → 2.0.0-beta.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/VERSION.json +1 -1
- package/assets/app.css +53 -13
- package/assets/app.js +79 -34
- package/finalize.cjs +2 -2
- package/jira.cjs +2 -2
- package/package.json +1 -1
- package/plugin.cjs +1 -1
- package/server.cjs +1 -1
package/VERSION.json
CHANGED
package/assets/app.css
CHANGED
|
@@ -850,19 +850,59 @@ button {
|
|
|
850
850
|
margin: 1rem 0;
|
|
851
851
|
}
|
|
852
852
|
|
|
853
|
-
.
|
|
854
|
-
background: var(--pw-blue-050);
|
|
855
|
-
border-radius: 999px;
|
|
856
|
-
color: var(--pw-gray-700);
|
|
857
|
-
font-size: 0.78rem;
|
|
858
|
-
padding: 0.45rem 0.65rem;
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
.
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
.
|
|
853
|
+
.historicalExecutionCount {
|
|
854
|
+
background: var(--pw-blue-050);
|
|
855
|
+
border-radius: 999px;
|
|
856
|
+
color: var(--pw-gray-700);
|
|
857
|
+
font-size: 0.78rem;
|
|
858
|
+
padding: 0.45rem 0.65rem;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
.historicalStatusFilters {
|
|
862
|
+
display: flex;
|
|
863
|
+
flex: 1 1 420px;
|
|
864
|
+
flex-wrap: wrap;
|
|
865
|
+
gap: 0.45rem;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
.historicalStatusFilter {
|
|
869
|
+
--historical-status-color: var(--pw-gray-700);
|
|
870
|
+
background: color-mix(in srgb, var(--historical-status-color) 7%, var(--pw-white));
|
|
871
|
+
border: 1px solid color-mix(in srgb, var(--historical-status-color) 55%, var(--pw-gray-200));
|
|
872
|
+
border-radius: 999px;
|
|
873
|
+
color: var(--historical-status-color);
|
|
874
|
+
font-size: 0.75rem;
|
|
875
|
+
font-weight: 700;
|
|
876
|
+
padding: 0.42rem 0.65rem;
|
|
877
|
+
transition:
|
|
878
|
+
background 140ms ease,
|
|
879
|
+
box-shadow 140ms ease,
|
|
880
|
+
transform 140ms ease;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
.historicalStatusFilter.passed { --historical-status-color: var(--pw-success); }
|
|
884
|
+
.historicalStatusFilter.failed { --historical-status-color: var(--pw-danger); }
|
|
885
|
+
.historicalStatusFilter.environment_error { --historical-status-color: var(--pw-warning); }
|
|
886
|
+
.historicalStatusFilter.precondition_error { --historical-status-color: #e87922; }
|
|
887
|
+
.historicalStatusFilter.outdated_test { --historical-status-color: #7c5ce5; }
|
|
888
|
+
.historicalStatusFilter.reported { --historical-status-color: var(--pw-blue-600); }
|
|
889
|
+
.historicalStatusFilter.skipped,
|
|
890
|
+
.historicalStatusFilter.pending { --historical-status-color: #71859a; }
|
|
891
|
+
|
|
892
|
+
.historicalStatusFilter:hover,
|
|
893
|
+
.historicalStatusFilter:focus-visible {
|
|
894
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--historical-status-color) 18%, transparent);
|
|
895
|
+
transform: translateY(-1px);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
.historicalStatusFilter.active {
|
|
899
|
+
background: var(--historical-status-color);
|
|
900
|
+
border-color: var(--historical-status-color);
|
|
901
|
+
color: #fff;
|
|
902
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--historical-status-color) 22%, transparent);
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
.historicalTestList {
|
|
866
906
|
display: grid;
|
|
867
907
|
gap: 0.55rem;
|
|
868
908
|
max-height: 480px;
|
package/assets/app.js
CHANGED
|
@@ -201,9 +201,10 @@
|
|
|
201
201
|
tag: initialUrlState.get("tag") || "all",
|
|
202
202
|
trendStatus: "total",
|
|
203
203
|
trendEnvironment: initialTrendEnvironment,
|
|
204
|
-
selectedTrendRunId: null,
|
|
205
|
-
historicalRun: null,
|
|
206
|
-
historicalRerun: null,
|
|
204
|
+
selectedTrendRunId: null,
|
|
205
|
+
historicalRun: null,
|
|
206
|
+
historicalRerun: null,
|
|
207
|
+
historicalStatusFilter: "",
|
|
207
208
|
historyJiraId: null,
|
|
208
209
|
historyTestTitle: "",
|
|
209
210
|
historyCurrentTestId: null,
|
|
@@ -1119,7 +1120,7 @@
|
|
|
1119
1120
|
</div>`;
|
|
1120
1121
|
}
|
|
1121
1122
|
|
|
1122
|
-
function renderHistoricalRun() {
|
|
1123
|
+
function renderHistoricalRun() {
|
|
1123
1124
|
const historicalRun = state.historicalRun;
|
|
1124
1125
|
if (!state.selectedTrendRunId) {
|
|
1125
1126
|
return `<div class="trendHistoryPlaceholder">
|
|
@@ -1130,11 +1131,39 @@
|
|
|
1130
1131
|
return `<div class="trendHistoryPlaceholder">Cargando resultados históricos…</div>`;
|
|
1131
1132
|
}
|
|
1132
1133
|
|
|
1133
|
-
const tests = historicalRun.tests || [];
|
|
1134
|
-
const
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1134
|
+
const tests = historicalRun.tests || [];
|
|
1135
|
+
const historicalStatusOrder = [
|
|
1136
|
+
"passed",
|
|
1137
|
+
"failed",
|
|
1138
|
+
"environment_error",
|
|
1139
|
+
"precondition_error",
|
|
1140
|
+
"outdated_test",
|
|
1141
|
+
"reported",
|
|
1142
|
+
"skipped",
|
|
1143
|
+
"pending",
|
|
1144
|
+
"unknown",
|
|
1145
|
+
];
|
|
1146
|
+
const statusCounts = tests.reduce((counts, test) => {
|
|
1147
|
+
const status = String(test.status || "unknown");
|
|
1148
|
+
counts.set(status, (counts.get(status) || 0) + 1);
|
|
1149
|
+
return counts;
|
|
1150
|
+
}, new Map());
|
|
1151
|
+
const visibleStatuses = [...statusCounts.entries()]
|
|
1152
|
+
.sort(([left], [right]) => {
|
|
1153
|
+
const leftIndex = historicalStatusOrder.indexOf(left);
|
|
1154
|
+
const rightIndex = historicalStatusOrder.indexOf(right);
|
|
1155
|
+
return (leftIndex < 0 ? historicalStatusOrder.length : leftIndex) -
|
|
1156
|
+
(rightIndex < 0 ? historicalStatusOrder.length : rightIndex);
|
|
1157
|
+
});
|
|
1158
|
+
if (
|
|
1159
|
+
state.historicalStatusFilter &&
|
|
1160
|
+
!statusCounts.has(state.historicalStatusFilter)
|
|
1161
|
+
) {
|
|
1162
|
+
state.historicalStatusFilter = "";
|
|
1163
|
+
}
|
|
1164
|
+
const filteredTests = state.historicalStatusFilter
|
|
1165
|
+
? tests.filter((test) => test.status === state.historicalStatusFilter)
|
|
1166
|
+
: tests;
|
|
1138
1167
|
const rerun = state.historicalRerun || historicalRun.rerun || {};
|
|
1139
1168
|
const rerunBusy = ["starting", "running"].includes(rerun.status);
|
|
1140
1169
|
const rerunLabel = rerun.status === "starting"
|
|
@@ -1172,18 +1201,23 @@
|
|
|
1172
1201
|
>×</button>
|
|
1173
1202
|
</div>
|
|
1174
1203
|
</header>
|
|
1175
|
-
${rerunFeedback
|
|
1176
|
-
? `<div class="trendRerunFeedback ${rerun.status === "failed" || rerun.status === "unavailable" ? "error" : "success"}" role="status">${escapeHtml(rerunFeedback)}</div>`
|
|
1177
|
-
: ""}
|
|
1178
|
-
<div class="trendHistoryStats">
|
|
1179
|
-
<span><strong>${tests.length}</strong> ejecuciones</span>
|
|
1180
|
-
<
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1204
|
+
${rerunFeedback
|
|
1205
|
+
? `<div class="trendRerunFeedback ${rerun.status === "failed" || rerun.status === "unavailable" ? "error" : "success"}" role="status">${escapeHtml(rerunFeedback)}</div>`
|
|
1206
|
+
: ""}
|
|
1207
|
+
<div class="trendHistoryStats">
|
|
1208
|
+
<span class="historicalExecutionCount"><strong>${tests.length}</strong> ejecuciones</span>
|
|
1209
|
+
<div class="historicalStatusFilters" aria-label="Filtrar pruebas históricas por estado">
|
|
1210
|
+
${visibleStatuses.map(([status, count]) => `<button
|
|
1211
|
+
class="historicalStatusFilter ${escapeHtml(status)} ${state.historicalStatusFilter === status ? "active" : ""}"
|
|
1212
|
+
type="button"
|
|
1213
|
+
data-historical-status-filter="${escapeHtml(status)}"
|
|
1214
|
+
aria-pressed="${state.historicalStatusFilter === status}"
|
|
1215
|
+
><strong>${escapeHtml(count)}</strong> ${escapeHtml(statusLabel[status] || status)}</button>`).join("")}
|
|
1216
|
+
</div>
|
|
1217
|
+
</div>
|
|
1218
|
+
<div class="historicalTestList">
|
|
1219
|
+
${filteredTests.length
|
|
1220
|
+
? filteredTests.map((test) => `<article class="historicalTestRow">
|
|
1187
1221
|
<span class="statusDot ${escapeHtml(test.status)}" aria-hidden="true"></span>
|
|
1188
1222
|
<span>
|
|
1189
1223
|
<strong>${escapeHtml(test.title)}</strong>
|
|
@@ -1196,7 +1230,7 @@
|
|
|
1196
1230
|
<small>${escapeHtml(formatDuration(test.duration_ms))}</small>
|
|
1197
1231
|
</span>
|
|
1198
1232
|
</article>`).join("")
|
|
1199
|
-
: `<div class="emptyState"><strong>Sin resultados</strong><span>Esta corrida no tiene pruebas registradas.</span></div>`}
|
|
1233
|
+
: `<div class="emptyState"><strong>Sin resultados</strong><span>Esta corrida no tiene pruebas registradas.</span></div>`}
|
|
1200
1234
|
</div>
|
|
1201
1235
|
</section>`;
|
|
1202
1236
|
}
|
|
@@ -1225,11 +1259,20 @@
|
|
|
1225
1259
|
const closeButton = document.querySelector("[data-close-trend-history]");
|
|
1226
1260
|
if (!closeButton) return;
|
|
1227
1261
|
closeButton.addEventListener("click", () => {
|
|
1228
|
-
state.selectedTrendRunId = null;
|
|
1229
|
-
state.historicalRun = null;
|
|
1230
|
-
state.historicalRerun = null;
|
|
1231
|
-
|
|
1232
|
-
|
|
1262
|
+
state.selectedTrendRunId = null;
|
|
1263
|
+
state.historicalRun = null;
|
|
1264
|
+
state.historicalRerun = null;
|
|
1265
|
+
state.historicalStatusFilter = "";
|
|
1266
|
+
renderTrendArea();
|
|
1267
|
+
});
|
|
1268
|
+
document.querySelectorAll("[data-historical-status-filter]").forEach((button) => {
|
|
1269
|
+
button.addEventListener("click", () => {
|
|
1270
|
+
const status = button.dataset.historicalStatusFilter;
|
|
1271
|
+
state.historicalStatusFilter =
|
|
1272
|
+
state.historicalStatusFilter === status ? "" : status;
|
|
1273
|
+
renderTrendHistoryPanel();
|
|
1274
|
+
});
|
|
1275
|
+
});
|
|
1233
1276
|
document.querySelector("[data-rerun-trend-report]")?.addEventListener(
|
|
1234
1277
|
"click",
|
|
1235
1278
|
startHistoricalRerun,
|
|
@@ -1302,10 +1345,11 @@
|
|
|
1302
1345
|
function bindTrendEvents() {
|
|
1303
1346
|
document.querySelectorAll("[data-trend-run-id]").forEach((button) => {
|
|
1304
1347
|
button.addEventListener("click", async () => {
|
|
1305
|
-
const requestedRunId = button.dataset.trendRunId;
|
|
1306
|
-
state.selectedTrendRunId = requestedRunId;
|
|
1307
|
-
state.historicalRun = null;
|
|
1308
|
-
state.historicalRerun = null;
|
|
1348
|
+
const requestedRunId = button.dataset.trendRunId;
|
|
1349
|
+
state.selectedTrendRunId = requestedRunId;
|
|
1350
|
+
state.historicalRun = null;
|
|
1351
|
+
state.historicalRerun = null;
|
|
1352
|
+
state.historicalStatusFilter = "";
|
|
1309
1353
|
renderTrendArea();
|
|
1310
1354
|
|
|
1311
1355
|
try {
|
|
@@ -1332,9 +1376,10 @@
|
|
|
1332
1376
|
|
|
1333
1377
|
async function loadTrendEnvironment(environment) {
|
|
1334
1378
|
state.trendEnvironment = environment;
|
|
1335
|
-
state.selectedTrendRunId = null;
|
|
1336
|
-
state.historicalRun = null;
|
|
1337
|
-
state.historicalRerun = null;
|
|
1379
|
+
state.selectedTrendRunId = null;
|
|
1380
|
+
state.historicalRun = null;
|
|
1381
|
+
state.historicalRerun = null;
|
|
1382
|
+
state.historicalStatusFilter = "";
|
|
1338
1383
|
const trendContent = document.getElementById("trend-content");
|
|
1339
1384
|
const trendHistory = document.getElementById("trend-history");
|
|
1340
1385
|
const trendCounter = document.getElementById("trend-run-count");
|
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.
|
|
438
|
+
reporterVersion: "2.0.0-beta.9",
|
|
439
439
|
}),
|
|
440
440
|
],
|
|
441
441
|
);
|
|
@@ -932,7 +932,7 @@ async function finalizeRun(options = {}) {
|
|
|
932
932
|
if (!run) throw new Error(`No se encontró ${rawPath}`);
|
|
933
933
|
|
|
934
934
|
run.schemaVersion = DATABASE_SCHEMA_VERSION;
|
|
935
|
-
run.reporterVersion = "2.0.0-beta.
|
|
935
|
+
run.reporterVersion = "2.0.0-beta.9";
|
|
936
936
|
run.lifecycle = run.lifecycle || "completed";
|
|
937
937
|
run.source = run.source || {
|
|
938
938
|
branch: process.env.CI_COMMIT_REF_NAME || "",
|
package/jira.cjs
CHANGED
|
@@ -303,12 +303,12 @@ async function jiraRequest(config, pathname, options = {}) {
|
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
async function findMatchingIssues(config, fingerprint) {
|
|
306
|
-
const
|
|
306
|
+
const conditions = [
|
|
307
307
|
`project = "${config.projectKey}"`,
|
|
308
308
|
`issuetype = "${config.issueTypeName}"`,
|
|
309
309
|
`labels = "${fingerprint}"`,
|
|
310
|
-
"ORDER BY created DESC",
|
|
311
310
|
].join(" AND ");
|
|
311
|
+
const jql = `${conditions} ORDER BY created DESC`;
|
|
312
312
|
const query = new URLSearchParams({
|
|
313
313
|
jql,
|
|
314
314
|
fields: "summary,status,labels",
|
package/package.json
CHANGED
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.
|
|
60
|
+
reporterVersion: "2.0.0-beta.9",
|
|
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.
|
|
185
|
+
version: "2.0.0-beta.9",
|
|
186
186
|
schemaVersion: 3,
|
|
187
187
|
});
|
|
188
188
|
return;
|