@mablhq/mabl-cli 2.31.44 → 2.34.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.
@@ -104,10 +104,12 @@ class BasicApiClient {
104
104
  };
105
105
  break;
106
106
  case types_1.AuthType.Bearer:
107
- if (!options.token) {
108
- throw new Error(`Auth type [${options.authType}] requires token`);
107
+ if (!options.token && !options.tokenAccessor) {
108
+ throw new Error(`Auth type [${options.authType}] requires token or tokenAccessor`);
109
+ }
110
+ if (options.token) {
111
+ config.headers.authorization = `Bearer ${options.token}`;
109
112
  }
110
- config.headers.authorization = `Bearer ${options.token}`;
111
113
  break;
112
114
  case types_1.AuthType.None:
113
115
  break;
@@ -128,6 +130,19 @@ class BasicApiClient {
128
130
  this.httpRequestConfig = config;
129
131
  this.httpClient = axios_1.default.create(config);
130
132
  this.httpClient.defaults.headers.common = { ...config.headers };
133
+ const { tokenAccessor } = options;
134
+ if (tokenAccessor) {
135
+ this.httpClient.interceptors.request.use(async (config) => {
136
+ const token = await tokenAccessor();
137
+ if (token) {
138
+ config.headers = {
139
+ ...config.headers,
140
+ authorization: `Bearer ${token}`,
141
+ };
142
+ }
143
+ return config;
144
+ });
145
+ }
131
146
  this.retryConfig = options.retryConfig;
132
147
  this.debugLogger = (_e = options.debugLogger) !== null && _e !== void 0 ? _e : logUtils_1.logInternal;
133
148
  }
@@ -410,7 +410,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
410
410
  throw toApiError(`Failed to get Flows`, error);
411
411
  }
412
412
  }
413
- async getSnippet(snippetId, preferLatestIfReusable) {
413
+ async getSnippet(snippetId, preferLatestIfReusable, workspaceId) {
414
414
  try {
415
415
  const queryParameter = typeof preferLatestIfReusable === 'boolean'
416
416
  ? `?=preferLatestIfReusable=${preferLatestIfReusable}`
@@ -418,7 +418,9 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
418
418
  return await this.makeGetRequest(`${this.baseApiUrl}/snippets/${snippetId}${queryParameter}`);
419
419
  }
420
420
  catch (error) {
421
- throw toApiError(`Failed to get Snippet [${snippetId}]`, error);
421
+ throw toApiError(`Failed to get Snippet [${snippetId}]. ${workspaceId
422
+ ? `The Snippet was likely deleted. To recover this snippet, visit the activity feed [workspaces/${workspaceId}/settings/activity-log?activityLogEntity=snippet&activityLogEvent=delete]`
423
+ : ''}`, error);
422
424
  }
423
425
  }
424
426
  async getBranchById(branchId) {
@@ -641,7 +643,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
641
643
  }
642
644
  }
643
645
  buildDeploymentRequestBody(options) {
644
- var _a, _b, _c, _d, _e, _f, _g, _h;
646
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
645
647
  const requestBody = { properties: {} };
646
648
  if (options.environmentId) {
647
649
  requestBody.environment_id = options.environmentId;
@@ -661,14 +663,18 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
661
663
  (_d = options.sourceControlMetadata) === null || _d === void 0 ? void 0 : _d.repoUrl;
662
664
  requestBody.properties.repository_name =
663
665
  (_e = options.sourceControlMetadata) === null || _e === void 0 ? void 0 : _e.repoName;
666
+ requestBody.properties.build_info_url =
667
+ (_f = options.sourceControlMetadata) === null || _f === void 0 ? void 0 : _f.buildInfoUrl;
668
+ requestBody.properties.deployment_origin = ((_g = options.sourceControlMetadata) === null || _g === void 0 ? void 0 : _g.integrationType)
669
+ ?
670
+ `mabl-${options.sourceControlMetadata.integrationType}`
671
+ : undefined;
672
+ requestBody.properties.build_id = (_h = options.sourceControlMetadata) === null || _h === void 0 ? void 0 : _h.buildId;
664
673
  const planOverrides = {};
665
- if ((_f = options.browserTypes) === null || _f === void 0 ? void 0 : _f.length) {
674
+ if ((_j = options.browserTypes) === null || _j === void 0 ? void 0 : _j.length) {
666
675
  planOverrides.browser_types = options.browserTypes;
667
676
  }
668
- if (options.runnerType) {
669
- planOverrides.nodejs_runtime_variant = options.runnerType;
670
- }
671
- if ((_g = options.labels) === null || _g === void 0 ? void 0 : _g.length) {
677
+ if ((_k = options.labels) === null || _k === void 0 ? void 0 : _k.length) {
672
678
  requestBody.plan_labels = options.labels;
673
679
  }
674
680
  if (options.uri) {
@@ -695,7 +701,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
695
701
  [mablApi_1.MobilePlatformEnum.Ios]: options.iOSMobileAppFileId,
696
702
  };
697
703
  }
698
- if ((_h = options.httpHeaders) === null || _h === void 0 ? void 0 : _h.length) {
704
+ if ((_l = options.httpHeaders) === null || _l === void 0 ? void 0 : _l.length) {
699
705
  planOverrides.http_headers = options.httpHeaders.map((header) => {
700
706
  const parts = header.split(':', 2);
701
707
  return {
@@ -834,7 +840,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
834
840
  try {
835
841
  const response = await this.makePatchRequest(`${this.baseApiUrl}/journeyRuns/${journeyRunId}`, {
836
842
  functionally_completed: false,
837
- status: mablApi_1.JourneyRun.StatusEnum.Failed,
843
+ status: mablApi_1.TestRun.StatusEnum.Failed,
838
844
  status_cause: cause,
839
845
  });
840
846
  return response;
@@ -46,3 +46,5 @@ function writeExportedEntityToFile(output, fileExtension, entityId, fileName) {
46
46
  return fileName;
47
47
  }
48
48
  exports.writeExportedEntityToFile = writeExportedEntityToFile;
49
+ const tester = 'hello:there:friend';
50
+ `mobileTestRun-${tester}-${Date.now()}`.replace(/:/g, '-');
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CommandArgMablBranchChangesOnly = exports.CommandArgMablBranch = exports.CommandArgMablAutoLogin = exports.CommandArgMablAutoBranch = exports.CommandArgLinkBypass = exports.CommandArgLinkLabel = exports.CommandArgLimitOutput = exports.CommandArgLabels = exports.CommandArgLabelsInclude = exports.CommandArgLabelsExclude = exports.CommandArgTestInteractionSpeed = exports.CommandArgTestRunId = exports.CommandArgTestFile = exports.CommandArgKeepBrowserOpen = exports.CommandArgInput = exports.CommandArgIncludedTests = exports.CommandArgIncludeDefaults = exports.CommandArgId = exports.CommandArgUserAgent = exports.CommandArgHttpHeaders = exports.CommandArgHelp = exports.CommandArgHeadless = exports.CommandArgFromPlanId = exports.CommandArgFrom = exports.CommandArgFormat = exports.CommandArgFindPath = exports.CommandArgFastFailure = exports.CommandArgOverrideEnvironmentId = exports.CommandArgGrep = exports.CommandArgExtraArguments = exports.CommandArgExistingReport = exports.CommandArgExcludedTests = exports.CommandArgEnvironmentId = exports.CommandArgDetailLevel = exports.CommandArgDestination = exports.CommandArgDescription = exports.CommandArgDeploymentId = exports.CommandArgDecrypt = exports.CommandArgDebug = exports.CommandArgDataTables = exports.CommandArgDataTableId = exports.CommandArgCredentials = exports.CommandArgBasicAuthCredentials = exports.CommandArgBrowsers = exports.CommandArgBrowser = exports.CommandArgBranch = exports.CommandArgAuto = exports.CommandArgApplicationId = exports.CommandArgApiKey = exports.CommandArgABConfigFile = void 0;
4
- exports.BrowserTypeSelections = exports.DefaultBrowserType = exports.DefaultBranchName = exports.DefaultOutputFormatChoices = exports.DetailLevelFormats = exports.ReporterOptions = exports.OutputFormats = exports.CommandArgAliases = exports.CommandArgBrowserEnableExtensions = exports.CommandArgBrowserIgnoreCertificateErrors = exports.CommandArgBrowserDisableIsolation = exports.ListTimeFormat = exports.CommandArgTimezoneID = exports.CommandArgLocale = exports.CommandArgUseTestExecutionProxy = exports.CommandArgScenarioId = exports.CommandArgReporterOptions = exports.CommandArgReporter = exports.CommandArgWorkspaceId = exports.CommandArgVersion = exports.CommandArgVariables = exports.CommandArgUrlApi = exports.CommandArgUrlApp = exports.CommandArgUrl = exports.CommandArgTo = exports.CommandArgTrainerVersion = exports.CommandArgTraceFile = exports.CommandArgTracesPath = exports.CommandArgTestPath = exports.CommandArgSilent = exports.CommandArgRevision = exports.CommandArgMaxHeartbeatAge = exports.CommandArgPlanId = exports.CommandArgContentTypes = exports.CommandArgPreview = exports.CommandArgPath = exports.CommandArgOutputFilePath = exports.CommandArgOutput = exports.CommandArgNoPrompt = exports.CommandArgPrompt = exports.CommandArgProject = exports.CommandArgPortNumber = exports.CommandArgName = exports.CommandArgMobileDeviceName = exports.CommandArgMobilePlatform = exports.CommandArgMobileAppFileId = exports.CommandArgMobileAppFile = exports.CommandArgiOSdMobileAppFileId = exports.CommandArgAndroidMobileAppFileId = exports.CommandArgMulti = void 0;
5
- exports.SCENARIO_ID_HEADER = exports.SCENARIO_NAME_HEADER = exports.ValidBrowserTypesForLocalRuns = void 0;
4
+ exports.DefaultBrowserType = exports.DefaultBranchName = exports.DefaultOutputFormatChoices = exports.DetailLevelFormats = exports.ReporterOptions = exports.OutputFormats = exports.CommandArgAliases = exports.CommandArgBrowserEnableExtensions = exports.CommandArgBrowserIgnoreCertificateErrors = exports.CommandArgBrowserDisableIsolation = exports.ListTimeFormat = exports.CommandArgTimezoneID = exports.CommandArgLocale = exports.CommandArgUseTestExecutionProxy = exports.CommandArgScenarioId = exports.CommandArgReporterOptions = exports.CommandArgReporter = exports.CommandArgWorkspaceId = exports.CommandArgVersion = exports.CommandArgVariables = exports.CommandArgUrlApi = exports.CommandArgUrlApp = exports.CommandArgUrl = exports.CommandArgTo = exports.CommandArgTrainerVersion = exports.CommandArgTraceFile = exports.CommandArgTracesPath = exports.CommandArgTestPath = exports.CommandArgSilent = exports.CommandArgRevision = exports.CommandArgRecordVideoPath = exports.CommandArgMaxHeartbeatAge = exports.CommandArgPlanId = exports.CommandArgContentTypes = exports.CommandArgPreview = exports.CommandArgPath = exports.CommandArgOutputFilePath = exports.CommandArgOutput = exports.CommandArgNoPrompt = exports.CommandArgPrompt = exports.CommandArgProject = exports.CommandArgPortNumber = exports.CommandArgName = exports.CommandArgMobileDeviceName = exports.CommandArgMobilePlatform = exports.CommandArgMobileAppFileId = exports.CommandArgMobileAppFile = exports.CommandArgiOSdMobileAppFileId = exports.CommandArgAndroidMobileAppFileId = exports.CommandArgMulti = void 0;
5
+ exports.SCENARIO_ID_HEADER = exports.SCENARIO_NAME_HEADER = exports.ValidBrowserTypesForLocalRuns = exports.BrowserTypeSelections = void 0;
6
6
  const browserTypes_1 = require("./browserTypes");
7
7
  exports.CommandArgABConfigFile = 'ab-config-file';
8
8
  exports.CommandArgApiKey = 'api-key';
@@ -73,6 +73,7 @@ exports.CommandArgPreview = 'preview';
73
73
  exports.CommandArgContentTypes = 'types';
74
74
  exports.CommandArgPlanId = 'plan-id';
75
75
  exports.CommandArgMaxHeartbeatAge = 'max-heartbeat-age';
76
+ exports.CommandArgRecordVideoPath = 'video-path';
76
77
  exports.CommandArgRevision = 'revision';
77
78
  exports.CommandArgSilent = 'silent';
78
79
  exports.CommandArgTestPath = 'tests-path';
@@ -8,6 +8,7 @@ const util_1 = require("../../commandUtil/util");
8
8
  const branches_1 = require("../../commandUtil/branches");
9
9
  const awaitDeploymentCompletion_1 = require("./awaitDeploymentCompletion");
10
10
  const scmContextProvider_1 = require("../../../providers/scmContextProvider");
11
+ const scmContextProviderV2_1 = require("../../../providers/scmContextProviderV2");
11
12
  const cliConfigProvider_1 = require("../../../providers/cliConfigProvider");
12
13
  const configKeys_1 = require("../../config/config_cmds/configKeys");
13
14
  const codeInsights_1 = require("../../commandUtil/codeInsights");
@@ -207,7 +208,6 @@ async function createDeployment(parsed) {
207
208
  if (!parsed.silent) {
208
209
  loggingProvider_1.logger.info('Creating Deployment...');
209
210
  }
210
- const runnerType = parsed['runner-type'];
211
211
  const applicationId = parsed['application-id'];
212
212
  const environmentId = parsed['environment-id'];
213
213
  const workspaceId = await (0, util_1.getWorkspaceIdFromAppOrEnv)(apiClient, applicationId, environmentId);
@@ -232,7 +232,7 @@ async function createDeployment(parsed) {
232
232
  await (0, branches_1.checkBranchNameAndAutoBranchMaybe)(workspaceId, apiClient, mablBranch, parsed['auto-branch']);
233
233
  const snapshotFromBranch = parsed['snapshot-from'];
234
234
  const httpHeaders = parsed['http-headers'];
235
- const scmMetadata = await collectSourceControlMetadataIfEnabled(parsed);
235
+ const scmMetadata = await attemptSourceControlMetadataCollection(parsed);
236
236
  const deploymentEvent = await apiClient.postDeploymentEvent({
237
237
  browserTypes: parsed.browsers,
238
238
  labels: parsed.labels,
@@ -247,7 +247,6 @@ async function createDeployment(parsed) {
247
247
  androidMobileAppFileId,
248
248
  iOSMobileAppFileId,
249
249
  mablBranch,
250
- runnerType,
251
250
  snapshotFromBranch,
252
251
  sourceControlMetadata: scmMetadata,
253
252
  deploymentIds,
@@ -291,8 +290,8 @@ function printDeploymentEventResultOutput(deploymentEventId, outputWebappLink, o
291
290
  }
292
291
  }
293
292
  exports.printDeploymentEventResultOutput = printDeploymentEventResultOutput;
294
- async function collectSourceControlMetadataIfEnabled(parsed) {
295
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
293
+ async function attemptSourceControlMetadataCollection(parsed) {
294
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
296
295
  const userSuppliedRepositoryUrl = parsed['repository-url'];
297
296
  if (await cliConfigProvider_1.CliConfigProvider.getConfigProperty(configKeys_1.configKeys.enableSourceControlMetadataCollection)) {
298
297
  const buildInfo = await new scmContextProvider_1.ScmContextProvider(process.env).extractScmAndBuildInfo();
@@ -314,6 +313,24 @@ async function collectSourceControlMetadataIfEnabled(parsed) {
314
313
  repoName: sourceControlRepoName,
315
314
  };
316
315
  }
316
+ const buildInfo = new scmContextProviderV2_1.ScmContextProviderV2(process.env).extractScmAndBuildInfo();
317
+ if (buildInfo) {
318
+ const sourceControlBranch = (_m = buildInfo === null || buildInfo === void 0 ? void 0 : buildInfo.buildInfo) === null || _m === void 0 ? void 0 : _m.branchName;
319
+ const sourceControlTag = (_o = buildInfo === null || buildInfo === void 0 ? void 0 : buildInfo.buildInfo) === null || _o === void 0 ? void 0 : _o.tagName;
320
+ const sourceControlRepoUrl = userSuppliedRepositoryUrl !== null && userSuppliedRepositoryUrl !== void 0 ? userSuppliedRepositoryUrl : (_p = buildInfo === null || buildInfo === void 0 ? void 0 : buildInfo.buildInfo) === null || _p === void 0 ? void 0 : _p.repoUrl;
321
+ const sourceControlRepoName = (_q = buildInfo === null || buildInfo === void 0 ? void 0 : buildInfo.buildInfo) === null || _q === void 0 ? void 0 : _q.repoName;
322
+ const revision = (_v = (_t = (_r = parsed.revision) !== null && _r !== void 0 ? _r : (_s = buildInfo === null || buildInfo === void 0 ? void 0 : buildInfo.buildInfo) === null || _s === void 0 ? void 0 : _s.commitSha) !== null && _t !== void 0 ? _t : (_u = buildInfo === null || buildInfo === void 0 ? void 0 : buildInfo.buildInfo) === null || _u === void 0 ? void 0 : _u.revision) !== null && _v !== void 0 ? _v : (_w = buildInfo === null || buildInfo === void 0 ? void 0 : buildInfo.buildInfo) === null || _w === void 0 ? void 0 : _w.revisionId;
323
+ return {
324
+ branchName: sourceControlBranch,
325
+ tag: sourceControlTag,
326
+ revision,
327
+ repoUrl: sourceControlRepoUrl,
328
+ repoName: sourceControlRepoName,
329
+ integrationType: (_x = buildInfo === null || buildInfo === void 0 ? void 0 : buildInfo.buildInfo) === null || _x === void 0 ? void 0 : _x.buildType,
330
+ buildInfoUrl: (_y = buildInfo === null || buildInfo === void 0 ? void 0 : buildInfo.buildInfo) === null || _y === void 0 ? void 0 : _y.buildInfoUrl,
331
+ buildId: (_z = buildInfo === null || buildInfo === void 0 ? void 0 : buildInfo.buildInfo) === null || _z === void 0 ? void 0 : _z.buildId,
332
+ };
333
+ }
317
334
  return {
318
335
  revision: parsed.revision,
319
336
  repoUrl: userSuppliedRepositoryUrl,
@@ -87,6 +87,17 @@ exports.builder = (yargs) => {
87
87
  hidden: false,
88
88
  type: 'string',
89
89
  })
90
+ .option(constants_1.CommandArgMablBranch, {
91
+ describe: 'Mabl branch to run test against',
92
+ nargs: 1,
93
+ type: 'string',
94
+ })
95
+ .option(constants_1.CommandArgMablBranchChangesOnly, {
96
+ describe: 'Only execute tests changed on specified mabl branch',
97
+ type: 'boolean',
98
+ default: false,
99
+ })
100
+ .implies(constants_1.CommandArgMablBranchChangesOnly, constants_1.CommandArgMablBranch)
90
101
  .option(constants_1.CommandArgLabelsInclude, {
91
102
  describe: 'Space delimited test labels. Run tests that match any label.',
92
103
  type: 'array',
@@ -96,6 +107,11 @@ exports.builder = (yargs) => {
96
107
  describe: 'Space delimited test labels. Exclude tests that match any label.',
97
108
  type: 'array',
98
109
  conflicts: [constants_1.CommandArgId],
110
+ })
111
+ .option(constants_1.CommandArgRecordVideoPath, {
112
+ hidden: true,
113
+ describe: 'The path of a directory to save a video recording of the test to',
114
+ type: 'string',
99
115
  })
100
116
  .implies(constants_1.CommandArgReporterOptions, constants_1.CommandArgReporter)
101
117
  .middleware(inferMobilePlatform)
@@ -138,6 +154,8 @@ async function run(parsed) {
138
154
  await validateSystemRequirements(platformName, parsed[constants_1.CommandArgMobileDeviceName]);
139
155
  const testRunnerConfig = {
140
156
  _cliCreated: true,
157
+ branchName: parsed[constants_1.CommandArgMablBranch],
158
+ branchChangesOnly: parsed[constants_1.CommandArgMablBranchChangesOnly],
141
159
  filterHttpRequests: false,
142
160
  labelsExclude: parsed[constants_1.CommandArgLabelsExclude],
143
161
  labelsInclude: parsed[constants_1.CommandArgLabelsInclude],
@@ -149,6 +167,7 @@ async function run(parsed) {
149
167
  path: parsed[constants_1.CommandArgMobileAppFile],
150
168
  platformName,
151
169
  avdName: parsed[constants_1.CommandArgMobileDeviceName],
170
+ recordVideoPath: parsed[constants_1.CommandArgRecordVideoPath],
152
171
  udid: parsed[constants_1.CommandArgMobileDeviceName],
153
172
  },
154
173
  };
@@ -175,7 +175,7 @@ Note: Setting the environment does not override the default URL. Please use the
175
175
  .option(constants_1.CommandArgTestInteractionSpeed, {
176
176
  describe: 'Set the speed that mabl interacts with webpages. Overrides test run settings if specified.',
177
177
  type: 'string',
178
- choices: Object.keys(mablApi_1.JourneyParameters.PageLoadWaitEnum).map((pageLoadWait) => pageLoadWait.toLowerCase()),
178
+ choices: Object.keys(mablApi_1.TestParameters.PageLoadWaitEnum).map((pageLoadWait) => pageLoadWait.toLowerCase()),
179
179
  })
180
180
  .option(constants_1.CommandArgBrowser, {
181
181
  describe: `Target browser to execute the test against, must be one of ${constants_1.ValidBrowserTypesForLocalRuns}, defaults to ${constants_1.DefaultBrowserType}`,