@mablhq/mabl-cli 1.40.12 → 1.42.7
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/api/basicApiClient.js +3 -2
- package/cli.js +0 -0
- package/commands/tests/tests_cmds/create.js +1 -1
- package/core/execution/ApiTestUtils.js +41 -1
- package/core/trainer/openUtils.js +2 -2
- package/core/trainer/trainingSessions-types.js +35 -0
- package/core/trainer/trainingSessions.js +52 -34
- package/execution/index.js +1 -1
- package/http/MablHttpAgent.js +73 -0
- package/http/RequestFilteringHttpAgent.js +119 -0
- package/http/RequestSecurityError.js +9 -0
- package/{util/httpUtil.js → http/axiosProxyConfig.js} +3 -6
- package/http/httpUtil.js +54 -0
- package/http/requestInterceptor.js +187 -0
- package/mablscript/MablAction.js +19 -1
- package/mablscript/MablStep.js +0 -17
- package/mablscript/actions/ConditionAction.js +7 -2
- package/mablscript/steps/AssertStep.js +24 -15
- package/mablscript/steps/IfConditionStep.js +8 -1
- package/mablscript/steps/ReleaseStep.js +2 -1
- package/mablscript/steps/SelectStep.js +1 -1
- package/mablscript/steps/SetFilesStep.js +2 -1
- package/mablscript/steps/SyntheticStep.js +1 -1
- package/package.json +3 -3
- package/providers/authenticationProvider.js +2 -2
- package/providers/cliConfigProvider.js +1 -1
- package/util/encodingUtil.js +37 -0
- package/util/fileUploadUtil.js +2 -2
|
@@ -158,12 +158,16 @@ class AssertStep extends MablStep_1.MablStep {
|
|
|
158
158
|
throw new Error(`Error generating step descriptor for ${this.getStepName()}: Unexpected find type ${find.findType}`);
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
|
+
if (this.conditionAction.options) {
|
|
162
|
+
formatted.conditionOptions = this.conditionAction.options;
|
|
163
|
+
}
|
|
161
164
|
return result;
|
|
162
165
|
}
|
|
163
166
|
static fromYaml(stepName, stepArgs) {
|
|
164
167
|
const actions = [];
|
|
165
168
|
const assertionType = exports.assertionStepToField[stepName];
|
|
166
169
|
const assertionValue = stepArgs.assertionValue;
|
|
170
|
+
const conditionOptions = stepArgs.conditionOptions;
|
|
167
171
|
let primaryAction;
|
|
168
172
|
if (stepArgs.kind === GetCurrentLocationDescriptor_1.GET_CURRENT_LOCATION_KIND) {
|
|
169
173
|
primaryAction = new GetUrlAction_1.GetUrlAction(GetUrlAction_1.GetUrlAction.mablScriptStepNames[0], []);
|
|
@@ -188,6 +192,7 @@ class AssertStep extends MablStep_1.MablStep {
|
|
|
188
192
|
actions.push(new ConditionAction_1.ConditionAction('evaluate_condition', [
|
|
189
193
|
assertionType,
|
|
190
194
|
assertionValue,
|
|
195
|
+
conditionOptions,
|
|
191
196
|
]));
|
|
192
197
|
}
|
|
193
198
|
return new AssertStep('assert', [
|
|
@@ -198,6 +203,7 @@ class AssertStep extends MablStep_1.MablStep {
|
|
|
198
203
|
], actions);
|
|
199
204
|
}
|
|
200
205
|
produceSelIdeFormattedSteps(stepIndex) {
|
|
206
|
+
var _a;
|
|
201
207
|
const find = this.primaryAction.toDescriptor();
|
|
202
208
|
if (!(0, GetCurrentLocationDescriptor_1.isGetCurrentLocationDescriptor)(find) &&
|
|
203
209
|
!(0, GetVariableDescriptor_1.isGetVariableDescriptor)(find) &&
|
|
@@ -231,7 +237,7 @@ class AssertStep extends MablStep_1.MablStep {
|
|
|
231
237
|
!(0, GetVariableDescriptor_1.isGetVariableDescriptor)(find) &&
|
|
232
238
|
find.findType === domUtil_1.FindType.FIND_ONE &&
|
|
233
239
|
find.findTarget.selector.xpath) ||
|
|
234
|
-
'', this.extractAction ? this.extractAction.extractionAttribute : '', this.substituteSeleniumVariable(this.conditionAction.conditionValueAttribute || ''), this.assertionType, this);
|
|
240
|
+
'', this.extractAction ? this.extractAction.extractionAttribute : '', this.substituteSeleniumVariable(this.conditionAction.conditionValueAttribute || ''), this.assertionType, this, (_a = this.conditionAction.options) === null || _a === void 0 ? void 0 : _a.caseInsensitive);
|
|
235
241
|
}
|
|
236
242
|
unsupportedSelIdeExportStep() {
|
|
237
243
|
const seleniumStep = (0, SeleniumIdeStep_1.buildSeleniumIdeStep)('echo', this);
|
|
@@ -246,7 +252,7 @@ class AssertStep extends MablStep_1.MablStep {
|
|
|
246
252
|
var _a, _b;
|
|
247
253
|
const assertAction = `.assert(${!!(((_a = this.assertArguments) === null || _a === void 0 ? void 0 : _a.onFailure) ||
|
|
248
254
|
((_b = this.assertArguments) === null || _b === void 0 ? void 0 : _b.observationScope))
|
|
249
|
-
?
|
|
255
|
+
? (0, MablAction_1.convertObjectToMablscriptArgs)(this.assertArguments)
|
|
250
256
|
: ''})`;
|
|
251
257
|
if (this.countAction) {
|
|
252
258
|
return `${this.primaryAction.toMablscript()}.${this.countAction.toMablscript()}.${this.conditionAction.toMablscript()}${assertAction}`;
|
|
@@ -273,7 +279,7 @@ class AssertStep extends MablStep_1.MablStep {
|
|
|
273
279
|
exports.AssertStep = AssertStep;
|
|
274
280
|
AssertStep.mablScriptStepNames = ['assert'];
|
|
275
281
|
AssertStep.yamlMablScriptNames = yamlMablScriptNames();
|
|
276
|
-
function buildSeleniumIdeJsAssertion(stepIndex, xpath, assertionAttribute, assertAgainst, assertionType, step) {
|
|
282
|
+
function buildSeleniumIdeJsAssertion(stepIndex, xpath, assertionAttribute, assertAgainst, assertionType, step, caseInsensitive = false) {
|
|
277
283
|
const variableName = `assertVariable-${stepIndex}`;
|
|
278
284
|
let storeAttribute;
|
|
279
285
|
if (assertionAttribute !== 'innerText') {
|
|
@@ -286,42 +292,45 @@ function buildSeleniumIdeJsAssertion(stepIndex, xpath, assertionAttribute, asser
|
|
|
286
292
|
}
|
|
287
293
|
storeAttribute.value = variableName;
|
|
288
294
|
let condition = '';
|
|
295
|
+
const toLowerCaseString = caseInsensitive
|
|
296
|
+
? '.toUpperCase().toLowerCase()'
|
|
297
|
+
: '';
|
|
289
298
|
switch (assertionType) {
|
|
290
299
|
case 'equals':
|
|
291
|
-
condition = `\${${variableName}} !== '${assertAgainst}'`;
|
|
300
|
+
condition = `\${${variableName}}${toLowerCaseString} !== '${assertAgainst}'${toLowerCaseString}`;
|
|
292
301
|
break;
|
|
293
302
|
case 'does_not_equal':
|
|
294
|
-
condition = `\${${variableName}} === '${assertAgainst}'`;
|
|
303
|
+
condition = `\${${variableName}}${toLowerCaseString} === '${assertAgainst}'${toLowerCaseString}`;
|
|
295
304
|
break;
|
|
296
305
|
case 'contains':
|
|
297
|
-
condition = `!\${${variableName}}.includes('${assertAgainst}')`;
|
|
306
|
+
condition = `!\${${variableName}}${toLowerCaseString}.includes('${assertAgainst}'${toLowerCaseString})`;
|
|
298
307
|
break;
|
|
299
308
|
case 'does_not_contain':
|
|
300
|
-
condition = `\${${variableName}}.includes('${assertAgainst}')`;
|
|
309
|
+
condition = `\${${variableName}}${toLowerCaseString}.includes('${assertAgainst}'${toLowerCaseString})`;
|
|
301
310
|
break;
|
|
302
311
|
case 'starts_with':
|
|
303
|
-
condition = `!\${${variableName}}.startsWith('${assertAgainst}')`;
|
|
312
|
+
condition = `!\${${variableName}}${toLowerCaseString}.startsWith('${assertAgainst}'${toLowerCaseString})`;
|
|
304
313
|
break;
|
|
305
314
|
case 'starts_without':
|
|
306
|
-
condition = `\${${variableName}}.startsWith('${assertAgainst}')`;
|
|
315
|
+
condition = `\${${variableName}}${toLowerCaseString}.startsWith('${assertAgainst}'${toLowerCaseString})`;
|
|
307
316
|
break;
|
|
308
317
|
case 'ends_with':
|
|
309
|
-
condition = `!\${${variableName}}.endsWith('${assertAgainst}')`;
|
|
318
|
+
condition = `!\${${variableName}}${toLowerCaseString}.endsWith('${assertAgainst}'${toLowerCaseString})`;
|
|
310
319
|
break;
|
|
311
320
|
case 'ends_without':
|
|
312
|
-
condition = `\${${variableName}}.endsWith('${assertAgainst}')`;
|
|
321
|
+
condition = `\${${variableName}}${toLowerCaseString}.endsWith('${assertAgainst}'${toLowerCaseString})`;
|
|
313
322
|
break;
|
|
314
323
|
case 'greater_than':
|
|
315
|
-
condition = `!\${${variableName}} > '${assertAgainst}'`;
|
|
324
|
+
condition = `!\${${variableName}}${toLowerCaseString} > '${assertAgainst}'${toLowerCaseString}`;
|
|
316
325
|
break;
|
|
317
326
|
case 'less_than':
|
|
318
|
-
condition = `!\${${variableName}} < '${assertAgainst}'`;
|
|
327
|
+
condition = `!\${${variableName}}${toLowerCaseString} < '${assertAgainst}'${toLowerCaseString}`;
|
|
319
328
|
break;
|
|
320
329
|
case 'greater_than_or_equals':
|
|
321
|
-
condition = `!\${${variableName}} >= '${assertAgainst}'`;
|
|
330
|
+
condition = `!\${${variableName}}${toLowerCaseString} >= '${assertAgainst}'${toLowerCaseString}`;
|
|
322
331
|
break;
|
|
323
332
|
case 'less_than_or_equals':
|
|
324
|
-
condition = `!\${${variableName}} <= '${assertAgainst}'`;
|
|
333
|
+
condition = `!\${${variableName}}${toLowerCaseString} <= '${assertAgainst}'${toLowerCaseString}`;
|
|
325
334
|
break;
|
|
326
335
|
}
|
|
327
336
|
const ifStep = (0, SeleniumIdeStep_1.buildSeleniumIdeStep)('if', step);
|
|
@@ -59,6 +59,9 @@ class IfConditionStep extends MablStep_1.MablStep {
|
|
|
59
59
|
if (this.conditionAction.conditionValueAttribute) {
|
|
60
60
|
details.conditionValue = this.conditionAction.conditionValueAttribute;
|
|
61
61
|
}
|
|
62
|
+
if (this.conditionAction.options !== undefined) {
|
|
63
|
+
details.conditionOptions = this.conditionAction.options;
|
|
64
|
+
}
|
|
62
65
|
}
|
|
63
66
|
if (this.primaryAction instanceof GetVariableValue_1.GetVariableValue) {
|
|
64
67
|
details.variableName = this.substituteMablscriptVariable(this.primaryAction.variable);
|
|
@@ -115,7 +118,11 @@ class IfConditionStep extends MablStep_1.MablStep {
|
|
|
115
118
|
const conditionType = AssertStep_1.assertionStepToField[stepArgs.condition];
|
|
116
119
|
actions.push(new ConditionAction_1.ConditionAction(conditionType === 'present' || conditionType === 'not_present'
|
|
117
120
|
? 'evaluate_presence'
|
|
118
|
-
: 'evaluate_condition', [
|
|
121
|
+
: 'evaluate_condition', [
|
|
122
|
+
AssertStep_1.assertionStepToField[stepArgs.condition],
|
|
123
|
+
stepArgs.conditionValue,
|
|
124
|
+
stepArgs.conditionOptions,
|
|
125
|
+
]));
|
|
119
126
|
}
|
|
120
127
|
return actions;
|
|
121
128
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ReleaseStep = void 0;
|
|
4
4
|
const FindAction_1 = require("../actions/FindAction");
|
|
5
5
|
const MablStep_1 = require("../MablStep");
|
|
6
|
+
const MablAction_1 = require("../MablAction");
|
|
6
7
|
const domUtil_1 = require("../../domUtil");
|
|
7
8
|
const ActionsUtils_1 = require("./ActionsUtils");
|
|
8
9
|
class ReleaseStep extends MablStep_1.MablStep {
|
|
@@ -55,7 +56,7 @@ class ReleaseStep extends MablStep_1.MablStep {
|
|
|
55
56
|
return new ReleaseStep('release', [], [FindAction_1.FindAction.findActionFromStepArgs(stepArgs)]);
|
|
56
57
|
}
|
|
57
58
|
toMablscript() {
|
|
58
|
-
const args =
|
|
59
|
+
const args = (0, MablAction_1.convertObjectToMablscriptArgs)(this.releaseArgs);
|
|
59
60
|
return `${this.findAction.toMablscript()}.release(${args})`;
|
|
60
61
|
}
|
|
61
62
|
getInputVariables() {
|
|
@@ -62,7 +62,7 @@ class SelectStep extends MablStep_1.MablStep {
|
|
|
62
62
|
const selectOptionType = this.selectOptionType
|
|
63
63
|
? `, "${this.selectOptionType}"`
|
|
64
64
|
: '';
|
|
65
|
-
return `${this.findAction.toMablscript()}.select(${
|
|
65
|
+
return `${this.findAction.toMablscript()}.select(${(0, MablAction_1.convertObjectToMablscriptArgs)(this.selectOptions)}${selectOptionType})`;
|
|
66
66
|
}
|
|
67
67
|
getInputVariables() {
|
|
68
68
|
return (0, MablAction_1.distinctStrings)([
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SetFilesStep = void 0;
|
|
4
4
|
const FindAction_1 = require("../actions/FindAction");
|
|
5
|
+
const MablAction_1 = require("../MablAction");
|
|
5
6
|
const MablStep_1 = require("../MablStep");
|
|
6
7
|
const domUtil_1 = require("../../domUtil");
|
|
7
8
|
class SetFilesStep extends MablStep_1.MablStep {
|
|
@@ -51,7 +52,7 @@ class SetFilesStep extends MablStep_1.MablStep {
|
|
|
51
52
|
}
|
|
52
53
|
toMablscript() {
|
|
53
54
|
const files = this.files
|
|
54
|
-
.map((key) =>
|
|
55
|
+
.map((key) => (0, MablAction_1.convertObjectToMablscriptArgs)(key))
|
|
55
56
|
.join(', ');
|
|
56
57
|
return `${this.findAction.toMablscript()}.set_files(${files})`;
|
|
57
58
|
}
|
|
@@ -4,7 +4,7 @@ exports.SyntheticStep = exports.DEFAULT_STEP_SOURCE_INDEX_IN_FLOW = void 0;
|
|
|
4
4
|
const MablStep_1 = require("../MablStep");
|
|
5
5
|
exports.DEFAULT_STEP_SOURCE_INDEX_IN_FLOW = -1;
|
|
6
6
|
class SyntheticStep extends MablStep_1.MablStep {
|
|
7
|
-
constructor(name, args, actions, stepSourceIndexInFlow = exports.DEFAULT_STEP_SOURCE_INDEX_IN_FLOW) {
|
|
7
|
+
constructor(name, args = [], actions = [], stepSourceIndexInFlow = exports.DEFAULT_STEP_SOURCE_INDEX_IN_FLOW) {
|
|
8
8
|
super(name, args, actions);
|
|
9
9
|
this.stepSourceIndexInFlow = stepSourceIndexInFlow;
|
|
10
10
|
this.actionSourceIndexInStep = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mablhq/mabl-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.42.7",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "The official mabl command line interface tool",
|
|
6
6
|
"main": "index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@mablhq/newman-reporter-mabl-console": "0.1.0",
|
|
24
|
-
"@playwright/test": "1.25.
|
|
24
|
+
"@playwright/test": "1.25.2",
|
|
25
25
|
"@types/fs-extra": "8.1.1",
|
|
26
26
|
"@types/serve-handler": "6.1.0",
|
|
27
27
|
"@types/tmp": "0.2.0",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"newman": "5.3.2",
|
|
67
67
|
"open": "6.4.0",
|
|
68
68
|
"ora": "4.0.4",
|
|
69
|
-
"playwright-core": "1.25.
|
|
69
|
+
"playwright-core": "1.25.2",
|
|
70
70
|
"pluralize": "8.0.0",
|
|
71
71
|
"pngjs": "6.0.0",
|
|
72
72
|
"portfinder": "1.0.28",
|
|
@@ -13,7 +13,7 @@ const mablApiClientFactory_1 = require("../api/mablApiClientFactory");
|
|
|
13
13
|
const loggingProvider_1 = require("./logging/loggingProvider");
|
|
14
14
|
const pureUtil_1 = require("../util/pureUtil");
|
|
15
15
|
const OktaClient_1 = require("../auth/OktaClient");
|
|
16
|
-
const
|
|
16
|
+
const axiosProxyConfig_1 = require("../http/axiosProxyConfig");
|
|
17
17
|
const types_2 = require("./types");
|
|
18
18
|
const humanizeDuration = require('humanize-duration');
|
|
19
19
|
const inquirer = require('inquirer');
|
|
@@ -24,7 +24,7 @@ class AuthenticationProvider {
|
|
|
24
24
|
}
|
|
25
25
|
async getOktaClient() {
|
|
26
26
|
if (!this.oktaClient) {
|
|
27
|
-
const client = axios_1.default.create(await (0,
|
|
27
|
+
const client = axios_1.default.create(await (0, axiosProxyConfig_1.currentProxyConfig)());
|
|
28
28
|
this.oktaClient = new OktaClient_1.OktaClient(client);
|
|
29
29
|
}
|
|
30
30
|
return this.oktaClient;
|
|
@@ -32,7 +32,7 @@ const conf_1 = __importDefault(require("conf"));
|
|
|
32
32
|
const types_1 = require("./types");
|
|
33
33
|
const types_2 = require("../api/types");
|
|
34
34
|
const configKeys_1 = require("../commands/config/config_cmds/configKeys");
|
|
35
|
-
const httpUtil_1 = require("../
|
|
35
|
+
const httpUtil_1 = require("../http/httpUtil");
|
|
36
36
|
const crypto = __importStar(require("crypto"));
|
|
37
37
|
const loggingProvider_1 = require("./logging/loggingProvider");
|
|
38
38
|
const utilities_1 = require("../utilities");
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.decodeTestConfigAsParamsForParsedUrlProtocol = exports.encodeTestConfigAsParamsForParsedUrlProtocol = exports.b64EncodeUnicodeInNode = exports.b64DecodeUnicodeInNode = exports.TEST_CONFIG_URL_PARAM_KEY = void 0;
|
|
7
|
+
const querystring_1 = __importDefault(require("querystring"));
|
|
8
|
+
const MAX_PARSED_URL_PROTOCOL_PARAMS_LENGTH = 2000;
|
|
9
|
+
exports.TEST_CONFIG_URL_PARAM_KEY = 'scriptConfig';
|
|
10
|
+
function b64DecodeUnicodeInNode(encoded) {
|
|
11
|
+
return Buffer.from(encoded, 'base64').toString();
|
|
12
|
+
}
|
|
13
|
+
exports.b64DecodeUnicodeInNode = b64DecodeUnicodeInNode;
|
|
14
|
+
function b64EncodeUnicodeInNode(text) {
|
|
15
|
+
return Buffer.from(text).toString('base64');
|
|
16
|
+
}
|
|
17
|
+
exports.b64EncodeUnicodeInNode = b64EncodeUnicodeInNode;
|
|
18
|
+
function encodeTestConfigAsParamsForParsedUrlProtocol(testConfig, b64Encode) {
|
|
19
|
+
const encoded = querystring_1.default.stringify({
|
|
20
|
+
...testConfig,
|
|
21
|
+
[exports.TEST_CONFIG_URL_PARAM_KEY]: b64Encode(JSON.stringify(testConfig)),
|
|
22
|
+
});
|
|
23
|
+
if (encoded.length > MAX_PARSED_URL_PROTOCOL_PARAMS_LENGTH) {
|
|
24
|
+
throw new Error('Test parameters exceed size limit. Please use the mabl Desktop App to create or edit tests.');
|
|
25
|
+
}
|
|
26
|
+
return encoded;
|
|
27
|
+
}
|
|
28
|
+
exports.encodeTestConfigAsParamsForParsedUrlProtocol = encodeTestConfigAsParamsForParsedUrlProtocol;
|
|
29
|
+
function decodeTestConfigAsParamsForParsedUrlProtocol(encoded, b64Decode, useV2) {
|
|
30
|
+
const params = querystring_1.default.parse(encoded);
|
|
31
|
+
if (useV2 && params[exports.TEST_CONFIG_URL_PARAM_KEY]) {
|
|
32
|
+
return JSON.parse(b64Decode(params[exports.TEST_CONFIG_URL_PARAM_KEY]));
|
|
33
|
+
}
|
|
34
|
+
delete params[exports.TEST_CONFIG_URL_PARAM_KEY];
|
|
35
|
+
return params;
|
|
36
|
+
}
|
|
37
|
+
exports.decodeTestConfigAsParamsForParsedUrlProtocol = decodeTestConfigAsParamsForParsedUrlProtocol;
|
package/util/fileUploadUtil.js
CHANGED
|
@@ -28,7 +28,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.removeUploadDirs = exports.cleanupOldFiles = exports.downloadFileUpload = void 0;
|
|
30
30
|
const axios_1 = __importDefault(require("axios"));
|
|
31
|
-
const
|
|
31
|
+
const axiosProxyConfig_1 = require("../http/axiosProxyConfig");
|
|
32
32
|
const path_1 = __importDefault(require("path"));
|
|
33
33
|
const fs = __importStar(require("fs-extra"));
|
|
34
34
|
const stream_1 = require("stream");
|
|
@@ -42,7 +42,7 @@ async function downloadFileUpload(fileUploadUrl, fileUpload, downloadDirectory,
|
|
|
42
42
|
client = mablApiClient.httpClient;
|
|
43
43
|
}
|
|
44
44
|
else {
|
|
45
|
-
client = axios_1.default.create(await (0,
|
|
45
|
+
client = axios_1.default.create(await (0, axiosProxyConfig_1.currentProxyConfig)());
|
|
46
46
|
}
|
|
47
47
|
try {
|
|
48
48
|
const finalDirectory = path_1.default.normalize(`${downloadDirectory}/${fileUpload.id}`);
|