@schwabyio/gta 0.14.2 → 0.14.4

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/dist/SPEC.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # The Gravity file format
2
2
 
3
- Version 0.14.2, the version of Gravity and `gta` that reads it: the two are released
3
+ Version 0.14.4, the version of Gravity and `gta` that reads it: the two are released
4
4
  together.
5
5
 
6
6
  This document specifies the YAML files that **Gravity**, the desktop app, and **`gta`**,
package/dist/gta.js CHANGED
@@ -367,7 +367,7 @@ function summaryPage(run2) {
367
367
  const rows = run2.collections.map((c, i) => {
368
368
  const t = c.tally;
369
369
  const status = statuses[i];
370
- return `<tr class="s-${status}" data-status="${status}" data-search="${escape(c.id.toLowerCase())}"><td class="r n">${i + 1}</td><td class="name"><a href="${escape(encodeURI(pageOf(c.id)))}">${escape(c.id)}</a></td><td class="r">${duration(c.durationMs)}</td><td class="r gs">${t.steps.total}</td><td class="r">${num(t.steps.passed)}</td><td class="r">${num(t.steps.failed, true)}</td><td class="r">${num(t.steps.errored, true)}</td><td class="r">${num(t.steps.skipped)}</td><td class="r gs">${t.assertions.total}</td><td class="r">${num(t.assertions.passed)}</td><td class="r">${num(t.assertions.failed, true)}</td><td class="gs">${pill(status)}</td></tr>`;
370
+ return `<tr class="s-${status}" data-status="${status}" data-search="${escape(c.id.toLowerCase())}"><td class="r n">${i + 1}</td><td class="name"><a href="${escape(encodeURI(pageOf(c.id)))}" target="_blank" rel="noopener">${breakable(c.id)}</a></td><td class="r">${duration(c.durationMs)}</td><td class="r gs">${t.steps.total}</td><td class="r">${num(t.steps.passed)}</td><td class="r">${num(t.steps.failed, true)}</td><td class="r">${num(t.steps.errored, true)}</td><td class="r">${num(t.steps.skipped)}</td><td class="r gs">${t.assertions.total}</td><td class="r">${num(t.assertions.passed)}</td><td class="r">${num(t.assertions.failed, true)}</td><td class="gs">${pill(status)}</td></tr>`;
371
371
  }).join("\n");
372
372
  const notRun = run2.excluded.length > 0 || run2.untagged > 0 ? card(
373
373
  "Not Run",
@@ -381,7 +381,7 @@ function summaryPage(run2) {
381
381
  return page({
382
382
  title: `${passed ? "PASSED" : "FAILED"} \xB7 ${run2.project} \xB7 gta Summary Results`,
383
383
  run: run2,
384
- body: `${pageHead(passed ? "passed" : "failed", `${escape(run2.project)} <span class="kind">\xB7 Summary Results</span>`, run2.startedAt, run2.durationMs)}
384
+ body: `${pageHead(passed ? "passed" : "failed", `${escape(run2.project)} <span class="kind">\xB7 Summary Results</span>`, run2.startedAt)}
385
385
 
386
386
  ${card("Settings", `<dl class="pairs">
387
387
  ${settings.map(([label, value]) => `<div><dt>${label}</dt><dd>${value}</dd></div>`).join("\n")}
@@ -405,6 +405,7 @@ ${ringStat("Assertions", [
405
405
  ["passed", sum((t) => t.assertions.passed)],
406
406
  ["failed", sum((t) => t.assertions.failed)]
407
407
  ])}
408
+ ${timeStat("Total Run Time", run2.durationMs)}
408
409
  </div>`
409
410
  )}
410
411
 
@@ -418,7 +419,8 @@ ${rows}
418
419
  </tbody></table></div>`,
419
420
  {
420
421
  flush: true,
421
- tools: `${chips({ passed: count("passed"), failed: count("failed"), skipped: count("skipped") })}${searchBox("Search collections")}`
422
+ // As a collection page's Tests: the search by the title, what to show at the far end.
423
+ tools: `${searchBox("Search collections")}<div class="tools-end">${chips({ passed: count("passed"), failed: count("failed"), skipped: count("skipped") })}</div>`
422
424
  }
423
425
  )}
424
426
  ${notRun}`
@@ -438,13 +440,13 @@ function collectionPage(run2, c) {
438
440
  title: `${status.toUpperCase()} \xB7 ${c.id} \xB7 gta Collection Results`,
439
441
  run: run2,
440
442
  body: `<nav class="crumbs"><a href="${SUMMARY_PAGE}">Summary</a><span aria-hidden="true">/</span><span>${escape(c.id)}</span></nav>
441
- ${pageHead(status, escape(c.id), c.startedAt, c.durationMs)}
443
+ ${pageHead(status, escape(c.id), c.startedAt)}
442
444
 
443
445
  ${card(
444
446
  "Results Overview",
445
447
  [
446
448
  c.docs?.trim() ? markdown(c.docs) : "",
447
- data ? `<dl class="pairs"><div><dt>Data File</dt><dd><code>${escape(data.file)}</code></dd></div><div><dt>Iterations</dt><dd>${data.rows}</dd></div></dl>` : "",
449
+ data ? `<dl class="pairs"><div><dt>Data File</dt><dd><code>${escape(data.file)}</code></dd></div><div><dt>Iterations</dt><dd>${thousands(data.rows)}</dd></div></dl>` : "",
448
450
  !c.outcome.ok ? `<section class="sub problem"><h3>Error</h3><pre>${escape(c.outcome.message)}</pre></section>` : "",
449
451
  `<div class="stats">
450
452
  ${ringStat("Tests", [
@@ -457,6 +459,7 @@ ${ringStat("Assertions", [
457
459
  ["passed", t.assertions.passed],
458
460
  ["failed", t.assertions.failed]
459
461
  ])}
462
+ ${timeStat("Total Run Time", c.durationMs)}
460
463
  </div>`
461
464
  ].filter(Boolean).join("\n"),
462
465
  { tools: `<code class="file">${escape(c.file)}</code>` }
@@ -822,7 +825,7 @@ ${options.body}
822
825
  </html>
823
826
  `;
824
827
  }
825
- var pageHead = (status, title, startedAt, ms) => `<header class="head"><div class="title">${pill(status, true)}<h1>${title}</h1></div><div class="meta"><span>${escape(timeOfRun(startedAt))}</span><span>${duration(ms)}</span></div></header>`;
828
+ var pageHead = (status, title, startedAt) => `<header class="head"><div class="title">${pill(status, true)}<h1>${title}</h1></div><div class="meta"><span>${escape(timeOfRun(startedAt))}</span></div></header>`;
826
829
  var card = (title, body, options = {}) => `<section class="card"${options.id ? ` id="${options.id}"` : ""}><div class="card-h"><h2>${title}</h2>${options.tools ?? ""}</div><div class="card-body${options.flush ? " flush" : ""}">
827
830
  ${body}
828
831
  </div></section>`;
@@ -842,8 +845,10 @@ function ringStat(label, parts) {
842
845
  const passed = parts.find(([s]) => s === "passed")?.[1] ?? 0;
843
846
  const ran = total - (parts.find(([s]) => s === "skipped")?.[1] ?? 0);
844
847
  const rate = ran === 0 ? "\u2014" : `${Math.floor(passed / ran * 100)}%`;
845
- return `<div class="stat"><div class="ring" title="${passed} of ${ran} that ran passed">${ring(parts)}<b>${rate}</b></div><div><div class="stat-label">${label}</div><div class="stat-total">${total}</div><div class="legend">${parts.map(([s, v]) => `<span class="${v ? `s-${s}` : "zero"}"><i></i>${v} ${s}</span>`).join("")}</div></div></div>`;
848
+ return `<div class="stat"><div class="ring" title="${thousands(passed)} of ${thousands(ran)} that ran passed">${ring(parts)}<b>${rate}</b></div><div><div class="stat-label">${label}</div><div class="stat-total">${thousands(total)}</div><div class="legend">${parts.map(([s, v]) => `<span class="${v ? `s-${s}` : "zero"}"><i></i>${thousands(v)} ${s}</span>`).join("")}</div></div></div>`;
846
849
  }
850
+ var timeStat = (label, ms) => `<div class="stat"><div class="ring clock">${clock}</div><div><div class="stat-label">${label}</div><div class="stat-time" title="${thousands(Math.round(ms))} ms">${runTime(ms).replace(/(\d) /g, "$1&nbsp;")}</div></div></div>`;
851
+ var clock = `<svg viewBox="0 0 64 64" width="64" height="64" aria-hidden="true"><circle cx="32" cy="32" r="25" fill="none" stroke-width="7" style="stroke:var(--surface-alt)"/><path d="M32 19v13l9 6" fill="none" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" style="stroke:var(--dim)"/></svg>`;
847
852
  function ring(parts) {
848
853
  const R = 25;
849
854
  const C = 2 * Math.PI * R;
@@ -878,7 +883,19 @@ function clip(text) {
878
883
  var userFrames = (stack) => stack.split("\n").filter((line) => !/^\s+at .*(\bnode:|file:\/\/)/.test(line)).join("\n");
879
884
  var capitalise = (text) => text.charAt(0).toUpperCase() + text.slice(1);
880
885
  var plural2 = (n, word) => `${n} ${word}${n === 1 ? "" : "s"}`;
886
+ var thousands = (n) => n.toLocaleString("en-US");
881
887
  var duration = (ms) => ms < 1e3 ? `${Math.round(ms)} ms` : `${(ms / 1e3).toFixed(2)} s`;
888
+ function runTime(ms) {
889
+ const hundredths = Math.round(ms / 10);
890
+ const hours = Math.floor(hundredths / 36e4);
891
+ const minutes = Math.floor(hundredths % 36e4 / 6e3);
892
+ const seconds2 = hundredths % 6e3;
893
+ return [
894
+ hours > 0 ? plural2(hours, "hour") : "",
895
+ minutes > 0 ? plural2(minutes, "minute") : "",
896
+ seconds2 > 0 || hundredths < 6e3 ? `${(seconds2 / 100).toFixed(2)} seconds` : ""
897
+ ].filter(Boolean).join(" ");
898
+ }
882
899
  function timeoutText(ms) {
883
900
  const round = ms >= 36e5 && ms % 36e5 === 0 ? `${ms / 36e5} h` : ms >= 6e4 && ms % 6e4 === 0 ? `${ms / 6e4} min` : ms >= 1e3 && ms % 1e3 === 0 ? `${ms / 1e3} s` : "";
884
901
  return `${ms.toLocaleString("en-US")} ms${round ? ` <span class="dim">\xB7 ${round}</span>` : ""}`;
@@ -892,6 +909,7 @@ function bytes(n) {
892
909
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
893
910
  return `${(n / 1024 / 1024).toFixed(1)} MB`;
894
911
  }
912
+ var breakable = (value) => escape(value).replace(/([_/.-])/g, "$1<wbr>");
895
913
  function escape(value) {
896
914
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
897
915
  }
@@ -964,7 +982,7 @@ pre{margin:0;white-space:pre-wrap;word-break:break-word}
964
982
  .card{background:var(--surface);border:1px solid var(--border);border-radius:8px;margin-bottom:16px;min-width:0}
965
983
  .card-h{display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;padding:10px 16px;border-bottom:1px solid var(--border-soft)}
966
984
  .card-h h2{margin:0 6px 0 0;font-size:13.5px;font-weight:650}
967
- .card-h .search,.card-h .file{margin-left:auto}
985
+ .card-h .file{margin-left:auto}
968
986
  .card-h .file{color:var(--dim);overflow-wrap:anywhere}
969
987
  .card-body{padding:16px}
970
988
  .card-body>*+*{margin-top:16px}
@@ -980,6 +998,7 @@ pre{margin:0;white-space:pre-wrap;word-break:break-word}
980
998
  .ring b{position:absolute;inset:0;display:grid;place-items:center;font-size:13.5px;font-variant-numeric:tabular-nums}
981
999
  .stat-label{font-size:12px;color:var(--dim)}
982
1000
  .stat-total{font-size:24px;font-weight:650;font-variant-numeric:tabular-nums;line-height:1;margin-top:3px}
1001
+ .stat-time{font-size:17px;font-weight:650;font-variant-numeric:tabular-nums;line-height:1.25;margin-top:3px}
983
1002
  .legend{display:flex;flex-wrap:wrap;gap:4px 12px;margin-top:6px;font-size:12.5px;font-variant-numeric:tabular-nums}
984
1003
  .legend span{display:inline-flex;align-items:center;gap:5px}
985
1004
  .legend i{width:8px;height:8px;border-radius:2px;background:var(--s)}
@@ -1012,7 +1031,8 @@ pre{margin:0;white-space:pre-wrap;word-break:break-word}
1012
1031
  .overview tbody tr:last-child td{border-bottom:none}
1013
1032
  .overview .r{text-align:right}
1014
1033
  .overview .gs{border-left:1px solid var(--border-soft)}
1015
- .overview td.name{min-width:17rem}
1034
+ .overview td.name{min-width:10rem;overflow-wrap:anywhere}
1035
+ @media (max-width:960px){.overview th,.overview td{padding-left:6px;padding-right:6px}.overview .groups th{padding-left:6px;padding-right:6px}}
1016
1036
  .overview td.n{color:var(--faint)}
1017
1037
  .overview tbody tr:hover td{background:var(--surface-alt)}
1018
1038
  .overview tr.s-failed td:first-child{box-shadow:inset 3px 0 0 var(--failed)}
@@ -1365,7 +1385,7 @@ function escape2(value) {
1365
1385
  var allowedInXml = (code) => code === 9 || code === 10 || code === 13 || code >= 32 && code <= 55295 || code >= 57344 && code <= 65533 || code >= 65536;
1366
1386
 
1367
1387
  // src/main.ts
1368
- var VERSION = true ? "0.14.2" : "0.0.0-dev";
1388
+ var VERSION = true ? "0.14.4" : "0.0.0-dev";
1369
1389
  var JUNIT_DIR = "junit";
1370
1390
  var JUNIT_FILE = "junit.xml";
1371
1391
  var HTML_DIR = "html";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schwabyio/gta",
3
- "version": "0.14.2",
3
+ "version": "0.14.4",
4
4
  "type": "module",
5
5
  "description": "gta, the Gravity Test Automation command-line runner: HTTP API tests written as YAML files, run from a terminal or CI.",
6
6
  "keywords": [