@mablhq/mabl-cli 2.16.4 → 2.20.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/README.md +2 -2
- package/api/mablApiClient.js +5 -4
- package/browserEngines/chromiumBrowserEngine.js +4 -2
- package/browserLauncher/pageEvent.js +0 -1
- package/browserLauncher/playwrightBrowserLauncher/playwrightHttpRequest.js +6 -7
- package/browserLauncher/playwrightBrowserLauncher/playwrightPage.js +21 -5
- package/commands/auth/auth_cmds/activate-key.js +12 -3
- package/commands/tests/tests_cmds/run-cloud.js +1 -1
- package/commands/tests/tests_cmds/run-mobile.js +36 -14
- package/commands/tests/tests_cmds/runUtils.js +11 -1
- package/core/execution/PostmanUtils.js +53 -0
- package/core/execution/VariableUtils.js +144 -0
- package/core/messaging/actions/MobileTrainingActions.js +17 -0
- package/domUtil/index.js +1 -1
- package/execution/index.js +2 -2
- package/execution/index.js.LICENSE.txt +15 -0
- package/mablApi/index.js +1 -1
- package/mablscript/steps/IfConditionStep.js +3 -1
- package/mablscriptFind/index.js +1 -1
- package/package.json +1 -1
- package/resources/mablFind.js +1 -1
- package/socketTunnel/index.js +1 -1
- package/upload/index.js +1 -1
- package/util/FileCache.js +5 -5
- package/util/pureUtil.js +10 -1
package/README.md
CHANGED
|
@@ -195,8 +195,8 @@ Use the:
|
|
|
195
195
|
- `--auto-branch` flag to automatically create the specified branch if it
|
|
196
196
|
doesn't exist already
|
|
197
197
|
- `--width` and `--height` flags to specify the viewport sizes of the browser
|
|
198
|
-
- `--creds` or `--credentials` flag to specify a testing credential set to
|
|
199
|
-
during edit (`mabl credentials list` to see available ones)
|
|
198
|
+
- `--creds` or `--credentials-id` flag to specify a testing credential set to
|
|
199
|
+
use during edit (`mabl credentials list` to see available ones)
|
|
200
200
|
|
|
201
201
|
_Note: required IDs can be found by using the CLI list commands or on the test
|
|
202
202
|
details or test output pages inside the mabl web app_
|
package/api/mablApiClient.js
CHANGED
|
@@ -13,9 +13,10 @@ const query_string_1 = __importDefault(require("query-string"));
|
|
|
13
13
|
const featureSet_1 = require("./featureSet");
|
|
14
14
|
class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
15
15
|
constructor(options) {
|
|
16
|
-
var _a;
|
|
16
|
+
var _a, _b;
|
|
17
17
|
super(options);
|
|
18
|
-
this.baseApiUrl =
|
|
18
|
+
this.baseApiUrl =
|
|
19
|
+
(_b = (_a = options.apiUrl) !== null && _a !== void 0 ? _a : process.env.MABL_API_URL) !== null && _b !== void 0 ? _b : env_1.BASE_API_URL;
|
|
19
20
|
}
|
|
20
21
|
async getPlan(planId) {
|
|
21
22
|
try {
|
|
@@ -842,14 +843,14 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
842
843
|
timeout: 3600000,
|
|
843
844
|
});
|
|
844
845
|
}
|
|
845
|
-
async
|
|
846
|
+
async getEnabledAccountFeaturesByWorkspaceId(workspaceId) {
|
|
846
847
|
var _a;
|
|
847
848
|
try {
|
|
848
849
|
const account = await this.getAccountByWorkspaceId(workspaceId);
|
|
849
850
|
return new featureSet_1.FeatureSet(new Set((_a = account.effective_features) !== null && _a !== void 0 ? _a : []));
|
|
850
851
|
}
|
|
851
852
|
catch (error) {
|
|
852
|
-
throw toApiError(`Failed to get
|
|
853
|
+
throw toApiError(`Failed to get effective account features for workspace ${workspaceId}`, error);
|
|
853
854
|
}
|
|
854
855
|
}
|
|
855
856
|
async getEnabledLabsFeaturesForWorkspace(workspaceId) {
|
|
@@ -65,9 +65,11 @@ class ChromiumBrowserEngine {
|
|
|
65
65
|
}
|
|
66
66
|
if (options.disableIsolation) {
|
|
67
67
|
disableFeaturesFlags.push('IsolateOrigins');
|
|
68
|
+
disableFeaturesFlags.push('site-per-process');
|
|
69
|
+
}
|
|
70
|
+
if (disableFeaturesFlags.length) {
|
|
71
|
+
commandLineArgs.push(`--disable-features=${disableFeaturesFlags.join(',')}`);
|
|
68
72
|
}
|
|
69
|
-
disableFeaturesFlags.push('site-per-process');
|
|
70
|
-
commandLineArgs.push(`--disable-features=${disableFeaturesFlags.join(',')}`);
|
|
71
73
|
if (options.autoOpenDevtoolsForTabs) {
|
|
72
74
|
commandLineArgs.push('--auto-open-devtools-for-tabs');
|
|
73
75
|
}
|
|
@@ -8,7 +8,6 @@ var PageEvent;
|
|
|
8
8
|
PageEvent["FrameAttached"] = "frameattached";
|
|
9
9
|
PageEvent["FrameNavigated"] = "framenavigated";
|
|
10
10
|
PageEvent["PageError"] = "pageerror";
|
|
11
|
-
PageEvent["Request"] = "request";
|
|
12
11
|
PageEvent["RequestWillBeSentExtraInfo"] = "requestwillbesentextrainfo";
|
|
13
12
|
PageEvent["Response"] = "response";
|
|
14
13
|
PageEvent["SecondaryWorldCreated"] = "secondaryworldcreated";
|
|
@@ -32,6 +32,7 @@ class PlaywrightHttpRequest {
|
|
|
32
32
|
this.page = page;
|
|
33
33
|
this.request = request;
|
|
34
34
|
this.route = route;
|
|
35
|
+
this.requestIntercepted = false;
|
|
35
36
|
try {
|
|
36
37
|
this.documentId = playwright._toImpl(this.request)._documentId;
|
|
37
38
|
}
|
|
@@ -45,15 +46,9 @@ class PlaywrightHttpRequest {
|
|
|
45
46
|
if (this.route === undefined) {
|
|
46
47
|
throw new Error('Unable to abort an unrouted request');
|
|
47
48
|
}
|
|
49
|
+
this.requestIntercepted = true;
|
|
48
50
|
return (_a = this.route) === null || _a === void 0 ? void 0 : _a.abort();
|
|
49
51
|
}
|
|
50
|
-
continue() {
|
|
51
|
-
var _a;
|
|
52
|
-
if (this.route === undefined) {
|
|
53
|
-
throw new Error('Unable to continue an unrouted request');
|
|
54
|
-
}
|
|
55
|
-
return (_a = this.route) === null || _a === void 0 ? void 0 : _a.continue();
|
|
56
|
-
}
|
|
57
52
|
frame() {
|
|
58
53
|
return this.page.getOrCreateFrame(this.request.frame());
|
|
59
54
|
}
|
|
@@ -65,6 +60,7 @@ class PlaywrightHttpRequest {
|
|
|
65
60
|
if (this.route === undefined) {
|
|
66
61
|
throw new Error('Unable to respond an unrouted request');
|
|
67
62
|
}
|
|
63
|
+
this.requestIntercepted = true;
|
|
68
64
|
return (_a = this.route) === null || _a === void 0 ? void 0 : _a.fulfill(response);
|
|
69
65
|
}
|
|
70
66
|
url() {
|
|
@@ -73,5 +69,8 @@ class PlaywrightHttpRequest {
|
|
|
73
69
|
headers() {
|
|
74
70
|
return this.request.allHeaders();
|
|
75
71
|
}
|
|
72
|
+
wasIntercepted() {
|
|
73
|
+
return this.requestIntercepted;
|
|
74
|
+
}
|
|
76
75
|
}
|
|
77
76
|
exports.PlaywrightHttpRequest = PlaywrightHttpRequest;
|
|
@@ -48,6 +48,7 @@ class PlaywrightPage extends events_1.default {
|
|
|
48
48
|
this.browser = browser;
|
|
49
49
|
this.delegate = delegate;
|
|
50
50
|
this.playwrightFrames = new Map();
|
|
51
|
+
this.requestListeners = [];
|
|
51
52
|
const guid = page._guid;
|
|
52
53
|
this.pageId = (_a = delegate.getTargetId()) !== null && _a !== void 0 ? _a : guid;
|
|
53
54
|
page.off('dialog', this.acceptDialogs);
|
|
@@ -75,6 +76,26 @@ class PlaywrightPage extends events_1.default {
|
|
|
75
76
|
}
|
|
76
77
|
});
|
|
77
78
|
}
|
|
79
|
+
addRequestListener(listener) {
|
|
80
|
+
if (this.requestListeners.length === 0) {
|
|
81
|
+
void this.page.route('**/*', async (route) => {
|
|
82
|
+
const listeners = this.requestListeners;
|
|
83
|
+
if (listeners.length === 0) {
|
|
84
|
+
void route.continue();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const request = new playwrightHttpRequest_1.PlaywrightHttpRequest(this, route.request(), route);
|
|
88
|
+
for (const listener of listeners) {
|
|
89
|
+
await listener(request);
|
|
90
|
+
if (request.wasIntercepted()) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
await route.continue();
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
this.requestListeners.push(listener);
|
|
98
|
+
}
|
|
78
99
|
createCDPSession() {
|
|
79
100
|
return this.delegate.createCDPSession();
|
|
80
101
|
}
|
|
@@ -108,11 +129,6 @@ class PlaywrightPage extends events_1.default {
|
|
|
108
129
|
this.emit(browserLauncher_1.PageEvent.Response, new playwrightHttpResponse_1.PlaywrightHttpResponse(this, event));
|
|
109
130
|
});
|
|
110
131
|
}
|
|
111
|
-
if (event === browserLauncher_1.PageEvent.Request && !this.listenerCount(event)) {
|
|
112
|
-
void this.page.route('**/*', (route) => {
|
|
113
|
-
this.emit(browserLauncher_1.PageEvent.Request, new playwrightHttpRequest_1.PlaywrightHttpRequest(this, route.request(), route));
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
132
|
if (event === browserLauncher_1.PageEvent.FrameNavigated && !this.listenerCount(event)) {
|
|
117
133
|
this.page.on('framenavigated', (frame) => {
|
|
118
134
|
this.emit(browserLauncher_1.PageEvent.FrameNavigated, this.getOrCreateFrame(frame));
|
|
@@ -9,11 +9,18 @@ exports.command = `activate-key <${constants_1.CommandArgApiKey}>`;
|
|
|
9
9
|
exports.describe = 'Activate auth by api key';
|
|
10
10
|
exports.builder = {};
|
|
11
11
|
exports.builder = (yargs) => {
|
|
12
|
-
yargs
|
|
12
|
+
yargs
|
|
13
|
+
.positional(constants_1.CommandArgApiKey, {
|
|
13
14
|
describe: 'API key (escape leading dashes with "\\" (e.g. "\\-yourKey")',
|
|
14
15
|
type: 'string',
|
|
15
16
|
nargs: 1,
|
|
16
17
|
demand: 'API key argument required',
|
|
18
|
+
})
|
|
19
|
+
.option('skip-workspace', {
|
|
20
|
+
describe: 'Set to skip validating and setting the workspace',
|
|
21
|
+
default: false,
|
|
22
|
+
hidden: true,
|
|
23
|
+
type: 'boolean',
|
|
17
24
|
});
|
|
18
25
|
};
|
|
19
26
|
exports.handler = (0, util_1.failWrapper)(activateApiKey);
|
|
@@ -23,7 +30,9 @@ async function activateApiKey(parsed) {
|
|
|
23
30
|
const cleanApiKey = apiKey.replace(/^\\+/, '');
|
|
24
31
|
const mablApi = await mablApiClientFactory_1.MablApiClientFactory.createApiClientFromApiKey(cleanApiKey);
|
|
25
32
|
const apiKeyDetails = await mablApi.getApiKeyDetails();
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
if (!parsed['skip-workspace']) {
|
|
34
|
+
const apiKeyWorkspace = await mablApi.getWorkspace(apiKeyDetails.workspace_id);
|
|
35
|
+
await cliConfigProvider_1.CliConfigProvider.setWorkspace(apiKeyWorkspace);
|
|
36
|
+
}
|
|
28
37
|
return auth.activateApiKey(cleanApiKey);
|
|
29
38
|
}
|
|
@@ -223,7 +223,7 @@ async function executeRunCloudTest(test, browsers, branchName, apiClient, maybeD
|
|
|
223
223
|
? test === null || test === void 0 ? void 0 : test.url
|
|
224
224
|
: undefined);
|
|
225
225
|
const effectiveApiUrl = apiUrl !== null && apiUrl !== void 0 ? apiUrl : (test.test_type && test.test_type !== mablApi_1.TestTypeEnum.Browser
|
|
226
|
-
? test === null || test === void 0 ? void 0 : test.
|
|
226
|
+
? test === null || test === void 0 ? void 0 : test.api_url
|
|
227
227
|
: undefined);
|
|
228
228
|
const workspaceId = test.organization_id;
|
|
229
229
|
const testId = test.invariant_id;
|
|
@@ -35,10 +35,11 @@ const runUtils_1 = require("./runUtils");
|
|
|
35
35
|
const MobileAppFileCache_1 = require("../../../util/MobileAppFileCache");
|
|
36
36
|
const fs = __importStar(require("fs"));
|
|
37
37
|
const resourceUtil_1 = require("../../../util/resourceUtil");
|
|
38
|
+
const mablApiClientFactory_1 = require("../../../api/mablApiClientFactory");
|
|
38
39
|
const chalk = require('chalk');
|
|
39
40
|
const execution = require('../../../execution/index');
|
|
40
41
|
exports.command = `run-mobile`;
|
|
41
|
-
exports.describe =
|
|
42
|
+
exports.describe = 'Run a mobile test locally';
|
|
42
43
|
exports.builder = (yargs) => {
|
|
43
44
|
yargs
|
|
44
45
|
.example('$0 tests run-mobile --id <id> --app-file <path> --platform <platform>', 'run mobile test locally by id')
|
|
@@ -71,6 +72,10 @@ exports.builder = (yargs) => {
|
|
|
71
72
|
hidden: true,
|
|
72
73
|
type: 'string',
|
|
73
74
|
choices: [constants_1.ReporterOptions.Mochawesome],
|
|
75
|
+
})
|
|
76
|
+
.option(constants_1.CommandArgTestRunId, {
|
|
77
|
+
describe: 'The id of the test run to pull config from',
|
|
78
|
+
type: 'string',
|
|
74
79
|
})
|
|
75
80
|
.option(constants_1.CommandArgReporterOptions, {
|
|
76
81
|
describe: 'Reporter options as comma separated key/values pairs. e.g. "reportDir=path/to,json=true"',
|
|
@@ -81,27 +86,33 @@ exports.builder = (yargs) => {
|
|
|
81
86
|
describe: 'Full name of the device to use for the test',
|
|
82
87
|
hidden: false,
|
|
83
88
|
type: 'string',
|
|
89
|
+
})
|
|
90
|
+
.option(constants_1.CommandArgLabelsInclude, {
|
|
91
|
+
describe: 'Space delimited test labels. Run tests that match any label.',
|
|
92
|
+
type: 'array',
|
|
93
|
+
conflicts: [constants_1.CommandArgId],
|
|
94
|
+
})
|
|
95
|
+
.option(constants_1.CommandArgLabelsExclude, {
|
|
96
|
+
describe: 'Space delimited test labels. Exclude tests that match any label.',
|
|
97
|
+
type: 'array',
|
|
98
|
+
conflicts: [constants_1.CommandArgId],
|
|
84
99
|
})
|
|
85
100
|
.implies(constants_1.CommandArgReporterOptions, constants_1.CommandArgReporter)
|
|
86
|
-
.middleware(inferMobilePlatform)
|
|
101
|
+
.middleware(inferMobilePlatform)
|
|
102
|
+
.check((argv) => {
|
|
103
|
+
(0, testsUtil_1.validateRunCommandWithLabels)(argv[constants_1.CommandArgId], argv[constants_1.CommandArgLabelsInclude], argv[constants_1.CommandArgLabelsExclude], argv[constants_1.CommandArgTestRunId], argv[constants_1.CommandArgFromPlanId], true, undefined);
|
|
104
|
+
validateMobileCommand(argv[constants_1.CommandArgMobileAppFile], argv[constants_1.CommandArgMobileAppFileId]);
|
|
105
|
+
return true;
|
|
106
|
+
});
|
|
87
107
|
};
|
|
88
108
|
const exitCodeOnError = 1;
|
|
89
109
|
exports.handler = (0, util_1.failWrapper)(run, exitCodeOnError);
|
|
90
|
-
function validateMobileCommand(
|
|
91
|
-
if (!id || (!appFile && !appFileId) || !platform) {
|
|
92
|
-
loggingProvider_1.logger.error(chalk.red(`Please provide the arguments --${constants_1.CommandArgId}, --${constants_1.CommandArgMobileAppFile} or --${constants_1.CommandArgMobileAppFileId}, and --${constants_1.CommandArgMobilePlatform}`));
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
110
|
+
function validateMobileCommand(appFile, appFileId) {
|
|
95
111
|
if (appFile && appFileId) {
|
|
96
|
-
|
|
97
|
-
return false;
|
|
112
|
+
throw new Error(`Only one of { --${constants_1.CommandArgMobileAppFile}, --${constants_1.CommandArgMobileAppFileId} } may be specified`);
|
|
98
113
|
}
|
|
99
|
-
return true;
|
|
100
114
|
}
|
|
101
115
|
async function run(parsed) {
|
|
102
|
-
if (!validateMobileCommand(parsed[constants_1.CommandArgId], parsed[constants_1.CommandArgMobileAppFile], parsed[constants_1.CommandArgMobileAppFileId], parsed[constants_1.CommandArgMobilePlatform])) {
|
|
103
|
-
process.exit(1);
|
|
104
|
-
}
|
|
105
116
|
const commandStartTime = Date.now();
|
|
106
117
|
let workspaceId;
|
|
107
118
|
try {
|
|
@@ -115,11 +126,22 @@ async function run(parsed) {
|
|
|
115
126
|
loggingProvider_1.logger.error(`[ERROR] Missing the mobile tools for running tests, run ${chalk.magenta('mabl config install mobile-tools')} to install them`);
|
|
116
127
|
return;
|
|
117
128
|
}
|
|
118
|
-
|
|
129
|
+
let platformName;
|
|
130
|
+
if (parsed[constants_1.CommandArgTestRunId]) {
|
|
131
|
+
const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClient();
|
|
132
|
+
const testRun = await apiClient.getJourneyRun(parsed[constants_1.CommandArgTestRunId]);
|
|
133
|
+
platformName = (0, runUtils_1.getPlatformFromTestRun)(testRun);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
platformName = (0, execution_1.parsePlatformName)(parsed[constants_1.CommandArgMobilePlatform]);
|
|
137
|
+
}
|
|
119
138
|
await validateSystemRequirements(platformName, parsed[constants_1.CommandArgMobileDeviceName]);
|
|
120
139
|
const testRunnerConfig = {
|
|
121
140
|
_cliCreated: true,
|
|
122
141
|
filterHttpRequests: false,
|
|
142
|
+
labelsExclude: parsed[constants_1.CommandArgLabelsExclude],
|
|
143
|
+
labelsInclude: parsed[constants_1.CommandArgLabelsInclude],
|
|
144
|
+
runId: parsed[constants_1.CommandArgTestRunId],
|
|
123
145
|
testId: parsed.id,
|
|
124
146
|
workspaceId,
|
|
125
147
|
mobileConfig: {
|
|
@@ -3,11 +3,12 @@ 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.logTestResults = void 0;
|
|
6
|
+
exports.getPlatformFromTestRun = exports.logTestResults = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const loggingProvider_1 = require("../../../providers/logging/loggingProvider");
|
|
9
9
|
const reporter_1 = require("../../../reporters/reporter");
|
|
10
10
|
const testsUtil_1 = require("../testsUtil");
|
|
11
|
+
const execution_1 = require("../../../execution");
|
|
11
12
|
async function logTestResults(results, parsed, commandStartTime, rerunCommandTemplate) {
|
|
12
13
|
loggingProvider_1.logger.logNewLine();
|
|
13
14
|
loggingProvider_1.logger.info(`Test count: ${results.numTotalTests}`);
|
|
@@ -48,3 +49,12 @@ exports.logTestResults = logTestResults;
|
|
|
48
49
|
function getTestResultDescription(result) {
|
|
49
50
|
return `${result.testName}${result.scenarioName ? ` - Scenario: ${result.scenarioName}` : ''}`;
|
|
50
51
|
}
|
|
52
|
+
function getPlatformFromTestRun(testRun) {
|
|
53
|
+
var _a, _b;
|
|
54
|
+
const platform = (_b = (_a = testRun.journey_parameters) === null || _a === void 0 ? void 0 : _a.mobile_device) === null || _b === void 0 ? void 0 : _b.platform;
|
|
55
|
+
if (!platform) {
|
|
56
|
+
throw new Error(`Unable to determine mobile platform from test run: ${testRun.id}`);
|
|
57
|
+
}
|
|
58
|
+
return (0, execution_1.parsePlatformName)(platform);
|
|
59
|
+
}
|
|
60
|
+
exports.getPlatformFromTestRun = getPlatformFromTestRun;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanitizeExportedVariables = exports.exportVariables = exports.convertVariablesSummaryToPostmanFormat = void 0;
|
|
4
|
+
const VariableUtils_1 = require("./VariableUtils");
|
|
5
|
+
const domUtil_1 = require("../../domUtil");
|
|
6
|
+
function convertVariablesSummaryToPostmanFormat(summary) {
|
|
7
|
+
const effectiveVariables = { ...summary.effective };
|
|
8
|
+
const values = Object.keys(effectiveVariables).map((key) => ({
|
|
9
|
+
key,
|
|
10
|
+
value: effectiveVariables[key],
|
|
11
|
+
}));
|
|
12
|
+
return {
|
|
13
|
+
values,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
exports.convertVariablesSummaryToPostmanFormat = convertVariablesSummaryToPostmanFormat;
|
|
17
|
+
function exportVariables(postmanResult) {
|
|
18
|
+
const variablePrecedence = [
|
|
19
|
+
postmanResult === null || postmanResult === void 0 ? void 0 : postmanResult.globals.values,
|
|
20
|
+
postmanResult === null || postmanResult === void 0 ? void 0 : postmanResult.collection.variables,
|
|
21
|
+
postmanResult === null || postmanResult === void 0 ? void 0 : postmanResult.environment.values,
|
|
22
|
+
].filter((variables) => !!variables);
|
|
23
|
+
const exportedVariables = {};
|
|
24
|
+
variablePrecedence
|
|
25
|
+
.map((variableList) => variableList.all())
|
|
26
|
+
.forEach((variables) => variables.forEach((variable) => (exportedVariables[variable.key] = variable.value)));
|
|
27
|
+
return exportedVariables;
|
|
28
|
+
}
|
|
29
|
+
exports.exportVariables = exportVariables;
|
|
30
|
+
function sanitizeExportedVariables(variables) {
|
|
31
|
+
const normalized = {};
|
|
32
|
+
if (variables) {
|
|
33
|
+
return normalizeExportedVariables(filterExportedVariables(variables));
|
|
34
|
+
}
|
|
35
|
+
return normalized;
|
|
36
|
+
}
|
|
37
|
+
exports.sanitizeExportedVariables = sanitizeExportedVariables;
|
|
38
|
+
function normalizeExportedVariables(variables) {
|
|
39
|
+
const normalized = {};
|
|
40
|
+
Object.keys(variables).forEach((name) => {
|
|
41
|
+
normalized[(0, VariableUtils_1.addUserNamespace)(name)] = variables[name];
|
|
42
|
+
});
|
|
43
|
+
return normalized;
|
|
44
|
+
}
|
|
45
|
+
function filterExportedVariables(variables) {
|
|
46
|
+
const filtered = {};
|
|
47
|
+
Object.keys(variables)
|
|
48
|
+
.filter((name) => (0, domUtil_1.isValidUserVariableName)(name))
|
|
49
|
+
.forEach((name) => {
|
|
50
|
+
filtered[name] = variables[name];
|
|
51
|
+
});
|
|
52
|
+
return filtered;
|
|
53
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addUserNamespace = exports.generateVariablesSummaryForExport = exports.generateVariablesSummaryForImport = exports.API_CREDENTIALS_PASSWORD_VARIABLE_NAME = exports.API_CREDENTIALS_USERNAME_VARIABLE_NAME = exports.API_CREDENTIALS_NAMESPACE = exports.API_URL_VARIABLE_NAME = exports.API_NAMESPACE = exports.FLOW_NAMESPACE = exports.USER_NAMESPACE = void 0;
|
|
4
|
+
const domUtil_1 = require("../../domUtil");
|
|
5
|
+
exports.USER_NAMESPACE = 'user.';
|
|
6
|
+
exports.FLOW_NAMESPACE = 'flow.';
|
|
7
|
+
exports.API_NAMESPACE = 'api.';
|
|
8
|
+
exports.API_URL_VARIABLE_NAME = `${exports.API_NAMESPACE}url`;
|
|
9
|
+
exports.API_CREDENTIALS_NAMESPACE = `${exports.API_NAMESPACE}credentials.`;
|
|
10
|
+
exports.API_CREDENTIALS_USERNAME_VARIABLE_NAME = `${exports.API_CREDENTIALS_NAMESPACE}username`;
|
|
11
|
+
exports.API_CREDENTIALS_PASSWORD_VARIABLE_NAME = `${exports.API_CREDENTIALS_NAMESPACE}password`;
|
|
12
|
+
function generateVariablesSummaryForImport(variableSources) {
|
|
13
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
14
|
+
const { environment, scenario, url, credentials, plan, flow, journeyRun, previousFlowVariables, } = variableSources;
|
|
15
|
+
const summary = {
|
|
16
|
+
dataDriven: {},
|
|
17
|
+
effective: {},
|
|
18
|
+
environment: {},
|
|
19
|
+
flow: {},
|
|
20
|
+
journey: {},
|
|
21
|
+
parameters: {},
|
|
22
|
+
};
|
|
23
|
+
const environmentVariables = (environment === null || environment === void 0 ? void 0 : environment.variables) || {};
|
|
24
|
+
Object.keys(environmentVariables).forEach((key) => (summary.environment[removeUserNamespace(key)] =
|
|
25
|
+
environmentVariables[key]));
|
|
26
|
+
const planParameters = extractValueParameters(plan === null || plan === void 0 ? void 0 : plan.parameters);
|
|
27
|
+
planParameters.forEach((parameter) => (summary.parameters[removeUserNamespace(parameter.name)] =
|
|
28
|
+
parameter.value));
|
|
29
|
+
const journeyParameters = extractValueParameters(journeyRun &&
|
|
30
|
+
(plan === null || plan === void 0 ? void 0 : plan.execution_stages) &&
|
|
31
|
+
((_c = (_b = (_a = plan.execution_stages[journeyRun.stage_index]) === null || _a === void 0 ? void 0 : _a.journeys) === null || _b === void 0 ? void 0 : _b.find((journey) => journey.journey_id)) === null || _c === void 0 ? void 0 : _c.parameters));
|
|
32
|
+
journeyParameters.forEach((parameter) => (summary.parameters[removeUserNamespace(parameter.name)] =
|
|
33
|
+
parameter.value));
|
|
34
|
+
const journeyInputs = ((_d = journeyRun === null || journeyRun === void 0 ? void 0 : journeyRun.journey_parameters) === null || _d === void 0 ? void 0 : _d.imported_variables) || {};
|
|
35
|
+
Object.keys(journeyInputs).forEach((key) => (summary.journey[removeUserNamespace(key)] = journeyInputs[key]));
|
|
36
|
+
const ddtVariables = ((_f = (_e = journeyRun === null || journeyRun === void 0 ? void 0 : journeyRun.journey_parameters) === null || _e === void 0 ? void 0 : _e.user_variables) === null || _f === void 0 ? void 0 : _f.row) ||
|
|
37
|
+
(scenario === null || scenario === void 0 ? void 0 : scenario.variables) ||
|
|
38
|
+
[];
|
|
39
|
+
ddtVariables.forEach((variable) => (summary.dataDriven[removeUserNamespace(variable.name)] =
|
|
40
|
+
variable.value));
|
|
41
|
+
const precedence = [
|
|
42
|
+
summary.environment,
|
|
43
|
+
summary.parameters,
|
|
44
|
+
summary.journey,
|
|
45
|
+
summary.dataDriven,
|
|
46
|
+
];
|
|
47
|
+
precedence.forEach((variables) => Object.keys(variables).forEach((name) => (summary.effective[name] = variables[name])));
|
|
48
|
+
if (flow === null || flow === void 0 ? void 0 : flow.parameters) {
|
|
49
|
+
flow.parameters.forEach((parameter) => {
|
|
50
|
+
const parameterName = removePrefix(parameter.name, exports.FLOW_NAMESPACE);
|
|
51
|
+
summary.flow[parameterName] = parameter.default_value;
|
|
52
|
+
if (!summary.effective[parameterName]) {
|
|
53
|
+
summary.effective[parameterName] = parameter.default_value;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
const exportedVariables = previousFlowVariables || {};
|
|
58
|
+
Object.keys(exportedVariables).forEach((key) => {
|
|
59
|
+
summary.dataDriven[key] = exportedVariables[key];
|
|
60
|
+
summary.effective[key] = exportedVariables[key];
|
|
61
|
+
});
|
|
62
|
+
if (url) {
|
|
63
|
+
summary.effective[exports.API_URL_VARIABLE_NAME] = url;
|
|
64
|
+
}
|
|
65
|
+
if (credentials) {
|
|
66
|
+
summary.effective[exports.API_CREDENTIALS_USERNAME_VARIABLE_NAME] =
|
|
67
|
+
(_g = credentials.properties) === null || _g === void 0 ? void 0 : _g.username;
|
|
68
|
+
summary.effective[exports.API_CREDENTIALS_PASSWORD_VARIABLE_NAME] =
|
|
69
|
+
(_h = credentials.properties) === null || _h === void 0 ? void 0 : _h.password;
|
|
70
|
+
}
|
|
71
|
+
return summary;
|
|
72
|
+
}
|
|
73
|
+
exports.generateVariablesSummaryForImport = generateVariablesSummaryForImport;
|
|
74
|
+
function generateVariablesSummaryForExport(testContext, plan, flow, journeyRun, exportedVariables) {
|
|
75
|
+
return normalizeVariablesSummaryForExport(generateVariablesSummaryForImport({
|
|
76
|
+
environment: testContext.environment,
|
|
77
|
+
url: testContext.url,
|
|
78
|
+
credentials: testContext.credentials,
|
|
79
|
+
scenario: testContext.getScenario(),
|
|
80
|
+
plan,
|
|
81
|
+
flow,
|
|
82
|
+
journeyRun,
|
|
83
|
+
previousFlowVariables: exportedVariables,
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
exports.generateVariablesSummaryForExport = generateVariablesSummaryForExport;
|
|
87
|
+
function normalizeVariablesSummaryForExport(summary) {
|
|
88
|
+
return {
|
|
89
|
+
dataDriven: addUserNamespaceToVariableNames(sanitizeVariables(summary.dataDriven)),
|
|
90
|
+
effective: sanitizeVariables(summary.effective),
|
|
91
|
+
environment: addUserNamespaceToVariableNames(sanitizeVariables(summary.environment)),
|
|
92
|
+
flow: addPrefixToVariableNames(sanitizeVariables(summary.flow), exports.FLOW_NAMESPACE),
|
|
93
|
+
journey: addUserNamespaceToVariableNames(sanitizeVariables(summary.journey)),
|
|
94
|
+
parameters: addUserNamespaceToVariableNames(sanitizeVariables(summary.parameters)),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function sanitizeVariables(variables) {
|
|
98
|
+
const sanitizedVariables = {};
|
|
99
|
+
Object.keys(variables)
|
|
100
|
+
.filter((name) => (0, domUtil_1.isValidUserVariableName)(name))
|
|
101
|
+
.forEach((name) => (sanitizedVariables[name] = variables[name]));
|
|
102
|
+
return sanitizedVariables;
|
|
103
|
+
}
|
|
104
|
+
function addUserNamespaceToVariableNames(variables) {
|
|
105
|
+
return addPrefixToVariableNames(variables, exports.USER_NAMESPACE);
|
|
106
|
+
}
|
|
107
|
+
function addPrefixToVariableNames(variables, prefix) {
|
|
108
|
+
return mapVariables(variables, (variable) => ({
|
|
109
|
+
name: addPrefix(variable.name, prefix),
|
|
110
|
+
value: variable.value,
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
function mapVariables(variables, mapper) {
|
|
114
|
+
const mappedVariables = {};
|
|
115
|
+
Object.keys(variables)
|
|
116
|
+
.map((name) => mapper({ name, value: variables[name] }))
|
|
117
|
+
.forEach((variable) => (mappedVariables[variable.name] = variable.value));
|
|
118
|
+
return mappedVariables;
|
|
119
|
+
}
|
|
120
|
+
function extractValueParameters(parameters) {
|
|
121
|
+
if (!parameters) {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
return parameters.filter((parameter) => { var _a; return ((_a = parameter.type) === null || _a === void 0 ? void 0 : _a.toString()) === 'value'; });
|
|
125
|
+
}
|
|
126
|
+
function removeUserNamespace(variableName) {
|
|
127
|
+
return removePrefix(variableName, exports.USER_NAMESPACE);
|
|
128
|
+
}
|
|
129
|
+
function removePrefix(variableName, prefix) {
|
|
130
|
+
if (variableName.startsWith(prefix)) {
|
|
131
|
+
return variableName.substring(prefix.length);
|
|
132
|
+
}
|
|
133
|
+
return variableName;
|
|
134
|
+
}
|
|
135
|
+
function addUserNamespace(variableName) {
|
|
136
|
+
return addPrefix(variableName, exports.USER_NAMESPACE);
|
|
137
|
+
}
|
|
138
|
+
exports.addUserNamespace = addUserNamespace;
|
|
139
|
+
function addPrefix(variableName, prefix) {
|
|
140
|
+
if (variableName.startsWith(prefix)) {
|
|
141
|
+
return variableName;
|
|
142
|
+
}
|
|
143
|
+
return `${prefix}${variableName}`;
|
|
144
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MobileTrainingActionsEventEmitter = exports.MobileTrainingMessageType = void 0;
|
|
4
|
+
const messaging_1 = require("../messaging");
|
|
5
|
+
var MobileTrainingMessageType;
|
|
6
|
+
(function (MobileTrainingMessageType) {
|
|
7
|
+
MobileTrainingMessageType["foundElement"] = "mobileFoundElement";
|
|
8
|
+
})(MobileTrainingMessageType = exports.MobileTrainingMessageType || (exports.MobileTrainingMessageType = {}));
|
|
9
|
+
class MobileTrainingActionsEventEmitter {
|
|
10
|
+
static emitFoundElementInfo(foundElement, isACandidateElement) {
|
|
11
|
+
return messaging_1.mablEventEmitter.dispatch(new messaging_1.MablCoreAction(MobileTrainingMessageType.foundElement, {
|
|
12
|
+
boundingBox: foundElement.boundingBox,
|
|
13
|
+
isACandidateElement,
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.MobileTrainingActionsEventEmitter = MobileTrainingActionsEventEmitter;
|