@devicecloud.dev/dcd 3.6.1 → 3.6.3
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/commands/cloud.d.ts +2 -0
- package/dist/commands/cloud.js +77 -28
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +8 -0
- package/oclif.manifest.json +14 -1
- package/package.json +1 -1
package/dist/commands/cloud.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export default class Cloud extends Command {
|
|
|
34
34
|
'additional-app-files': import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
35
35
|
'android-api-level': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
36
36
|
'android-device': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
37
|
+
'skip-chrome-onboarding': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
37
38
|
apiKey: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
38
39
|
apiUrl: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
39
40
|
'app-binary-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
@@ -61,6 +62,7 @@ export default class Cloud extends Command {
|
|
|
61
62
|
'runner-type': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
62
63
|
report: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
63
64
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
65
|
+
'json-file': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
64
66
|
};
|
|
65
67
|
static enableJsonFlag: boolean;
|
|
66
68
|
private versionCheck;
|
package/dist/commands/cloud.js
CHANGED
|
@@ -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,27 @@ 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)
|
|
91
|
+
commandParts.push(escapeShellValue(args.firstFile));
|
|
92
|
+
if (args.secondFile)
|
|
93
|
+
commandParts.push(escapeShellValue(args.secondFile));
|
|
94
|
+
for (const [key, value] of Object.entries(flags)) {
|
|
95
|
+
if (value && value.toString().length > 0) {
|
|
96
|
+
if (typeof value === 'boolean') {
|
|
97
|
+
commandParts.push(`--${key}`);
|
|
98
|
+
}
|
|
99
|
+
else if (Array.isArray(value)) {
|
|
100
|
+
commandParts.push(`--${key}=${value.map((v) => escapeShellValue(v)).join(',')}`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
commandParts.push(`--${key}=${escapeShellValue(value.toString())}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
this.log(`\nCommand ran: ${commandParts.join(' ')}\n`);
|
|
83
108
|
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
109
|
if (json) {
|
|
86
110
|
const originalStdoutWrite = process.stdout.write;
|
|
87
111
|
process.stdout.write = function (chunk, encodingOrCallback, cb) {
|
|
@@ -281,6 +305,7 @@ class Cloud extends core_1.Command {
|
|
|
281
305
|
raw: JSON.stringify(raw),
|
|
282
306
|
uploadedBinaryIds,
|
|
283
307
|
version: this.config.version,
|
|
308
|
+
skipChromeOnboarding: flags['skip-chrome-onboarding'],
|
|
284
309
|
};
|
|
285
310
|
if (finalAdditionalBinaryIds?.length > 0) {
|
|
286
311
|
config.additionalAppBinaryIds = finalAdditionalBinaryIds;
|
|
@@ -326,16 +351,24 @@ class Cloud extends core_1.Command {
|
|
|
326
351
|
this.log(`Your upload ID is: ${results[0].test_upload_id}`);
|
|
327
352
|
this.log(`Poll upload status using: dcd status --api-key ... --upload-id ${results[0].test_upload_id}`);
|
|
328
353
|
if (async) {
|
|
354
|
+
const jsonOutput = {
|
|
355
|
+
uploadId: results[0].test_upload_id,
|
|
356
|
+
consoleUrl: url,
|
|
357
|
+
status: 'PENDING',
|
|
358
|
+
tests: results.map((r) => ({
|
|
359
|
+
name: r.test_file_name,
|
|
360
|
+
status: r.status,
|
|
361
|
+
})),
|
|
362
|
+
};
|
|
363
|
+
if (flags['json-file']) {
|
|
364
|
+
const jsonFilePath = name
|
|
365
|
+
? `${name}_dcd.json`
|
|
366
|
+
: `${results[0].test_upload_id}_dcd.json`;
|
|
367
|
+
fs.writeFileSync(jsonFilePath, JSON.stringify(jsonOutput, null, 2));
|
|
368
|
+
this.log(`JSON output written to: ${path.resolve(jsonFilePath)}`);
|
|
369
|
+
}
|
|
329
370
|
if (json) {
|
|
330
|
-
return
|
|
331
|
-
uploadId: results[0].test_upload_id,
|
|
332
|
-
consoleUrl: url,
|
|
333
|
-
status: 'PENDING',
|
|
334
|
-
tests: results.map((r) => ({
|
|
335
|
-
name: r.test_file_name,
|
|
336
|
-
status: r.status,
|
|
337
|
-
})),
|
|
338
|
-
};
|
|
371
|
+
return jsonOutput;
|
|
339
372
|
}
|
|
340
373
|
this.log('Not waiting for results as async flag is set to true');
|
|
341
374
|
return;
|
|
@@ -402,30 +435,46 @@ class Cloud extends core_1.Command {
|
|
|
402
435
|
return result.id === Math.max(...tries.map((t) => t.id));
|
|
403
436
|
});
|
|
404
437
|
if (resultsWithoutEarlierTries.some((result) => result.status === 'FAILED')) {
|
|
438
|
+
const jsonOutput = {
|
|
439
|
+
uploadId: results[0].test_upload_id,
|
|
440
|
+
consoleUrl: url,
|
|
441
|
+
status: 'FAILED',
|
|
442
|
+
tests: resultsWithoutEarlierTries.map((r) => ({
|
|
443
|
+
name: r.test_file_name,
|
|
444
|
+
status: r.status,
|
|
445
|
+
})),
|
|
446
|
+
};
|
|
447
|
+
if (flags['json-file']) {
|
|
448
|
+
const jsonFilePath = name
|
|
449
|
+
? `${name}_dcd.json`
|
|
450
|
+
: `${results[0].test_upload_id}_dcd.json`;
|
|
451
|
+
fs.writeFileSync(jsonFilePath, JSON.stringify(jsonOutput, null, 2));
|
|
452
|
+
this.log(`JSON output written to: ${path.resolve(jsonFilePath)}`);
|
|
453
|
+
}
|
|
405
454
|
if (json) {
|
|
406
|
-
output =
|
|
407
|
-
uploadId: results[0].test_upload_id,
|
|
408
|
-
consoleUrl: url,
|
|
409
|
-
status: 'FAILED',
|
|
410
|
-
tests: resultsWithoutEarlierTries.map((r) => ({
|
|
411
|
-
name: r.test_file_name,
|
|
412
|
-
status: r.status,
|
|
413
|
-
})),
|
|
414
|
-
};
|
|
455
|
+
output = jsonOutput;
|
|
415
456
|
}
|
|
416
457
|
reject(new Error('RUN_FAILED'));
|
|
417
458
|
}
|
|
418
459
|
else {
|
|
460
|
+
const jsonOutput = {
|
|
461
|
+
uploadId: results[0].test_upload_id,
|
|
462
|
+
consoleUrl: url,
|
|
463
|
+
status: 'PASSED',
|
|
464
|
+
tests: resultsWithoutEarlierTries.map((r) => ({
|
|
465
|
+
name: r.test_file_name,
|
|
466
|
+
status: r.status,
|
|
467
|
+
})),
|
|
468
|
+
};
|
|
469
|
+
if (flags['json-file']) {
|
|
470
|
+
const jsonFilePath = name
|
|
471
|
+
? `${name}_dcd.json`
|
|
472
|
+
: `${results[0].test_upload_id}_dcd.json`;
|
|
473
|
+
fs.writeFileSync(jsonFilePath, JSON.stringify(jsonOutput, null, 2));
|
|
474
|
+
this.log(`JSON output written to: ${path.resolve(jsonFilePath)}`);
|
|
475
|
+
}
|
|
419
476
|
if (json) {
|
|
420
|
-
output =
|
|
421
|
-
uploadId: results[0].test_upload_id,
|
|
422
|
-
consoleUrl: url,
|
|
423
|
-
status: 'PASSED',
|
|
424
|
-
tests: resultsWithoutEarlierTries.map((r) => ({
|
|
425
|
-
name: r.test_file_name,
|
|
426
|
-
status: r.status,
|
|
427
|
-
})),
|
|
428
|
-
};
|
|
477
|
+
output = jsonOutput;
|
|
429
478
|
}
|
|
430
479
|
}
|
|
431
480
|
sequentialPollFaillures = 0;
|
package/dist/constants.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export declare const flags: {
|
|
|
4
4
|
'additional-app-files': import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
5
5
|
'android-api-level': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
6
6
|
'android-device': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
'skip-chrome-onboarding': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
7
8
|
apiKey: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
9
|
apiUrl: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
10
|
'app-binary-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
@@ -31,6 +32,7 @@ export declare const flags: {
|
|
|
31
32
|
'runner-type': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
32
33
|
report: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
33
34
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
35
|
+
'json-file': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
34
36
|
};
|
|
35
37
|
export declare const iOSCompatibilityLookup: {
|
|
36
38
|
[k in EiOSDevices]: string[];
|
package/dist/constants.js
CHANGED
|
@@ -31,6 +31,10 @@ exports.flags = {
|
|
|
31
31
|
'generic-tablet',
|
|
32
32
|
],
|
|
33
33
|
}),
|
|
34
|
+
'skip-chrome-onboarding': core_1.Flags.boolean({
|
|
35
|
+
description: '[Android only] Skip Chrome browser onboarding screens when running tests',
|
|
36
|
+
default: false,
|
|
37
|
+
}),
|
|
34
38
|
apiKey: core_1.Flags.string({
|
|
35
39
|
aliases: ['api-key'],
|
|
36
40
|
description: 'API key for devicecloud.dev (find this in the console UI). You can also set the DEVICE_CLOUD_API_KEY environment variable.',
|
|
@@ -181,6 +185,10 @@ exports.flags = {
|
|
|
181
185
|
json: core_1.Flags.boolean({
|
|
182
186
|
description: 'Output results in JSON format - note: will always provide exit code 0',
|
|
183
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
|
+
}),
|
|
184
192
|
};
|
|
185
193
|
exports.iOSCompatibilityLookup = {
|
|
186
194
|
'ipad-pro-6th-gen': ['16', '17', '18'],
|
package/oclif.manifest.json
CHANGED
|
@@ -71,6 +71,12 @@
|
|
|
71
71
|
],
|
|
72
72
|
"type": "option"
|
|
73
73
|
},
|
|
74
|
+
"skip-chrome-onboarding": {
|
|
75
|
+
"description": "[Android only] Skip Chrome browser onboarding screens when running tests",
|
|
76
|
+
"name": "skip-chrome-onboarding",
|
|
77
|
+
"allowNo": false,
|
|
78
|
+
"type": "boolean"
|
|
79
|
+
},
|
|
74
80
|
"apiKey": {
|
|
75
81
|
"aliases": [
|
|
76
82
|
"api-key"
|
|
@@ -342,6 +348,13 @@
|
|
|
342
348
|
"html"
|
|
343
349
|
],
|
|
344
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"
|
|
345
358
|
}
|
|
346
359
|
},
|
|
347
360
|
"hasDynamicHelp": false,
|
|
@@ -501,5 +514,5 @@
|
|
|
501
514
|
]
|
|
502
515
|
}
|
|
503
516
|
},
|
|
504
|
-
"version": "3.6.
|
|
517
|
+
"version": "3.6.3"
|
|
505
518
|
}
|