@mablhq/mabl-cli 2.51.18 → 2.51.28

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.
@@ -397,6 +397,10 @@ async function pullDownTestRunConfig(testRunId, apiClient) {
397
397
  const planRun = await apiClient.getPlanRun(journeyRun.parent_execution);
398
398
  const testDatatablevariables = ((_a = journeyRun === null || journeyRun === void 0 ? void 0 : journeyRun.journey_parameters) === null || _a === void 0 ? void 0 : _a.user_variables) &&
399
399
  (0, utils_1.variableRowAsScenario)((_b = journeyRun === null || journeyRun === void 0 ? void 0 : journeyRun.journey_parameters) === null || _b === void 0 ? void 0 : _b.user_variables);
400
+ const dataTableId = testDatatablevariables === null || testDatatablevariables === void 0 ? void 0 : testDatatablevariables.table_id;
401
+ if (dataTableId) {
402
+ await apiClient.getDataTable(dataTableId);
403
+ }
400
404
  return {
401
405
  basicAuthCredentialsId: ((_c = planRun === null || planRun === void 0 ? void 0 : planRun.run_policy) === null || _c === void 0 ? void 0 : _c.http_auth_credentials_required)
402
406
  ? (_d = planRun === null || planRun === void 0 ? void 0 : planRun.run_policy) === null || _d === void 0 ? void 0 : _d.http_auth_credentials_id
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.executeRunCloudTest = void 0;
6
7
  const mablApiClientFactory_1 = require("../../../api/mablApiClientFactory");
7
8
  const mablApi_1 = require("../../../mablApi");
8
9
  const constants_1 = require("../../constants");
@@ -12,6 +13,7 @@ const env_1 = require("../../../env/env");
12
13
  const pluralize_1 = __importDefault(require("pluralize"));
13
14
  const testsUtil_1 = require("../testsUtil");
14
15
  const loggingProvider_1 = require("../../../providers/logging/loggingProvider");
16
+ const runUtil_1 = require("../../../util/runUtil");
15
17
  const inquirer = require('inquirer');
16
18
  const chalk = require('chalk');
17
19
  const CommandArgTestId = constants_1.CommandArgId;
@@ -218,7 +220,7 @@ async function runInCloud(parsed) {
218
220
  return outputUrl;
219
221
  }
220
222
  async function executeRunCloudTest(test, browsers, branchName, apiClient, maybeDeploymentId, appUrl, apiUrl, credentialsId, applicationId, environmentId, basicAuthCredentialsId, localizationOptions) {
221
- var _a;
223
+ var _a, _b;
222
224
  const effectiveAppUrl = appUrl !== null && appUrl !== void 0 ? appUrl : (test.test_type === undefined || test.test_type === mablApi_1.TestTypeEnum.Browser
223
225
  ? test === null || test === void 0 ? void 0 : test.url
224
226
  : undefined);
@@ -243,9 +245,12 @@ async function executeRunCloudTest(test, browsers, branchName, apiClient, maybeD
243
245
  }
244
246
  if (applicationId || environmentId) {
245
247
  const deploymentsResult = await apiClient.queryDeploymentEntities(workspaceId);
248
+ const testType = (_a = test.test_type) !== null && _a !== void 0 ? _a : mablApi_1.TestTypeEnum.Browser;
249
+ const expectedDeploymentType = (0, runUtil_1.getExpectedDeploymentType)(testType);
246
250
  const foundDeployments = deploymentsResult.deployments
247
251
  ? deploymentsResult.deployments.filter((deployment) => (!applicationId || deployment.application_id === applicationId) &&
248
- (!environmentId || deployment.environment_id === environmentId))
252
+ (!environmentId || deployment.environment_id === environmentId) &&
253
+ deployment.deployment_type === expectedDeploymentType)
249
254
  : [];
250
255
  if (!foundDeployments.length) {
251
256
  throw new Error('No configuration was found for the applicationId/environmentId specified');
@@ -254,8 +259,9 @@ async function executeRunCloudTest(test, browsers, branchName, apiClient, maybeD
254
259
  }
255
260
  const planRun = await apiClient.postPlanRun(workspaceId, testId, branchName, browsers, effectiveAppUrl, effectiveApiUrl, maybeDeploymentId, credentialsId, deploymentIds, basicAuthCredentialsId, localizationOptions);
256
261
  const testRunsQueryResult = await apiClient.getTestRunsForPlan(planRun.id);
257
- return (_a = testRunsQueryResult.test_script_executions) !== null && _a !== void 0 ? _a : [];
262
+ return (_b = testRunsQueryResult.test_script_executions) !== null && _b !== void 0 ? _b : [];
258
263
  }
264
+ exports.executeRunCloudTest = executeRunCloudTest;
259
265
  async function getJourneysForLabels(workspaceId, branchName, branchChangesOnly, labelsInclude, labelsExclude, limit, prompt, apiClient) {
260
266
  var _a;
261
267
  const journeys = await apiClient.getJourneys({
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.PRE_REQUEST_LISTEN = exports.convertMablAssertionsToExecArray = exports.convertMablVariableAssignmentsToExecArray = exports.createMablGeneratedScripts = exports.insertMablAssertionScripts = exports.toPostmanScript = exports.replaceVariables = exports.getActualValue = exports.readBody = exports.getResponseContentType = exports.valueToUnquotedString = exports.assertionTypeSupportsCaseSensitivity = exports.assertionTargetSupportsCaseSensitivity = exports.humanizeAssertion = exports.getAssertionTargetArgument = exports.assertionHasTest = exports.isValidMablAssertion = exports.normalizeRegExpExpectedValue = exports.normalizeExpectedValue = exports.normalizeAssertionValue = exports.assertionRequiresValue = exports.filterValidMablAssertions = exports.filterValidMablVariableAssignments = exports.isValidMablVariableAssignment = exports.removeMablGeneratedScripts = exports.createEmptyRequestEvent = exports.findFirstMatchingEvent = exports.restoreCustomRequestFields = exports.deduplicateApiTestExecutionResults = exports.createEmptyVariable = exports.createEmptyAssertion = exports.humanizeAssertionType = exports.getAssertionTypesForTarget = exports.caseInsensitiveEquals = exports.compareStringsCaseInsensitive = exports.ASSERT_TYPES = exports.ASSERT_TARGETS = exports.COLLECTION_WITH_FOLDERS_ERROR = exports.HMAC_SHA1_SIGNATURE = exports.DEFAULT_ADD_OAUTH1_TO_HEADER_VALUE = exports.DEFAULT_OAUTH1_VERSION = exports.OAUTH1_AUTH = exports.NO_AUTH = exports.BEARER_TOKEN_AUTH = exports.BASIC_AUTH = exports.API_KEY_AUTH = exports.INHERIT_AUTH_FROM_PARENT_VALUE = exports.MABL_GENERATED_COMMENT = exports.MABL_GENERATED_ASSERTION_TOKEN = exports.TEST_LISTEN = void 0;
7
- exports.uuid = exports.postmanEventToExecutableSnippets = exports.postmanAuthToApiTestAuth = exports.getValueFromAuthVariables = exports.executableSnippetToApiTestSnippet = exports.executableSnippetsToPostmanEvent = exports.apiTestAuthToPostmanAuth = exports.insertTestConfigurationIntoFlow = exports.createCommentForApiTestSnippet = exports.convertMablSnippetsToExecArray = exports.createPostmanScript = exports.insertMablScriptsIntoCollection = exports.processPostmanItem = exports.replaceRawScriptWithExecArray = exports.removeInvalidHeaders = exports.processItemAuth = exports.mablAuthToPostman = exports.formatContent = exports.getRequestMode = exports.getFormDataArray = exports.isText = exports.isXML = exports.isJson = exports.isSupportedAuthType = exports.isItemDefinition = exports.isCollectionDefinition = exports.isItemGroupDefinition = exports.isFolder = exports.validateCollectionFeaturesForApiTestEditor = exports.generateRawScriptField = exports.processPostmanItems = exports.createEmptyRequest = exports.createEmptyRequestEventArray = exports.splitLines = void 0;
7
+ exports.uuid = exports.postmanEventToExecutableSnippets = exports.postmanAuthToApiTestAuth = exports.getValueFromAuthVariables = exports.executableSnippetToApiTestSnippet = exports.executableSnippetsToPostmanEvent = exports.apiTestAuthToPostmanAuth = exports.insertTestConfigurationIntoFlow = exports.createCommentForApiTestSnippet = exports.convertMablSnippetsToExecArray = exports.createPostmanScript = exports.insertMablScriptsIntoCollection = exports.processPostmanItem = exports.replaceRawScriptWithExecArray = exports.removeInvalidHeaders = exports.processItemAuth = exports.mablAuthToPostman = exports.formatContent = exports.getRequestMode = exports.getFormDataArray = exports.isBinary = exports.isText = exports.isXML = exports.isJson = exports.isSupportedAuthType = exports.isItemDefinition = exports.isCollectionDefinition = exports.isItemGroupDefinition = exports.isFolder = exports.validateCollectionFeaturesForApiTestEditor = exports.generateRawScriptField = exports.processPostmanItems = exports.createEmptyRequest = exports.createEmptyRequestEventArray = exports.splitLines = void 0;
8
8
  const newman_types_1 = require("./newman-types");
9
9
  const lodash_1 = __importDefault(require("lodash"));
10
10
  const uuid_1 = require("uuid");
@@ -28,12 +28,14 @@ exports.COLLECTION_WITH_FOLDERS_ERROR = 'Collections with folders are not suppor
28
28
  const RESPONSE_PROPERTIES = {
29
29
  Size: 'size().body',
30
30
  Status: 'code',
31
+ TextBody: 'text()',
31
32
  };
32
33
  exports.ASSERT_TARGETS = [
33
34
  { label: 'Header', value: newman_types_1.AssertionTarget.Header },
34
35
  { label: 'Status', value: newman_types_1.AssertionTarget.Status },
35
36
  { label: 'Size', value: newman_types_1.AssertionTarget.Size },
36
37
  { label: 'JSON Body', value: newman_types_1.AssertionTarget.JSONBody },
38
+ { label: 'Text Body', value: newman_types_1.AssertionTarget.TextBody },
37
39
  ];
38
40
  exports.ASSERT_TYPES = [
39
41
  { label: 'Equals', value: newman_types_1.AssertionType.Equals },
@@ -100,6 +102,7 @@ function getAssertionTypesForTarget(target) {
100
102
  ].includes(assertType.value));
101
103
  case newman_types_1.AssertionTarget.Header:
102
104
  case newman_types_1.AssertionTarget.JSONBody:
105
+ case newman_types_1.AssertionTarget.TextBody:
103
106
  default:
104
107
  return exports.ASSERT_TYPES;
105
108
  }
@@ -134,19 +137,29 @@ function humanizeAssertionType(assertionType) {
134
137
  }
135
138
  }
136
139
  exports.humanizeAssertionType = humanizeAssertionType;
137
- function createEmptyAssertion() {
140
+ function createEmptyAssertion(contentType) {
141
+ const isJsonContent = !contentType || isJson(contentType);
138
142
  return {
139
143
  id: (0, uuid_1.v4)(),
140
- assertTarget: newman_types_1.AssertionTarget.JSONBody,
144
+ assertTarget: isJsonContent
145
+ ? newman_types_1.AssertionTarget.JSONBody
146
+ : isText(contentType) || isXML(contentType)
147
+ ? newman_types_1.AssertionTarget.TextBody
148
+ : newman_types_1.AssertionTarget.Header,
141
149
  assertType: newman_types_1.AssertionType.Present,
142
150
  description: '',
143
151
  };
144
152
  }
145
153
  exports.createEmptyAssertion = createEmptyAssertion;
146
- function createEmptyVariable() {
154
+ function createEmptyVariable(contentType) {
155
+ const isJsonContent = !contentType || isJson(contentType);
147
156
  return {
148
157
  id: (0, uuid_1.v4)(),
149
- assertTarget: newman_types_1.AssertionTarget.JSONBody,
158
+ assertTarget: isJsonContent
159
+ ? newman_types_1.AssertionTarget.JSONBody
160
+ : isText(contentType) || isXML(contentType)
161
+ ? newman_types_1.AssertionTarget.TextBody
162
+ : newman_types_1.AssertionTarget.Header,
150
163
  variableName: '',
151
164
  description: '',
152
165
  };
@@ -337,6 +350,9 @@ function isValidMablAssertion(assertion) {
337
350
  valid =
338
351
  isValidSizeAssertionType(assertion.assertType) && hasExpectedValue;
339
352
  break;
353
+ case 'TextBody':
354
+ valid = hasExpectedValue;
355
+ break;
340
356
  }
341
357
  return valid;
342
358
  }
@@ -379,17 +395,22 @@ function getAssertionTargetArgument(assertion) {
379
395
  }
380
396
  exports.getAssertionTargetArgument = getAssertionTargetArgument;
381
397
  function humanizeAssertion(assertion) {
398
+ var _a, _b;
382
399
  const { assertTarget, assertType, value, description } = assertion;
383
400
  if (description && description !== '') {
384
401
  return description;
385
402
  }
403
+ const humanizedAssertTarget = (_b = (_a = exports.ASSERT_TARGETS.filter((target) => target.value === assertTarget)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.label;
386
404
  if (assertionHasTest(assertion)) {
387
405
  const assertionTargetArgument = getAssertionTargetArgument(assertion);
388
- const humanized = `${exports.ASSERT_TARGETS.filter((target) => target.value === assertTarget)[0].label}${assertionTargetArgument ? ` ${assertionTargetArgument}` : ''} ${humanizeAssertionType(assertType)}`;
406
+ const humanized = `${humanizedAssertTarget}${assertionTargetArgument ? ` ${assertionTargetArgument}` : ''} ${humanizeAssertionType(assertType)}`;
389
407
  return assertionRequiresValue(assertion)
390
408
  ? `${humanized} ${value}`
391
409
  : humanized;
392
410
  }
411
+ if (assertType && humanizedAssertTarget) {
412
+ return `${humanizedAssertTarget} ${humanizeAssertionType(assertType)}`;
413
+ }
393
414
  return '';
394
415
  }
395
416
  exports.humanizeAssertion = humanizeAssertion;
@@ -412,6 +433,8 @@ function generateAssertionScript(assertion) {
412
433
  return generateHeaderAssertion(description, assertType, assertion.headerName, expectedValue, caseSensitive);
413
434
  case 'Size':
414
435
  return generateSizeAssertion(description, assertTarget, assertType, expectedValue);
436
+ case 'TextBody':
437
+ return generateTextBodyAssertion(description, assertType, expectedValue, caseSensitive);
415
438
  }
416
439
  return;
417
440
  }
@@ -552,6 +575,31 @@ function generateSizeAssertion(description, target, type, expectedValue) {
552
575
  }
553
576
  return generateSimpleAssertion(description, target, type, expectedValue);
554
577
  }
578
+ function generateTextBodyAssertion(description, assertType, expectedValue, caseSensitive) {
579
+ let target = 'pm.response.text()';
580
+ switch (assertType) {
581
+ case 'Present':
582
+ case 'NotPresent':
583
+ case 'Equals':
584
+ case 'NotEquals':
585
+ case 'Contains':
586
+ case 'DoesNotContain':
587
+ case 'StartsWith':
588
+ case 'EndsWith':
589
+ case 'MatchesRegExp':
590
+ break;
591
+ case 'GreaterThan':
592
+ case 'GreaterThanOrEqualTo':
593
+ case 'LessThan':
594
+ case 'LessThanOrEqualTo':
595
+ target = `parseFloat(${target})`;
596
+ expectedValue = `parseFloat(${expectedValue})`;
597
+ break;
598
+ default:
599
+ throw new Error(`Unexpected header assert type: ${assertType}`);
600
+ }
601
+ return generatePostmanAssertion(description, target, assertType, expectedValue, caseSensitive);
602
+ }
555
603
  function generateSimpleAssertion(description, target, type, expectedValue, caseSensitive = true) {
556
604
  return generatePostmanTest(description, generatePostmanExpect(getResponseProperty(target), type, expectedValue, caseSensitive));
557
605
  }
@@ -579,6 +627,7 @@ function assertionTargetSupportsCaseSensitivity(assertTarget) {
579
627
  switch (assertTarget) {
580
628
  case 'Header':
581
629
  case 'JSONBody':
630
+ case 'TextBody':
582
631
  return true;
583
632
  default:
584
633
  return false;
@@ -653,13 +702,13 @@ function readBody(body, contentType) {
653
702
  }
654
703
  exports.readBody = readBody;
655
704
  function getActualValue(assertion, apiStepExecutionResult, variables) {
656
- var _a, _b, _c, _d, _e;
705
+ var _a, _b, _c, _d, _e, _f;
657
706
  const { assertTarget, bodyPath, headerName } = assertion;
707
+ const contentType = getResponseContentType(apiStepExecutionResult.response);
658
708
  switch (assertTarget) {
659
709
  case newman_types_1.AssertionTarget.Header:
660
710
  return ((_b = (_a = apiStepExecutionResult.response) === null || _a === void 0 ? void 0 : _a.header) !== null && _b !== void 0 ? _b : []).find((header) => caseInsensitiveEquals(header.key, headerName));
661
711
  case newman_types_1.AssertionTarget.JSONBody:
662
- const contentType = getResponseContentType(apiStepExecutionResult.response);
663
712
  const content = readBody((_c = apiStepExecutionResult.response) === null || _c === void 0 ? void 0 : _c.stream, contentType);
664
713
  return bodyPath
665
714
  ? lodash_1.default.get(content, replaceVariables(bodyPath, variables))
@@ -668,6 +717,8 @@ function getActualValue(assertion, apiStepExecutionResult, variables) {
668
717
  return (_d = apiStepExecutionResult.response) === null || _d === void 0 ? void 0 : _d.responseSize;
669
718
  case newman_types_1.AssertionTarget.Status:
670
719
  return (_e = apiStepExecutionResult.response) === null || _e === void 0 ? void 0 : _e.code;
720
+ case newman_types_1.AssertionTarget.TextBody:
721
+ return readBody((_f = apiStepExecutionResult.response) === null || _f === void 0 ? void 0 : _f.stream, contentType);
671
722
  }
672
723
  return null;
673
724
  }
@@ -822,6 +873,10 @@ function isText(contentType) {
822
873
  return contentTypeMatches(contentType, (ct) => ct.startsWith('text/'));
823
874
  }
824
875
  exports.isText = isText;
876
+ function isBinary(contentType) {
877
+ return contentTypeMatches(contentType, (ct) => ct.startsWith('image/'), (ct) => ct.startsWith('audio/'), (ct) => ct.startsWith('video/'), (ct) => ct.startsWith('application/octet-stream'), (ct) => ct.startsWith('application/zip'), (ct) => ct.startsWith('application/gzip'), (ct) => ct.startsWith('application/x-gzip'), (ct) => ct.startsWith('application/x-tar'), (ct) => ct.startsWith('application/x-rar-compressed'), (ct) => ct.startsWith('application/x-7z-compressed'), (ct) => ct.startsWith('application/x-bzip'), (ct) => ct.startsWith('application/x-rar'));
878
+ }
879
+ exports.isBinary = isBinary;
825
880
  function contentTypeMatches(contentType, ...predicates) {
826
881
  if (!contentType) {
827
882
  return false;
@@ -22,8 +22,9 @@ function exportVariables(postmanResult) {
22
22
  ].filter((variables) => !!variables);
23
23
  const exportedVariables = {};
24
24
  variablePrecedence
25
- .map((variableList) => variableList.all())
26
- .forEach((variables) => variables.forEach((variable) => (exportedVariables[variable.key] = variable.value)));
25
+ .flatMap((variableList) => variableList.all())
26
+ .filter((variable) => { var _a; return Boolean(variable.key) && !((_a = variable.key) === null || _a === void 0 ? void 0 : _a.startsWith(VariableUtils_1.FLOW_NAMESPACE)); })
27
+ .forEach((variable) => (exportedVariables[variable.key] = variable.value));
27
28
  return exportedVariables;
28
29
  }
29
30
  exports.exportVariables = exportVariables;
@@ -11,7 +11,7 @@ exports.API_CREDENTIALS_USERNAME_VARIABLE_NAME = `${exports.API_CREDENTIALS_NAME
11
11
  exports.API_CREDENTIALS_PASSWORD_VARIABLE_NAME = `${exports.API_CREDENTIALS_NAMESPACE}password`;
12
12
  function generateVariablesSummaryForImport(variableSources) {
13
13
  var _a, _b, _c, _d, _e, _f, _g, _h;
14
- const { environment, scenario, url, credentials, plan, flow, journeyRun, previousFlowVariables, } = variableSources;
14
+ const { environment, scenario, url, credentials, plan, flow, journeyRun, previousFlowVariables, flowConfiguration, } = variableSources;
15
15
  const summary = {
16
16
  dataDriven: {},
17
17
  effective: {},
@@ -47,10 +47,12 @@ function generateVariablesSummaryForImport(variableSources) {
47
47
  precedence.forEach((variables) => Object.keys(variables).forEach((name) => (summary.effective[name] = variables[name])));
48
48
  if (flow === null || flow === void 0 ? void 0 : flow.parameters) {
49
49
  flow.parameters.forEach((parameter) => {
50
- const parameterName = removePrefix(parameter.name, exports.FLOW_NAMESPACE);
51
- summary.flow[parameterName] = parameter.default_value;
50
+ var _a, _b;
51
+ const parameterName = `${exports.FLOW_NAMESPACE}${parameter.name}`;
52
+ const parameterValue = (_b = (_a = flowConfiguration === null || flowConfiguration === void 0 ? void 0 : flowConfiguration.parameters) === null || _a === void 0 ? void 0 : _a[parameter.name]) !== null && _b !== void 0 ? _b : parameter.default_value;
53
+ summary.flow[parameterName] = parameterValue;
52
54
  if (!summary.effective[parameterName]) {
53
- summary.effective[parameterName] = parameter.default_value;
55
+ summary.effective[parameterName] = parameterValue;
54
56
  }
55
57
  });
56
58
  }
@@ -7,6 +7,7 @@ var AssertionTarget;
7
7
  AssertionTarget["JSONBody"] = "JSONBody";
8
8
  AssertionTarget["Size"] = "Size";
9
9
  AssertionTarget["Status"] = "Status";
10
+ AssertionTarget["TextBody"] = "TextBody";
10
11
  })(AssertionTarget || (exports.AssertionTarget = AssertionTarget = {}));
11
12
  var AssertionType;
12
13
  (function (AssertionType) {
@@ -9,6 +9,7 @@ const util_1 = require("../util");
9
9
  const openUtils_1 = require("./openUtils");
10
10
  const util_2 = require("../../commands/commandUtil/util");
11
11
  const loggingProvider_1 = require("../../providers/logging/loggingProvider");
12
+ const rbacUtils_1 = require("../../util/rbacUtils");
12
13
  const chalk = require('chalk');
13
14
  exports.DEFAULT_HEIGHT = 800;
14
15
  exports.DEFAULT_WIDTH = 1000;
@@ -40,6 +41,7 @@ async function trainNewTest(trainingSessionOptions) {
40
41
  process.exit(1);
41
42
  }
42
43
  }
44
+ await (0, rbacUtils_1.dataTablesRbacPreflight)(apiClient, dataTableIds);
43
45
  if (applicationId) {
44
46
  await apiClient.getApplication(applicationId);
45
47
  }
@@ -110,6 +112,7 @@ async function editTest(trainingSessionOptions) {
110
112
  if (test.default) {
111
113
  throw new Error('Editing of the mabl default supplied tests is not supported');
112
114
  }
115
+ await (0, rbacUtils_1.dataTablesRbacPreflight)(apiClient, test === null || test === void 0 ? void 0 : test.datatables);
113
116
  if (!((_g = test.flows) === null || _g === void 0 ? void 0 : _g.length) && test.test_type !== mablApi_1.TestTypeEnum.Performance) {
114
117
  throw new Error(util_2.TEST_WITHOUT_FLOWS_MESSAGE);
115
118
  }