@testrigor/testrigor-cli 1.0.1 → 2.0.1
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/README.md +33 -432
- package/dist/commands/authenticate.d.ts +14 -0
- package/dist/commands/authenticate.js +86 -25
- package/dist/commands/test-suite/run.js +240 -222
- package/dist/commands/test-suite/validate-syntax.js +1 -3
- package/dist/types.d.ts +0 -11
- package/dist/util/appium.js +67 -13
- package/dist/util/certificate-uploader.js +1 -2
- package/dist/util/request-builder.d.ts +2 -8
- package/dist/util/request-builder.js +10 -33
- package/dist/util/trtc.js +4 -4
- package/dist/util/variable-file-uploader.js +4 -10
- package/npm-shrinkwrap.json +11056 -0
- package/oclif.manifest.json +253 -180
- package/package.json +19 -16
|
@@ -3,9 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const core_1 = require("@oclif/core");
|
|
5
5
|
const fs_1 = tslib_1.__importDefault(require("@supercharge/fs"));
|
|
6
|
-
const
|
|
6
|
+
const fs_2 = require("fs");
|
|
7
7
|
const listr2_1 = require("listr2");
|
|
8
|
-
const node_fetch_commonjs_1 = tslib_1.__importDefault(require("node-fetch-commonjs"));
|
|
9
8
|
const command_base_1 = require("../../command-base");
|
|
10
9
|
const environments_1 = require("../../config/environments");
|
|
11
10
|
const chrome_extension_1 = require("../../flags/chrome-extension");
|
|
@@ -32,6 +31,7 @@ const JUNIT_REPORT_STATUS = {
|
|
|
32
31
|
FAILED: "JUnit report generation is failed",
|
|
33
32
|
RUNNING: "JUnit report is still in progress",
|
|
34
33
|
};
|
|
34
|
+
const FAILED_TO_START_TITLE = "Test suite run failed";
|
|
35
35
|
class Run extends command_base_1.CommandBase {
|
|
36
36
|
initializeUrls(flags) {
|
|
37
37
|
const baseUrlWeb = flags["base-url-web"];
|
|
@@ -223,6 +223,11 @@ class Run extends command_base_1.CommandBase {
|
|
|
223
223
|
enabled: () => (flags.localhost || !!localTestNodesPath) && context.isMobile,
|
|
224
224
|
task: (ctx, task) => {
|
|
225
225
|
task.title = "Starting mobile server";
|
|
226
|
+
// A driver that fails to install is tolerated (xcuitest is useless on
|
|
227
|
+
// Linux, uiautomator2 on a Mac targeting iOS), but losing all of them
|
|
228
|
+
// means the server has nothing to drive - fail there, with the
|
|
229
|
+
// reasons, instead of timing out on the health check 30s later.
|
|
230
|
+
const driverFailures = [];
|
|
226
231
|
return task.newListr([
|
|
227
232
|
{
|
|
228
233
|
task: async (_ctx, subtask) => {
|
|
@@ -242,14 +247,22 @@ class Run extends command_base_1.CommandBase {
|
|
|
242
247
|
? `Updating ${driver.name} (${status.version} → ${driver.version})`
|
|
243
248
|
: `Installing ${driver.name}@${driver.version}`;
|
|
244
249
|
const err = await (0, appium_1.ensureDriver)(driver.name, driver.version);
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
250
|
+
if (err) {
|
|
251
|
+
driverFailures.push(`${driver.name}@${driver.version}: ${err}`);
|
|
252
|
+
subtask.title = `Driver ${driver.name} skipped — ${err.split("\n")[0]}`;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
subtask.title = `Driver ${driver.name}@${driver.version} ready`;
|
|
256
|
+
}
|
|
248
257
|
},
|
|
249
258
|
rendererOptions: { timer: listr2_1.PRESET_TIMER },
|
|
250
259
|
})),
|
|
251
260
|
{
|
|
252
261
|
task: async (ctx, subtask) => {
|
|
262
|
+
if (driverFailures.length === appium_1.REQUIRED_DRIVERS.length) {
|
|
263
|
+
throw new Error("No mobile driver could be installed, so the mobile server has nothing to run:\n" +
|
|
264
|
+
driverFailures.map((f) => ` - ${f}`).join("\n"));
|
|
265
|
+
}
|
|
253
266
|
const result = await (0, appium_1.startAppium)();
|
|
254
267
|
ctx.appiumStartedByUs = !result.alreadyRunning;
|
|
255
268
|
subtask.title = result.alreadyRunning
|
|
@@ -297,90 +310,143 @@ class Run extends command_base_1.CommandBase {
|
|
|
297
310
|
},
|
|
298
311
|
{
|
|
299
312
|
title: "Running test suite",
|
|
300
|
-
task: async (ctx, task) =>
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
313
|
+
task: async (ctx, task) => {
|
|
314
|
+
const steps = task.newListr([
|
|
315
|
+
{
|
|
316
|
+
task: async (ctx) => {
|
|
317
|
+
let pollBranch = flags.branch;
|
|
318
|
+
if (this.isSingleTestCaseExecution(testCaseUuids, flags.branch)) {
|
|
319
|
+
pollBranch = `single-test-execution-${testCaseUuids[0]}`;
|
|
320
|
+
}
|
|
321
|
+
const statusResponse = await this.fetchStatus(testSuiteId, token, pollBranch, ctx.configuration.labels, ctx.configuration.excludedLabels);
|
|
322
|
+
context.lastRunId = (0, utils_1.extractRunIdFromDetailsUrl)(statusResponse.detailsUrl);
|
|
323
|
+
},
|
|
324
|
+
exitOnError: false,
|
|
310
325
|
},
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
task: (ctx) => this.uploadVariableFiles(ctx, testSuiteId, token),
|
|
317
|
-
exitOnError: false,
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
title: "Uploading client certificates",
|
|
321
|
-
enabled: () => !!context.storedValueCertInputs?.length,
|
|
322
|
-
task: (ctx, task) => this.uploadClientCertificates(ctx, testSuiteId, token, task),
|
|
323
|
-
exitOnError: false,
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
enabled: () => !flags["file-path"] && !flags["chrome-extension"],
|
|
327
|
-
task: async (ctx) => {
|
|
328
|
-
if (flags.url) {
|
|
329
|
-
ctx.configuration.url = flags.url;
|
|
330
|
-
}
|
|
331
|
-
if (flags.branch && flags.commit) {
|
|
332
|
-
ctx.configuration.branch = {
|
|
333
|
-
name: flags.branch,
|
|
334
|
-
commit: flags.commit,
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
const response = await this.callRetest(testSuiteId, ctx.configuration, token);
|
|
338
|
-
ctx.response = (await response.json());
|
|
339
|
-
if (!response.ok) {
|
|
340
|
-
const errorMessage = JSON.stringify(ctx.response);
|
|
341
|
-
throw new Error(`Test suite failed to start: ${ctx.response?.msg ||
|
|
342
|
-
ctx.response?.errName ||
|
|
343
|
-
errorMessage}`);
|
|
344
|
-
}
|
|
345
|
-
if (ctx.response?.taskId) {
|
|
346
|
-
task.title = `Running test suite [ ${this.TESTRIGOR_URL}/test-suites/${testSuiteId}/runs/${ctx.response?.taskId} ]`;
|
|
347
|
-
}
|
|
326
|
+
{
|
|
327
|
+
title: "Uploading variable files",
|
|
328
|
+
enabled: () => !!context.storedValueFileInputs?.length,
|
|
329
|
+
task: (ctx) => this.uploadVariableFiles(ctx, testSuiteId, token),
|
|
330
|
+
exitOnError: false,
|
|
348
331
|
},
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
332
|
+
{
|
|
333
|
+
title: "Uploading client certificates",
|
|
334
|
+
enabled: () => !!context.storedValueCertInputs?.length,
|
|
335
|
+
task: (ctx, task) => this.uploadClientCertificates(ctx, testSuiteId, token, task),
|
|
336
|
+
exitOnError: false,
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
enabled: () => !flags["file-path"] && !flags["chrome-extension"],
|
|
340
|
+
task: async (ctx) => {
|
|
341
|
+
if (flags.url) {
|
|
342
|
+
ctx.configuration.url = flags.url;
|
|
343
|
+
}
|
|
344
|
+
if (flags.branch && flags.commit) {
|
|
345
|
+
ctx.configuration.branch = {
|
|
346
|
+
name: flags.branch,
|
|
347
|
+
commit: flags.commit,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
const response = await this.callRetest(testSuiteId, ctx.configuration, token);
|
|
351
|
+
ctx.response = (await response.json());
|
|
352
|
+
if (!response.ok) {
|
|
353
|
+
task.title = FAILED_TO_START_TITLE;
|
|
354
|
+
const errorMessage = JSON.stringify(ctx.response);
|
|
355
|
+
throw new Error(`Test suite failed to start: ${ctx.response?.msg ||
|
|
356
|
+
ctx.response?.errName ||
|
|
357
|
+
errorMessage}`);
|
|
358
|
+
}
|
|
359
|
+
if (ctx.response?.taskId) {
|
|
360
|
+
task.title = `Running test suite [ ${this.TESTRIGOR_URL}/test-suites/${testSuiteId}/runs/${ctx.response?.taskId} ]`;
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
exitOnError: false,
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
title: "Uploading Chrome extension(s)",
|
|
367
|
+
enabled: () => !!context.chromeExtensions?.length,
|
|
368
|
+
task: async (ctx) => {
|
|
369
|
+
if (flags.url) {
|
|
370
|
+
ctx.configuration.url = flags.url;
|
|
371
|
+
}
|
|
372
|
+
if (flags.branch && flags.commit) {
|
|
373
|
+
ctx.configuration.branch = {
|
|
374
|
+
name: flags.branch,
|
|
375
|
+
commit: flags.commit,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
const form = await (0, request_builder_1.buildChromeExtensionFormData)(ctx.chromeExtensions);
|
|
379
|
+
form.append("data", JSON.stringify(ctx.configuration));
|
|
380
|
+
const controller = new AbortController();
|
|
381
|
+
const timeoutId = setTimeout(() => controller.abort(), utils_1.UPLOAD_TIMEOUT_MS);
|
|
382
|
+
try {
|
|
383
|
+
const response = await fetch(`${this.TESTRIGOR_API2_URL}/apps/${testSuiteId}/retest`, {
|
|
384
|
+
method: "POST",
|
|
385
|
+
body: form,
|
|
386
|
+
headers: {
|
|
387
|
+
Accept: "application/json",
|
|
388
|
+
"auth-token": token,
|
|
389
|
+
},
|
|
390
|
+
signal: controller.signal,
|
|
391
|
+
});
|
|
392
|
+
const retestApi2Response = (await response.json());
|
|
393
|
+
if (!response.ok || retestApi2Response.status >= 300) {
|
|
394
|
+
throw new Error(`Chrome extension upload failed: ${retestApi2Response?.message ||
|
|
395
|
+
retestApi2Response?.errors}`);
|
|
396
|
+
}
|
|
397
|
+
ctx.response = {
|
|
398
|
+
result: "ok",
|
|
399
|
+
msg: retestApi2Response.message,
|
|
400
|
+
taskId: retestApi2Response.data?.taskId,
|
|
401
|
+
queueId: retestApi2Response.data?.queueId,
|
|
402
|
+
};
|
|
403
|
+
if (ctx.response?.taskId) {
|
|
404
|
+
task.title = `Running test suite [ ${this.TESTRIGOR_URL}/test-suites/${testSuiteId}/runs/${ctx.response?.taskId} ]`;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
if (error.name === "AbortError") {
|
|
409
|
+
throw new Error("Chrome extension upload timed out. Please check your network connection.");
|
|
410
|
+
}
|
|
411
|
+
throw error;
|
|
412
|
+
}
|
|
413
|
+
finally {
|
|
414
|
+
clearTimeout(timeoutId);
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
exitOnError: false,
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
title: "Uploading file",
|
|
421
|
+
enabled: () => context.fileProperties &&
|
|
422
|
+
context.fileProperties.fileSize < utils_1.MAX_FILE_SIZE_100_MB,
|
|
423
|
+
task: async (ctx) => {
|
|
424
|
+
if (flags.branch && flags.commit) {
|
|
425
|
+
ctx.configuration.branch = {
|
|
426
|
+
name: flags.branch,
|
|
427
|
+
commit: flags.commit,
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
if (!flags["file-path"]) {
|
|
431
|
+
throw new Error("file-path is not provided");
|
|
432
|
+
}
|
|
433
|
+
const configuration = ctx.configuration;
|
|
434
|
+
const filePath = flags["file-path"];
|
|
435
|
+
const form = new FormData();
|
|
436
|
+
form.append("file", await (0, fs_2.openAsBlob)(filePath), fs_1.default.basename(filePath));
|
|
437
|
+
form.append("data", JSON.stringify(configuration));
|
|
438
|
+
const response = await fetch(`${this.TESTRIGOR_API2_URL}/apps/${testSuiteId}/retest`, {
|
|
376
439
|
method: "POST",
|
|
377
440
|
body: form,
|
|
378
|
-
headers:
|
|
379
|
-
|
|
441
|
+
headers: {
|
|
442
|
+
Accept: "application/json",
|
|
443
|
+
"auth-token": token,
|
|
444
|
+
},
|
|
380
445
|
});
|
|
381
446
|
const retestApi2Response = (await response.json());
|
|
382
447
|
if (!response.ok || retestApi2Response.status >= 300) {
|
|
383
|
-
|
|
448
|
+
task.title = FAILED_TO_START_TITLE;
|
|
449
|
+
throw new Error(`Test suite failed to start: ${retestApi2Response?.message ||
|
|
384
450
|
retestApi2Response?.errors}`);
|
|
385
451
|
}
|
|
386
452
|
ctx.response = {
|
|
@@ -389,145 +455,101 @@ class Run extends command_base_1.CommandBase {
|
|
|
389
455
|
taskId: retestApi2Response.data?.taskId,
|
|
390
456
|
queueId: retestApi2Response.data?.queueId,
|
|
391
457
|
};
|
|
392
|
-
|
|
393
|
-
|
|
458
|
+
},
|
|
459
|
+
exitOnError: false,
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
title: "Uploading file (> 100 MB)",
|
|
463
|
+
enabled: () => context.fileProperties &&
|
|
464
|
+
context.fileProperties.fileSize >= utils_1.MAX_FILE_SIZE_100_MB,
|
|
465
|
+
task: async (ctx) => {
|
|
466
|
+
if (flags.branch && flags.commit) {
|
|
467
|
+
ctx.configuration.branch = {
|
|
468
|
+
name: flags.branch,
|
|
469
|
+
commit: flags.commit,
|
|
470
|
+
};
|
|
394
471
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
if (error.name === "AbortError") {
|
|
398
|
-
throw new Error("Chrome extension upload timed out. Please check your network connection.");
|
|
472
|
+
if (!flags["file-path"]) {
|
|
473
|
+
throw new Error("file-path is not provided");
|
|
399
474
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
task: async (ctx) => {
|
|
414
|
-
if (flags.branch && flags.commit) {
|
|
415
|
-
ctx.configuration.branch = {
|
|
416
|
-
name: flags.branch,
|
|
417
|
-
commit: flags.commit,
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
if (!flags["file-path"]) {
|
|
421
|
-
throw new Error("file-path is not provided");
|
|
422
|
-
}
|
|
423
|
-
const configuration = ctx.configuration;
|
|
424
|
-
const filePath = flags["file-path"];
|
|
425
|
-
const form = new form_data_1.default();
|
|
426
|
-
form.append("file", fs_1.default.createReadStream(filePath));
|
|
427
|
-
form.append("data", JSON.stringify(configuration));
|
|
428
|
-
const response = await (0, node_fetch_commonjs_1.default)(`${this.TESTRIGOR_API2_URL}/apps/${testSuiteId}/retest`, {
|
|
429
|
-
method: "POST",
|
|
430
|
-
body: form,
|
|
431
|
-
headers: {
|
|
432
|
-
...form.getHeaders(),
|
|
433
|
-
Accept: "application/json",
|
|
434
|
-
"auth-token": token,
|
|
435
|
-
},
|
|
436
|
-
});
|
|
437
|
-
const retestApi2Response = (await response.json());
|
|
438
|
-
if (!response.ok || retestApi2Response.status >= 300) {
|
|
439
|
-
throw new Error(`Test suite failed to start: ${retestApi2Response?.message ||
|
|
440
|
-
retestApi2Response?.errors}`);
|
|
441
|
-
}
|
|
442
|
-
ctx.response = {
|
|
443
|
-
result: "ok",
|
|
444
|
-
msg: retestApi2Response.message,
|
|
445
|
-
taskId: retestApi2Response.data?.taskId,
|
|
446
|
-
queueId: retestApi2Response.data?.queueId,
|
|
447
|
-
};
|
|
475
|
+
if (!ctx.fileProperties) {
|
|
476
|
+
throw new Error(`Error getting details of file provided by --file-path ${flags["file-path"]}`);
|
|
477
|
+
}
|
|
478
|
+
const configuration = ctx.configuration;
|
|
479
|
+
const filePath = flags["file-path"];
|
|
480
|
+
const response = await this.uploadFile(task, testSuiteId, configuration, filePath, token, ctx.fileProperties);
|
|
481
|
+
ctx.response = (await response.json());
|
|
482
|
+
if (!response.ok) {
|
|
483
|
+
task.title = FAILED_TO_START_TITLE;
|
|
484
|
+
throw new Error(`Test suite failed to start: ${ctx.response?.msg || ctx.response?.errName}`);
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
exitOnError: false,
|
|
448
488
|
},
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
ctx.configuration.
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
if (!flags["file-path"]) {
|
|
463
|
-
throw new Error("file-path is not provided");
|
|
464
|
-
}
|
|
465
|
-
if (!ctx.fileProperties) {
|
|
466
|
-
throw new Error(`Error getting details of file provided by --file-path ${flags["file-path"]}`);
|
|
467
|
-
}
|
|
468
|
-
const configuration = ctx.configuration;
|
|
469
|
-
const filePath = flags["file-path"];
|
|
470
|
-
const response = await this.uploadFile(task, testSuiteId, configuration, filePath, token, ctx.fileProperties);
|
|
471
|
-
ctx.response = (await response.json());
|
|
472
|
-
if (!response.ok) {
|
|
473
|
-
throw new Error(`Test suite failed to start: ${ctx.response?.msg || ctx.response?.errName}`);
|
|
474
|
-
}
|
|
489
|
+
{
|
|
490
|
+
title: "Waiting for test suite run creation",
|
|
491
|
+
enabled: (ctx) => ctx.response?.queueId,
|
|
492
|
+
task: async (ctx, currentTask) => {
|
|
493
|
+
let pollBranch = flags.branch;
|
|
494
|
+
if (this.isSingleTestCaseExecution(testCaseUuids, flags.branch)) {
|
|
495
|
+
pollBranch = `single-test-execution-${testCaseUuids[0]}`;
|
|
496
|
+
}
|
|
497
|
+
const detailsUrl = await this.waitForTestSuiteToBeCreated(testSuiteId, token, ctx.lastRunId, pollBranch, ctx.configuration.labels, ctx.configuration.excludedLabels);
|
|
498
|
+
task.title = `Running test suite [ ${detailsUrl} ]`;
|
|
499
|
+
currentTask.title = "Test suite run created successfully";
|
|
500
|
+
},
|
|
501
|
+
exitOnError: false,
|
|
475
502
|
},
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
503
|
+
{
|
|
504
|
+
title: "Checking status",
|
|
505
|
+
enabled: (ctx) => ctx.response?.result === "ok" && !flags.async,
|
|
506
|
+
task: async (ctx, task) => {
|
|
507
|
+
let pollBranch = flags.branch;
|
|
508
|
+
if (this.isSingleTestCaseExecution(testCaseUuids, flags.branch)) {
|
|
509
|
+
pollBranch = `single-test-execution-${testCaseUuids[0]}`;
|
|
510
|
+
}
|
|
511
|
+
return task.newListr([
|
|
512
|
+
{
|
|
513
|
+
task: async (ctx, statusTask) => {
|
|
514
|
+
await this.waitForTestSuiteToFinish(testSuiteId, token, statusTask, pollBranch, ctx.configuration.labels, ctx.configuration.excludedLabels);
|
|
515
|
+
},
|
|
516
|
+
},
|
|
517
|
+
]);
|
|
518
|
+
},
|
|
519
|
+
exitOnError: false,
|
|
489
520
|
},
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
if (this.isSingleTestCaseExecution(testCaseUuids, flags.branch)) {
|
|
498
|
-
pollBranch = `single-test-execution-${testCaseUuids[0]}`;
|
|
499
|
-
}
|
|
500
|
-
return task.newListr([
|
|
521
|
+
{
|
|
522
|
+
title: "Generating JUnit report",
|
|
523
|
+
enabled: (ctx) => ctx.response?.result === "ok" &&
|
|
524
|
+
!flags.async &&
|
|
525
|
+
flags["junit-report-save-path"] &&
|
|
526
|
+
ctx.response?.taskId,
|
|
527
|
+
task: async (ctx, task) => task.newListr([
|
|
501
528
|
{
|
|
502
529
|
task: async (ctx, statusTask) => {
|
|
503
|
-
await this.
|
|
530
|
+
await this.startAndWaitForJunitReportToFinish(testSuiteId, String(ctx.response?.taskId), String(flags["junit-report-save-path"]), token, statusTask);
|
|
504
531
|
},
|
|
505
532
|
},
|
|
506
|
-
])
|
|
533
|
+
]),
|
|
534
|
+
exitOnError: false,
|
|
507
535
|
},
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
flags["junit-report-save-path"] &&
|
|
515
|
-
ctx.response?.taskId,
|
|
516
|
-
task: async (ctx, task) => task.newListr([
|
|
517
|
-
{
|
|
518
|
-
task: async (ctx, statusTask) => {
|
|
519
|
-
await this.startAndWaitForJunitReportToFinish(testSuiteId, String(ctx.response?.taskId), String(flags["junit-report-save-path"]), token, statusTask);
|
|
520
|
-
},
|
|
536
|
+
{
|
|
537
|
+
task: () => {
|
|
538
|
+
const failed = steps.tasks.find((step) => step.hasFailed());
|
|
539
|
+
if (failed) {
|
|
540
|
+
throw new Error(failed.message?.error ?? FAILED_TO_START_TITLE);
|
|
541
|
+
}
|
|
521
542
|
},
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
543
|
+
exitOnError: true,
|
|
544
|
+
},
|
|
545
|
+
], {
|
|
546
|
+
concurrent: false,
|
|
547
|
+
rendererOptions: { collapseSubtasks: false, timer: listr2_1.PRESET_TIMER },
|
|
548
|
+
fallbackRendererCondition: true,
|
|
549
|
+
fallbackRendererOptions: { timer: listr2_1.PRESET_TIMER },
|
|
550
|
+
});
|
|
551
|
+
return steps;
|
|
552
|
+
},
|
|
531
553
|
exitOnError: false,
|
|
532
554
|
rendererOptions: {
|
|
533
555
|
timer: listr2_1.PRESET_TIMER,
|
|
@@ -569,7 +591,7 @@ class Run extends command_base_1.CommandBase {
|
|
|
569
591
|
}
|
|
570
592
|
async fetchStatus(testSuiteId, token, branch, labels, excludedLabels) {
|
|
571
593
|
const statusApiEndpoint = this.getStatusApiEndpoint(testSuiteId, branch, labels, excludedLabels);
|
|
572
|
-
const response = await (
|
|
594
|
+
const response = await fetch(statusApiEndpoint, {
|
|
573
595
|
method: "GET",
|
|
574
596
|
headers: {
|
|
575
597
|
Accept: "application/json",
|
|
@@ -660,7 +682,7 @@ class Run extends command_base_1.CommandBase {
|
|
|
660
682
|
}
|
|
661
683
|
}
|
|
662
684
|
async callRetest(testSuiteId, configuration, token) {
|
|
663
|
-
return (
|
|
685
|
+
return fetch(`${this.TESTRIGOR_API_URL}/apps/${testSuiteId}/retest`, {
|
|
664
686
|
method: "POST",
|
|
665
687
|
body: JSON.stringify(configuration),
|
|
666
688
|
headers: {
|
|
@@ -671,7 +693,7 @@ class Run extends command_base_1.CommandBase {
|
|
|
671
693
|
});
|
|
672
694
|
}
|
|
673
695
|
async fetchSuiteType(testSuiteId, token) {
|
|
674
|
-
const response = await (
|
|
696
|
+
const response = await fetch(`${this.TESTRIGOR_API_URL}/apps/${testSuiteId}/status`, {
|
|
675
697
|
method: "GET",
|
|
676
698
|
headers: {
|
|
677
699
|
Accept: "application/json",
|
|
@@ -692,7 +714,7 @@ class Run extends command_base_1.CommandBase {
|
|
|
692
714
|
const body = {
|
|
693
715
|
fileName: fileProperties.fileName,
|
|
694
716
|
};
|
|
695
|
-
const preSignedUrl = await (
|
|
717
|
+
const preSignedUrl = await fetch(`${this.TESTRIGOR_API2_URL}/apps/${testSuiteId}/retest/pre-signed-url`, {
|
|
696
718
|
method: "POST",
|
|
697
719
|
body: JSON.stringify(body),
|
|
698
720
|
headers: {
|
|
@@ -708,13 +730,9 @@ class Run extends command_base_1.CommandBase {
|
|
|
708
730
|
throw new Error(`Failed to prepare upload: ${preSignedUrlResponse.message}`);
|
|
709
731
|
}
|
|
710
732
|
const preSignedUrlData = preSignedUrlResponse.data;
|
|
711
|
-
const
|
|
712
|
-
const uploadFileResponse = await (0, node_fetch_commonjs_1.default)(preSignedUrlData.url, {
|
|
733
|
+
const uploadFileResponse = await fetch(preSignedUrlData.url, {
|
|
713
734
|
method: "PUT",
|
|
714
|
-
body:
|
|
715
|
-
headers: {
|
|
716
|
-
"Content-length": `${fileProperties.fileSize}`,
|
|
717
|
-
},
|
|
735
|
+
body: await (0, fs_2.openAsBlob)(filePath),
|
|
718
736
|
});
|
|
719
737
|
if (!uploadFileResponse.ok) {
|
|
720
738
|
throw new Error(`Failed to upload file: ${uploadFileResponse.statusText}`);
|
|
@@ -775,7 +793,7 @@ class Run extends command_base_1.CommandBase {
|
|
|
775
793
|
}
|
|
776
794
|
}
|
|
777
795
|
async fetchTestSuiteStatus(statusApiEndpoint, token) {
|
|
778
|
-
return await (
|
|
796
|
+
return await fetch(statusApiEndpoint, {
|
|
779
797
|
method: "GET",
|
|
780
798
|
headers: {
|
|
781
799
|
Accept: "application/json",
|
|
@@ -811,7 +829,7 @@ class Run extends command_base_1.CommandBase {
|
|
|
811
829
|
const url = `${this.TESTRIGOR_API2_URL}/apps/${testSuiteId}/runs/${runId}/junit_report`;
|
|
812
830
|
for (;;) {
|
|
813
831
|
// eslint-disable-next-line no-await-in-loop
|
|
814
|
-
const response = await (
|
|
832
|
+
const response = await fetch(url, {
|
|
815
833
|
method: "GET",
|
|
816
834
|
headers: {
|
|
817
835
|
Accept: "application/json",
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
3
|
const core_1 = require("@oclif/core");
|
|
5
|
-
const node_fetch_commonjs_1 = tslib_1.__importDefault(require("node-fetch-commonjs"));
|
|
6
4
|
const command_base_1 = require("../../command-base");
|
|
7
5
|
const environments_1 = require("../../config/environments");
|
|
8
6
|
const parser_1 = require("../../util/parser");
|
|
@@ -68,7 +66,7 @@ class ValidateSyntax extends command_base_1.CommandBase {
|
|
|
68
66
|
if (explicitMutations) {
|
|
69
67
|
body.explicitMutations = explicitMutations;
|
|
70
68
|
}
|
|
71
|
-
const response = await (
|
|
69
|
+
const response = await fetch(`${this.TESTRIGOR_API2_URL}/apps/${testSuiteId}/validate-syntax`, {
|
|
72
70
|
method: "POST",
|
|
73
71
|
body: JSON.stringify(body),
|
|
74
72
|
headers: {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ReadStream } from "fs";
|
|
2
1
|
export type RetestResponse = {
|
|
3
2
|
result: string;
|
|
4
3
|
msg: string;
|
|
@@ -61,16 +60,6 @@ export type ChromeExtensionInput = {
|
|
|
61
60
|
name: string;
|
|
62
61
|
file: string;
|
|
63
62
|
};
|
|
64
|
-
/**
|
|
65
|
-
* Represents a single chrome extension override with its binary file.
|
|
66
|
-
*/
|
|
67
|
-
export type ChromeExtensionOverrideItem = {
|
|
68
|
-
name: string;
|
|
69
|
-
file: ReadStream;
|
|
70
|
-
};
|
|
71
|
-
export type ChromeExtensionOverridesRequest = {
|
|
72
|
-
chromeExtensions: ChromeExtensionOverrideItem[];
|
|
73
|
-
};
|
|
74
63
|
export type StoredValueFileInput = {
|
|
75
64
|
name: string;
|
|
76
65
|
file: string;
|