@mablhq/mabl-cli 1.12.7 → 1.12.33
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 +1 -1
- package/api/mablApiClient.js +9 -9
- package/auth/AuthClient.js +1 -4
- package/browserLauncher/browserLauncher.js +3 -1
- package/browserLauncher/elementHandle.js +8 -1
- package/browserLauncher/frame.js +15 -0
- package/browserLauncher/frameBase.js +4 -0
- package/browserLauncher/playwrightBrowserLauncher/playwrightBrowser.js +2 -2
- package/browserLauncher/playwrightBrowserLauncher/playwrightDom.js +119 -31
- package/browserLauncher/playwrightBrowserLauncher/playwrightFrame.js +32 -21
- package/browserLauncher/playwrightBrowserLauncher/playwrightPage.js +43 -75
- package/browserLauncher/playwrightBrowserLauncher/wrappers.js +1 -1
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerBrowser.js +3 -3
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerElementHandle.js +59 -5
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerFrame.js +9 -8
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerHttpRequest.js +1 -1
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerHttpResponse.js +1 -1
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerJsHandle.js +3 -3
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerPage.js +23 -61
- package/browserLauncher/puppeteerBrowserLauncher/wrappers.js +1 -1
- package/cli.js +3 -6
- package/commands/applications/applications_cmds/list.js +1 -1
- package/commands/branches/branches_cmds/create.js +1 -1
- package/commands/branches/branches_cmds/list.js +1 -1
- package/commands/branches/branches_cmds/merge.js +1 -1
- package/commands/commandUtil/awaitCompletion.js +2 -2
- package/commands/commandUtil/codeInsights.js +6 -6
- package/commands/commandUtil/fileUtil.js +1 -1
- package/commands/commandUtil/util.js +12 -12
- package/commands/config/config_cmds/list.js +1 -1
- package/commands/constants.js +1 -1
- package/commands/credentials/credentials_cmds/list.js +1 -1
- package/commands/deploy/deploy_cmds/create.js +2 -2
- package/commands/deploy/deploy_cmds/executionResultPresenter.js +7 -7
- package/commands/deploy/deploy_cmds/list.js +1 -1
- package/commands/environments/environments_cmds/create.js +3 -3
- package/commands/environments/environments_cmds/list.js +1 -1
- package/commands/environments/environments_cmds/urls_cmds/add.js +1 -1
- package/commands/flows/flows_cmds/list.js +1 -1
- package/commands/plans/plans_cmds/list.js +1 -1
- package/commands/test-runs/test-runs_cmds/export.js +1 -1
- package/commands/tests/executionUtil.js +1 -1
- package/commands/tests/testsUtil.js +10 -17
- package/commands/tests/tests_cmds/edit.js +1 -1
- package/commands/tests/tests_cmds/export.js +1 -1
- package/commands/tests/tests_cmds/import.js +13 -13
- package/commands/tests/tests_cmds/list.js +2 -2
- package/commands/tests/tests_cmds/run-alpha.js +1 -1
- package/commands/tests/tests_cmds/run-cloud.js +6 -6
- package/commands/tests/tests_cmds/run-legacy.js +2 -2
- package/commands/tests/tests_cmds/run.js +4 -4
- package/commands/workspaces/workspace_cmds/copy.js +1 -1
- package/commands/workspaces/workspace_cmds/list.js +1 -1
- package/configGenerators/flowConfigGenerator.js +3 -3
- package/configGenerators/selIdeGenerator.js +1 -1
- package/configGenerators/testConfigGenerator.js +7 -8
- package/core/execution/ApiTestUtils.js +2 -2
- package/core/messaging/messaging.js +14 -1
- package/core/trainer/openUtils.js +47 -0
- package/core/trainer/trainingSessions.js +36 -61
- package/env/defaultEnv.js +2 -1
- package/env/dev.js +2 -1
- package/env/env.js +3 -1
- package/env/local.js +2 -1
- package/env/prod.js +2 -1
- package/execution/index.js +1 -1
- package/mablApi/index.js +1 -1
- package/mablscript/MablStep.js +11 -7
- package/mablscript/actions/ConditionAction.js +2 -4
- package/mablscript/actions/FindAction.js +4 -4
- package/mablscript/importer.js +16 -14
- package/mablscript/steps/AccessibilityCheck.js +88 -0
- package/mablscript/steps/AssertStep.js +6 -5
- package/mablscript/steps/CreateVariableStep.js +2 -3
- package/mablscript/steps/DownloadStep.js +1 -2
- package/mablscript/steps/EnterTextStep.js +2 -1
- package/mablscript/steps/IfConditionStep.js +3 -3
- package/mablscript/steps/SendHttpRequestStep.js +2 -2
- package/mablscript/steps/SendKeyStep.js +2 -2
- package/mablscript/steps/SetFilesStep.js +1 -1
- package/mablscript/steps/SwitchContextStep.js +2 -1
- package/mablscript/types/AccessibilityCheckStepDescriptor.js +2 -0
- package/mablscript/types/AccessibilityCheckTypes.js +9 -0
- package/mablscript/types/VariableDataType.js +1 -8
- package/mablscript/types/VariableNamespace.js +1 -1
- package/mablscriptFind/index.js +1 -1
- package/package.json +6 -4
- package/popupDismissal/index.js +13 -12
- package/providers/authenticationProvider.js +2 -3
- package/providers/cliConfigProvider.js +1 -1
- package/providers/exportRequestProvider.js +1 -1
- package/providers/logging/loggingProvider.js +2 -2
- package/providers/scmContextProvider.js +1 -1
- package/reporters/mochAwesome/mochAwesomeReporter.js +10 -6
- package/reporters/reporter.js +1 -1
- package/resources/mablFind.js +1 -1
- package/resources/popupDismissal.js +1 -1
- package/util/RichPromise.js +2 -2
- package/util/actionabilityUtil.js +39 -14
- package/util/downloadUtil.js +1 -1
- package/util/logUtils.js +20 -1
- package/util/markdownUtil.js +3 -3
- package/util/pureUtil.js +6 -6
- package/util/resourceUtil.js +14 -1
- package/core/trainer/trainerBrowserUtil.js +0 -33
|
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.toBasicHttpAuthenticationCredentials = exports.generateChromiumPreferencesFile = exports.
|
|
25
|
+
exports.toBasicHttpAuthenticationCredentials = exports.generateChromiumPreferencesFile = exports.logTestInfoIfPresent = exports.calculateTotalTimeSeconds = exports.extractTestRunConfig = exports.pullDownTestRunConfig = exports.validateRunCommandWithLabels = exports.validateRunEditCommand = exports.downloadUploadFile = exports.sleep = exports.editTheTest = exports.runTheTest = exports.prepareTrainerForSplitPlayback = exports.createTrainingSession = exports.cleanUpInitialPages = exports.getExtensionBackgroundPageWithCliTool = exports.setUpAuthTokenForExtension = exports.connectToExistingBrowserWebsocket = exports.connectToExistingBrowser = exports.createBrowserForExecutionEngine = exports.addExecutionEngineLaunchArgs = exports.createBrowser = exports.prepareChromePreferencesDirectory = exports.createBrowserWithAuthedExtension = exports.findChrome = exports.searchForChrome = exports.getFinalUrl = exports.getTempChromePrefDirectory = void 0;
|
|
26
26
|
const os = __importStar(require("os"));
|
|
27
27
|
const trainerUtil_1 = require("./tests_cmds/trainer_cmds/trainerUtil");
|
|
28
28
|
const fs = __importStar(require("fs-extra"));
|
|
@@ -81,7 +81,7 @@ function getFinalUrl(test, parsedUrl) {
|
|
|
81
81
|
exports.getFinalUrl = getFinalUrl;
|
|
82
82
|
function searchForChrome() {
|
|
83
83
|
const chromes = chromeFinder[launchUtils.getPlatform()]();
|
|
84
|
-
return chromes.filter(chrome => {
|
|
84
|
+
return chromes.filter((chrome) => {
|
|
85
85
|
const lowCase = chrome.toLowerCase();
|
|
86
86
|
return !(lowCase.includes('canary') ||
|
|
87
87
|
lowCase.includes('dev') ||
|
|
@@ -152,7 +152,7 @@ async function launchBrowserInstance(chromePath, launchArgs, userDataDir, headle
|
|
|
152
152
|
defaultDeviceDescriptor,
|
|
153
153
|
ignoreDefaultArgs,
|
|
154
154
|
runnerType,
|
|
155
|
-
}).catch(error => {
|
|
155
|
+
}).catch((error) => {
|
|
156
156
|
messaging_1.mablEventEmitter.log('Browser launch failed', Date.now(), logLineMessaging_1.LogLineColor.red);
|
|
157
157
|
messaging_1.mablEventEmitter.log(error.message);
|
|
158
158
|
});
|
|
@@ -298,7 +298,7 @@ function connectToExistingBrowserWebsocket(websocketEndpoint, currentDownloadPat
|
|
|
298
298
|
exports.connectToExistingBrowserWebsocket = connectToExistingBrowserWebsocket;
|
|
299
299
|
async function setUpAuthTokenForExtension(browser, accessToken) {
|
|
300
300
|
const backgroundPage = await browser.getExtensionBackgroundPage(trainerUtil_1.getTrainerId());
|
|
301
|
-
await backgroundPage.evaluate(token => {
|
|
301
|
+
await backgroundPage.evaluate((token) => {
|
|
302
302
|
localStorage.setItem('authResult', JSON.stringify({ idToken: token }));
|
|
303
303
|
localStorage.setItem('trainerWorld', 'mablCLI');
|
|
304
304
|
}, accessToken);
|
|
@@ -342,7 +342,7 @@ exports.cleanUpInitialPages = cleanUpInitialPages;
|
|
|
342
342
|
async function exposeMessagingFunctionToTrainer(backgroundPage, browser) {
|
|
343
343
|
await backgroundPage
|
|
344
344
|
.exposeFunction('postMessageToCli', (message) => handleExtensionMessage(message, browser))
|
|
345
|
-
.catch(error => messaging_1.mablEventEmitter.log('Error on the handle' + error));
|
|
345
|
+
.catch((error) => messaging_1.mablEventEmitter.log('Error on the handle' + error));
|
|
346
346
|
}
|
|
347
347
|
async function createTrainingSession(backgroundPage, trainingSessionOptions, environment, plan, deployment, application, autoLoginFlow) {
|
|
348
348
|
var _a;
|
|
@@ -350,7 +350,7 @@ async function createTrainingSession(backgroundPage, trainingSessionOptions, env
|
|
|
350
350
|
autoLogin: trainingSessionOptions.autoLogin,
|
|
351
351
|
datatables: trainingSessionOptions.dataTableIds,
|
|
352
352
|
flowIndexToTrain: 0,
|
|
353
|
-
labels: (_a = trainingSessionOptions.labels) === null || _a === void 0 ? void 0 : _a.map(label => ({ name: label })),
|
|
353
|
+
labels: (_a = trainingSessionOptions.labels) === null || _a === void 0 ? void 0 : _a.map((label) => ({ name: label })),
|
|
354
354
|
description: trainingSessionOptions.testDescription,
|
|
355
355
|
name: trainingSessionOptions.testName,
|
|
356
356
|
flows: autoLoginFlow ? [autoLoginFlow.id] : [],
|
|
@@ -437,7 +437,7 @@ async function shutItDown(trainingBrowser) {
|
|
|
437
437
|
await trainingBrowser.close().catch(() => 'Shutdown was a little bumpy');
|
|
438
438
|
}
|
|
439
439
|
function sleep(milliseconds) {
|
|
440
|
-
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
|
440
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
441
441
|
}
|
|
442
442
|
exports.sleep = sleep;
|
|
443
443
|
const TRAINER_SHUTDOWN = 'TRAINER_SHUTDOWN';
|
|
@@ -586,17 +586,14 @@ function validateRunCommandWithLabels(testId, suppliedLabelsInclude, suppliedLab
|
|
|
586
586
|
function cleanLabels(input) {
|
|
587
587
|
const distinctLabels = new Set();
|
|
588
588
|
input
|
|
589
|
-
.map((label) => label
|
|
590
|
-
.
|
|
591
|
-
.trim()
|
|
592
|
-
.toLowerCase())
|
|
593
|
-
.forEach(label => distinctLabels.add(label));
|
|
589
|
+
.map((label) => label.toString().trim().toLowerCase())
|
|
590
|
+
.forEach((label) => distinctLabels.add(label));
|
|
594
591
|
return [...distinctLabels];
|
|
595
592
|
}
|
|
596
593
|
const labelsInclude = cleanLabels(suppliedLabelsInclude !== null && suppliedLabelsInclude !== void 0 ? suppliedLabelsInclude : []);
|
|
597
594
|
const labelsExclude = cleanLabels(suppliedLabelsExclude !== null && suppliedLabelsExclude !== void 0 ? suppliedLabelsExclude : []);
|
|
598
595
|
if (labelsInclude.length > 0 && labelsExclude.length > 0) {
|
|
599
|
-
const intersection = labelsInclude.filter(label => labelsExclude.includes(label));
|
|
596
|
+
const intersection = labelsInclude.filter((label) => labelsExclude.includes(label));
|
|
600
597
|
if (intersection.length > 0) {
|
|
601
598
|
throw new Error(`Include labels --${constants_1.CommandArgLabelsInclude} and exclude labels --${constants_1.CommandArgLabelsExclude} have overlapping values [${intersection.join(',')}]`);
|
|
602
599
|
}
|
|
@@ -671,10 +668,6 @@ function logTestInfoIfPresent(description, infoArg) {
|
|
|
671
668
|
}
|
|
672
669
|
}
|
|
673
670
|
exports.logTestInfoIfPresent = logTestInfoIfPresent;
|
|
674
|
-
function logCtlCLine() {
|
|
675
|
-
messaging_1.mablEventEmitter.log(chalk.yellowBright('Session started (Press CTRL + C to cancel)'));
|
|
676
|
-
}
|
|
677
|
-
exports.logCtlCLine = logCtlCLine;
|
|
678
671
|
function generateChromiumPreferencesFile(windowPlacement) {
|
|
679
672
|
const preferences = {
|
|
680
673
|
download: {
|
|
@@ -76,7 +76,7 @@ exports.builder = (yargs) => {
|
|
|
76
76
|
default: false,
|
|
77
77
|
type: 'boolean',
|
|
78
78
|
})
|
|
79
|
-
.check(argv => testsUtil_1.validateRunEditCommand(argv[constants_1.CommandArgId], argv[constants_1.CommandArgTestRunId]));
|
|
79
|
+
.check((argv) => testsUtil_1.validateRunEditCommand(argv[constants_1.CommandArgId], argv[constants_1.CommandArgTestRunId]));
|
|
80
80
|
};
|
|
81
81
|
exports.handler = util_1.failWrapper(launchEditTrainingSession);
|
|
82
82
|
async function launchEditTrainingSession(parsed) {
|
|
@@ -54,7 +54,7 @@ async function pullJourney(parsed) {
|
|
|
54
54
|
const journey = await apiClient.getJourney(testId, branchName, format);
|
|
55
55
|
const flowArray = await util_1.getJourneyFlowArray(journey, apiClient, branchName);
|
|
56
56
|
if (flowArray
|
|
57
|
-
.map(flow => flow.flow_type === mablApi_1.Flow.FlowTypeEnum.Mablscript ||
|
|
57
|
+
.map((flow) => flow.flow_type === mablApi_1.Flow.FlowTypeEnum.Mablscript ||
|
|
58
58
|
flow.flow_type === mablApi_1.Flow.FlowTypeEnum.Api)
|
|
59
59
|
.includes(false)) {
|
|
60
60
|
loggingProvider_1.logger.info(chalk.red(`Default mabl tests can not be exported`));
|
|
@@ -128,7 +128,7 @@ function getTestName(name) {
|
|
|
128
128
|
validate: nameValidator,
|
|
129
129
|
},
|
|
130
130
|
])
|
|
131
|
-
.then(answers => answers.name);
|
|
131
|
+
.then((answers) => answers.name);
|
|
132
132
|
}
|
|
133
133
|
async function importTests(port, debug, importMultipleTests) {
|
|
134
134
|
const importedTests = [];
|
|
@@ -215,10 +215,10 @@ function saveTests(workspaceId, name, apiClient, importedTests) {
|
|
|
215
215
|
loggingProvider_1.logger.info(`Saving ${pluralize_1.default('test', importedTests.length, true)}...`);
|
|
216
216
|
const savePromises = importedTests.map((steps, index) => apiClient
|
|
217
217
|
.createFlow(stepsToFlow(workspaceId, steps))
|
|
218
|
-
.then(flow => apiClient.createJourney(flowToJourney(importedTests.length === 1
|
|
218
|
+
.then((flow) => apiClient.createJourney(flowToJourney(importedTests.length === 1
|
|
219
219
|
? name
|
|
220
220
|
: `${name} (${index + 1} of ${importedTests.length})`, flow)))
|
|
221
|
-
.then(journey => {
|
|
221
|
+
.then((journey) => {
|
|
222
222
|
loggingProvider_1.logger.info(`Saved test ${journey.invariant_id} : ${env_1.BASE_APP_URL}/workspaces/${journey.organization_id}/train/journeys/${journey.invariant_id}/current`);
|
|
223
223
|
return journey;
|
|
224
224
|
}));
|
|
@@ -229,14 +229,14 @@ function displayTestDescriptions(importedTests) {
|
|
|
229
229
|
if (importedTests.length > 1) {
|
|
230
230
|
loggingProvider_1.logger.info(`Test ${index + 1} of ${importedTests.length}:`);
|
|
231
231
|
}
|
|
232
|
-
loggingProvider_1.logger.info(steps.map(step => step.description).join('\n'));
|
|
232
|
+
loggingProvider_1.logger.info(steps.map((step) => step.description).join('\n'));
|
|
233
233
|
loggingProvider_1.logger.logNewLine();
|
|
234
234
|
});
|
|
235
235
|
}
|
|
236
236
|
async function runTests(workspaceId, name, importedTests) {
|
|
237
237
|
var _a, _b;
|
|
238
|
-
const flows = importedTests.map(steps => stepsToFlow(workspaceId, steps));
|
|
239
|
-
const firstUrl = (_a = flows.find(flow => flow.url)) === null || _a === void 0 ? void 0 : _a.url;
|
|
238
|
+
const flows = importedTests.map((steps) => stepsToFlow(workspaceId, steps));
|
|
239
|
+
const firstUrl = (_a = flows.find((flow) => flow.url)) === null || _a === void 0 ? void 0 : _a.url;
|
|
240
240
|
for (let flowIndex = 0; flowIndex < flows.length; flowIndex++) {
|
|
241
241
|
loggingProvider_1.logger.info(`Running test ${flowIndex + 1} of ${flows.length}.`);
|
|
242
242
|
const flow = flows[flowIndex];
|
|
@@ -257,13 +257,13 @@ function stepsToFlow(workspaceId, steps) {
|
|
|
257
257
|
organization_id: workspaceId,
|
|
258
258
|
reusable: false,
|
|
259
259
|
selectors: steps
|
|
260
|
-
.map(step => step.selector)
|
|
261
|
-
.map(selector => selector === null || selector === void 0 ? void 0 : selector.toMablscriptSelector())
|
|
262
|
-
.filter(selector => !!selector)
|
|
263
|
-
.map(selector => selector),
|
|
264
|
-
script: steps.map(step => step.mablscript).join('\n'),
|
|
265
|
-
script_description: steps.map(step => step.description).join('\n'),
|
|
266
|
-
url: steps.map(step => step.url).find(url => url),
|
|
260
|
+
.map((step) => step.selector)
|
|
261
|
+
.map((selector) => selector === null || selector === void 0 ? void 0 : selector.toMablscriptSelector())
|
|
262
|
+
.filter((selector) => !!selector)
|
|
263
|
+
.map((selector) => selector),
|
|
264
|
+
script: steps.map((step) => step.mablscript).join('\n'),
|
|
265
|
+
script_description: steps.map((step) => step.description).join('\n'),
|
|
266
|
+
url: steps.map((step) => step.url).find((url) => url),
|
|
267
267
|
};
|
|
268
268
|
return prototype;
|
|
269
269
|
}
|
|
@@ -48,7 +48,7 @@ async function listTests(parsed) {
|
|
|
48
48
|
limit,
|
|
49
49
|
include_labels: labels,
|
|
50
50
|
});
|
|
51
|
-
const outputJourneys = journeys.map(journey => ({
|
|
51
|
+
const outputJourneys = journeys.map((journey) => ({
|
|
52
52
|
created_time: journey.created_time,
|
|
53
53
|
id: journey.invariant_id,
|
|
54
54
|
name: journey.name,
|
|
@@ -76,7 +76,7 @@ function printTestsAsTable(tests) {
|
|
|
76
76
|
head: ['ID', 'Name', 'Created time'],
|
|
77
77
|
wordWrap: true,
|
|
78
78
|
});
|
|
79
|
-
tests.forEach(test => {
|
|
79
|
+
tests.forEach((test) => {
|
|
80
80
|
table.push([
|
|
81
81
|
{ rowSpan: 1, content: test.invariant_id, vAlign: 'center' },
|
|
82
82
|
{ rowSpan: 1, content: test.name, vAlign: 'center' },
|
|
@@ -119,7 +119,7 @@ exports.builder = (yargs) => {
|
|
|
119
119
|
default: false,
|
|
120
120
|
type: 'boolean',
|
|
121
121
|
})
|
|
122
|
-
.check(argv => testsUtil_1.validateRunCommandWithLabels(argv[constants_1.CommandArgId], argv[constants_1.CommandArgLabelsInclude], argv[constants_1.CommandArgLabelsExclude], argv[constants_1.CommandArgTestRunId], argv[constants_1.CommandArgFromPlanId], true, argv[constants_1.CommandArgTestFile]));
|
|
122
|
+
.check((argv) => testsUtil_1.validateRunCommandWithLabels(argv[constants_1.CommandArgId], argv[constants_1.CommandArgLabelsInclude], argv[constants_1.CommandArgLabelsExclude], argv[constants_1.CommandArgTestRunId], argv[constants_1.CommandArgFromPlanId], true, argv[constants_1.CommandArgTestFile]));
|
|
123
123
|
};
|
|
124
124
|
const exitCodeOnError = 1;
|
|
125
125
|
exports.handler = util_1.failWrapper(runAlpha, exitCodeOnError);
|
|
@@ -130,7 +130,7 @@ exports.builder = (yargs) => {
|
|
|
130
130
|
type: 'boolean',
|
|
131
131
|
alias: constants_1.CommandArgAliases.NoPrompt,
|
|
132
132
|
})
|
|
133
|
-
.check(argv => testsUtil_1.validateRunCommandWithLabels(argv[constants_1.CommandArgId], argv[constants_1.CommandArgLabelsInclude], argv[constants_1.CommandArgLabelsExclude]));
|
|
133
|
+
.check((argv) => testsUtil_1.validateRunCommandWithLabels(argv[constants_1.CommandArgId], argv[constants_1.CommandArgLabelsInclude], argv[constants_1.CommandArgLabelsExclude]));
|
|
134
134
|
};
|
|
135
135
|
exports.handler = util_1.failWrapper(runInCloud);
|
|
136
136
|
async function runInCloud(parsed) {
|
|
@@ -217,17 +217,17 @@ async function executeRunCloudTest(test, browsers, branchName, apiClient, maybeD
|
|
|
217
217
|
if (applicationId || environmentId) {
|
|
218
218
|
const deploymentsResult = await apiClient.queryDeploymentEntities(workspaceId);
|
|
219
219
|
const foundDeployments = deploymentsResult.deployments
|
|
220
|
-
? deploymentsResult.deployments.filter(deployment => (!applicationId || deployment.application_id === applicationId) &&
|
|
220
|
+
? deploymentsResult.deployments.filter((deployment) => (!applicationId || deployment.application_id === applicationId) &&
|
|
221
221
|
(!environmentId || deployment.environment_id === environmentId))
|
|
222
222
|
: [];
|
|
223
223
|
if (!foundDeployments.length) {
|
|
224
224
|
throw new Error('No configuration was found for the applicationId/environmentId specified');
|
|
225
225
|
}
|
|
226
|
-
deploymentIds = foundDeployments.map(deployment => deployment.id);
|
|
226
|
+
deploymentIds = foundDeployments.map((deployment) => deployment.id);
|
|
227
227
|
}
|
|
228
228
|
const planRun = await apiClient.postPlanRun(workspaceId, testId, branchName, browsers, effectiveAppUrl, apiUrl, maybeDeploymentId, credentialsId, deploymentIds, basicAuthCredentialsId);
|
|
229
229
|
return planRun.scripts
|
|
230
|
-
? planRun.scripts.map(script => `${env_1.BASE_APP_URL}/workspaces/${planRun.organization_id}/test/journey-runs/${script.id}`)
|
|
230
|
+
? planRun.scripts.map((script) => `${env_1.BASE_APP_URL}/workspaces/${planRun.organization_id}/test/journey-runs/${script.id}`)
|
|
231
231
|
: [];
|
|
232
232
|
}
|
|
233
233
|
async function getJourneysForLabels(workspaceId, branchName, branchChangesOnly, labelsInclude, labelsExclude, limit, prompt, apiClient) {
|
|
@@ -262,10 +262,10 @@ async function getJourneysForLabels(workspaceId, branchName, branchChangesOnly,
|
|
|
262
262
|
message: `Run these [${journeys.length}] tests?`,
|
|
263
263
|
pageSize: 20,
|
|
264
264
|
choices: journeyChoices,
|
|
265
|
-
default: journeyChoices.map(choice => choice.value),
|
|
265
|
+
default: journeyChoices.map((choice) => choice.value),
|
|
266
266
|
},
|
|
267
267
|
]);
|
|
268
|
-
const selectedJourneys = (_a = journeys.filter(journey => { var _a; return (_a = testsToRun === null || testsToRun === void 0 ? void 0 : testsToRun.test_selection) === null || _a === void 0 ? void 0 : _a.includes(journey.id); })) !== null && _a !== void 0 ? _a : [];
|
|
268
|
+
const selectedJourneys = (_a = journeys.filter((journey) => { var _a; return (_a = testsToRun === null || testsToRun === void 0 ? void 0 : testsToRun.test_selection) === null || _a === void 0 ? void 0 : _a.includes(journey.id); })) !== null && _a !== void 0 ? _a : [];
|
|
269
269
|
if (selectedJourneys.length === 0) {
|
|
270
270
|
return [];
|
|
271
271
|
}
|
|
@@ -60,7 +60,7 @@ exports.builder = (yargs) => {
|
|
|
60
60
|
nargs: 1,
|
|
61
61
|
type: 'string',
|
|
62
62
|
})
|
|
63
|
-
.check(argv => testsUtil_1.validateRunEditCommand(argv[constants_1.CommandArgId], argv[constants_1.CommandArgTestRunId]));
|
|
63
|
+
.check((argv) => testsUtil_1.validateRunEditCommand(argv[constants_1.CommandArgId], argv[constants_1.CommandArgTestRunId]));
|
|
64
64
|
};
|
|
65
65
|
exports.handler = util_1.failWrapper(runLegacy);
|
|
66
66
|
async function runLegacy(parsed) {
|
|
@@ -87,7 +87,7 @@ async function runLegacy(parsed) {
|
|
|
87
87
|
const flowArray = await util_1.getJourneyFlowArray(test, apiClient, branchName);
|
|
88
88
|
const finalUrl = testsUtil_1.getFinalUrl(test, url);
|
|
89
89
|
if (flowArray
|
|
90
|
-
.map(flow => flow.flow_type === mablApi_1.Flow.FlowTypeEnum.Mablscript)
|
|
90
|
+
.map((flow) => flow.flow_type === mablApi_1.Flow.FlowTypeEnum.Mablscript)
|
|
91
91
|
.includes(false)) {
|
|
92
92
|
loggingProvider_1.logger.info(chalk_1.default.red('Default mabl tests are not supported for local runs yet including any test with an auto login flow'));
|
|
93
93
|
return 'error';
|
|
@@ -149,7 +149,7 @@ exports.builder = (yargs) => {
|
|
|
149
149
|
.option(constants_1.CommandArgTestInteractionSpeed, {
|
|
150
150
|
describe: 'Set the speed that mabl interacts with webpages. Overrides test run settings if specified.',
|
|
151
151
|
type: 'string',
|
|
152
|
-
choices: Object.keys(mablApi_1.JourneyParameters.PageLoadWaitEnum).map(pageLoadWait => pageLoadWait.toLowerCase()),
|
|
152
|
+
choices: Object.keys(mablApi_1.JourneyParameters.PageLoadWaitEnum).map((pageLoadWait) => pageLoadWait.toLowerCase()),
|
|
153
153
|
})
|
|
154
154
|
.check((argv) => testsUtil_1.validateRunCommandWithLabels(argv[constants_1.CommandArgId], argv[constants_1.CommandArgLabelsInclude], argv[constants_1.CommandArgLabelsExclude], argv[constants_1.CommandArgTestRunId], argv[constants_1.CommandArgFromPlanId], true, argv[constants_1.CommandArgTestFile]));
|
|
155
155
|
};
|
|
@@ -192,7 +192,7 @@ async function run(parsed) {
|
|
|
192
192
|
loggingProvider_1.logger.info(`Test count: ${results.numTotalTests}`);
|
|
193
193
|
loggingProvider_1.logger.info(`Passed: ${results.numPassedTests}`);
|
|
194
194
|
if (results.numPassedTests) {
|
|
195
|
-
results.testResults.forEach(result => {
|
|
195
|
+
results.testResults.forEach((result) => {
|
|
196
196
|
if (result.status === 'passed') {
|
|
197
197
|
loggingProvider_1.logger.info(` - ${result.testName} (${testsUtil_1.calculateTotalTimeSeconds(result.startTime, result.endTime)}s)`);
|
|
198
198
|
}
|
|
@@ -200,7 +200,7 @@ async function run(parsed) {
|
|
|
200
200
|
}
|
|
201
201
|
loggingProvider_1.logger.info(`Skipped: ${results.numSkippedTests}`);
|
|
202
202
|
if (results.numSkippedTests) {
|
|
203
|
-
results.testResults.forEach(result => {
|
|
203
|
+
results.testResults.forEach((result) => {
|
|
204
204
|
if (result.status === 'skipped') {
|
|
205
205
|
loggingProvider_1.logger.info(chalk.yellow(` - ${result.testName}`));
|
|
206
206
|
}
|
|
@@ -208,7 +208,7 @@ async function run(parsed) {
|
|
|
208
208
|
}
|
|
209
209
|
loggingProvider_1.logger.info(`Failed: ${results.numFailedTests}`);
|
|
210
210
|
if (results.numFailedTests) {
|
|
211
|
-
results.testResults.forEach(result => {
|
|
211
|
+
results.testResults.forEach((result) => {
|
|
212
212
|
if (result.status === 'failed') {
|
|
213
213
|
loggingProvider_1.logger.info(chalk.red(` - ${result.testName} (${testsUtil_1.calculateTotalTimeSeconds(result.startTime, result.endTime)}s)`));
|
|
214
214
|
}
|
|
@@ -33,7 +33,7 @@ function getTimestamp() {
|
|
|
33
33
|
}
|
|
34
34
|
function hasOwnerRoleInWorkspace(user, workspaceId) {
|
|
35
35
|
var _a;
|
|
36
|
-
const hasOwnerRole = (_a = user.roles) === null || _a === void 0 ? void 0 : _a.some(role => role.organization_id === workspaceId &&
|
|
36
|
+
const hasOwnerRole = (_a = user.roles) === null || _a === void 0 ? void 0 : _a.some((role) => role.organization_id === workspaceId &&
|
|
37
37
|
role.role === mablApi_1.UserRole.RoleEnum.Owner);
|
|
38
38
|
if (!hasOwnerRole) {
|
|
39
39
|
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}`));
|
|
@@ -47,7 +47,7 @@ function printWorkspaces(workspaces, output) {
|
|
|
47
47
|
head: ['ID', 'Name', 'Created time'],
|
|
48
48
|
wordWrap: true,
|
|
49
49
|
});
|
|
50
|
-
workspaces.forEach(workspace => {
|
|
50
|
+
workspaces.forEach((workspace) => {
|
|
51
51
|
table.push([
|
|
52
52
|
{ rowSpan: 1, content: workspace.id, vAlign: 'center' },
|
|
53
53
|
{ rowSpan: 1, content: workspace.name, vAlign: 'center' },
|
|
@@ -19,7 +19,7 @@ class FlowConfig {
|
|
|
19
19
|
flowConfig.workspaceId = this.flow.organization_id;
|
|
20
20
|
flowConfig.reusable = this.flow.reusable;
|
|
21
21
|
const loadedSteps = importer_1.parseMablScriptIntoSteps(this.flow);
|
|
22
|
-
flowConfig.steps = loadedSteps.map(step => step.getFormattedStep(this.includeLocatorInfo));
|
|
22
|
+
flowConfig.steps = loadedSteps.map((step) => step.getFormattedStep(this.includeLocatorInfo));
|
|
23
23
|
return flowConfig;
|
|
24
24
|
}
|
|
25
25
|
generateSimpleFormat() {
|
|
@@ -42,7 +42,7 @@ class FlowConfig {
|
|
|
42
42
|
}
|
|
43
43
|
static generateStepsSimpleFormat(suppliedSteps) {
|
|
44
44
|
const steps = [];
|
|
45
|
-
suppliedSteps.forEach(step => {
|
|
45
|
+
suppliedSteps.forEach((step) => {
|
|
46
46
|
var _a, _b, _c, _d;
|
|
47
47
|
const stepName = Object.keys(step)[0];
|
|
48
48
|
const stepObj = step;
|
|
@@ -72,7 +72,7 @@ class FlowConfig {
|
|
|
72
72
|
' ,Step Number, Step Type, Description, Annotation, Note',
|
|
73
73
|
];
|
|
74
74
|
let count = 0;
|
|
75
|
-
flowConfig.steps.forEach(step => {
|
|
75
|
+
flowConfig.steps.forEach((step) => {
|
|
76
76
|
var _a, _b;
|
|
77
77
|
const stepName = Object.keys(step)[0];
|
|
78
78
|
const stepObj = step;
|
|
@@ -15,7 +15,7 @@ class SelIdeConfig {
|
|
|
15
15
|
selIdeTest.id = SeleniumIdeStep_1.generateIdForSeleniumEntity(this.journey.id + 'test');
|
|
16
16
|
selIdeTest.name = (_a = this.journey.name) !== null && _a !== void 0 ? _a : '';
|
|
17
17
|
let steps = [];
|
|
18
|
-
this.flows.forEach(flow => {
|
|
18
|
+
this.flows.forEach((flow) => {
|
|
19
19
|
const loadedSteps = importer_1.parseMablScriptIntoSteps(flow);
|
|
20
20
|
steps = steps.concat(loadedSteps);
|
|
21
21
|
});
|
|
@@ -18,9 +18,9 @@ class JourneyConfig {
|
|
|
18
18
|
journeyConfig.name = this.journey.name;
|
|
19
19
|
journeyConfig.description = this.journey.description;
|
|
20
20
|
journeyConfig.tags = this.journey.tags;
|
|
21
|
-
journeyConfig.labels = (_a = this.journey.labels) === null || _a === void 0 ? void 0 : _a.map(label => label.name);
|
|
21
|
+
journeyConfig.labels = (_a = this.journey.labels) === null || _a === void 0 ? void 0 : _a.map((label) => label.name);
|
|
22
22
|
journeyConfig.dataTables = this.journey.datatables;
|
|
23
|
-
journeyConfig.flows = this.flows.map(flow => {
|
|
23
|
+
journeyConfig.flows = this.flows.map((flow) => {
|
|
24
24
|
const flowConfigGenerator = new flowConfigGenerator_1.FlowConfig(flow, this.includeLocatorInfo);
|
|
25
25
|
return flowConfigGenerator.generateConfigFile();
|
|
26
26
|
});
|
|
@@ -31,7 +31,7 @@ class JourneyConfig {
|
|
|
31
31
|
const config = this.generateConfigFile();
|
|
32
32
|
let steps = [];
|
|
33
33
|
let apiSteps;
|
|
34
|
-
config.flows.forEach(flow => {
|
|
34
|
+
config.flows.forEach((flow) => {
|
|
35
35
|
if (flow.api_steps) {
|
|
36
36
|
apiSteps = flow.api_steps;
|
|
37
37
|
}
|
|
@@ -54,14 +54,13 @@ class JourneyConfig {
|
|
|
54
54
|
' ,Step Number, Step Type, Description, Annotation, Note',
|
|
55
55
|
];
|
|
56
56
|
let count = 0;
|
|
57
|
-
config.flows.forEach(flow => {
|
|
58
|
-
flow.steps.forEach(step => {
|
|
57
|
+
config.flows.forEach((flow) => {
|
|
58
|
+
flow.steps.forEach((step) => {
|
|
59
59
|
var _a, _b;
|
|
60
60
|
const stepName = Object.keys(step)[0];
|
|
61
61
|
const stepObj = step;
|
|
62
62
|
const mablStep = stepObj[stepName];
|
|
63
|
-
output.push(`${count}, ${stepName}, ${mablStep.description}, ${((_a = mablStep === null || mablStep === void 0 ? void 0 : mablStep.annotation) === null || _a === void 0 ? void 0 : _a.note) || '-'}, ${((_b = mablStep === null || mablStep === void 0 ? void 0 : mablStep.annotation) === null || _b === void 0 ? void 0 : _b.description) ||
|
|
64
|
-
'-'}`);
|
|
63
|
+
output.push(`${count}, ${stepName}, ${mablStep.description}, ${((_a = mablStep === null || mablStep === void 0 ? void 0 : mablStep.annotation) === null || _a === void 0 ? void 0 : _a.note) || '-'}, ${((_b = mablStep === null || mablStep === void 0 ? void 0 : mablStep.annotation) === null || _b === void 0 ? void 0 : _b.description) || '-'}`);
|
|
65
64
|
count += 1;
|
|
66
65
|
});
|
|
67
66
|
});
|
|
@@ -70,7 +69,7 @@ class JourneyConfig {
|
|
|
70
69
|
}
|
|
71
70
|
exports.JourneyConfig = JourneyConfig;
|
|
72
71
|
function convertUndefined(mablObjectConfigFile) {
|
|
73
|
-
Object.keys(mablObjectConfigFile).forEach(key => {
|
|
72
|
+
Object.keys(mablObjectConfigFile).forEach((key) => {
|
|
74
73
|
if (mablObjectConfigFile[key] === undefined) {
|
|
75
74
|
mablObjectConfigFile[key] = null;
|
|
76
75
|
}
|
|
@@ -5,14 +5,14 @@ function deduplicateApiTestExecutionResults(postmanResult) {
|
|
|
5
5
|
var _a;
|
|
6
6
|
const executionsById = {};
|
|
7
7
|
const orderedExecutionIds = [];
|
|
8
|
-
(_a = postmanResult.run.executions) === null || _a === void 0 ? void 0 : _a.forEach(execution => {
|
|
8
|
+
(_a = postmanResult.run.executions) === null || _a === void 0 ? void 0 : _a.forEach((execution) => {
|
|
9
9
|
const executionId = execution.id;
|
|
10
10
|
if (!executionsById[executionId]) {
|
|
11
11
|
orderedExecutionIds.push(executionId);
|
|
12
12
|
}
|
|
13
13
|
executionsById[executionId] = execution;
|
|
14
14
|
});
|
|
15
|
-
postmanResult.run.executions = orderedExecutionIds.map(executionId => executionsById[executionId]);
|
|
15
|
+
postmanResult.run.executions = orderedExecutionIds.map((executionId) => executionsById[executionId]);
|
|
16
16
|
return postmanResult;
|
|
17
17
|
}
|
|
18
18
|
exports.deduplicateApiTestExecutionResults = deduplicateApiTestExecutionResults;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.MablCoreProcessAction = exports.MablCoreAction = exports.ExecutionPhase = exports.EventChannelMessageType = exports.getEmitter = exports.mablEventEmitter = exports.MablCoreEventEmitter = void 0;
|
|
4
|
+
exports.getDefaultLogMetadataForInfo = exports.MablCoreProcessAction = exports.MablCoreAction = exports.ExecutionPhase = exports.EventChannelMessageType = exports.getEmitter = exports.mablEventEmitter = exports.MablCoreEventEmitter = void 0;
|
|
5
5
|
const events_1 = require("events");
|
|
6
6
|
const loggingProvider_1 = require("../../providers/logging/loggingProvider");
|
|
7
|
+
const NO_ID_PLACEHOLDER = 'NO_ID_PROVIDED';
|
|
7
8
|
class MablCoreEventEmitter {
|
|
8
9
|
constructor(debug) {
|
|
9
10
|
this.messageIndex = -1;
|
|
@@ -78,3 +79,15 @@ exports.MablCoreAction = MablCoreAction;
|
|
|
78
79
|
class MablCoreProcessAction extends MablCoreAction {
|
|
79
80
|
}
|
|
80
81
|
exports.MablCoreProcessAction = MablCoreProcessAction;
|
|
82
|
+
function getDefaultLogMetadataForInfo(testId, testInvariantId) {
|
|
83
|
+
return {
|
|
84
|
+
executionIndex: {
|
|
85
|
+
testId: testId !== null && testId !== void 0 ? testId : NO_ID_PLACEHOLDER,
|
|
86
|
+
testInvariantId: testInvariantId !== null && testInvariantId !== void 0 ? testInvariantId : NO_ID_PLACEHOLDER,
|
|
87
|
+
},
|
|
88
|
+
executionPhase: ExecutionPhase.BEFORE_TEST,
|
|
89
|
+
logLevel: loggingProvider_1.LogLevel.Info,
|
|
90
|
+
timestamp: Date.now(),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
exports.getDefaultLogMetadataForInfo = getDefaultLogMetadataForInfo;
|
|
@@ -0,0 +1,47 @@
|
|
|
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.logSessionStarted = exports.openUrlInDesktopApp = void 0;
|
|
7
|
+
const querystring_1 = __importDefault(require("querystring"));
|
|
8
|
+
const open_1 = __importDefault(require("open"));
|
|
9
|
+
const env_1 = require("../../env/env");
|
|
10
|
+
const timers_1 = require("timers");
|
|
11
|
+
const messaging_1 = require("../messaging/messaging");
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
13
|
+
async function openUrlInDesktopApp(url, trainingSessionOptions) {
|
|
14
|
+
const params = querystring_1.default.stringify({ ...trainingSessionOptions });
|
|
15
|
+
const childProcess = await open_1.default(`${env_1.ELECTRON_PROTOCOL}://${url}/${params}`);
|
|
16
|
+
let childProcessExited = false;
|
|
17
|
+
const keepAliveUntilExited = () => {
|
|
18
|
+
if (!childProcessExited) {
|
|
19
|
+
timers_1.setTimeout(keepAliveUntilExited, 1000);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
keepAliveUntilExited();
|
|
23
|
+
const exitCode = await new Promise((resolve) => {
|
|
24
|
+
childProcess.on('error', () => {
|
|
25
|
+
childProcessExited = true;
|
|
26
|
+
resolve(1);
|
|
27
|
+
});
|
|
28
|
+
childProcess.on('exit', function () {
|
|
29
|
+
childProcessExited = true;
|
|
30
|
+
resolve(childProcess.exitCode);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
if (exitCode === 0) {
|
|
34
|
+
logSessionStarted();
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
logInstallDesktopApp();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.openUrlInDesktopApp = openUrlInDesktopApp;
|
|
41
|
+
function logSessionStarted() {
|
|
42
|
+
messaging_1.mablEventEmitter.log(chalk_1.default.yellowBright('Session started in the desktop app'));
|
|
43
|
+
}
|
|
44
|
+
exports.logSessionStarted = logSessionStarted;
|
|
45
|
+
function logInstallDesktopApp() {
|
|
46
|
+
messaging_1.mablEventEmitter.log(chalk_1.default.red(`\nFailed to launch mabl desktop app!`, chalk_1.default.cyan(`\nPlease check your installation or download and install it from`), chalk_1.default.magenta('https://www.mabl.com/desktop-app')));
|
|
47
|
+
}
|