@schwabyio/gta 0.9.0 → 0.10.0

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/gta.js CHANGED
@@ -20,13 +20,15 @@ import {
20
20
  parseMarkdown,
21
21
  projectEnvironments,
22
22
  readProject,
23
+ referenceProblems,
23
24
  relativePosix,
24
25
  require_dist,
25
26
  resolveFlags,
27
+ resultName,
26
28
  samePath,
27
29
  stepsForTags,
28
30
  unattempted
29
- } from "./chunks/chunk-VRAFYQNE.js";
31
+ } from "./chunks/chunk-MZSHHPAQ.js";
30
32
 
31
33
  // src/args.ts
32
34
  var UsageError = class extends Error {
@@ -194,7 +196,7 @@ function tally(target, outcome, durationMs) {
194
196
  error: null,
195
197
  // Named for the row they ran with, when a data file drove the collection.
196
198
  problems: summary2.results.flatMap(
197
- (r, i) => r.status === "fail" || r.status === "error" ? [{ ...r, item: { ...r.item, name: iterationName(r.item.name, outcome.steps[i]) } }] : []
199
+ (r, i) => r.status === "fail" || r.status === "error" ? [{ ...r, item: { ...r.item, name: iterationName(resultName(r), outcome.steps[i]) } }] : []
198
200
  )
199
201
  };
200
202
  }
@@ -491,13 +493,13 @@ ${tests || '<p class="dim">No tests were run.</p>'}
491
493
  var statusOf = (r) => r.status === "pass" ? "passed" : r.status === "fail" ? "failed" : r.status === "error" ? "errored" : "skipped";
492
494
  function testSection(r, index, ref) {
493
495
  const status = statusOf(r);
494
- const named = escape(iterationName(r.item.name, ref));
496
+ const named = escape(iterationName(resultName(r), ref));
495
497
  const name = r.use ? `${named} <span class="dim">(${escape(r.use.set)} ${r.use.child + 1}/${r.use.of})</span>` : named;
496
498
  if (r.skipped) {
497
- return `<details class="acc skipped skipped" data-search="${escape(iterationName(r.item.name, ref).toLowerCase())}">
499
+ return `<details class="acc skipped skipped" data-search="${escape(iterationName(resultName(r), ref).toLowerCase())}">
498
500
  <summary><span>Test ${index + 1}: ${name}</span>${icon("skipped")}</summary>
499
501
  <div class="acc-body">
500
- ${card("Skipped", field2("Feature Flag", `<span class="c-skipped">${escape(r.skipped.reason)} \u2014 this test was not run</span>`, "wide"))}
502
+ ${card("Skipped", field2("Reason", `<span class="c-skipped">${escape(r.skipped.reason)} \u2014 this test was not run</span>`, "wide"))}
501
503
  </div>
502
504
  </details>`;
503
505
  }
@@ -509,7 +511,7 @@ ${card("Skipped", field2("Feature Flag", `<span class="c-skipped">${escape(r.ski
509
511
  r.logs?.length ? consoleCard(r) : ""
510
512
  ].filter(Boolean);
511
513
  const group = status === "passed" ? "passed" : status === "skipped" ? "skipped" : "failed";
512
- const search = iterationName(r.item.name, ref).toLowerCase();
514
+ const search = iterationName(resultName(r), ref).toLowerCase();
513
515
  return `<details class="acc ${group} ${status}" data-search="${escape(search)}"${status === "passed" ? "" : " open"}>
514
516
  <summary><span>Test ${index + 1}: ${name}</span>${icon(status)}</summary>
515
517
  <div class="acc-body">
@@ -950,7 +952,7 @@ function testcase(classname, name, durationMs, body) {
950
952
  if (body.length === 0) return [`${open}/>`];
951
953
  return [`${open}>`, ...body.map((line) => ` ${line}`), " </testcase>"];
952
954
  }
953
- var caseName = (result) => result.use ? `${result.item.name} [${result.use.set} ${result.use.child + 1}/${result.use.of}]` : result.item.name;
955
+ var caseName = (result) => result.use ? `${resultName(result)} [${result.use.set} ${result.use.child + 1}/${result.use.of}]` : result.item.name;
954
956
  var summarize = (a) => a.message ? `${a.name}: ${a.message}` : a.name;
955
957
  function describe(a) {
956
958
  const lines = [summarize(a)];
@@ -1086,7 +1088,8 @@ function jsonListing(options) {
1086
1088
  tags: target.collection.doc.tags ?? [],
1087
1089
  broken: target.broken
1088
1090
  })),
1089
- leftOut: { excluded: options.excluded, untagged: options.untagged }
1091
+ leftOut: { excluded: options.excluded, untagged: options.untagged },
1092
+ problems: options.problems
1090
1093
  };
1091
1094
  }
1092
1095
  var fileOf = (collection) => `collections/${collection.relativePath}`;
@@ -1248,7 +1251,7 @@ function coerce(key, value, where) {
1248
1251
  }
1249
1252
 
1250
1253
  // src/main.ts
1251
- var VERSION = true ? "0.9.0" : "0.0.0-dev";
1254
+ var VERSION = true ? "0.10.0" : "0.0.0-dev";
1252
1255
  var JUNIT_DIR = "junit";
1253
1256
  var JUNIT_FILE = "junit.xml";
1254
1257
  var HTML_DIR = "html";
@@ -1283,6 +1286,8 @@ async function main(argv, cli) {
1283
1286
  const command = args.command;
1284
1287
  if (command === "g" || command === "get") {
1285
1288
  const selection = selectFor(project, { kind: "all" });
1289
+ const problems = await listingProblems(project, selection);
1290
+ const code = problems.length > 0 || selection.targets.some((target) => target.broken) ? EXIT.failed : EXIT.passed;
1286
1291
  if (emit) {
1287
1292
  emit(
1288
1293
  jsonListing({
@@ -1294,12 +1299,14 @@ async function main(argv, cli) {
1294
1299
  notTags: project.settings.notTags,
1295
1300
  targets: selection.targets,
1296
1301
  excluded: selection.excluded,
1297
- untagged: selection.untagged
1302
+ untagged: selection.untagged,
1303
+ problems
1298
1304
  })
1299
1305
  );
1300
- return EXIT.passed;
1306
+ return code;
1301
1307
  }
1302
- return list(project, selection, ctx, p);
1308
+ list(project, selection, problems, ctx, p);
1309
+ return code;
1303
1310
  }
1304
1311
  const request = command === "a" || command === "all" ? { kind: "all" } : { kind: "list", selectors: command.split(",").filter((s) => s.trim() !== "") };
1305
1312
  return await run(project, selectFor(project, request), ctx, p, emit);
@@ -1368,7 +1375,24 @@ var selectFor = (project, request) => selectCollections(project.collections, req
1368
1375
  tags: project.settings.tags,
1369
1376
  notTags: project.settings.notTags
1370
1377
  });
1371
- function list(project, selection, ctx, p) {
1378
+ async function listingProblems(project, selection) {
1379
+ const listed = new Set(selection.targets.map((target) => target.id));
1380
+ const problems = [];
1381
+ for (const collection of project.collections) {
1382
+ const id = idOf(collection);
1383
+ const leftOut = listed.has(id) ? null : collection.doc.exclude === true ? "excluded" : "tags";
1384
+ if (collection.problems.length > 0) {
1385
+ const message = collection.problems.map((problem) => problem.message).join("; ");
1386
+ if (leftOut) problems.push({ id, leftOut, step: null, message });
1387
+ continue;
1388
+ }
1389
+ for (const problem of await referenceProblems(collection.doc, collection.path)) {
1390
+ problems.push({ id, leftOut, ...problem });
1391
+ }
1392
+ }
1393
+ return problems;
1394
+ }
1395
+ function list(project, selection, problems, ctx, p) {
1372
1396
  const { settings } = project;
1373
1397
  ctx.out(field("Project", `${project.name} ${p.dim(project.root)}`));
1374
1398
  ctx.out(
@@ -1406,6 +1430,12 @@ function list(project, selection, ctx, p) {
1406
1430
  for (const target of selection.targets.filter((t) => t.broken)) {
1407
1431
  ctx.out(`${p.red("broken")} ${target.id}: ${target.broken}`);
1408
1432
  }
1433
+ const leftOut = { excluded: " (excluded)", tags: " (left out by tags)" };
1434
+ for (const problem of problems) {
1435
+ const step = problem.step === null ? "" : `, ${problem.stage ? `${problem.stage} ` : ""}step ${problem.step + 1}`;
1436
+ const where = `${problem.id}${problem.leftOut ? leftOut[problem.leftOut] : ""}${step}`;
1437
+ ctx.out(`${p.red("broken")} ${where}: ${problem.message}`);
1438
+ }
1409
1439
  if (selection.excluded.length > 0) {
1410
1440
  ctx.out(field("Excluded", `${selection.excluded.join(", ")} ${p.dim("(exclude: true)")}`));
1411
1441
  }
@@ -1414,7 +1444,6 @@ function list(project, selection, ctx, p) {
1414
1444
  }
1415
1445
  const steps = selection.targets.reduce((n, t) => n + stepCountOf(t), 0);
1416
1446
  ctx.out(field("Total", `${selection.targets.length} collections, ${steps} steps`));
1417
- return EXIT.passed;
1418
1447
  }
1419
1448
  async function run(project, selection, ctx, p, emit = null) {
1420
1449
  const { settings } = project;
@@ -1603,6 +1632,8 @@ function usage(p) {
1603
1632
  "",
1604
1633
  ` ${p.bold("Commands:")}`,
1605
1634
  " g, get List the collections `gta all` would run, without running them.",
1635
+ " Exits 1 on a broken collection, or a use: or extends: that",
1636
+ " would stop a run, in any collection.",
1606
1637
  " a, all Run every collection, less those with exclude: true.",
1607
1638
  " <list> Run the collections and directories named, comma separated,",
1608
1639
  " in that order: smoke,checkout/sessions,payments",
package/dist/worker.js CHANGED
@@ -3,7 +3,7 @@ import { createRequire as __gtaCreateRequire } from 'node:module';
3
3
  const require = __gtaCreateRequire(import.meta.url);
4
4
  import {
5
5
  runJob
6
- } from "./chunks/chunk-VRAFYQNE.js";
6
+ } from "./chunks/chunk-MZSHHPAQ.js";
7
7
 
8
8
  // src/worker.ts
9
9
  import { parentPort, workerData } from "node:worker_threads";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schwabyio/gta",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
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": [