@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.
@@ -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>;
@@ -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
  };
@@ -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: ['1.39.0', '1.39.1', '1.39.2', '1.39.4', '1.39.5', '1.39.7'],
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 with name <run_name>_dcd.json or <upload_id>_dcd.json if no name is provided - note: will always provide exit code 0',
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': ['33', '34', '35'],
237
+ 'generic-tablet': [],
222
238
  'pixel-6': ['34', '35'],
223
239
  'pixel-6-pro': [],
224
240
  'pixel-7': ['34', '35'],
225
- 'pixel-7-pro': ['34', '35'],
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,
@@ -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 with name <run_name>_dcd.json or <upload_id>_dcd.json if no name is provided - note: will always provide exit code 0",
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.3"
558
+ "version": "3.7.5"
548
559
  }
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.7.3",
82
+ "version": "3.7.5",
83
83
  "bugs": {
84
84
  "url": "https://discord.gg/gm3mJwcNw8"
85
85
  },