@devicecloud.dev/dcd 3.7.3 → 3.7.5
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 +1 -0
- package/dist/commands/cloud.js +8 -9
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +20 -4
- package/dist/plan.d.ts +1 -0
- package/dist/plan.js +10 -0
- package/oclif.manifest.json +14 -3
- package/package.json +1 -1
package/dist/commands/cloud.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export default class Cloud extends Command {
|
|
|
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
37
|
'skip-chrome-onboarding': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
38
|
+
'show-crosshairs': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
38
39
|
apiKey: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
39
40
|
apiUrl: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
40
41
|
'app-binary-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
package/dist/commands/cloud.js
CHANGED
|
@@ -100,7 +100,7 @@ class Cloud extends core_1.Command {
|
|
|
100
100
|
let jsonFile = false;
|
|
101
101
|
try {
|
|
102
102
|
const { args, flags, raw } = await this.parse(Cloud);
|
|
103
|
-
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, debug, '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, mitmHost, mitmPath, 'moropo-v1-api-key': moropoApiKey, 'dry-run': dryRun, ...rest } = flags;
|
|
103
|
+
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, debug, '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, 'show-crosshairs': showCrosshairs, 'x86-arch': x86Arch, json, mitmHost, mitmPath, 'moropo-v1-api-key': moropoApiKey, 'dry-run': dryRun, ...rest } = flags;
|
|
104
104
|
// Store debug flag for use in catch block
|
|
105
105
|
debugFlag = debug === true;
|
|
106
106
|
jsonFile = flags['json-file'] === true;
|
|
@@ -187,7 +187,7 @@ class Cloud extends core_1.Command {
|
|
|
187
187
|
fileStream.write(value);
|
|
188
188
|
}
|
|
189
189
|
fileStream.end();
|
|
190
|
-
await new Promise((resolve) => fileStream.on('finish', resolve));
|
|
190
|
+
await new Promise((resolve) => fileStream.on('finish', () => resolve()));
|
|
191
191
|
if (!quiet && !json) {
|
|
192
192
|
core_1.ux.action.status = 'Extracting tests...';
|
|
193
193
|
}
|
|
@@ -229,12 +229,6 @@ class Cloud extends core_1.Command {
|
|
|
229
229
|
this.log(`DEBUG: API URL: ${apiUrl}`);
|
|
230
230
|
this.log(`DEBUG: API Key provided: ${apiKey ? 'Yes' : 'No'}`);
|
|
231
231
|
}
|
|
232
|
-
const [maestroMajorString, maestroMinorString] = maestroVersion.split('.');
|
|
233
|
-
if (report === 'html' &&
|
|
234
|
-
maestroMajorString === '1' &&
|
|
235
|
-
Number(maestroMinorString) < 39) {
|
|
236
|
-
throw new Error('HTML report is not supported for Maestro 1.38 and below. Please use --maestro-version flag to specify a newer runtime.');
|
|
237
|
-
}
|
|
238
232
|
if (retry && retry > 2) {
|
|
239
233
|
this.log("Retries are now free of charge but limited to 2. If you're test is still failing after 2 retries, please ask for help on Discord.");
|
|
240
234
|
flags.retry = 2;
|
|
@@ -333,7 +327,7 @@ class Cloud extends core_1.Command {
|
|
|
333
327
|
}
|
|
334
328
|
throw error;
|
|
335
329
|
}
|
|
336
|
-
const { allExcludeTags, allIncludeTags, flowsToRun: testFileNames, referencedFiles, sequence, workspaceConfig, } = executionPlan;
|
|
330
|
+
const { allExcludeTags, allIncludeTags, flowsToRun: testFileNames, flowMetadata, referencedFiles, sequence, workspaceConfig, } = executionPlan;
|
|
337
331
|
if (debug) {
|
|
338
332
|
this.log(`DEBUG: All include tags: ${allIncludeTags?.join(', ') || 'none'}`);
|
|
339
333
|
this.log(`DEBUG: All exclude tags: ${allExcludeTags?.join(', ') || 'none'}`);
|
|
@@ -473,6 +467,10 @@ class Cloud extends core_1.Command {
|
|
|
473
467
|
testFormData.set('file', blob, 'flowFile.zip');
|
|
474
468
|
testFormData.set('appBinaryId', finalBinaryId);
|
|
475
469
|
testFormData.set('testFileNames', JSON.stringify(testFileNames.map((t) => t.replaceAll(commonRoot, '.').split(path.sep).join('/'))));
|
|
470
|
+
testFormData.set('flowMetadata', JSON.stringify(Object.fromEntries(Object.entries(flowMetadata).map(([key, value]) => [
|
|
471
|
+
key.replaceAll(commonRoot, '.').split(path.sep).join('/'),
|
|
472
|
+
value,
|
|
473
|
+
]))));
|
|
476
474
|
testFormData.set('sequentialFlows', JSON.stringify(sequentialFlows.map((t) => t.replaceAll(commonRoot, '.').split(path.sep).join('/'))));
|
|
477
475
|
testFormData.set('env', JSON.stringify(envObject));
|
|
478
476
|
testFormData.set('googlePlay', googlePlay ? 'true' : 'false');
|
|
@@ -490,6 +488,7 @@ class Cloud extends core_1.Command {
|
|
|
490
488
|
uploadedBinaryIds,
|
|
491
489
|
version: this.config.version,
|
|
492
490
|
skipChromeOnboarding: flags['skip-chrome-onboarding'],
|
|
491
|
+
showCrosshairs: flags['show-crosshairs'],
|
|
493
492
|
mitmHost,
|
|
494
493
|
mitmPath,
|
|
495
494
|
};
|
package/dist/constants.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const flags: {
|
|
|
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
7
|
'skip-chrome-onboarding': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
'show-crosshairs': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
9
|
apiKey: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
10
|
apiUrl: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
11
|
'app-binary-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
package/dist/constants.js
CHANGED
|
@@ -35,6 +35,10 @@ exports.flags = {
|
|
|
35
35
|
description: '[Android only] Skip Chrome browser onboarding screens when running tests',
|
|
36
36
|
default: false,
|
|
37
37
|
}),
|
|
38
|
+
'show-crosshairs': core_1.Flags.boolean({
|
|
39
|
+
description: '[Android only] Display crosshairs for screen interactions during test execution',
|
|
40
|
+
default: false,
|
|
41
|
+
}),
|
|
38
42
|
apiKey: core_1.Flags.string({
|
|
39
43
|
aliases: ['api-key'],
|
|
40
44
|
description: 'API key for devicecloud.dev (find this in the console UI). You can also set the DEVICE_CLOUD_API_KEY environment variable.',
|
|
@@ -145,7 +149,19 @@ exports.flags = {
|
|
|
145
149
|
aliases: ['maestroVersion'],
|
|
146
150
|
default: '1.39.5',
|
|
147
151
|
description: 'Maestro version to run your flow against',
|
|
148
|
-
options: [
|
|
152
|
+
options: [
|
|
153
|
+
'1.39.0',
|
|
154
|
+
'1.39.1',
|
|
155
|
+
'1.39.2',
|
|
156
|
+
'1.39.4',
|
|
157
|
+
'1.39.5',
|
|
158
|
+
'1.39.7',
|
|
159
|
+
'1.40.0',
|
|
160
|
+
'1.40.1',
|
|
161
|
+
'1.40.2',
|
|
162
|
+
'1.40.3',
|
|
163
|
+
'1.41.0',
|
|
164
|
+
],
|
|
149
165
|
}),
|
|
150
166
|
mitmHost: core_1.Flags.string({
|
|
151
167
|
description: 'used for mitmproxy support, enterprise only, contact support if interested',
|
|
@@ -183,7 +199,7 @@ exports.flags = {
|
|
|
183
199
|
description: 'Output results in JSON format - note: will always provide exit code 0',
|
|
184
200
|
}),
|
|
185
201
|
'json-file': core_1.Flags.boolean({
|
|
186
|
-
description: 'Write JSON output to a file
|
|
202
|
+
description: 'Write JSON output to a file. If you supply the --name flag, file <name>_dcd.json will be written, otherwise file <upload_id>_dcd.json will be written - note: will always exit with code 0',
|
|
187
203
|
required: false,
|
|
188
204
|
}),
|
|
189
205
|
'moropo-v1-api-key': core_1.Flags.string({
|
|
@@ -218,9 +234,9 @@ exports.AndroidCompatibilityLookup = {
|
|
|
218
234
|
'pixel-7-pro': ['33', '34', '35'],
|
|
219
235
|
};
|
|
220
236
|
exports.AndroidCompatibilityLookupPlay = {
|
|
221
|
-
'generic-tablet': [
|
|
237
|
+
'generic-tablet': [],
|
|
222
238
|
'pixel-6': ['34', '35'],
|
|
223
239
|
'pixel-6-pro': [],
|
|
224
240
|
'pixel-7': ['34', '35'],
|
|
225
|
-
'pixel-7-pro': [
|
|
241
|
+
'pixel-7-pro': [],
|
|
226
242
|
};
|
package/dist/plan.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ interface IExecutionPlan {
|
|
|
17
17
|
allIncludeTags?: null | string[];
|
|
18
18
|
flowsToRun: string[];
|
|
19
19
|
referencedFiles: string[];
|
|
20
|
+
flowMetadata: Record<string, Record<string, unknown>>;
|
|
20
21
|
sequence?: IFlowSequence | null;
|
|
21
22
|
totalFlowFiles: number;
|
|
22
23
|
workspaceConfig?: IWorkspaceConfig;
|
package/dist/plan.js
CHANGED
|
@@ -54,6 +54,7 @@ function getWorkspaceConfig(input, unfilteredFlowFiles) {
|
|
|
54
54
|
}
|
|
55
55
|
async function plan(input, includeTags, excludeTags, excludeFlows, configFile) {
|
|
56
56
|
const normalizedInput = path.normalize(input);
|
|
57
|
+
const flowMetadata = {};
|
|
57
58
|
if (!fs.existsSync(normalizedInput)) {
|
|
58
59
|
throw new Error(`Flow path does not exist: ${path.resolve(normalizedInput)}`);
|
|
59
60
|
}
|
|
@@ -62,10 +63,15 @@ async function plan(input, includeTags, excludeTags, excludeFlows, configFile) {
|
|
|
62
63
|
normalizedInput.endsWith('config.yml')) {
|
|
63
64
|
throw new Error('If using config.yaml, pass the workspace folder path, not the config file or a custom path via --config');
|
|
64
65
|
}
|
|
66
|
+
const { config } = (0, planMethods_1.readTestYamlFileAsJson)(normalizedInput);
|
|
67
|
+
if (config) {
|
|
68
|
+
flowMetadata[normalizedInput] = config;
|
|
69
|
+
}
|
|
65
70
|
const checkedDependancies = await checkDependencies(normalizedInput);
|
|
66
71
|
return {
|
|
67
72
|
flowsToRun: [normalizedInput],
|
|
68
73
|
referencedFiles: [...new Set(checkedDependancies)],
|
|
74
|
+
flowMetadata,
|
|
69
75
|
totalFlowFiles: 1,
|
|
70
76
|
};
|
|
71
77
|
}
|
|
@@ -129,6 +135,9 @@ async function plan(input, includeTags, excludeTags, excludeFlows, configFile) {
|
|
|
129
135
|
const allFlows = unfilteredFlowFiles.filter((filePath) => {
|
|
130
136
|
const config = configPerFlowFile[filePath];
|
|
131
137
|
const tags = config?.tags || [];
|
|
138
|
+
if (config) {
|
|
139
|
+
flowMetadata[filePath] = config;
|
|
140
|
+
}
|
|
132
141
|
return ((allIncludeTags.length === 0 ||
|
|
133
142
|
tags.some((tag) => allIncludeTags.includes(tag))) &&
|
|
134
143
|
(allExcludeTags.length === 0 ||
|
|
@@ -158,6 +167,7 @@ async function plan(input, includeTags, excludeTags, excludeFlows, configFile) {
|
|
|
158
167
|
allIncludeTags,
|
|
159
168
|
flowsToRun: normalFlows,
|
|
160
169
|
referencedFiles: [...new Set(allFiles)],
|
|
170
|
+
flowMetadata,
|
|
161
171
|
sequence: {
|
|
162
172
|
continueOnFailure: workspaceConfig.executionOrder?.continueOnFailure,
|
|
163
173
|
flows: flowsToRunInSequence,
|
package/oclif.manifest.json
CHANGED
|
@@ -77,6 +77,12 @@
|
|
|
77
77
|
"allowNo": false,
|
|
78
78
|
"type": "boolean"
|
|
79
79
|
},
|
|
80
|
+
"show-crosshairs": {
|
|
81
|
+
"description": "[Android only] Display crosshairs for screen interactions during test execution",
|
|
82
|
+
"name": "show-crosshairs",
|
|
83
|
+
"allowNo": false,
|
|
84
|
+
"type": "boolean"
|
|
85
|
+
},
|
|
80
86
|
"apiKey": {
|
|
81
87
|
"aliases": [
|
|
82
88
|
"api-key"
|
|
@@ -283,7 +289,12 @@
|
|
|
283
289
|
"1.39.2",
|
|
284
290
|
"1.39.4",
|
|
285
291
|
"1.39.5",
|
|
286
|
-
"1.39.7"
|
|
292
|
+
"1.39.7",
|
|
293
|
+
"1.40.0",
|
|
294
|
+
"1.40.1",
|
|
295
|
+
"1.40.2",
|
|
296
|
+
"1.40.3",
|
|
297
|
+
"1.41.0"
|
|
287
298
|
],
|
|
288
299
|
"type": "option"
|
|
289
300
|
},
|
|
@@ -366,7 +377,7 @@
|
|
|
366
377
|
"type": "option"
|
|
367
378
|
},
|
|
368
379
|
"json-file": {
|
|
369
|
-
"description": "Write JSON output to a file
|
|
380
|
+
"description": "Write JSON output to a file. If you supply the --name flag, file <name>_dcd.json will be written, otherwise file <upload_id>_dcd.json will be written - note: will always exit with code 0",
|
|
370
381
|
"name": "json-file",
|
|
371
382
|
"required": false,
|
|
372
383
|
"allowNo": false,
|
|
@@ -544,5 +555,5 @@
|
|
|
544
555
|
]
|
|
545
556
|
}
|
|
546
557
|
},
|
|
547
|
-
"version": "3.7.
|
|
558
|
+
"version": "3.7.5"
|
|
548
559
|
}
|