@mablhq/mabl-cli 1.58.20 → 1.58.25
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 +21 -15
- package/api/mablApiClient.js +40 -48
- package/api/mablApiClientFactory.js +1 -1
- package/auth/OktaClient.js +1 -2
- package/browserEngines/chromiumBrowserEngine.js +1 -2
- package/browserEngines/firefoxBrowserEngine.js +2 -2
- package/browserEngines/webkitBrowerEngine.js +2 -2
- package/browserLauncher/browserLauncherFactory.js +2 -3
- package/browserLauncher/elementHandle.js +1 -2
- package/browserLauncher/playwrightBrowserLauncher/chromium/chromiumElementHandleDelegate.js +12 -20
- package/browserLauncher/playwrightBrowserLauncher/chromium/chromiumFrameDelegate.js +1 -1
- package/browserLauncher/playwrightBrowserLauncher/chromium/chromiumPageDelegate.js +7 -10
- package/browserLauncher/playwrightBrowserLauncher/firefox/firefoxFrameDelegate.js +3 -4
- package/browserLauncher/playwrightBrowserLauncher/nonChromium/nonChromiumAbstractElementHandleDelegate.js +4 -5
- package/browserLauncher/playwrightBrowserLauncher/nonChromium/nonChromiumAbstractPageDelegate.js +4 -7
- package/browserLauncher/playwrightBrowserLauncher/playwrightBrowser.js +1 -1
- package/browserLauncher/playwrightBrowserLauncher/playwrightBrowserLauncher.js +6 -5
- package/browserLauncher/playwrightBrowserLauncher/playwrightDom.js +31 -37
- package/browserLauncher/playwrightBrowserLauncher/playwrightFrame.js +8 -9
- package/browserLauncher/playwrightBrowserLauncher/playwrightHttpRequest.js +4 -8
- package/browserLauncher/playwrightBrowserLauncher/playwrightPage.js +4 -6
- package/browserLauncher/playwrightBrowserLauncher/webkit/webkitElementHandleDelegate.js +1 -2
- package/browserLauncher/playwrightBrowserLauncher/webkit/webkitFrameDelegate.js +1 -1
- package/browserTestMonitoring/metricsRecorder.js +6 -6
- package/commands/commandUtil/branches.js +2 -3
- package/commands/commandUtil/codeInsights.js +13 -16
- package/commands/commandUtil/fileUtil.js +1 -1
- package/commands/commandUtil/util.js +3 -4
- package/commands/commandUtil/versionUtil.js +4 -5
- package/commands/config/config_cmds/list.js +2 -2
- package/commands/constants.js +3 -1
- package/commands/datatables/datatables_cmds/create.js +2 -3
- package/commands/datatables/datatables_cmds/export.js +3 -5
- package/commands/datatables/datatables_cmds/list.js +1 -2
- package/commands/datatables/datatables_cmds/scenarios.js +1 -2
- package/commands/datatables/datatables_cmds/update.js +11 -11
- package/commands/datatables/utils.js +9 -9
- package/commands/deploy/deploy_cmds/awaitDeploymentCompletion.js +6 -8
- package/commands/deploy/deploy_cmds/create.js +11 -13
- package/commands/deploy/deploy_cmds/executionResultPresenter.js +8 -11
- package/commands/deploy/deploy_cmds/list.js +3 -4
- package/commands/deploy/deploy_cmds/watch.js +1 -2
- package/commands/environments/environments_cmds/create.js +1 -2
- package/commands/environments/environments_cmds/delete.js +1 -2
- package/commands/environments/environments_cmds/update.js +1 -2
- package/commands/environments/environments_cmds/urls_cmds/list.js +1 -2
- package/commands/flows/flows_cmds/export.js +1 -2
- package/commands/plans/plans_cmds/describe.js +1 -2
- package/commands/tests/mobileEmulationUtil.js +5 -7
- package/commands/tests/testsUtil.js +40 -42
- package/commands/tests/tests_cmds/export.js +1 -2
- package/commands/tests/tests_cmds/import.js +4 -5
- package/commands/tests/tests_cmds/run-cloud.js +12 -13
- package/commands/tests/tests_cmds/run.js +30 -11
- package/commands/users/users_cmds/list.js +2 -2
- package/commands/workspaces/workspace_cmds/copy.js +1 -2
- package/core/execution/ApiTestUtils.js +82 -94
- package/core/execution/LocalizationOptionsLists.js +1253 -0
- package/core/messaging/logLineMessaging.js +2 -3
- package/core/messaging/messaging.js +6 -7
- package/core/trainer/trainingSessions.js +15 -15
- package/coreWebVitals/index.js +14 -18
- package/domUtil/index.js +1 -1
- package/execution/index.js +1 -1
- package/functions/apiTest/utils.js +4 -5
- package/http/MablHttpAgent.js +4 -6
- package/http/RequestSecurityError.js +1 -1
- package/http/axiosProxyConfig.js +3 -5
- package/http/httpUtil.js +2 -3
- package/http/requestInterceptor.js +11 -15
- package/mablApi/index.js +1 -1
- package/mablscript/MablAction.js +2 -3
- package/mablscript/MablStep.js +2 -4
- package/mablscript/MablSymbol.js +1 -1
- package/mablscript/actions/ConditionAction.js +2 -4
- package/mablscript/actions/FindAction.js +2 -4
- package/mablscript/diffing/diffingUtil.js +8 -7
- package/mablscript/importer.js +1 -2
- package/mablscript/steps/AccessibilityCheck.js +7 -9
- package/mablscript/steps/AssertStep.js +11 -16
- package/mablscript/steps/ClickAndHoldStep.js +1 -2
- package/mablscript/steps/CookieUtils.js +40 -7
- package/mablscript/steps/CreateVariableStep.js +1 -2
- package/mablscript/steps/DownloadStep.js +1 -2
- package/mablscript/steps/EnterTextStep.js +1 -2
- package/mablscript/steps/EvaluateFlowStep.js +1 -1
- package/mablscript/steps/IfConditionStep.js +4 -6
- package/mablscript/steps/ReleaseStep.js +1 -2
- package/mablscript/steps/SendHttpRequestStep.js +2 -4
- package/mablscript/steps/SendKeyStep.js +1 -1
- package/mablscript/steps/SetCookieStep.js +35 -20
- package/mablscript/steps/SetViewportStep.js +1 -1
- package/mablscript/steps/SwitchContextStep.js +3 -6
- package/mablscript/steps/SyntheticStep.js +1 -2
- package/mablscriptFind/index.js +1 -1
- package/middleware.js +1 -2
- package/package.json +2 -2
- package/popupDismissal/index.js +4 -5
- package/providers/authenticationProvider.js +5 -6
- package/providers/cliConfigProvider.js +10 -12
- package/providers/exportRequestProvider.js +3 -5
- package/providers/logging/loggingProvider.js +1 -1
- package/reporters/mochAwesome/mochAwesomeReporter.js +12 -14
- package/resources/mablFind.js +1 -1
- package/util/actionabilityUtil.js +1 -1
- package/util/analytics.js +6 -9
- package/util/browserTestUtils.js +1 -2
- package/util/markdownUtil.js +9 -11
|
@@ -36,12 +36,11 @@ exports.builder = (yargs) => {
|
|
|
36
36
|
};
|
|
37
37
|
exports.handler = (0, util_1.failWrapper)(pullFlow);
|
|
38
38
|
async function pullFlow(parsed) {
|
|
39
|
-
var _a;
|
|
40
39
|
const flowId = parsed.id;
|
|
41
40
|
const format = parsed.format;
|
|
42
41
|
const detailLevel = parsed[constants_1.CommandArgDetailLevel];
|
|
43
42
|
const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClient();
|
|
44
|
-
const branchName =
|
|
43
|
+
const branchName = parsed['mabl-branch'] ?? constants_1.DefaultBranchName;
|
|
45
44
|
const flow = await apiClient.getFlow(flowId, branchName);
|
|
46
45
|
switch (format) {
|
|
47
46
|
case constants_1.OutputFormats.Csv:
|
|
@@ -8,14 +8,13 @@ exports.describe = (0, util_1.getDescribeDescriptions)('plan');
|
|
|
8
8
|
exports.builder = (0, describe_1.getDescribeBuilderOptions)();
|
|
9
9
|
exports.handler = (0, util_1.failWrapper)(getPlan);
|
|
10
10
|
async function getPlan(parsed) {
|
|
11
|
-
var _a;
|
|
12
11
|
try {
|
|
13
12
|
const planId = parsed.id;
|
|
14
13
|
const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClient();
|
|
15
14
|
const plan = await apiClient.getPlan(planId);
|
|
16
15
|
delete plan.journeys_ddt_migration_backup;
|
|
17
16
|
(0, describe_1.outputEntity)(plan, parsed.output);
|
|
18
|
-
return
|
|
17
|
+
return plan.id ?? '';
|
|
19
18
|
}
|
|
20
19
|
catch (error) {
|
|
21
20
|
throw new Error(`Error getting plan: ${error}`);
|
|
@@ -3,32 +3,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getDeviceDescriptorForEmulation = exports.getProperScreenConfig = void 0;
|
|
4
4
|
const mablApi_1 = require("../../mablApi");
|
|
5
5
|
function getProperScreenConfig(emulationConfig) {
|
|
6
|
-
var _a, _b, _c, _d;
|
|
7
6
|
switch (emulationConfig.orientation) {
|
|
8
7
|
case mablApi_1.DeviceEmulation.OrientationEnum.LandscapePrimary:
|
|
9
8
|
case mablApi_1.DeviceEmulation.OrientationEnum.LandscapeSecondary:
|
|
10
|
-
return
|
|
9
|
+
return emulationConfig.device_config?.screen?.horizontal;
|
|
11
10
|
case mablApi_1.DeviceEmulation.OrientationEnum.PortraitPrimary:
|
|
12
11
|
case mablApi_1.DeviceEmulation.OrientationEnum.PortraitSecondary:
|
|
13
|
-
return
|
|
12
|
+
return emulationConfig.device_config?.screen?.vertical;
|
|
14
13
|
default:
|
|
15
14
|
throw new Error(`Unhandled mobile orientation type [${emulationConfig.orientation}]`);
|
|
16
15
|
}
|
|
17
16
|
}
|
|
18
17
|
exports.getProperScreenConfig = getProperScreenConfig;
|
|
19
18
|
function getDeviceDescriptorForEmulation(emulationConfig) {
|
|
20
|
-
var _a, _b, _c, _d, _e;
|
|
21
19
|
if (emulationConfig) {
|
|
22
20
|
const screenConfig = getProperScreenConfig(emulationConfig);
|
|
23
|
-
if (!
|
|
21
|
+
if (!screenConfig?.height && !screenConfig?.width) {
|
|
24
22
|
throw new Error('Could not get viewport settings - invalid emulation config supplied with missing height or width');
|
|
25
23
|
}
|
|
26
24
|
return {
|
|
27
25
|
width: screenConfig.width,
|
|
28
26
|
height: screenConfig.height,
|
|
29
|
-
deviceScaleFactor:
|
|
27
|
+
deviceScaleFactor: emulationConfig.device_config?.screen?.device_pixel_ratio ?? 1,
|
|
30
28
|
isMobile: isMobile(emulationConfig),
|
|
31
|
-
hasTouch:
|
|
29
|
+
hasTouch: emulationConfig.device_config?.capabilities?.includes(mablApi_1.DeviceEmulationConfiguration.CapabilitiesEnum.Touch),
|
|
32
30
|
isLandscape: emulationConfig.orientation ===
|
|
33
31
|
mablApi_1.DeviceEmulation.OrientationEnum.LandscapePrimary ||
|
|
34
32
|
emulationConfig.orientation ===
|
|
@@ -55,7 +55,6 @@ function getFinalUrl(test, parsedUrl) {
|
|
|
55
55
|
}
|
|
56
56
|
exports.getFinalUrl = getFinalUrl;
|
|
57
57
|
async function launchBrowserInstance(options) {
|
|
58
|
-
var _a;
|
|
59
58
|
const optionsProxy = await maybeGetProxyOptions(options);
|
|
60
59
|
if (optionsProxy) {
|
|
61
60
|
options = {
|
|
@@ -69,7 +68,7 @@ async function launchBrowserInstance(options) {
|
|
|
69
68
|
}
|
|
70
69
|
catch (error) {
|
|
71
70
|
if (error.message.includes('Running as root without --no-sandbox is not supported')) {
|
|
72
|
-
|
|
71
|
+
options.commandLineArgs?.push('--no-sandbox');
|
|
73
72
|
messaging_1.mablEventEmitter.log('Unable to initialize browser with standard settings, attempting to run with --no-sandbox setting', Date.now(), logLineMessaging_1.LogLineColor.yellow);
|
|
74
73
|
return maybeLaunchBrowser(options).catch((error) => {
|
|
75
74
|
messaging_1.mablEventEmitter.log('Browser launch failed', Date.now(), logLineMessaging_1.LogLineColor.red);
|
|
@@ -85,7 +84,7 @@ async function maybeGetProxyOptions(options) {
|
|
|
85
84
|
const proxyServer = (await cliConfigProvider_1.CliConfigProvider.getCliConfig()).http.test
|
|
86
85
|
.proxyHost;
|
|
87
86
|
let optionsProxy;
|
|
88
|
-
if (options
|
|
87
|
+
if (options?.proxy) {
|
|
89
88
|
optionsProxy = {
|
|
90
89
|
server: options.proxy.server,
|
|
91
90
|
username: options.proxy.username,
|
|
@@ -102,7 +101,7 @@ async function maybeGetProxyOptions(options) {
|
|
|
102
101
|
return optionsProxy;
|
|
103
102
|
}
|
|
104
103
|
function maybeLaunchBrowser(options) {
|
|
105
|
-
return browserLauncher_1.BrowserLauncherFactory.createRunner(options
|
|
104
|
+
return browserLauncher_1.BrowserLauncherFactory.createRunner(options?.runnerType, options?.loggerFunc).launch(options);
|
|
106
105
|
}
|
|
107
106
|
function removeTempBrowserPreferencesDirectory(tempDirPath) {
|
|
108
107
|
try {
|
|
@@ -368,8 +367,8 @@ function validateRunCommandWithLabels(testId, suppliedLabelsInclude, suppliedLab
|
|
|
368
367
|
.forEach((label) => distinctLabels.add(label));
|
|
369
368
|
return [...distinctLabels];
|
|
370
369
|
}
|
|
371
|
-
const labelsInclude = cleanLabels(suppliedLabelsInclude
|
|
372
|
-
const labelsExclude = cleanLabels(suppliedLabelsExclude
|
|
370
|
+
const labelsInclude = cleanLabels(suppliedLabelsInclude ?? []);
|
|
371
|
+
const labelsExclude = cleanLabels(suppliedLabelsExclude ?? []);
|
|
373
372
|
if (labelsInclude.length > 0 && labelsExclude.length > 0) {
|
|
374
373
|
const intersection = labelsInclude.filter((label) => labelsExclude.includes(label));
|
|
375
374
|
if (intersection.length > 0) {
|
|
@@ -396,58 +395,58 @@ function validateRunCommandWithLabels(testId, suppliedLabelsInclude, suppliedLab
|
|
|
396
395
|
}
|
|
397
396
|
exports.validateRunCommandWithLabels = validateRunCommandWithLabels;
|
|
398
397
|
async function pullDownTestRunConfig(testRunId, apiClient) {
|
|
399
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
400
398
|
const journeyRun = await apiClient.getTestRun(testRunId);
|
|
401
399
|
const planRun = await apiClient.getPlanRun(journeyRun.parent_execution);
|
|
402
|
-
const testDatatablevariables =
|
|
403
|
-
(0, utils_1.variableRowAsScenario)(
|
|
400
|
+
const testDatatablevariables = journeyRun?.journey_parameters?.user_variables &&
|
|
401
|
+
(0, utils_1.variableRowAsScenario)(journeyRun?.journey_parameters?.user_variables);
|
|
404
402
|
return {
|
|
405
|
-
basicAuthCredentialsId:
|
|
406
|
-
?
|
|
403
|
+
basicAuthCredentialsId: planRun?.run_policy?.http_auth_credentials_required
|
|
404
|
+
? planRun?.run_policy?.http_auth_credentials_id
|
|
407
405
|
: undefined,
|
|
408
|
-
branchName:
|
|
409
|
-
credentialsId:
|
|
410
|
-
?
|
|
406
|
+
branchName: journeyRun.journey_parameters?.source_control_tag,
|
|
407
|
+
credentialsId: planRun.run_policy?.credentials_required
|
|
408
|
+
? planRun.run_policy?.credentials_id
|
|
411
409
|
: undefined,
|
|
412
410
|
dataTableVariables: testDatatablevariables,
|
|
413
|
-
deviceEmulation:
|
|
414
|
-
environmentId:
|
|
411
|
+
deviceEmulation: journeyRun.journey_parameters?.device_emulation,
|
|
412
|
+
environmentId: journeyRun.journey_parameters?.deployment?.environment_id,
|
|
415
413
|
filterHttpRequests: false,
|
|
416
|
-
importedVariables:
|
|
417
|
-
pageLoadWait:
|
|
414
|
+
importedVariables: journeyRun.journey_parameters?.imported_variables,
|
|
415
|
+
pageLoadWait: journeyRun.journey_parameters?.page_load_wait,
|
|
418
416
|
runId: journeyRun.id,
|
|
419
|
-
testId:
|
|
420
|
-
url:
|
|
417
|
+
testId: journeyRun.journey?.invariant_id,
|
|
418
|
+
url: journeyRun.journey_parameters?.deployment?.uri,
|
|
421
419
|
};
|
|
422
420
|
}
|
|
423
421
|
exports.pullDownTestRunConfig = pullDownTestRunConfig;
|
|
424
422
|
async function extractTestRunConfig(executionMessage, apiClient) {
|
|
425
|
-
|
|
426
|
-
|
|
423
|
+
const journeyRun = executionMessage.journey_run ??
|
|
424
|
+
(await apiClient.getTestRun(executionMessage.journey_run_id));
|
|
427
425
|
const planRun = executionMessage.plan_run;
|
|
428
|
-
const maybeRunnerType =
|
|
426
|
+
const maybeRunnerType = planRun?.run_policy
|
|
427
|
+
?.nodejs_runtime_variant
|
|
429
428
|
?
|
|
430
|
-
|
|
429
|
+
planRun?.run_policy?.nodejs_runtime_variant
|
|
431
430
|
: undefined;
|
|
432
431
|
return {
|
|
433
|
-
branchName:
|
|
434
|
-
basicAuthCredentialsId:
|
|
435
|
-
?
|
|
432
|
+
branchName: journeyRun?.journey_parameters?.source_control_tag,
|
|
433
|
+
basicAuthCredentialsId: planRun?.run_policy?.http_auth_credentials_required
|
|
434
|
+
? planRun?.run_policy?.http_auth_credentials_id
|
|
436
435
|
: undefined,
|
|
437
|
-
credentialsId:
|
|
438
|
-
?
|
|
436
|
+
credentialsId: planRun?.run_policy?.credentials_required
|
|
437
|
+
? planRun?.run_policy?.credentials_id
|
|
439
438
|
: undefined,
|
|
440
|
-
dataTableVariables:
|
|
441
|
-
(0, utils_1.variableRowAsScenario)(
|
|
442
|
-
deviceEmulation:
|
|
443
|
-
environmentId:
|
|
439
|
+
dataTableVariables: journeyRun?.journey_parameters?.user_variables &&
|
|
440
|
+
(0, utils_1.variableRowAsScenario)(journeyRun?.journey_parameters?.user_variables),
|
|
441
|
+
deviceEmulation: journeyRun?.journey_parameters?.device_emulation,
|
|
442
|
+
environmentId: journeyRun?.journey_parameters?.deployment?.environment_id,
|
|
444
443
|
filterHttpRequests: true,
|
|
445
|
-
importedVariables:
|
|
446
|
-
pageLoadWait:
|
|
444
|
+
importedVariables: journeyRun.journey_parameters?.imported_variables,
|
|
445
|
+
pageLoadWait: journeyRun.journey_parameters?.page_load_wait,
|
|
447
446
|
runId: journeyRun.id,
|
|
448
447
|
runnerType: maybeRunnerType,
|
|
449
|
-
testId:
|
|
450
|
-
url:
|
|
448
|
+
testId: journeyRun?.journey?.invariant_id,
|
|
449
|
+
url: journeyRun?.journey_parameters?.deployment?.uri,
|
|
451
450
|
};
|
|
452
451
|
}
|
|
453
452
|
exports.extractTestRunConfig = extractTestRunConfig;
|
|
@@ -456,7 +455,7 @@ function calculateTotalTimeSeconds(startTimeMillis, endTimeMillis) {
|
|
|
456
455
|
}
|
|
457
456
|
exports.calculateTotalTimeSeconds = calculateTotalTimeSeconds;
|
|
458
457
|
function milliSecondsToSeconds(timeMs) {
|
|
459
|
-
return Math.round((timeMs
|
|
458
|
+
return Math.round((timeMs ?? 0) / 100) / 10;
|
|
460
459
|
}
|
|
461
460
|
exports.milliSecondsToSeconds = milliSecondsToSeconds;
|
|
462
461
|
function logTestInfoIfPresent(description, infoArg) {
|
|
@@ -469,14 +468,13 @@ function createDownloadDirectory() {
|
|
|
469
468
|
return fs.mkdtempSync(path.join(os.tmpdir(), `mablTestRun-${Date.now()}-`));
|
|
470
469
|
}
|
|
471
470
|
function toBasicHttpAuthenticationCredentials(credentials) {
|
|
472
|
-
var _a, _b, _c, _d, _e;
|
|
473
471
|
if (credentials === undefined ||
|
|
474
|
-
|
|
472
|
+
credentials.properties?.username === undefined) {
|
|
475
473
|
return undefined;
|
|
476
474
|
}
|
|
477
475
|
return {
|
|
478
|
-
username:
|
|
479
|
-
password:
|
|
476
|
+
username: credentials.properties?.username ?? '',
|
|
477
|
+
password: credentials.properties?.password ?? '',
|
|
480
478
|
};
|
|
481
479
|
}
|
|
482
480
|
exports.toBasicHttpAuthenticationCredentials = toBasicHttpAuthenticationCredentials;
|
|
@@ -56,14 +56,13 @@ exports.builder = (yargs) => {
|
|
|
56
56
|
};
|
|
57
57
|
exports.handler = (0, util_1.failWrapper)(exportTest);
|
|
58
58
|
async function exportTest(parsed) {
|
|
59
|
-
var _a;
|
|
60
59
|
const testId = parsed.id;
|
|
61
60
|
const format = parsed.format;
|
|
62
61
|
const environmentId = parsed[constants_1.CommandArgEnvironmentId];
|
|
63
62
|
const detailLevel = parsed[constants_1.CommandArgDetailLevel];
|
|
64
63
|
const fileName = parsed[constants_1.CommandArgOutputFilePath];
|
|
65
64
|
const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClient();
|
|
66
|
-
const branchName =
|
|
65
|
+
const branchName = parsed['mabl-branch'] ?? constants_1.DefaultBranchName;
|
|
67
66
|
const journey = await apiClient.getJourney(testId, branchName, format);
|
|
68
67
|
if (journey.test_type === mablApi_1.TestTypeEnum.Performance) {
|
|
69
68
|
throw new Error('Export functionality is not yet available for performance tests.');
|
|
@@ -124,7 +124,7 @@ async function importTest(parsed) {
|
|
|
124
124
|
return handlePostImportActions(workspaceId, name, apiClient, importedTests, parsed.autoSave);
|
|
125
125
|
}
|
|
126
126
|
function getTestName(name) {
|
|
127
|
-
const nameValidator = (value) => !
|
|
127
|
+
const nameValidator = (value) => !value?.length ? 'Name must not be empty' : true;
|
|
128
128
|
return name
|
|
129
129
|
? Promise.resolve(name)
|
|
130
130
|
: inquirer
|
|
@@ -242,9 +242,8 @@ function displayTestDescriptions(importedTests) {
|
|
|
242
242
|
});
|
|
243
243
|
}
|
|
244
244
|
async function runTests(workspaceId, name, apiClient, importedTests) {
|
|
245
|
-
var _a, _b;
|
|
246
245
|
const flows = importedTests.map((steps) => stepsToFlow(workspaceId, steps));
|
|
247
|
-
const firstUrl =
|
|
246
|
+
const firstUrl = flows.find((flow) => flow.url)?.url;
|
|
248
247
|
const browserPath = await new chromiumBrowserEngine_1.ChromiumBrowserEngine().findBrowserExecutable();
|
|
249
248
|
for (let flowIndex = 0; flowIndex < flows.length; flowIndex++) {
|
|
250
249
|
loggingProvider_1.logger.info(`Running test ${flowIndex + 1} of ${flows.length}.`);
|
|
@@ -253,7 +252,7 @@ async function runTests(workspaceId, name, apiClient, importedTests) {
|
|
|
253
252
|
organization_id: workspaceId,
|
|
254
253
|
name,
|
|
255
254
|
flows: [],
|
|
256
|
-
url:
|
|
255
|
+
url: flow.url ?? firstUrl,
|
|
257
256
|
};
|
|
258
257
|
const testRunner = await createTestRunner(apiClient, journey, flow, journey.url, workspaceId, browserPath);
|
|
259
258
|
const results = await testRunner.run();
|
|
@@ -269,7 +268,7 @@ function stepsToFlow(workspaceId, steps) {
|
|
|
269
268
|
reusable: false,
|
|
270
269
|
selectors: steps
|
|
271
270
|
.map((step) => step.selector)
|
|
272
|
-
.map((selector) => selector
|
|
271
|
+
.map((selector) => selector?.toMablscriptSelector())
|
|
273
272
|
.filter((selector) => selector)
|
|
274
273
|
.map((selector) => selector),
|
|
275
274
|
script: steps.map((step) => step.mablscript).join('\n'),
|
|
@@ -133,7 +133,6 @@ exports.builder = (yargs) => {
|
|
|
133
133
|
};
|
|
134
134
|
exports.handler = (0, util_1.failWrapper)(runInCloud);
|
|
135
135
|
async function runInCloud(parsed) {
|
|
136
|
-
var _a;
|
|
137
136
|
const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClientFromOptionalApiKey(parsed['api-key']);
|
|
138
137
|
const workspaceId = await (0, util_1.getWorkspaceId)(parsed);
|
|
139
138
|
const prompt = parsed.prompt && !parsed[constants_1.CommandArgNoPrompt];
|
|
@@ -143,7 +142,7 @@ async function runInCloud(parsed) {
|
|
|
143
142
|
const labelsInclude = parsed.labels || [];
|
|
144
143
|
const labelsExclude = parsed['exclude-labels'] || [];
|
|
145
144
|
const maybeDeploymentId = parsed['deployment-id'];
|
|
146
|
-
const maybeUrlApp =
|
|
145
|
+
const maybeUrlApp = parsed['app-url'] ?? parsed.url;
|
|
147
146
|
const maybeUrlApi = parsed['api-url'];
|
|
148
147
|
const browsers = parsed.browsers;
|
|
149
148
|
const credentialsId = parsed['credentials-id'];
|
|
@@ -200,13 +199,14 @@ async function runInCloud(parsed) {
|
|
|
200
199
|
return outputUrl;
|
|
201
200
|
}
|
|
202
201
|
async function executeRunCloudTest(test, browsers, branchName, apiClient, maybeDeploymentId, appUrl, apiUrl, credentialsId, applicationId, environmentId, basicAuthCredentialsId) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const effectiveApiUrl = apiUrl
|
|
208
|
-
|
|
209
|
-
|
|
202
|
+
const effectiveAppUrl = appUrl ??
|
|
203
|
+
(test.test_type === undefined || test.test_type === mablApi_1.TestTypeEnum.Browser
|
|
204
|
+
? test?.url
|
|
205
|
+
: undefined);
|
|
206
|
+
const effectiveApiUrl = apiUrl ??
|
|
207
|
+
(test.test_type && test.test_type !== mablApi_1.TestTypeEnum.Browser
|
|
208
|
+
? test?.url
|
|
209
|
+
: undefined);
|
|
210
210
|
const workspaceId = test.organization_id;
|
|
211
211
|
const testId = test.invariant_id;
|
|
212
212
|
let deploymentIds;
|
|
@@ -236,10 +236,9 @@ async function executeRunCloudTest(test, browsers, branchName, apiClient, maybeD
|
|
|
236
236
|
}
|
|
237
237
|
const planRun = await apiClient.postPlanRun(workspaceId, testId, branchName, browsers, effectiveAppUrl, effectiveApiUrl, maybeDeploymentId, credentialsId, deploymentIds, basicAuthCredentialsId);
|
|
238
238
|
const testRunsQueryResult = await apiClient.getTestRunsForPlan(planRun.id);
|
|
239
|
-
return
|
|
239
|
+
return testRunsQueryResult.test_script_executions ?? [];
|
|
240
240
|
}
|
|
241
241
|
async function getJourneysForLabels(workspaceId, branchName, branchChangesOnly, labelsInclude, labelsExclude, limit, prompt, apiClient) {
|
|
242
|
-
var _a;
|
|
243
242
|
const journeys = await apiClient.getJourneys({
|
|
244
243
|
limit,
|
|
245
244
|
organization_id: workspaceId,
|
|
@@ -273,7 +272,7 @@ async function getJourneysForLabels(workspaceId, branchName, branchChangesOnly,
|
|
|
273
272
|
default: journeyChoices.map((choice) => choice.value),
|
|
274
273
|
},
|
|
275
274
|
]);
|
|
276
|
-
const selectedJourneys =
|
|
275
|
+
const selectedJourneys = journeys.filter((journey) => testsToRun?.test_selection?.includes(journey.id)) ?? [];
|
|
277
276
|
if (selectedJourneys.length === 0) {
|
|
278
277
|
return [];
|
|
279
278
|
}
|
|
@@ -289,7 +288,7 @@ async function getJourneysForLabels(workspaceId, branchName, branchChangesOnly,
|
|
|
289
288
|
default: 'Yes',
|
|
290
289
|
},
|
|
291
290
|
]);
|
|
292
|
-
if (response
|
|
291
|
+
if (response?.do_continue) {
|
|
293
292
|
return selectedJourneys;
|
|
294
293
|
}
|
|
295
294
|
return [];
|
|
@@ -72,6 +72,18 @@ exports.builder = (yargs) => {
|
|
|
72
72
|
describe: 'Mabl environment to run under. Specify to ensure the test runs with environment variables and the latest find information.',
|
|
73
73
|
nargs: 1,
|
|
74
74
|
type: 'string',
|
|
75
|
+
})
|
|
76
|
+
.option(constants_1.CommandArgLocale, {
|
|
77
|
+
describe: 'Locale to run the test in, e.g. en-US',
|
|
78
|
+
nargs: 1,
|
|
79
|
+
type: 'string',
|
|
80
|
+
hidden: true,
|
|
81
|
+
})
|
|
82
|
+
.option(constants_1.CommandArgTimezoneID, {
|
|
83
|
+
describe: 'Identifier of the timezone to run the test in, e.g. America/Buenos_Aires',
|
|
84
|
+
nargs: 1,
|
|
85
|
+
type: 'string',
|
|
86
|
+
hidden: true,
|
|
75
87
|
})
|
|
76
88
|
.option('width', {
|
|
77
89
|
describe: 'Set the browser width in pixels',
|
|
@@ -194,7 +206,6 @@ exports.builder = (yargs) => {
|
|
|
194
206
|
const exitCodeOnError = 1;
|
|
195
207
|
exports.handler = (0, util_1.failWrapper)(run, exitCodeOnError);
|
|
196
208
|
async function run(parsed) {
|
|
197
|
-
var _a;
|
|
198
209
|
const commandStartTime = Date.now();
|
|
199
210
|
let workspaceId;
|
|
200
211
|
try {
|
|
@@ -203,7 +214,7 @@ async function run(parsed) {
|
|
|
203
214
|
catch {
|
|
204
215
|
}
|
|
205
216
|
const extraHttpHeaders = {};
|
|
206
|
-
(
|
|
217
|
+
(parsed['http-headers'] ?? []).forEach((header) => {
|
|
207
218
|
const headerParts = header.split(':');
|
|
208
219
|
if (headerParts.length === 2 && headerParts[0] && headerParts[1]) {
|
|
209
220
|
extraHttpHeaders[headerParts[0].toLowerCase()] = headerParts[1];
|
|
@@ -218,6 +229,14 @@ async function run(parsed) {
|
|
|
218
229
|
throw new Error(`Scenario with ID ${parsed[constants_1.CommandArgScenarioId]} not found`);
|
|
219
230
|
}
|
|
220
231
|
}
|
|
232
|
+
const parsedLocale = parsed[constants_1.CommandArgLocale];
|
|
233
|
+
const parsedTimezone = parsed[constants_1.CommandArgTimezoneID];
|
|
234
|
+
const localizationOptions = parsedLocale || parsedTimezone
|
|
235
|
+
? {
|
|
236
|
+
locale: parsedLocale,
|
|
237
|
+
timezone_identifier: parsedTimezone,
|
|
238
|
+
}
|
|
239
|
+
: undefined;
|
|
221
240
|
const testRunnerConfig = {
|
|
222
241
|
_cliCreated: true,
|
|
223
242
|
basicAuthCredentialsId: parsed[constants_1.CommandArgBasicAuthCredentials],
|
|
@@ -240,6 +259,7 @@ async function run(parsed) {
|
|
|
240
259
|
keepBrowserOpen: parsed['keep-browser-open'],
|
|
241
260
|
labelsExclude: parsed['exclude-labels'],
|
|
242
261
|
labelsInclude: parsed.labels,
|
|
262
|
+
localizationOptions,
|
|
243
263
|
runId: parsed['run-id'],
|
|
244
264
|
testFile: parsed[constants_1.CommandArgTestFile],
|
|
245
265
|
testId: parsed.id,
|
|
@@ -252,7 +272,7 @@ async function run(parsed) {
|
|
|
252
272
|
loggingProvider_1.logger.info('Warming up test runner...');
|
|
253
273
|
const mablTestsRunner = await execution.createMablTestRunner(testRunnerConfig);
|
|
254
274
|
const results = await mablTestsRunner.run();
|
|
255
|
-
if (
|
|
275
|
+
if (mablTestsRunner?.mablTestRunners !== undefined) {
|
|
256
276
|
mablTestsRunner.mablTestRunners
|
|
257
277
|
.filter((tr) => tr instanceof execution_1.MablTestRunner)
|
|
258
278
|
.forEach((tr) => {
|
|
@@ -268,19 +288,18 @@ async function run(parsed) {
|
|
|
268
288
|
}
|
|
269
289
|
exports.run = run;
|
|
270
290
|
function generateRunCommandTemplate(parsed, testResults) {
|
|
271
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
272
291
|
const testResult = testResults.testResults[0];
|
|
273
292
|
let templateCommand = `${defaultEnv_1.SCRIPT_NAME} ${parsed._.join(' ')} \\\n`;
|
|
274
|
-
if (
|
|
275
|
-
templateCommand = `${templateCommand} --${constants_1.CommandArgEnvironmentId} ${
|
|
293
|
+
if (testResult?.rerunConfig?.environmentId) {
|
|
294
|
+
templateCommand = `${templateCommand} --${constants_1.CommandArgEnvironmentId} ${testResult?.rerunConfig?.environmentId} \\\n`;
|
|
276
295
|
}
|
|
277
|
-
if (
|
|
278
|
-
templateCommand = `${templateCommand} --${constants_1.CommandArgCredentials} ${
|
|
296
|
+
if (testResult?.rerunConfig?.credentialsId) {
|
|
297
|
+
templateCommand = `${templateCommand} --${constants_1.CommandArgCredentials} ${testResult?.rerunConfig?.credentialsId} \\\n`;
|
|
279
298
|
}
|
|
280
|
-
if (
|
|
281
|
-
templateCommand = `${templateCommand} --${constants_1.CommandArgUrl} ${
|
|
299
|
+
if (testResult?.rerunConfig?.url) {
|
|
300
|
+
templateCommand = `${templateCommand} --${constants_1.CommandArgUrl} ${testResult?.rerunConfig?.url} \\\n`;
|
|
282
301
|
}
|
|
283
|
-
if (
|
|
302
|
+
if (testResult?.rerunConfig?.branch) {
|
|
284
303
|
templateCommand = `${templateCommand} --${constants_1.CommandArgMablBranch} ${testResult.rerunConfig.branch} \\\n`;
|
|
285
304
|
}
|
|
286
305
|
const testIdVal = parsed.id ? parsed.id : '<TEST-ID>';
|
|
@@ -38,8 +38,8 @@ function printUsers(users, outputFormat, workspaceId) {
|
|
|
38
38
|
wordWrap: true,
|
|
39
39
|
});
|
|
40
40
|
users.forEach((user) => {
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
const userRole = user.roles?.find((role) => role.organization_id === workspaceId)
|
|
42
|
+
?.role ?? 'unknown';
|
|
43
43
|
table.push([
|
|
44
44
|
{ rowSpan: 1, content: user.id, vAlign: 'center' },
|
|
45
45
|
{ rowSpan: 1, content: user.name, vAlign: 'center' },
|
|
@@ -32,8 +32,7 @@ function getTimestamp() {
|
|
|
32
32
|
return (0, moment_1.default)().format('HH:mm:ss');
|
|
33
33
|
}
|
|
34
34
|
function hasOwnerRoleInWorkspace(user, workspaceId) {
|
|
35
|
-
|
|
36
|
-
const hasOwnerRole = (_a = user.roles) === null || _a === void 0 ? void 0 : _a.some((role) => role.organization_id === workspaceId && role.role === mablApi_1.UserRoleEnum.Owner);
|
|
35
|
+
const hasOwnerRole = user.roles?.some((role) => role.organization_id === workspaceId && role.role === mablApi_1.UserRoleEnum.Owner);
|
|
37
36
|
if (!hasOwnerRole) {
|
|
38
37
|
loggingProvider_1.logger.warn(chalk_1.default.yellow(`You must be an owner in both workspaces to copy. You do not have owner permissions in workspace: ${workspaceId}`));
|
|
39
38
|
}
|