@devicecloud.dev/dcd 3.6.2 → 3.6.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.
@@ -62,6 +62,7 @@ export default class Cloud extends Command {
62
62
  'runner-type': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
63
63
  report: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
64
64
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
65
+ 'json-file': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
65
66
  };
66
67
  static enableJsonFlag: boolean;
67
68
  private versionCheck;
@@ -6,6 +6,7 @@ const core_1 = require("@oclif/core");
6
6
  const cli_ux_1 = require("@oclif/core/lib/cli-ux");
7
7
  const errors_1 = require("@oclif/core/lib/errors");
8
8
  const path = require("node:path");
9
+ const fs = require("node:fs");
9
10
  const constants_1 = require("../constants");
10
11
  const methods_1 = require("../methods");
11
12
  const plan_1 = require("../plan");
@@ -46,6 +47,10 @@ process.on('warning', (warning) => {
46
47
  return;
47
48
  }
48
49
  });
50
+ const escapeShellValue = (value) => {
51
+ // Escape special characters that could cause shell interpretation issues
52
+ return value.replace(/(["\\'$`!\s\[\]{}()&|;<>*?#^~])/g, '\\$1');
53
+ };
49
54
  class Cloud extends core_1.Command {
50
55
  static args = {
51
56
  firstFile: core_1.Args.string({
@@ -80,8 +85,25 @@ class Cloud extends core_1.Command {
80
85
  let output = null;
81
86
  try {
82
87
  const { args, flags, raw } = await this.parse(Cloud);
88
+ // // Log the full command that was run
89
+ // const commandParts = ['dcd cloud'];
90
+ // if (args.firstFile) commandParts.push(escapeShellValue(args.firstFile));
91
+ // if (args.secondFile) commandParts.push(escapeShellValue(args.secondFile));
92
+ // for (const [key, value] of Object.entries(flags)) {
93
+ // if (value && value.toString().length > 0) {
94
+ // if (typeof value === 'boolean') {
95
+ // commandParts.push(`--${key}`);
96
+ // } else if (Array.isArray(value)) {
97
+ // commandParts.push(
98
+ // `--${key}=${value.map((v) => escapeShellValue(v)).join(',')}`,
99
+ // );
100
+ // } else {
101
+ // commandParts.push(`--${key}=${escapeShellValue(value.toString())}`);
102
+ // }
103
+ // }
104
+ // }
105
+ // this.log(`\nCommand ran: ${commandParts.join(' ')}\n`);
83
106
  let { 'additional-app-binary-ids': nonFlatAdditionalAppBinaryIds, 'additional-app-files': nonFlatAdditionalAppFiles, 'android-api-level': androidApiLevel, 'android-device': androidDevice, apiKey: apiKeyFlag, apiUrl, 'app-binary-id': appBinaryId, 'app-file': appFile, 'artifacts-path': artifactsPath, async, config: configFile, 'device-locale': deviceLocale, 'download-artifacts': downloadArtifacts, env, 'exclude-flows': excludeFlows, 'exclude-tags': excludeTags, flows, 'google-play': googlePlay, 'include-tags': includeTags, 'ignore-sha-check': ignoreShaCheck, 'ios-device': iOSDevice, 'ios-version': iOSVersion, 'maestro-version': maestroVersion, name, orientation, quiet, retry, report, 'runner-type': runnerType, 'x86-arch': x86Arch, json, ...rest } = flags;
84
- // If in JSON mode, temporarily intercept stdout to suppress the warning
85
107
  if (json) {
86
108
  const originalStdoutWrite = process.stdout.write;
87
109
  process.stdout.write = function (chunk, encodingOrCallback, cb) {
@@ -327,16 +349,24 @@ class Cloud extends core_1.Command {
327
349
  this.log(`Your upload ID is: ${results[0].test_upload_id}`);
328
350
  this.log(`Poll upload status using: dcd status --api-key ... --upload-id ${results[0].test_upload_id}`);
329
351
  if (async) {
352
+ const jsonOutput = {
353
+ uploadId: results[0].test_upload_id,
354
+ consoleUrl: url,
355
+ status: 'PENDING',
356
+ tests: results.map((r) => ({
357
+ name: r.test_file_name,
358
+ status: r.status,
359
+ })),
360
+ };
361
+ if (flags['json-file']) {
362
+ const jsonFilePath = name
363
+ ? `${name}_dcd.json`
364
+ : `${results[0].test_upload_id}_dcd.json`;
365
+ fs.writeFileSync(jsonFilePath, JSON.stringify(jsonOutput, null, 2));
366
+ this.log(`JSON output written to: ${path.resolve(jsonFilePath)}`);
367
+ }
330
368
  if (json) {
331
- return {
332
- uploadId: results[0].test_upload_id,
333
- consoleUrl: url,
334
- status: 'PENDING',
335
- tests: results.map((r) => ({
336
- name: r.test_file_name,
337
- status: r.status,
338
- })),
339
- };
369
+ return jsonOutput;
340
370
  }
341
371
  this.log('Not waiting for results as async flag is set to true');
342
372
  return;
@@ -403,30 +433,46 @@ class Cloud extends core_1.Command {
403
433
  return result.id === Math.max(...tries.map((t) => t.id));
404
434
  });
405
435
  if (resultsWithoutEarlierTries.some((result) => result.status === 'FAILED')) {
436
+ const jsonOutput = {
437
+ uploadId: results[0].test_upload_id,
438
+ consoleUrl: url,
439
+ status: 'FAILED',
440
+ tests: resultsWithoutEarlierTries.map((r) => ({
441
+ name: r.test_file_name,
442
+ status: r.status,
443
+ })),
444
+ };
445
+ if (flags['json-file']) {
446
+ const jsonFilePath = name
447
+ ? `${name}_dcd.json`
448
+ : `${results[0].test_upload_id}_dcd.json`;
449
+ fs.writeFileSync(jsonFilePath, JSON.stringify(jsonOutput, null, 2));
450
+ this.log(`JSON output written to: ${path.resolve(jsonFilePath)}`);
451
+ }
406
452
  if (json) {
407
- output = {
408
- uploadId: results[0].test_upload_id,
409
- consoleUrl: url,
410
- status: 'FAILED',
411
- tests: resultsWithoutEarlierTries.map((r) => ({
412
- name: r.test_file_name,
413
- status: r.status,
414
- })),
415
- };
453
+ output = jsonOutput;
416
454
  }
417
455
  reject(new Error('RUN_FAILED'));
418
456
  }
419
457
  else {
458
+ const jsonOutput = {
459
+ uploadId: results[0].test_upload_id,
460
+ consoleUrl: url,
461
+ status: 'PASSED',
462
+ tests: resultsWithoutEarlierTries.map((r) => ({
463
+ name: r.test_file_name,
464
+ status: r.status,
465
+ })),
466
+ };
467
+ if (flags['json-file']) {
468
+ const jsonFilePath = name
469
+ ? `${name}_dcd.json`
470
+ : `${results[0].test_upload_id}_dcd.json`;
471
+ fs.writeFileSync(jsonFilePath, JSON.stringify(jsonOutput, null, 2));
472
+ this.log(`JSON output written to: ${path.resolve(jsonFilePath)}`);
473
+ }
420
474
  if (json) {
421
- output = {
422
- uploadId: results[0].test_upload_id,
423
- consoleUrl: url,
424
- status: 'PASSED',
425
- tests: resultsWithoutEarlierTries.map((r) => ({
426
- name: r.test_file_name,
427
- status: r.status,
428
- })),
429
- };
475
+ output = jsonOutput;
430
476
  }
431
477
  }
432
478
  sequentialPollFaillures = 0;
@@ -32,6 +32,7 @@ export declare const flags: {
32
32
  'runner-type': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
33
33
  report: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
34
34
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
35
+ 'json-file': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
35
36
  };
36
37
  export declare const iOSCompatibilityLookup: {
37
38
  [k in EiOSDevices]: string[];
package/dist/constants.js CHANGED
@@ -185,6 +185,10 @@ exports.flags = {
185
185
  json: core_1.Flags.boolean({
186
186
  description: 'Output results in JSON format - note: will always provide exit code 0',
187
187
  }),
188
+ 'json-file': core_1.Flags.boolean({
189
+ description: 'Write JSON output to a file with name <run_name>_dcd.json or <upload_id>_dcd.json if no name is provided',
190
+ required: false,
191
+ }),
188
192
  };
189
193
  exports.iOSCompatibilityLookup = {
190
194
  'ipad-pro-6th-gen': ['16', '17', '18'],
@@ -348,6 +348,13 @@
348
348
  "html"
349
349
  ],
350
350
  "type": "option"
351
+ },
352
+ "json-file": {
353
+ "description": "Write JSON output to a file with name <run_name>_dcd.json or <upload_id>_dcd.json if no name is provided",
354
+ "name": "json-file",
355
+ "required": false,
356
+ "allowNo": false,
357
+ "type": "boolean"
351
358
  }
352
359
  },
353
360
  "hasDynamicHelp": false,
@@ -507,5 +514,5 @@
507
514
  ]
508
515
  }
509
516
  },
510
- "version": "3.6.2"
517
+ "version": "3.6.4"
511
518
  }
package/package.json CHANGED
@@ -79,7 +79,7 @@
79
79
  "prepare": "yarn build",
80
80
  "version": "oclif readme && git add README.md"
81
81
  },
82
- "version": "3.6.2",
82
+ "version": "3.6.4",
83
83
  "bugs": {
84
84
  "url": "https://discord.gg/gm3mJwcNw8"
85
85
  },