@devicecloud.dev/dcd 1.0.7 → 1.0.9

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.
@@ -14,7 +14,11 @@ export declare enum EiOSDevices {
14
14
  'iphone-15' = "iphone-15",
15
15
  'iphone-15-plus' = "iphone-15-plus",
16
16
  'iphone-15-pro' = "iphone-15-pro",
17
- 'iphone-15-pro-max' = "iphone-15-pro-max"
17
+ 'iphone-15-pro-max' = "iphone-15-pro-max",
18
+ 'iphone-16' = "iphone-16",
19
+ 'iphone-16-plus' = "iphone-16-plus",
20
+ 'iphone-16-pro' = "iphone-16-pro",
21
+ 'iphone-16-pro-max' = "iphone-16-pro-max"
18
22
  }
19
23
  export default class Cloud extends Command {
20
24
  static args: {
@@ -32,6 +36,7 @@ export default class Cloud extends Command {
32
36
  'app-file': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
33
37
  arm64: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
34
38
  async: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
39
+ 'device-locale': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
35
40
  env: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
36
41
  'exclude-flows': import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
37
42
  'exclude-tags': import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -41,8 +46,10 @@ export default class Cloud extends Command {
41
46
  'ios-device': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
42
47
  'ios-version': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
43
48
  'legacy-upload': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
49
+ 'maestro-version': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
44
50
  name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
45
51
  orientation: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
52
+ quiet: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
46
53
  };
47
54
  run(): Promise<void>;
48
55
  }
@@ -34,6 +34,10 @@ var EiOSDevices;
34
34
  EiOSDevices["iphone-15-plus"] = "iphone-15-plus";
35
35
  EiOSDevices["iphone-15-pro"] = "iphone-15-pro";
36
36
  EiOSDevices["iphone-15-pro-max"] = "iphone-15-pro-max";
37
+ EiOSDevices["iphone-16"] = "iphone-16";
38
+ EiOSDevices["iphone-16-plus"] = "iphone-16-plus";
39
+ EiOSDevices["iphone-16-pro"] = "iphone-16-pro";
40
+ EiOSDevices["iphone-16-pro-max"] = "iphone-16-pro-max";
37
41
  })(EiOSDevices || (exports.EiOSDevices = EiOSDevices = {}));
38
42
  class Cloud extends core_1.Command {
39
43
  static args = {
@@ -53,9 +57,13 @@ class Cloud extends core_1.Command {
53
57
  static flags = constants_1.flags;
54
58
  async run() {
55
59
  try {
60
+ const [major] = process.versions.node.split('.').map(Number);
61
+ if (major < 18) {
62
+ throw new Error(`You are using node version ${major}. DCD requires node version 18 or later`);
63
+ }
56
64
  await (0, methods_1.versionCheck)(this.config.version);
57
65
  const { args, flags, raw } = await this.parse(Cloud);
58
- const { 'android-api-level': androidApiLevel, 'android-device': androidDevice, apiKey, apiUrl, 'app-binary-id': appBinaryId, 'app-file': appFile, arm64, async, env, 'exclude-flows': excludeFlows, 'exclude-tags': excludeTags, flows, 'google-play': googlePlay, 'include-tags': includeTags, 'ios-device': iOSDevice, 'ios-version': iOSVersion, 'legacy-upload': legacyUpload, name, orientation, ...rest } = flags;
66
+ const { 'android-api-level': androidApiLevel, 'android-device': androidDevice, apiKey, apiUrl, 'app-binary-id': appBinaryId, 'app-file': appFile, arm64, async, 'device-locale': deviceLocale, env, 'exclude-flows': excludeFlows, 'exclude-tags': excludeTags, flows, 'google-play': googlePlay, 'include-tags': includeTags, 'ios-device': iOSDevice, 'ios-version': iOSVersion, 'legacy-upload': legacyUpload, 'maestro-version': maestroVersion, name, orientation, quiet, ...rest } = flags;
59
67
  if (arm64) {
60
68
  (0, cli_ux_1.info)('Contact hello@devicecloud.dev to enquire about arm64 devices');
61
69
  (0, cli_ux_1.exit)();
@@ -243,6 +251,8 @@ class Cloud extends core_1.Command {
243
251
  allExcludeTags,
244
252
  allIncludeTags,
245
253
  continueOnFailure,
254
+ deviceLocale,
255
+ maestroVersion,
246
256
  orientation,
247
257
  raw,
248
258
  version: this.config.version,
@@ -284,34 +294,49 @@ class Cloud extends core_1.Command {
284
294
  // poll for the run status every 5 seconds
285
295
  core_1.ux.action.start('Waiting for results', 'Initializing', { stdout: true });
286
296
  (0, cli_ux_1.info)('\nYou can safely close this terminal and the tests will continue\n');
297
+ let sequentialPollFaillures = 0;
287
298
  const intervalId = setInterval(async () => {
288
- const { results: updatedResults } = await (0, methods_1.typeSafeGet)(apiUrl, `/results/${results[0].test_upload_id}`, {
289
- headers: { 'x-app-api-key': apiKey },
290
- });
291
- if (!updatedResults) {
292
- clearInterval(intervalId);
293
- (0, errors_1.error)('No results found');
294
- }
295
- core_1.ux.action.status = '\nStatus Test\n─────────── ───────────────';
296
- for (const { status, test_file_name: test } of updatedResults) {
297
- core_1.ux.action.status += `\n${status.padEnd(10, ' ')} ${test}`;
299
+ try {
300
+ const { results: updatedResults } = await (0, methods_1.typeSafeGet)(apiUrl, `/results/${results[0].test_upload_id}`, {
301
+ headers: { 'x-app-api-key': apiKey },
302
+ });
303
+ if (!updatedResults) {
304
+ throw new Error('no results');
305
+ }
306
+ if (!quiet) {
307
+ core_1.ux.action.status =
308
+ '\nStatus Test\n─────────── ───────────────';
309
+ for (const { status, test_file_name: test } of updatedResults) {
310
+ core_1.ux.action.status += `\n${status.padEnd(10, ' ')} ${test}`;
311
+ }
312
+ }
313
+ if (updatedResults.every((result) => !['PENDING', 'RUNNING'].includes(result.status))) {
314
+ core_1.ux.action.stop('completed');
315
+ (0, cli_ux_1.info)('\n');
316
+ (0, cli_ux_1.table)(updatedResults, {
317
+ status: { get: (row) => row.status },
318
+ test: { get: (row) => row.test_file_name },
319
+ }, { printLine: this.log.bind(this) });
320
+ (0, cli_ux_1.info)('\n');
321
+ (0, cli_ux_1.info)('Run completed, you can access the results at:');
322
+ core_1.ux.url(url, url);
323
+ (0, cli_ux_1.info)('\n');
324
+ clearInterval(intervalId);
325
+ if (updatedResults.some((result) => result.status === 'FAILED')) {
326
+ // eslint-disable-next-line no-process-exit, unicorn/no-process-exit
327
+ process.exit(2);
328
+ }
329
+ sequentialPollFaillures = 0;
330
+ }
298
331
  }
299
- if (updatedResults.every((result) => !['PENDING', 'RUNNING'].includes(result.status))) {
300
- core_1.ux.action.stop('completed');
301
- (0, cli_ux_1.info)('\n');
302
- (0, cli_ux_1.table)(updatedResults, {
303
- status: { get: (row) => row.status },
304
- test: { get: (row) => row.test_file_name },
305
- }, { printLine: this.log.bind(this) });
306
- (0, cli_ux_1.info)('\n');
307
- (0, cli_ux_1.info)('Run completed, you can access the results at:');
308
- core_1.ux.url(url, url);
309
- (0, cli_ux_1.info)('\n');
310
- clearInterval(intervalId);
311
- if (updatedResults.some((result) => result.status === 'FAILED')) {
312
- // eslint-disable-next-line no-process-exit, unicorn/no-process-exit
313
- process.exit(2);
332
+ catch {
333
+ sequentialPollFaillures++;
334
+ if (sequentialPollFaillures > 5) {
335
+ // dropped poll requests shouldn't err user CI
336
+ clearInterval(intervalId);
337
+ throw new Error('unable to fetch results');
314
338
  }
339
+ (0, cli_ux_1.info)('unable to fetch results, trying again...');
315
340
  }
316
341
  }, 5000);
317
342
  }
@@ -8,6 +8,7 @@ export declare const flags: {
8
8
  'app-file': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
9
9
  arm64: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
10
  async: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
+ 'device-locale': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
12
  env: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
13
  'exclude-flows': import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
13
14
  'exclude-tags': import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -17,8 +18,10 @@ export declare const flags: {
17
18
  'ios-device': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
18
19
  'ios-version': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
19
20
  'legacy-upload': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
21
+ 'maestro-version': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
20
22
  name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
21
23
  orientation: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
24
+ quiet: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
22
25
  };
23
26
  export declare const iOSCompatibilityLookup: {
24
27
  [k in EiOSDevices]: string[];
package/dist/constants.js CHANGED
@@ -42,6 +42,9 @@ exports.flags = {
42
42
  async: core_1.Flags.boolean({
43
43
  description: 'Wait for the results of the run',
44
44
  }),
45
+ 'device-locale': core_1.Flags.string({
46
+ description: 'Locale that will be set to a device, ISO-639-1 code and uppercase ISO-3166-1 code e.g. "de_DE" for Germany',
47
+ }),
45
48
  env: core_1.Flags.file({
46
49
  char: 'e',
47
50
  description: 'One or more environment variables to inject into your flows',
@@ -96,17 +99,39 @@ exports.flags = {
96
99
  'iphone-15-plus',
97
100
  'iphone-15-pro',
98
101
  'iphone-15-pro-max',
102
+ 'iphone-16',
103
+ 'iphone-16-plus',
104
+ 'iphone-16-pro',
105
+ 'iphone-16-pro-max',
99
106
  'ipad-pro-6th-gen',
100
107
  ],
101
108
  }),
102
109
  'ios-version': core_1.Flags.string({
103
110
  description: '[iOS only] iOS version to run your flow against',
104
- options: ['15', '16', '17'],
111
+ options: ['15', '16', '17', '18'],
105
112
  }),
106
113
  'legacy-upload': core_1.Flags.boolean({
107
114
  default: false,
108
115
  description: 'Use the legacy direct upload method',
109
116
  }),
117
+ 'maestro-version': core_1.Flags.string({
118
+ aliases: ['maestroVersion'],
119
+ description: '[ALPHA pre-release] - Maestro version to run your flow against',
120
+ options: [
121
+ '1.36.0',
122
+ '1.37.0',
123
+ '1.37.1',
124
+ '1.37.2',
125
+ '1.37.3',
126
+ '1.37.4',
127
+ '1.37.5',
128
+ '1.37.6',
129
+ '1.37.7',
130
+ '1.37.8',
131
+ '1.37.9',
132
+ '1.38.1',
133
+ ],
134
+ }),
110
135
  name: core_1.Flags.string({
111
136
  description: 'A custom name for your upload (useful for tagging commits etc)',
112
137
  }),
@@ -114,6 +139,11 @@ exports.flags = {
114
139
  description: '[Android only] The orientation of the device to run your flow against in degrees',
115
140
  options: ['0', '90', '180', '270'],
116
141
  }),
142
+ quiet: core_1.Flags.boolean({
143
+ char: 'q',
144
+ default: false,
145
+ description: 'Quieter console output that wont provide progress updates',
146
+ }),
117
147
  };
118
148
  exports.iOSCompatibilityLookup = {
119
149
  'ipad-pro-6th-gen': ['16', '17'],
@@ -123,12 +153,16 @@ exports.iOSCompatibilityLookup = {
123
153
  'iphone-13': ['15', '16', '17'],
124
154
  'iphone-13-mini': ['15', '16', '17'],
125
155
  'iphone-13-pro-max': ['15', '16', '17'],
126
- 'iphone-14': ['16', '17'],
127
- 'iphone-14-plus': ['16', '17'],
128
- 'iphone-14-pro': ['16', '17'],
129
- 'iphone-14-pro-max': ['16', '17'],
130
- 'iphone-15': ['17'],
131
- 'iphone-15-plus': ['17'],
132
- 'iphone-15-pro': ['17'],
133
- 'iphone-15-pro-max': ['17'],
156
+ 'iphone-14': ['16', '17', '18'],
157
+ 'iphone-14-plus': ['16', '17', '18'],
158
+ 'iphone-14-pro': ['16', '17', '18'],
159
+ 'iphone-14-pro-max': ['16', '17', '18'],
160
+ 'iphone-15': ['17', '18'],
161
+ 'iphone-15-plus': ['17', '18'],
162
+ 'iphone-15-pro': ['17', '18'],
163
+ 'iphone-15-pro-max': ['17', '18'],
164
+ 'iphone-16': ['18'],
165
+ 'iphone-16-plus': ['18'],
166
+ 'iphone-16-pro': ['18'],
167
+ 'iphone-16-pro-max': ['18'],
134
168
  };
package/dist/methods.js CHANGED
@@ -30,7 +30,7 @@ const versionCheck = async (currentVersion) => {
30
30
  (0, cli_ux_1.warn)(`
31
31
  -------------------
32
32
  A new version of the devicecloud.dev CLI is available: ${latestVersion}
33
- Run 'npm install -g @devicecloud.dev/dcd' to update to the latest version
33
+ Run 'npm install -g @devicecloud.dev/dcd@latest' to update to the latest version
34
34
  -------------------
35
35
  `);
36
36
  }
@@ -99,6 +99,13 @@
99
99
  "allowNo": false,
100
100
  "type": "boolean"
101
101
  },
102
+ "device-locale": {
103
+ "description": "Locale that will be set to a device, ISO-639-1 code and uppercase ISO-3166-1 code e.g. \"de_DE\" for Germany",
104
+ "name": "device-locale",
105
+ "hasDynamicHelp": false,
106
+ "multiple": false,
107
+ "type": "option"
108
+ },
102
109
  "env": {
103
110
  "char": "e",
104
111
  "description": "One or more environment variables to inject into your flows",
@@ -173,6 +180,10 @@
173
180
  "iphone-15-plus",
174
181
  "iphone-15-pro",
175
182
  "iphone-15-pro-max",
183
+ "iphone-16",
184
+ "iphone-16-plus",
185
+ "iphone-16-pro",
186
+ "iphone-16-pro-max",
176
187
  "ipad-pro-6th-gen"
177
188
  ],
178
189
  "type": "option"
@@ -185,7 +196,8 @@
185
196
  "options": [
186
197
  "15",
187
198
  "16",
188
- "17"
199
+ "17",
200
+ "18"
189
201
  ],
190
202
  "type": "option"
191
203
  },
@@ -195,6 +207,30 @@
195
207
  "allowNo": false,
196
208
  "type": "boolean"
197
209
  },
210
+ "maestro-version": {
211
+ "aliases": [
212
+ "maestroVersion"
213
+ ],
214
+ "description": "[ALPHA pre-release] - Maestro version to run your flow against",
215
+ "name": "maestro-version",
216
+ "hasDynamicHelp": false,
217
+ "multiple": false,
218
+ "options": [
219
+ "1.36.0",
220
+ "1.37.0",
221
+ "1.37.1",
222
+ "1.37.2",
223
+ "1.37.3",
224
+ "1.37.4",
225
+ "1.37.5",
226
+ "1.37.6",
227
+ "1.37.7",
228
+ "1.37.8",
229
+ "1.37.9",
230
+ "1.38.1"
231
+ ],
232
+ "type": "option"
233
+ },
198
234
  "name": {
199
235
  "description": "A custom name for your upload (useful for tagging commits etc)",
200
236
  "name": "name",
@@ -214,6 +250,13 @@
214
250
  "270"
215
251
  ],
216
252
  "type": "option"
253
+ },
254
+ "quiet": {
255
+ "char": "q",
256
+ "description": "Quieter console output that wont provide progress updates",
257
+ "name": "quiet",
258
+ "allowNo": false,
259
+ "type": "boolean"
217
260
  }
218
261
  },
219
262
  "hasDynamicHelp": false,
@@ -232,5 +275,5 @@
232
275
  ]
233
276
  }
234
277
  },
235
- "version": "1.0.7"
278
+ "version": "1.0.9"
236
279
  }
package/package.json CHANGED
@@ -80,7 +80,7 @@
80
80
  "test": "mocha --forbid-only \"test/**/*.test.ts\"",
81
81
  "version": "oclif readme && git add README.md"
82
82
  },
83
- "version": "1.0.7",
83
+ "version": "1.0.9",
84
84
  "bugs": {
85
85
  "url": "https://discord.gg/gm3mJwcNw8"
86
86
  },