@mablhq/mabl-cli 1.12.9 → 1.12.38
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/browserLauncherFactory.js +6 -2
- 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/playwrightBrowserLauncher.js +1 -0
- package/browserLauncher/playwrightBrowserLauncher/playwrightDom.js +119 -31
- package/browserLauncher/playwrightBrowserLauncher/playwrightFrame.js +32 -21
- package/browserLauncher/playwrightBrowserLauncher/playwrightHttpResponse.js +3 -0
- 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 +4 -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 +6 -4
- 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 +16 -20
- 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 +7 -7
- package/commands/tests/tests_cmds/run-legacy.js +2 -2
- package/commands/tests/tests_cmds/run.js +25 -7
- 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/index.d.ts +7 -0
- 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 +44 -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
|
@@ -7,7 +7,6 @@ exports.PuppeteerPage = exports.highlightColor = exports.MAX_HIGHLIGHT_OPACITY =
|
|
|
7
7
|
const browserLauncher_1 = require("../browserLauncher");
|
|
8
8
|
const puppeteer_core_1 = __importDefault(require("puppeteer-core"));
|
|
9
9
|
const events_1 = __importDefault(require("events"));
|
|
10
|
-
const testsUtil_1 = require("../../commands/tests/testsUtil");
|
|
11
10
|
const puppeteerBrowserLauncher_1 = require("./puppeteerBrowserLauncher");
|
|
12
11
|
const puppeteerHttpRequest_1 = require("./puppeteerHttpRequest");
|
|
13
12
|
const puppeteerHttpResponse_1 = require("./puppeteerHttpResponse");
|
|
@@ -36,12 +35,21 @@ class PuppeteerPage extends events_1.default {
|
|
|
36
35
|
this.browser.onPageClose(this);
|
|
37
36
|
});
|
|
38
37
|
}
|
|
39
|
-
async screenshot() {
|
|
38
|
+
async screenshot(clip) {
|
|
39
|
+
const { visualViewport } = await this.makeCdpCall('Page.getLayoutMetrics');
|
|
40
40
|
await this.makeCdpCall('Target.activateTarget', {
|
|
41
41
|
targetId: this.getPageId(),
|
|
42
42
|
});
|
|
43
|
+
let cdpClip;
|
|
44
|
+
if (clip) {
|
|
45
|
+
cdpClip = {
|
|
46
|
+
...clip,
|
|
47
|
+
scale: visualViewport.scale,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
43
50
|
return this.makeCdpCall('Page.captureScreenshot', {
|
|
44
51
|
format: 'png',
|
|
52
|
+
clip: cdpClip,
|
|
45
53
|
captureBeyondViewport: false,
|
|
46
54
|
});
|
|
47
55
|
}
|
|
@@ -50,10 +58,8 @@ class PuppeteerPage extends events_1.default {
|
|
|
50
58
|
if (this.browser.credentials !== undefined) {
|
|
51
59
|
await this.page.authenticate(this.browser.credentials);
|
|
52
60
|
}
|
|
53
|
-
const opener = await ((_a = this.page
|
|
54
|
-
|
|
55
|
-
.opener()) === null || _a === void 0 ? void 0 : _a.page());
|
|
56
|
-
this.openerPage = await utils_1.mapIfNotNull(opener, page => this.browser.getOrCreatePage(page));
|
|
61
|
+
const opener = await ((_a = this.page.target().opener()) === null || _a === void 0 ? void 0 : _a.page());
|
|
62
|
+
this.openerPage = await utils_1.mapIfNotNull(opener, (page) => this.browser.getOrCreatePage(page));
|
|
57
63
|
}
|
|
58
64
|
makeCdpCall(method, paramArgs) {
|
|
59
65
|
return this.getCdpClient().send(method, paramArgs);
|
|
@@ -112,7 +118,7 @@ class PuppeteerPage extends events_1.default {
|
|
|
112
118
|
async waitForNavigation(options) {
|
|
113
119
|
try {
|
|
114
120
|
const result = await this.page.waitForNavigation(puppeteerBrowserLauncher_1.convertWaitForOptions(options));
|
|
115
|
-
return utils_1.mapIfNotNull(result, result => new puppeteerHttpResponse_1.PuppeteerHttpResponse(result, this));
|
|
121
|
+
return utils_1.mapIfNotNull(result, (result) => new puppeteerHttpResponse_1.PuppeteerHttpResponse(result, this));
|
|
116
122
|
}
|
|
117
123
|
catch (e) {
|
|
118
124
|
if (e instanceof puppeteer_core_1.default.errors.TimeoutError) {
|
|
@@ -134,7 +140,7 @@ class PuppeteerPage extends events_1.default {
|
|
|
134
140
|
}
|
|
135
141
|
async reload(options) {
|
|
136
142
|
try {
|
|
137
|
-
return utils_1.mapIfNotNull(await this.page.reload(puppeteerBrowserLauncher_1.convertWaitForOptions(options)), response => new puppeteerHttpResponse_1.PuppeteerHttpResponse(response, this));
|
|
143
|
+
return utils_1.mapIfNotNull(await this.page.reload(puppeteerBrowserLauncher_1.convertWaitForOptions(options)), (response) => new puppeteerHttpResponse_1.PuppeteerHttpResponse(response, this));
|
|
138
144
|
}
|
|
139
145
|
catch (e) {
|
|
140
146
|
if (e instanceof puppeteer_core_1.default.errors.TimeoutError) {
|
|
@@ -215,17 +221,17 @@ class PuppeteerPage extends events_1.default {
|
|
|
215
221
|
});
|
|
216
222
|
}
|
|
217
223
|
if (event === browserLauncher_1.PageEvent.Console && !this.listenerCount(event)) {
|
|
218
|
-
this.page.on('console', console => {
|
|
224
|
+
this.page.on('console', (console) => {
|
|
219
225
|
this.emit(browserLauncher_1.PageEvent.Console, new wrappers_1.PuppeteerWrappedConsoleMessage(console, this));
|
|
220
226
|
});
|
|
221
227
|
}
|
|
222
228
|
if (event === browserLauncher_1.PageEvent.PageError && !this.listenerCount(event)) {
|
|
223
|
-
this.page.on("pageerror", error => {
|
|
229
|
+
this.page.on("pageerror", (error) => {
|
|
224
230
|
this.emit(browserLauncher_1.PageEvent.PageError, error);
|
|
225
231
|
});
|
|
226
232
|
}
|
|
227
233
|
if (event === browserLauncher_1.PageEvent.Error && !this.listenerCount(event)) {
|
|
228
|
-
this.page.on("error", error => {
|
|
234
|
+
this.page.on("error", (error) => {
|
|
229
235
|
this.emit(browserLauncher_1.PageEvent.Error, error);
|
|
230
236
|
});
|
|
231
237
|
}
|
|
@@ -244,7 +250,7 @@ class PuppeteerPage extends events_1.default {
|
|
|
244
250
|
return this.mainFrame().evaluateHandleInSecondaryWorld(code, ...args);
|
|
245
251
|
}
|
|
246
252
|
evaluate(pageFunction, ...args) {
|
|
247
|
-
return this.page.evaluate(pageFunction, ...args === null || args === void 0 ? void 0 : args.map(argument => argument instanceof puppeteerJsHandle_1.PuppeteerJsHandle
|
|
253
|
+
return this.page.evaluate(pageFunction, ...args === null || args === void 0 ? void 0 : args.map((argument) => argument instanceof puppeteerJsHandle_1.PuppeteerJsHandle
|
|
248
254
|
? argument.getPuppeteerHandle()
|
|
249
255
|
: argument));
|
|
250
256
|
}
|
|
@@ -276,42 +282,23 @@ class PuppeteerPage extends events_1.default {
|
|
|
276
282
|
}
|
|
277
283
|
async $(selector) {
|
|
278
284
|
const handle = await this.page.$(selector);
|
|
279
|
-
return utils_1.mapIfNotNull(handle, handle => new puppeteerElementHandle_1.PuppeteerElementHandle(handle, this));
|
|
285
|
+
return utils_1.mapIfNotNull(handle, (handle) => new puppeteerElementHandle_1.PuppeteerElementHandle(handle, this));
|
|
280
286
|
}
|
|
281
287
|
async $$(selector) {
|
|
282
|
-
return (await this.page.$$(selector)).map(element => new puppeteerElementHandle_1.PuppeteerElementHandle(element, this));
|
|
288
|
+
return (await this.page.$$(selector)).map((element) => new puppeteerElementHandle_1.PuppeteerElementHandle(element, this));
|
|
283
289
|
}
|
|
284
290
|
async $x(xpathQuery) {
|
|
285
|
-
return (await this.page.$x(xpathQuery)).map(element => new puppeteerElementHandle_1.PuppeteerElementHandle(element, this));
|
|
291
|
+
return (await this.page.$x(xpathQuery)).map((element) => new puppeteerElementHandle_1.PuppeteerElementHandle(element, this));
|
|
286
292
|
}
|
|
287
293
|
static acceptDialogs(dialog) {
|
|
288
294
|
return dialog.accept();
|
|
289
295
|
}
|
|
290
296
|
async waitForSelector(selector, options) {
|
|
291
297
|
const handle = await this.page.waitForSelector(selector, puppeteerBrowserLauncher_1.convertWaitForOptions(options));
|
|
292
|
-
return utils_1.mapIfNotNull(handle, handle => new puppeteerElementHandle_1.PuppeteerElementHandle(handle, this));
|
|
298
|
+
return utils_1.mapIfNotNull(handle, (handle) => new puppeteerElementHandle_1.PuppeteerElementHandle(handle, this));
|
|
293
299
|
}
|
|
294
300
|
frames() {
|
|
295
|
-
return this.page.frames().map(frame => this.getOrCreateFrame(frame));
|
|
296
|
-
}
|
|
297
|
-
async highlightElement(element, highlightDurationMillis, highlightPhases) {
|
|
298
|
-
await this.enableDom();
|
|
299
|
-
await this.enableOverlay();
|
|
300
|
-
const nodeInfo = await this.makeCdpCall('DOM.describeNode', {
|
|
301
|
-
objectId: element.getRemoteObjectId(),
|
|
302
|
-
depth: -1,
|
|
303
|
-
pierce: true,
|
|
304
|
-
});
|
|
305
|
-
const highlightConfig = {
|
|
306
|
-
backendNodeId: nodeInfo.node.backendNodeId,
|
|
307
|
-
highlightConfig: {
|
|
308
|
-
borderColor: exports.highlightColor(0),
|
|
309
|
-
contentColor: exports.highlightColor(1),
|
|
310
|
-
colorFormat: 'rgb',
|
|
311
|
-
},
|
|
312
|
-
};
|
|
313
|
-
await this.fadeInOutHighlight(highlightConfig, highlightDurationMillis, highlightPhases);
|
|
314
|
-
await this.hideHighlight();
|
|
301
|
+
return this.page.frames().map((frame) => this.getOrCreateFrame(frame));
|
|
315
302
|
}
|
|
316
303
|
async getBrowserBounds() {
|
|
317
304
|
const getWindowForTarget = await this.makeCdpCall('Browser.getWindowForTarget', { targetId: this.page.target()._targetId });
|
|
@@ -323,31 +310,6 @@ class PuppeteerPage extends events_1.default {
|
|
|
323
310
|
opener() {
|
|
324
311
|
return this.openerPage;
|
|
325
312
|
}
|
|
326
|
-
async enableDom() {
|
|
327
|
-
await this.makeCdpCall('DOM.enable');
|
|
328
|
-
}
|
|
329
|
-
async enableOverlay() {
|
|
330
|
-
await this.makeCdpCall('Overlay.enable');
|
|
331
|
-
}
|
|
332
|
-
async hideHighlight() {
|
|
333
|
-
await this.makeCdpCall('Overlay.hideHighlight');
|
|
334
|
-
}
|
|
335
|
-
async fadeInOutHighlight(highlightConfig, highlightDurationMillis, highlightPhases) {
|
|
336
|
-
var _a;
|
|
337
|
-
if (highlightPhases === 0) {
|
|
338
|
-
throw new Error('Highlight phases must be greater than 0');
|
|
339
|
-
}
|
|
340
|
-
const phaseIntervalMilliseconds = highlightDurationMillis / highlightPhases;
|
|
341
|
-
for (let iteration = 0; iteration < highlightPhases; iteration++) {
|
|
342
|
-
if (((_a = highlightConfig.highlightConfig.contentColor) === null || _a === void 0 ? void 0 : _a.a) !== undefined) {
|
|
343
|
-
const x = iteration / highlightPhases;
|
|
344
|
-
highlightConfig.highlightConfig.contentColor.a =
|
|
345
|
-
x * (1 - x) * 4 * exports.MAX_HIGHLIGHT_OPACITY;
|
|
346
|
-
}
|
|
347
|
-
await this.makeCdpCall('Overlay.highlightNode', highlightConfig);
|
|
348
|
-
await testsUtil_1.sleep(phaseIntervalMilliseconds);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
313
|
getOrCreateFrame(frame) {
|
|
352
314
|
const frameId = frame._id;
|
|
353
315
|
if (!this.puppeteerFrames.has(frameId)) {
|
|
@@ -13,7 +13,7 @@ class PuppeteerWrappedConsoleMessage {
|
|
|
13
13
|
args() {
|
|
14
14
|
return this.message
|
|
15
15
|
.args()
|
|
16
|
-
.map(handle => new puppeteerJsHandle_1.PuppeteerJsHandle(handle, this.page));
|
|
16
|
+
.map((handle) => new puppeteerJsHandle_1.PuppeteerJsHandle(handle, this.page));
|
|
17
17
|
}
|
|
18
18
|
type() {
|
|
19
19
|
return this.message.type();
|
package/cli.js
CHANGED
|
@@ -32,15 +32,14 @@ const pureUtil_1 = require("./util/pureUtil");
|
|
|
32
32
|
const versionUtil_1 = require("./commands/commandUtil/versionUtil");
|
|
33
33
|
const chalk_1 = __importDefault(require("chalk"));
|
|
34
34
|
const loggingProvider_1 = require("./providers/logging/loggingProvider");
|
|
35
|
+
const logLineMessaging_1 = require("./core/messaging/logLineMessaging");
|
|
36
|
+
const messaging_1 = require("./core/messaging/messaging");
|
|
35
37
|
const updateNotifier = require('update-notifier');
|
|
36
38
|
const cliPackage = require('./package.json');
|
|
37
39
|
const UPDATE_CHECK_INTERVAL_MILLISECONDS = 24 * 60 * 60 * 1000;
|
|
38
40
|
const MIN_SUPPORTED_NODE_VERSION = versionUtil_1.extractNodeVersionTuple((_a = cliPackage === null || cliPackage === void 0 ? void 0 : cliPackage.engines) === null || _a === void 0 ? void 0 : _a.node);
|
|
39
41
|
require('v8-compile-cache');
|
|
40
|
-
require('yargonaut')
|
|
41
|
-
.style('cyan')
|
|
42
|
-
.helpStyle('magenta')
|
|
43
|
-
.errorsStyle('red');
|
|
42
|
+
require('yargonaut').style('cyan').helpStyle('magenta').errorsStyle('red');
|
|
44
43
|
yargs
|
|
45
44
|
.scriptName(env_1.SCRIPT_NAME)
|
|
46
45
|
.commandDir('./commands/applications')
|
|
@@ -65,6 +64,9 @@ yargs
|
|
|
65
64
|
.wrap(null)
|
|
66
65
|
.epilogue('Read full docs @ https://help.mabl.com/docs/mabl-cli')
|
|
67
66
|
.middleware([
|
|
67
|
+
() => {
|
|
68
|
+
logLineMessaging_1.registerConsoleLoggerForOutput(messaging_1.mablEventEmitter);
|
|
69
|
+
},
|
|
68
70
|
() => {
|
|
69
71
|
try {
|
|
70
72
|
const nodeVersion = versionUtil_1.extractNodeVersionTuple(process.version);
|
|
@@ -34,7 +34,7 @@ function printApplications(applications, output) {
|
|
|
34
34
|
head: ['ID', 'Name', 'Created time'],
|
|
35
35
|
wordWrap: true,
|
|
36
36
|
});
|
|
37
|
-
applications.forEach(application => {
|
|
37
|
+
applications.forEach((application) => {
|
|
38
38
|
table.push([
|
|
39
39
|
{ rowSpan: 1, content: application.id, vAlign: 'center' },
|
|
40
40
|
{ rowSpan: 1, content: application.name, vAlign: 'center' },
|
|
@@ -28,7 +28,7 @@ exports.builder = (yargs) => {
|
|
|
28
28
|
nargs: 1,
|
|
29
29
|
type: 'string',
|
|
30
30
|
})
|
|
31
|
-
.check(argv => {
|
|
31
|
+
.check((argv) => {
|
|
32
32
|
const branchName = argv[constants_1.CommandArgName];
|
|
33
33
|
if (!branches_1.isValidMablBranchName(branchName)) {
|
|
34
34
|
throw new Error(`[${branchName}] is not a valid mabl branch name. Please specify a valid name`);
|
|
@@ -58,7 +58,7 @@ function printBranches(branches, output) {
|
|
|
58
58
|
const table = new Table({
|
|
59
59
|
head: ['ID', 'Name', 'Status', 'Created'],
|
|
60
60
|
});
|
|
61
|
-
branches.forEach(branch => {
|
|
61
|
+
branches.forEach((branch) => {
|
|
62
62
|
table.push([
|
|
63
63
|
{ rowSpan: 1, content: branch.id, vAlign: 'center' },
|
|
64
64
|
{ rowSpan: 1, content: branch.name, vAlign: 'center' },
|
|
@@ -36,7 +36,7 @@ exports.builder = (yargs) => {
|
|
|
36
36
|
nargs: 1,
|
|
37
37
|
type: 'string',
|
|
38
38
|
})
|
|
39
|
-
.check(argv => {
|
|
39
|
+
.check((argv) => {
|
|
40
40
|
const fromBranchName = argv[CommandArgFrom];
|
|
41
41
|
if (!branches_1.isValidMablBranchName(fromBranchName)) {
|
|
42
42
|
throw new Error(`[${fromBranchName}] is not a valid mabl branch name. Please specify a valid name`);
|
|
@@ -59,8 +59,8 @@ class AwaitCompletion {
|
|
|
59
59
|
}
|
|
60
60
|
return new Promise((resolve, reject) => {
|
|
61
61
|
setTimeout(() => this.awaitCompletion(seedId)
|
|
62
|
-
.then(result => resolve(result))
|
|
63
|
-
.catch(error => reject(error)), this.pollingIntervalMilliseconds);
|
|
62
|
+
.then((result) => resolve(result))
|
|
63
|
+
.catch((error) => reject(error)), this.pollingIntervalMilliseconds);
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -65,13 +65,13 @@ function generateCodeReportForCommit(executionEventId, outputLink, executionResu
|
|
|
65
65
|
}
|
|
66
66
|
if (executionResult.executions) {
|
|
67
67
|
const minStartTimes = [];
|
|
68
|
-
executionResult.executions.forEach(execution => {
|
|
68
|
+
executionResult.executions.forEach((execution) => {
|
|
69
69
|
if (execution.start_time) {
|
|
70
70
|
minStartTimes.push(execution.start_time);
|
|
71
71
|
}
|
|
72
72
|
});
|
|
73
73
|
const maxStartTimes = [];
|
|
74
|
-
executionResult.executions.forEach(execution => {
|
|
74
|
+
executionResult.executions.forEach((execution) => {
|
|
75
75
|
if (execution.stop_time) {
|
|
76
76
|
maxStartTimes.push(execution.stop_time);
|
|
77
77
|
}
|
|
@@ -91,9 +91,9 @@ exports.generateCodeReportForCommit = generateCodeReportForCommit;
|
|
|
91
91
|
function generateCodeAnnotationsForReport(executionResult) {
|
|
92
92
|
const codeAnnotations = [];
|
|
93
93
|
if (executionResult.executions) {
|
|
94
|
-
executionResult.executions.forEach(execution => {
|
|
94
|
+
executionResult.executions.forEach((execution) => {
|
|
95
95
|
if (execution.journey_executions) {
|
|
96
|
-
execution.journey_executions.forEach(testExecution => {
|
|
96
|
+
execution.journey_executions.forEach((testExecution) => {
|
|
97
97
|
const codeAnnotation = {
|
|
98
98
|
external_id: `${testExecution.journey_execution_id}-ca`,
|
|
99
99
|
annotation_type: CodeAnnotation_1.CodeInsightsAnnotationType.BUG,
|
|
@@ -123,7 +123,7 @@ function generateAnnotationDetails(testExecution) {
|
|
|
123
123
|
function generateAnnotationSummary(testExecution, journeySummaries) {
|
|
124
124
|
let testForAnnotation;
|
|
125
125
|
if (journeySummaries) {
|
|
126
|
-
testForAnnotation = journeySummaries.find(test => test.id === testExecution.journey_id);
|
|
126
|
+
testForAnnotation = journeySummaries.find((test) => test.id === testExecution.journey_id);
|
|
127
127
|
}
|
|
128
128
|
if (testForAnnotation) {
|
|
129
129
|
return `${testForAnnotation.name}`;
|
|
@@ -135,7 +135,7 @@ async function putCodeReportAndAnnotations(executionResult, executionEventId, ou
|
|
|
135
135
|
const bitBucketApiClient = getBitBucketApiClient(isCustomBitBucketPipe, noProxy);
|
|
136
136
|
const codeReportResponse = await bitBucketApiClient.putCodeReport(codeReport, workspace, repoSlug, node);
|
|
137
137
|
const codeAnnotations = generateCodeAnnotationsForReport(executionResult);
|
|
138
|
-
const requests = codeAnnotations.map(annotation => bitBucketApiClient.putCodeAnnotation(annotation, workspace, repoSlug, node, codeReportResponse.external_id));
|
|
138
|
+
const requests = codeAnnotations.map((annotation) => bitBucketApiClient.putCodeAnnotation(annotation, workspace, repoSlug, node, codeReportResponse.external_id));
|
|
139
139
|
await Promise.all(requests).catch(() => new Error('Error writing Code Annotations to Bitbucket'));
|
|
140
140
|
return codeReportResponse;
|
|
141
141
|
}
|
|
@@ -25,7 +25,7 @@ const loggingProvider_1 = require("../../providers/logging/loggingProvider");
|
|
|
25
25
|
const chalk = require('chalk');
|
|
26
26
|
function writeExportedEntityToFile(output, fileExtension, entityId) {
|
|
27
27
|
const fileName = `${entityId}.mabl.${fileExtension}`.replace(':', '-');
|
|
28
|
-
fs.writeFile(`./${fileName}`, output, err => {
|
|
28
|
+
fs.writeFile(`./${fileName}`, output, (err) => {
|
|
29
29
|
if (err) {
|
|
30
30
|
loggingProvider_1.logger.info(chalk.red.bold(`Error exporting flow to filesystem: ${err}`));
|
|
31
31
|
}
|
|
@@ -42,11 +42,11 @@ async function getJourneyFlowArray(journey, apiClient, branchName) {
|
|
|
42
42
|
throw new Error(exports.TEST_INFO_NOT_FOUND);
|
|
43
43
|
}
|
|
44
44
|
const flows = {};
|
|
45
|
-
const requests = journey.flows.map(flowId => apiClient
|
|
45
|
+
const requests = journey.flows.map((flowId) => apiClient
|
|
46
46
|
.getFlow(flowId, branchName)
|
|
47
|
-
.then(result => (flows[flowId] = result)));
|
|
47
|
+
.then((result) => (flows[flowId] = result)));
|
|
48
48
|
await Promise.all(requests);
|
|
49
|
-
return journey.flows.map(flowId => flows[flowId]).filter(flow => flow);
|
|
49
|
+
return journey.flows.map((flowId) => flows[flowId]).filter((flow) => flow);
|
|
50
50
|
}
|
|
51
51
|
exports.getJourneyFlowArray = getJourneyFlowArray;
|
|
52
52
|
async function getWorkspaceIdFromAppOrEnv(apiClient, applicationId, environmentId) {
|
|
@@ -64,7 +64,7 @@ exports.getWorkspaceIdFromAppOrEnv = getWorkspaceIdFromAppOrEnv;
|
|
|
64
64
|
function validateArrayInputs(possibleInput, errorMessage) {
|
|
65
65
|
if (possibleInput !== undefined) {
|
|
66
66
|
const labels = possibleInput;
|
|
67
|
-
if (labels.some(label => /[,|;]/.test(label))) {
|
|
67
|
+
if (labels.some((label) => /[,|;]/.test(label))) {
|
|
68
68
|
throw new Error(errorMessage);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -73,27 +73,27 @@ exports.validateArrayInputs = validateArrayInputs;
|
|
|
73
73
|
function validateValuePairInputs(inputName, inputs) {
|
|
74
74
|
if (inputs) {
|
|
75
75
|
const missingColonInputs = inputs
|
|
76
|
-
.map(input => input.trim())
|
|
77
|
-
.filter(input => !/^([^:]+)?:(.+)?$/m.test(input));
|
|
76
|
+
.map((input) => input.trim())
|
|
77
|
+
.filter((input) => !/^([^:]+)?:(.+)?$/m.test(input));
|
|
78
78
|
if (missingColonInputs.length > 0) {
|
|
79
79
|
throw new Error(`${inputName} ${pluralize_1.default('value', missingColonInputs.length)} must separate kev/value with a colon ':', [${missingColonInputs.join(',')}]`);
|
|
80
80
|
}
|
|
81
81
|
const missingNameInputs = inputs
|
|
82
|
-
.map(input => input.replace(/^[ ]+/, ''))
|
|
83
|
-
.filter(input => !/^([^:]+):(.+)?$/m.test(input));
|
|
82
|
+
.map((input) => input.replace(/^[ ]+/, ''))
|
|
83
|
+
.filter((input) => !/^([^:]+):(.+)?$/m.test(input));
|
|
84
84
|
if (missingNameInputs.length > 0) {
|
|
85
85
|
throw new Error(`${inputName} ${pluralize_1.default('name', missingNameInputs.length)} cannot be blank [${missingNameInputs.join(',')}]`);
|
|
86
86
|
}
|
|
87
|
-
const illegalCharacterHeaders = inputs.filter(input => /[\n\r]/m.test(input));
|
|
87
|
+
const illegalCharacterHeaders = inputs.filter((input) => /[\n\r]/m.test(input));
|
|
88
88
|
if (illegalCharacterHeaders.length > 0) {
|
|
89
|
-
const escapedHeaders = illegalCharacterHeaders.map(input => input.replace('\n', '\\n').replace('\r', '\\r'));
|
|
89
|
+
const escapedHeaders = illegalCharacterHeaders.map((input) => input.replace('\n', '\\n').replace('\r', '\\r'));
|
|
90
90
|
throw new Error(`${inputName} shouldn't contain carriage return or line feed characters [${escapedHeaders.join(',')}]`);
|
|
91
91
|
}
|
|
92
|
-
const wrappingWhitespace = inputs.filter(header => !/^([^\s:]{1,2}|[^\s:][^:]+[^\s:]):([^\s:]{1,2}|[^\s:][^:]+[^\s:])?$/m.test(header));
|
|
92
|
+
const wrappingWhitespace = inputs.filter((header) => !/^([^\s:]{1,2}|[^\s:][^:]+[^\s:]):([^\s:]{1,2}|[^\s:][^:]+[^\s:])?$/m.test(header));
|
|
93
93
|
if (wrappingWhitespace.length > 0) {
|
|
94
94
|
const cleanFunction = (header) => header
|
|
95
95
|
.split(':', 2)
|
|
96
|
-
.map(part => part.trim())
|
|
96
|
+
.map((part) => part.trim())
|
|
97
97
|
.join(':');
|
|
98
98
|
const cleaned = inputs.map(cleanFunction);
|
|
99
99
|
const cleanedAffectedHeaders = wrappingWhitespace.map(cleanFunction);
|
|
@@ -14,7 +14,7 @@ function listConfig() {
|
|
|
14
14
|
head: ['Config', 'Value', 'Details'],
|
|
15
15
|
colWidths: [null, 60],
|
|
16
16
|
});
|
|
17
|
-
Object.values(set_1.configKeys).forEach(propertyKey => {
|
|
17
|
+
Object.values(set_1.configKeys).forEach((propertyKey) => {
|
|
18
18
|
let value;
|
|
19
19
|
let details;
|
|
20
20
|
switch (propertyKey) {
|
package/commands/constants.js
CHANGED
|
@@ -34,7 +34,7 @@ function printCredentials(credentials, output) {
|
|
|
34
34
|
head: ['ID', 'Name', 'Description', 'Created time'],
|
|
35
35
|
wordWrap: true,
|
|
36
36
|
});
|
|
37
|
-
credentials.forEach(credential => {
|
|
37
|
+
credentials.forEach((credential) => {
|
|
38
38
|
table.push([
|
|
39
39
|
{ rowSpan: 1, content: credential.id, vAlign: 'center' },
|
|
40
40
|
{ rowSpan: 1, content: credential.name, vAlign: 'center' },
|
|
@@ -165,7 +165,7 @@ exports.builder = (yargs) => {
|
|
|
165
165
|
.implies(constants_1.CommandArgMablAutoBranch, constants_1.CommandArgMablBranch)
|
|
166
166
|
.implies(CommandArgSnapshotBranch, constants_1.CommandArgEnvironmentId)
|
|
167
167
|
.implies(constants_1.CommandArgOverrideEnvironmentId, constants_1.CommandArgApplicationId)
|
|
168
|
-
.check(argv => {
|
|
168
|
+
.check((argv) => {
|
|
169
169
|
if (!(argv[constants_1.CommandArgApplicationId] || argv[constants_1.CommandArgEnvironmentId])) {
|
|
170
170
|
throw new Error(`At least one of ${constants_1.CommandArgApplicationId} or ${constants_1.CommandArgEnvironmentId} required`);
|
|
171
171
|
}
|
|
@@ -207,7 +207,7 @@ async function createDeployment(parsed) {
|
|
|
207
207
|
const environmentOverride = parsed[constants_1.CommandArgOverrideEnvironmentId];
|
|
208
208
|
let deploymentIds;
|
|
209
209
|
if (environmentOverride) {
|
|
210
|
-
deploymentIds = (_a = (await apiClient.queryDeploymentEntities(workspaceId, environmentOverride, applicationId)).deployments) === null || _a === void 0 ? void 0 : _a.map(deployment => deployment.id);
|
|
210
|
+
deploymentIds = (_a = (await apiClient.queryDeploymentEntities(workspaceId, environmentOverride, applicationId)).deployments) === null || _a === void 0 ? void 0 : _a.map((deployment) => deployment.id);
|
|
211
211
|
if (!deploymentIds || deploymentIds.length === 0) {
|
|
212
212
|
loggingProvider_1.logger.error(chalk.red.bold(`Application ${applicationId} is not defined in override environment ${environmentOverride}`));
|
|
213
213
|
process.exit(1);
|
|
@@ -27,14 +27,14 @@ class ExecutionResultPresenter {
|
|
|
27
27
|
}
|
|
28
28
|
const table = new Table(tableConfig);
|
|
29
29
|
const finalExecutions = (_a = results === null || results === void 0 ? void 0 : results.executions) !== null && _a !== void 0 ? _a : [];
|
|
30
|
-
finalExecutions.forEach(summary => {
|
|
30
|
+
finalExecutions.forEach((summary) => {
|
|
31
31
|
var _a, _b, _c, _d, _e;
|
|
32
32
|
const retryPrefix = ((_a = summary === null || summary === void 0 ? void 0 : summary.plan_execution) === null || _a === void 0 ? void 0 : _a.is_retry) ? '[Retry] ' : '';
|
|
33
33
|
const planId = summary.plan.id;
|
|
34
34
|
const planName = retryPrefix + ((_c = (_b = summary.plan) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : '<plan name unavailable>');
|
|
35
35
|
const planRunStatus = summary.plan_execution.status;
|
|
36
36
|
const journeyMap = new Map();
|
|
37
|
-
(_d = summary === null || summary === void 0 ? void 0 : summary.journeys) === null || _d === void 0 ? void 0 : _d.forEach(journeySummary => journeyMap.set(journeySummary.id, journeySummary));
|
|
37
|
+
(_d = summary === null || summary === void 0 ? void 0 : summary.journeys) === null || _d === void 0 ? void 0 : _d.forEach((journeySummary) => journeyMap.set(journeySummary.id, journeySummary));
|
|
38
38
|
const statusChalk = this.mapPlanRunStatusToColor(planRunStatus);
|
|
39
39
|
table.push([
|
|
40
40
|
`${planName}`,
|
|
@@ -44,13 +44,13 @@ class ExecutionResultPresenter {
|
|
|
44
44
|
statusChalk(this.maybeCapitalize(planRunStatus.toString())),
|
|
45
45
|
this.summaryToElapsedTime(summary),
|
|
46
46
|
]);
|
|
47
|
-
(_e = summary === null || summary === void 0 ? void 0 : summary.journey_executions) === null || _e === void 0 ? void 0 : _e.forEach(journeyRun => {
|
|
48
|
-
var _a, _b, _c;
|
|
47
|
+
(_e = summary === null || summary === void 0 ? void 0 : summary.journey_executions) === null || _e === void 0 ? void 0 : _e.forEach((journeyRun) => {
|
|
48
|
+
var _a, _b, _c, _d;
|
|
49
49
|
const journeyId = journeyRun.journey_execution_id;
|
|
50
|
-
const journeyStatus = (_a =
|
|
51
|
-
const journeyBrowser = this.maybeCapitalize((
|
|
50
|
+
const journeyStatus = this.maybeCapitalize((_b = (_a = journeyRun.status) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '<status unavailable>');
|
|
51
|
+
const journeyBrowser = this.maybeCapitalize((_c = journeyRun.browser_type) !== null && _c !== void 0 ? _c : '<unknown browser>');
|
|
52
52
|
const journeySummary = journeyMap.get(journeyRun.journey_id);
|
|
53
|
-
const journeyName = `${retryPrefix}${(
|
|
53
|
+
const journeyName = `${retryPrefix}${(_d = journeySummary === null || journeySummary === void 0 ? void 0 : journeySummary.name) !== null && _d !== void 0 ? _d : '<test name >'}`;
|
|
54
54
|
const statusChalk = this.mapJourneyRunStatusToColor(journeyRun.status);
|
|
55
55
|
table.push([
|
|
56
56
|
'',
|
|
@@ -33,7 +33,7 @@ function printDeployments(deployments, output) {
|
|
|
33
33
|
const table = new Table({
|
|
34
34
|
head: ['ID', 'Time', 'Application/Env.', 'Pass', 'Fail', 'Total'],
|
|
35
35
|
});
|
|
36
|
-
deployments.forEach(deployment => {
|
|
36
|
+
deployments.forEach((deployment) => {
|
|
37
37
|
var _a, _b, _c, _d, _e, _f;
|
|
38
38
|
table.push([
|
|
39
39
|
{ rowSpan: 2, content: deployment.id, vAlign: 'center' },
|
|
@@ -77,7 +77,7 @@ function addUpdateEnvCommands(argv) {
|
|
|
77
77
|
boolean: true,
|
|
78
78
|
default: false,
|
|
79
79
|
})
|
|
80
|
-
.check(argv => {
|
|
80
|
+
.check((argv) => {
|
|
81
81
|
const branchName = argv[constants_1.CommandArgMablBranch];
|
|
82
82
|
if (branchName !== undefined && !branches_1.isValidMablBranchName(branchName)) {
|
|
83
83
|
throw new Error(`[${branchName}] is not a valid mabl branch name. Please specify a valid name`);
|
|
@@ -119,8 +119,8 @@ async function createEnvironment(parsed) {
|
|
|
119
119
|
if (applicationId) {
|
|
120
120
|
loggingProvider_1.logger.info('Associating URLs with environment');
|
|
121
121
|
const createDeploymentsPromises = (parsed[constants_1.CommandArgUrlApp] || [])
|
|
122
|
-
.map(url => add_1.createDeploymentForUrl(apiClient, environment, applicationId, url, mablApi_1.Deployment.DeploymentTypeEnum.WebApplication))
|
|
123
|
-
.concat((parsed[constants_1.CommandArgUrlApi] || []).map(url => add_1.createDeploymentForUrl(apiClient, environment, applicationId, url, mablApi_1.Deployment.DeploymentTypeEnum.Api)));
|
|
122
|
+
.map((url) => add_1.createDeploymentForUrl(apiClient, environment, applicationId, url, mablApi_1.Deployment.DeploymentTypeEnum.WebApplication))
|
|
123
|
+
.concat((parsed[constants_1.CommandArgUrlApi] || []).map((url) => add_1.createDeploymentForUrl(apiClient, environment, applicationId, url, mablApi_1.Deployment.DeploymentTypeEnum.Api)));
|
|
124
124
|
await Promise.all(createDeploymentsPromises);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -34,7 +34,7 @@ function printEnvironments(environments, output) {
|
|
|
34
34
|
head: ['ID', 'Name', 'Created time'],
|
|
35
35
|
wordWrap: true,
|
|
36
36
|
});
|
|
37
|
-
environments.forEach(environment => {
|
|
37
|
+
environments.forEach((environment) => {
|
|
38
38
|
table.push([
|
|
39
39
|
{ rowSpan: 1, content: environment.id, vAlign: 'center' },
|
|
40
40
|
{ rowSpan: 1, content: environment.name, vAlign: 'center' },
|
|
@@ -36,7 +36,7 @@ function addEnvironmentUrlOptions(yargs) {
|
|
|
36
36
|
describe: 'api urls to associate with the application-environment pair',
|
|
37
37
|
type: 'array',
|
|
38
38
|
})
|
|
39
|
-
.check(argv => {
|
|
39
|
+
.check((argv) => {
|
|
40
40
|
const applicationId = argv[constants_1.CommandArgApplicationId];
|
|
41
41
|
const appUrls = argv[constants_1.CommandArgUrlApp];
|
|
42
42
|
const apiUrls = argv[constants_1.CommandArgUrlApi];
|
|
@@ -46,7 +46,7 @@ function printFlows(flows) {
|
|
|
46
46
|
head: ['ID', 'Description', 'Created time'],
|
|
47
47
|
wordWrap: true,
|
|
48
48
|
});
|
|
49
|
-
flows.forEach(flow => {
|
|
49
|
+
flows.forEach((flow) => {
|
|
50
50
|
table.push([
|
|
51
51
|
{ rowSpan: 1, content: flow.invariant_id, vAlign: 'center' },
|
|
52
52
|
{ rowSpan: 1, content: flow.description, vAlign: 'center' },
|
|
@@ -45,7 +45,7 @@ function printPlans(plans) {
|
|
|
45
45
|
head: ['ID', 'Name', 'Created time'],
|
|
46
46
|
wordWrap: true,
|
|
47
47
|
});
|
|
48
|
-
plans.forEach(plan => {
|
|
48
|
+
plans.forEach((plan) => {
|
|
49
49
|
table.push([
|
|
50
50
|
{ rowSpan: 1, content: plan.id, vAlign: 'center' },
|
|
51
51
|
{ rowSpan: 1, content: plan.name, vAlign: 'center' },
|
|
@@ -33,7 +33,7 @@ exports.builder = (yargs) => {
|
|
|
33
33
|
})
|
|
34
34
|
.example('$0 test-runs export <id>', 'export test run screenshots to file')
|
|
35
35
|
.example('$0 test-runs export <id> --type screenshots doms', 'export test run screenshots and doms to file')
|
|
36
|
-
.check(argv => {
|
|
36
|
+
.check((argv) => {
|
|
37
37
|
util_1.validateArrayInputs(argv[constants_1.CommandArgContentTypes], 'export types must be SPACE delimited, e.g. "--types=screenshots doms"');
|
|
38
38
|
return true;
|
|
39
39
|
});
|
|
@@ -24,7 +24,7 @@ async function runTheTestInNewWindow(test, flows, branchName, url, credentialsId
|
|
|
24
24
|
loggingProvider_1.logger.info(chalk_1.default.yellowBright('Closing local run of test'));
|
|
25
25
|
trainingBrowser
|
|
26
26
|
.close()
|
|
27
|
-
.catch(error => loggingProvider_1.logger.info('Error shutting down browser on CTRL + C: ' + error));
|
|
27
|
+
.catch((error) => loggingProvider_1.logger.info('Error shutting down browser on CTRL + C: ' + error));
|
|
28
28
|
});
|
|
29
29
|
await testsUtil_1.runTheTest(trainingBrowser, backgroundPage, test, flows, branchName, url, credentialsId, environment);
|
|
30
30
|
}
|