@testomatio/reporter 2.14.0 → 2.15.0-beta.1-json-output

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/lib/bin/cli.js CHANGED
@@ -55,7 +55,7 @@ program
55
55
  .description('Start a new run and return its ID')
56
56
  .option('--kind <type>', 'Specify run type: automated, manual, mixed, or detect')
57
57
  .option('--filter <filter>', 'Scope the prepared run to tests matching the filter (no execution)')
58
- .option('--format <format>', 'Machine-readable output: print only the run id to stdout (e.g. --format id)')
58
+ .option('--format <format>', 'Machine-readable output: the run id (--format id) or run details (--format json)')
59
59
  .option('--warn', 'Exit 0 instead of 1 when the filter matches no tests (warn only)')
60
60
  .action(async (opts) => {
61
61
  (0, utils_js_1.cleanLatestRunId)();
@@ -89,8 +89,8 @@ program
89
89
  // pipes add their report now and replace it when the run is finished
90
90
  const plannedTests = (client.pipeStore.preparedTestIds || []).map(id => ({ test_id: id, title: id }));
91
91
  await client.updateRunStatus('pending', { tests: plannedTests });
92
- // stdout carries ONLY the run id so it can be captured: RUN_ID=$(reporter start)
93
- console.log(runId);
92
+ // stdout carries ONLY the run data so it can be captured: RUN_ID=$(reporter start)
93
+ console.log((0, pipe_utils_js_1.formatRunOutput)({ ...client.pipeStore, runId }, opts.format));
94
94
  process.exit(0);
95
95
  });
96
96
  program
@@ -120,7 +120,7 @@ program
120
120
  .argument('[command]', 'Test runner command')
121
121
  .option('--filter <filter>', 'Additional execution filter')
122
122
  .option('--filter-list <filter>', 'Get a list of all tests by filter before running')
123
- .option('--format <format>', 'Machine-readable output format for --filter-list (grep, json, newline, ids)')
123
+ .option('--format <format>', 'Machine-readable output: test ids for --filter-list (grep, json, newline, ids), or the run created (id, json)')
124
124
  .option('--kind <type>', 'Specify run type: automated, manual, mixed, or detect')
125
125
  .option('--remote <profile>', 'Trigger run on the named Testomat.io CI profile instead of executing locally')
126
126
  .option('--remote-param <kv>', 'key=value pair forwarded to the CI profile config (repeat for multiple)', (value, prev) => prev.concat([value]), [])
@@ -210,6 +210,9 @@ program
210
210
  }
211
211
  log_js_1.log.info(`🚀 CI build triggered on profile ${picocolors_1.default.cyan(opts.remote)}`);
212
212
  log_js_1.log.info(`📊 Report URL: ${picocolors_1.default.magenta(client.pipeStore.runUrl)}`);
213
+ const remoteOutput = (0, pipe_utils_js_1.formatRunOutput)(client.pipeStore, opts.format);
214
+ if (opts.format && remoteOutput)
215
+ console.log(remoteOutput);
213
216
  return process.exit(0);
214
217
  }
215
218
  // just create a run (wich tests which match filters) without executing tests
@@ -230,6 +233,9 @@ program
230
233
  log_js_1.log.info(`No command passed, so you need to run tests yourself:`);
231
234
  log_js_1.log.info(`TESTOMATIO_RUN=${runId} <command>`);
232
235
  }
236
+ const runOutput = (0, pipe_utils_js_1.formatRunOutput)({ ...client.pipeStore, runId }, opts.format);
237
+ if (opts.format && runOutput)
238
+ console.log(runOutput);
233
239
  }
234
240
  else {
235
241
  log_js_1.log.info('⚠️ No API key provided. Cannot create run without TESTOMATIO key.');
@@ -262,7 +268,12 @@ program
262
268
  createRunParams.kind = opts.kind;
263
269
  }
264
270
  if (apiKey) {
265
- await client.createRun(createRunParams).then(runTests);
271
+ await client.createRun(createRunParams);
272
+ // the runner inherits stdout, so the run data is printed first, on its own line
273
+ const createdOutput = (0, pipe_utils_js_1.formatRunOutput)(client.pipeStore, opts.format);
274
+ if (opts.format && createdOutput)
275
+ console.log(createdOutput);
276
+ await runTests();
266
277
  }
267
278
  else {
268
279
  await runTests();
@@ -108,6 +108,19 @@ export function parsePipeOptions(optionsStr?: string): any;
108
108
  * @returns {string} Empty string if no ids; otherwise the formatted output.
109
109
  */
110
110
  export function formatFilterListIds(ids: string[], format: "grep" | "json" | "newline" | "ids"): string;
111
+ /**
112
+ * Format the created run for machine-readable output of `start` and `run`.
113
+ * `json` prints an object with the run details, any other format prints the bare run id.
114
+ *
115
+ * @param {{runId?: string, runUrl?: string, runPublicUrl?: string}} store - Pipe store of the client.
116
+ * @param {string} [format] - Value of the CLI `--format` option.
117
+ * @returns {string} Empty string if there is no run id.
118
+ */
119
+ export function formatRunOutput(store: {
120
+ runId?: string;
121
+ runUrl?: string;
122
+ runPublicUrl?: string;
123
+ }, format?: string): string;
111
124
  /**
112
125
  * Calculate the approximate size of data in bytes (JSON stringified, UTF-8 encoded length).
113
126
  * @param {Object} data - Data to measure
@@ -15,6 +15,7 @@ exports.totalDuration = totalDuration;
15
15
  exports.plannedTestsLabel = plannedTestsLabel;
16
16
  exports.parsePipeOptions = parsePipeOptions;
17
17
  exports.formatFilterListIds = formatFilterListIds;
18
+ exports.formatRunOutput = formatRunOutput;
18
19
  exports.getObjectSize = getObjectSize;
19
20
  exports.splitTestsIntoChunks = splitTestsIntoChunks;
20
21
  const humanize_duration_1 = __importDefault(require("humanize-duration"));
@@ -302,6 +303,27 @@ function plannedTestsLabel(tests, testsCount) {
302
303
  return `**${suitesCount}** suites planned`;
303
304
  return `**${knownTestsCount}** tests and **${suitesCount}** suites planned`;
304
305
  }
306
+ /**
307
+ * Format the created run for machine-readable output of `start` and `run`.
308
+ * `json` prints an object with the run details, any other format prints the bare run id.
309
+ *
310
+ * @param {{runId?: string, runUrl?: string, runPublicUrl?: string}} store - Pipe store of the client.
311
+ * @param {string} [format] - Value of the CLI `--format` option.
312
+ * @returns {string} Empty string if there is no run id.
313
+ */
314
+ function formatRunOutput(store, format) {
315
+ const runId = store?.runId;
316
+ if (!runId)
317
+ return '';
318
+ if (format !== 'json')
319
+ return runId;
320
+ const output = { runId };
321
+ if (store.runUrl)
322
+ output.runUrl = store.runUrl;
323
+ if (store.runPublicUrl)
324
+ output.runPublicUrl = store.runPublicUrl;
325
+ return JSON.stringify(output);
326
+ }
305
327
 
306
328
  module.exports.updateFilterType = updateFilterType;
307
329
 
@@ -327,6 +349,8 @@ module.exports.parsePipeOptions = parsePipeOptions;
327
349
 
328
350
  module.exports.formatFilterListIds = formatFilterListIds;
329
351
 
352
+ module.exports.formatRunOutput = formatRunOutput;
353
+
330
354
  module.exports.getObjectSize = getObjectSize;
331
355
 
332
356
  module.exports.splitTestsIntoChunks = splitTestsIntoChunks;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testomatio/reporter",
3
- "version": "2.14.0",
3
+ "version": "2.15.0-beta.1-json-output",
4
4
  "description": "Testomatio Reporter Client",
5
5
  "engines": {
6
6
  "node": ">=18"
package/src/bin/cli.js CHANGED
@@ -16,7 +16,7 @@ import { filesize as prettyBytes } from 'filesize';
16
16
  import dotenv from 'dotenv';
17
17
  import Replay from '../replay.js';
18
18
  import { log } from '../utils/log.js';
19
- import { formatFilterListIds } from '../utils/pipe_utils.js';
19
+ import { formatFilterListIds, formatRunOutput } from '../utils/pipe_utils.js';
20
20
  import fs from 'fs';
21
21
  import path from 'path';
22
22
 
@@ -53,7 +53,7 @@ program
53
53
  .description('Start a new run and return its ID')
54
54
  .option('--kind <type>', 'Specify run type: automated, manual, mixed, or detect')
55
55
  .option('--filter <filter>', 'Scope the prepared run to tests matching the filter (no execution)')
56
- .option('--format <format>', 'Machine-readable output: print only the run id to stdout (e.g. --format id)')
56
+ .option('--format <format>', 'Machine-readable output: the run id (--format id) or run details (--format json)')
57
57
  .option('--warn', 'Exit 0 instead of 1 when the filter matches no tests (warn only)')
58
58
  .action(async opts => {
59
59
  cleanLatestRunId();
@@ -93,8 +93,8 @@ program
93
93
  const plannedTests = (client.pipeStore.preparedTestIds || []).map(id => ({ test_id: id, title: id }));
94
94
  await client.updateRunStatus('pending', { tests: plannedTests });
95
95
 
96
- // stdout carries ONLY the run id so it can be captured: RUN_ID=$(reporter start)
97
- console.log(runId);
96
+ // stdout carries ONLY the run data so it can be captured: RUN_ID=$(reporter start)
97
+ console.log(formatRunOutput({ ...client.pipeStore, runId }, opts.format));
98
98
  process.exit(0);
99
99
  });
100
100
 
@@ -129,7 +129,10 @@ program
129
129
  .argument('[command]', 'Test runner command')
130
130
  .option('--filter <filter>', 'Additional execution filter')
131
131
  .option('--filter-list <filter>', 'Get a list of all tests by filter before running')
132
- .option('--format <format>', 'Machine-readable output format for --filter-list (grep, json, newline, ids)')
132
+ .option(
133
+ '--format <format>',
134
+ 'Machine-readable output: test ids for --filter-list (grep, json, newline, ids), or the run created (id, json)',
135
+ )
133
136
  .option('--kind <type>', 'Specify run type: automated, manual, mixed, or detect')
134
137
  .option('--remote <profile>', 'Trigger run on the named Testomat.io CI profile instead of executing locally')
135
138
  .option(
@@ -230,6 +233,8 @@ program
230
233
 
231
234
  log.info(`🚀 CI build triggered on profile ${pc.cyan(opts.remote)}`);
232
235
  log.info(`📊 Report URL: ${pc.magenta(client.pipeStore.runUrl)}`);
236
+ const remoteOutput = formatRunOutput(client.pipeStore, opts.format);
237
+ if (opts.format && remoteOutput) console.log(remoteOutput);
233
238
  return process.exit(0);
234
239
  }
235
240
 
@@ -252,6 +257,8 @@ program
252
257
  log.info( `No command passed, so you need to run tests yourself:`);
253
258
  log.info( `TESTOMATIO_RUN=${runId} <command>`);
254
259
  }
260
+ const runOutput = formatRunOutput({ ...client.pipeStore, runId }, opts.format);
261
+ if (opts.format && runOutput) console.log(runOutput);
255
262
  } else {
256
263
  log.info( '⚠️ No API key provided. Cannot create run without TESTOMATIO key.');
257
264
  process.exit(1);
@@ -288,7 +295,11 @@ program
288
295
  }
289
296
 
290
297
  if (apiKey) {
291
- await client.createRun(createRunParams).then(runTests);
298
+ await client.createRun(createRunParams);
299
+ // the runner inherits stdout, so the run data is printed first, on its own line
300
+ const createdOutput = formatRunOutput(client.pipeStore, opts.format);
301
+ if (opts.format && createdOutput) console.log(createdOutput);
302
+ await runTests();
292
303
  } else {
293
304
  await runTests();
294
305
  }
@@ -304,6 +304,27 @@ function plannedTestsLabel(tests, testsCount) {
304
304
  return `**${knownTestsCount}** tests and **${suitesCount}** suites planned`;
305
305
  }
306
306
 
307
+ /**
308
+ * Format the created run for machine-readable output of `start` and `run`.
309
+ * `json` prints an object with the run details, any other format prints the bare run id.
310
+ *
311
+ * @param {{runId?: string, runUrl?: string, runPublicUrl?: string}} store - Pipe store of the client.
312
+ * @param {string} [format] - Value of the CLI `--format` option.
313
+ * @returns {string} Empty string if there is no run id.
314
+ */
315
+ function formatRunOutput(store, format) {
316
+ const runId = store?.runId;
317
+ if (!runId) return '';
318
+
319
+ if (format !== 'json') return runId;
320
+
321
+ const output = { runId };
322
+ if (store.runUrl) output.runUrl = store.runUrl;
323
+ if (store.runPublicUrl) output.runPublicUrl = store.runPublicUrl;
324
+
325
+ return JSON.stringify(output);
326
+ }
327
+
307
328
  export {
308
329
  updateFilterType,
309
330
  parseFilterParams,
@@ -317,6 +338,7 @@ export {
317
338
  plannedTestsLabel,
318
339
  parsePipeOptions,
319
340
  formatFilterListIds,
341
+ formatRunOutput,
320
342
  getObjectSize,
321
343
  splitTestsIntoChunks,
322
344
  };