@mablhq/mabl-cli 1.25.5 → 1.26.0
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/Globals.js +20 -0
- package/api/entities/Browser.js +1 -0
- package/api/featureSet.js +6 -2
- package/api/mablApiClient.js +10 -2
- package/browserLauncher/browserLauncherFactory.js +3 -3
- package/browserLauncher/playwrightBrowserLauncher/playwrightBrowser.js +2 -2
- package/browserLauncher/playwrightBrowserLauncher/playwrightBrowserLauncher.js +13 -1
- package/browserLauncher/playwrightBrowserLauncher/playwrightDom.js +18 -0
- package/browserLauncher/types.js +5 -1
- package/commands/browserTypes.js +19 -8
- package/commands/constants.js +6 -5
- package/commands/environments/environments_cmds/create.js +3 -0
- package/commands/tests/testsUtil.js +68 -85
- package/commands/tests/tests_cmds/run-cloud.js +2 -2
- package/commands/tests/tests_cmds/run.js +2 -0
- package/domUtil/index.js +1 -2
- package/execution/index.js +1 -1
- package/execution/index.js.LICENSE.txt +6 -0
- package/index.d.ts +2 -0
- package/mablApi/index.js +1 -1
- package/mablscript/MablAction.js +31 -1
- package/mablscript/actions/ConditionAction.js +4 -0
- package/mablscript/actions/FindAction.js +3 -0
- package/mablscript/actions/GenerateRandomStringAction.js +3 -0
- package/mablscript/actions/GetVariableValue.js +3 -0
- package/mablscript/actions/JavaScriptAction.js +7 -0
- package/mablscript/diffing/diffingUtil.js +81 -16
- package/mablscript/importer.js +10 -3
- package/mablscript/steps/AssertStep.js +10 -0
- package/mablscript/steps/ClickAndHoldStep.js +3 -0
- package/mablscript/steps/ClickStep.js +3 -0
- package/mablscript/steps/CreateVariableStep.js +6 -0
- package/mablscript/steps/DoubleClickStep.js +3 -0
- package/mablscript/steps/DownloadStep.js +4 -0
- package/mablscript/steps/EchoStep.js +3 -0
- package/mablscript/steps/EnterTextStep.js +6 -0
- package/mablscript/steps/EvaluateFlowStep.js +8 -3
- package/mablscript/steps/EvaluateJavaScriptStep.js +3 -0
- package/mablscript/steps/HoverStep.js +3 -0
- package/mablscript/steps/IfConditionStep.js +9 -0
- package/mablscript/steps/OpenEmailStep.js +3 -0
- package/mablscript/steps/ReleaseStep.js +3 -0
- package/mablscript/steps/RemoveCookieStep.js +4 -0
- package/mablscript/steps/SelectStep.js +7 -0
- package/mablscript/steps/SendHttpRequestStep.js +8 -0
- package/mablscript/steps/SendKeyStep.js +3 -0
- package/mablscript/steps/SetCookieStep.js +7 -0
- package/mablscript/steps/SetFilesStep.js +3 -0
- package/mablscript/steps/SwitchContextStep.js +4 -0
- package/mablscript/steps/VisitUrlStep.js +4 -0
- package/mablscript/steps/WaitUntilStep.js +3 -0
- package/mablscriptFind/index.js +1 -1
- package/package.json +8 -7
- package/reporters/__tests__/resources/sampleData.js +5 -0
- package/resources/mablFind.js +1 -1
- package/util/asyncUtil.js +7 -6
- package/browserLauncher/runnerType.js +0 -7
- package/domUtil/index.js.LICENSE.txt +0 -14
- package/mablscript/AttributesConstants.js +0 -115
package/Globals.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Globals = void 0;
|
|
4
|
+
class Globals {
|
|
5
|
+
static getFindOverallTimeoutMs() {
|
|
6
|
+
return Globals.findOverallTimeoutMs;
|
|
7
|
+
}
|
|
8
|
+
static setFindOverallTimeoutMs(timeout) {
|
|
9
|
+
Globals.findOverallTimeoutMs = timeout;
|
|
10
|
+
}
|
|
11
|
+
static getPlaywrightInteractionWarningMs() {
|
|
12
|
+
return Globals.playwrightInteractionWarningMs;
|
|
13
|
+
}
|
|
14
|
+
static setPlaywrightInteractionWarningMs(timeout) {
|
|
15
|
+
Globals.playwrightInteractionWarningMs = timeout;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.Globals = Globals;
|
|
19
|
+
Globals.findOverallTimeoutMs = 18.5 * 60 * 1000;
|
|
20
|
+
Globals.playwrightInteractionWarningMs = 30 * 1000;
|
package/api/entities/Browser.js
CHANGED
package/api/featureSet.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FeatureSet = exports.FindImplementationVersion = void 0;
|
|
4
|
-
const
|
|
4
|
+
const types_1 = require("../browserLauncher/types");
|
|
5
|
+
const ACCESSIBILITY_CHECK_FEATURE_FLAG = 'accessibility_checks';
|
|
5
6
|
const SMARTER_WAIT_FEATURE_FLAG = 'smarter_wait';
|
|
6
7
|
var FindImplementationVersion;
|
|
7
8
|
(function (FindImplementationVersion) {
|
|
@@ -13,12 +14,15 @@ class FeatureSet {
|
|
|
13
14
|
this.featureFlags = featureFlags;
|
|
14
15
|
}
|
|
15
16
|
getRunnerType() {
|
|
16
|
-
return
|
|
17
|
+
return types_1.RunnerType.Playwright;
|
|
17
18
|
}
|
|
18
19
|
getFindImplementationVersion() {
|
|
19
20
|
return this.featureFlags.has(SMARTER_WAIT_FEATURE_FLAG)
|
|
20
21
|
? FindImplementationVersion.SmartFind
|
|
21
22
|
: FindImplementationVersion.V1;
|
|
22
23
|
}
|
|
24
|
+
hasAccessibilityChecksEnabled() {
|
|
25
|
+
return this.featureFlags.has(ACCESSIBILITY_CHECK_FEATURE_FLAG);
|
|
26
|
+
}
|
|
23
27
|
}
|
|
24
28
|
exports.FeatureSet = FeatureSet;
|
package/api/mablApiClient.js
CHANGED
|
@@ -329,6 +329,14 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
329
329
|
throw toApiError(`Failed to get account`, error);
|
|
330
330
|
}
|
|
331
331
|
}
|
|
332
|
+
async getAccountByWorkspaceId(workspaceId) {
|
|
333
|
+
try {
|
|
334
|
+
return await this.makeGetRequest(`${this.baseApiUrl}/organizations/${workspaceId}/account`);
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
throw toApiError(`Failed to get account from workspace id`, error);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
332
340
|
async getApiKeyDetails() {
|
|
333
341
|
try {
|
|
334
342
|
return await this.makeGetRequest(`${this.baseApiUrl}/apiKeys/self`);
|
|
@@ -698,6 +706,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
698
706
|
async failJourneyRun(journeyRunId, cause) {
|
|
699
707
|
try {
|
|
700
708
|
const response = await this.makePatchRequest(`${this.baseApiUrl}/journeyRuns/${journeyRunId}`, {
|
|
709
|
+
functionally_completed: false,
|
|
701
710
|
status: mablApi_1.JourneyRun.StatusEnum.Failed,
|
|
702
711
|
status_cause: cause,
|
|
703
712
|
});
|
|
@@ -726,8 +735,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
726
735
|
}
|
|
727
736
|
async getEffectiveFeaturesByWorkspaceId(workspaceId) {
|
|
728
737
|
try {
|
|
729
|
-
const
|
|
730
|
-
const account = await this.getAccount(workspace.account_id);
|
|
738
|
+
const account = await this.getAccountByWorkspaceId(workspaceId);
|
|
731
739
|
const features = account.effective_features
|
|
732
740
|
? new Set(account.effective_features)
|
|
733
741
|
: new Set();
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.BrowserLauncherFactory = void 0;
|
|
7
7
|
const playwrightBrowserLauncher_1 = require("./playwrightBrowserLauncher/playwrightBrowserLauncher");
|
|
8
|
-
const
|
|
8
|
+
const types_1 = require("./types");
|
|
9
9
|
const logUtils_1 = require("../util/logUtils");
|
|
10
10
|
const loggingProvider_1 = require("../providers/logging/loggingProvider");
|
|
11
11
|
const chalk_1 = __importDefault(require("chalk"));
|
|
@@ -14,12 +14,12 @@ class BrowserLauncherFactory {
|
|
|
14
14
|
var _a;
|
|
15
15
|
return (_a = process.env.MABL_RUNNER) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
16
16
|
}
|
|
17
|
-
static createRunner(runnerType =
|
|
17
|
+
static createRunner(runnerType = types_1.RunnerType.Playwright, loggerFunc) {
|
|
18
18
|
const runnerFromEnv = BrowserLauncherFactory.getRunnerFromEnvironment();
|
|
19
19
|
const runner = runnerFromEnv ? runnerFromEnv : runnerType;
|
|
20
20
|
loggerFunc =
|
|
21
21
|
loggerFunc !== null && loggerFunc !== void 0 ? loggerFunc : ((line) => (0, logUtils_1.logCliOutput)(loggingProvider_1.LogLevel.Info, line));
|
|
22
|
-
if (runner ===
|
|
22
|
+
if (runner === types_1.RunnerType.Playwright) {
|
|
23
23
|
loggerFunc(chalk_1.default.cyan(`Browser launcher:`, chalk_1.default.magenta('Playwright')));
|
|
24
24
|
return new playwrightBrowserLauncher_1.PlaywrightBrowserLauncher();
|
|
25
25
|
}
|
|
@@ -31,9 +31,9 @@ const events_1 = __importDefault(require("events"));
|
|
|
31
31
|
const playwright = __importStar(require("@playwright/test"));
|
|
32
32
|
const browserLauncher_1 = require("../browserLauncher");
|
|
33
33
|
const playwrightPage_1 = require("./playwrightPage");
|
|
34
|
+
const types_1 = require("../types");
|
|
34
35
|
const path_1 = __importDefault(require("path"));
|
|
35
36
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
36
|
-
const runnerType_1 = require("../runnerType");
|
|
37
37
|
class PlaywrightBrowser extends events_1.default {
|
|
38
38
|
constructor(defaultContext, downloadDirectory, browserWSEndpoint, disableFocusEmulation) {
|
|
39
39
|
super();
|
|
@@ -61,7 +61,7 @@ class PlaywrightBrowser extends events_1.default {
|
|
|
61
61
|
return browser;
|
|
62
62
|
}
|
|
63
63
|
getRunnerType() {
|
|
64
|
-
return
|
|
64
|
+
return types_1.RunnerType.Playwright;
|
|
65
65
|
}
|
|
66
66
|
makeCdpCall(method, paramArgs) {
|
|
67
67
|
return this.cdpSession.send(method, paramArgs);
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PlaywrightBrowserLauncher = void 0;
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
|
+
const browserTypes_1 = require("../../commands/browserTypes");
|
|
6
|
+
const loggingProvider_1 = require("../../providers/logging/loggingProvider");
|
|
5
7
|
const playwrightBrowser_1 = require("./playwrightBrowser");
|
|
6
8
|
const BROWSER_LAUNCH_TIMEOUT_MS = 60000;
|
|
7
9
|
class PlaywrightBrowserLauncher {
|
|
@@ -18,13 +20,23 @@ class PlaywrightBrowserLauncher {
|
|
|
18
20
|
}
|
|
19
21
|
:
|
|
20
22
|
null;
|
|
23
|
+
if (!options.userDataDir) {
|
|
24
|
+
loggingProvider_1.logger.error('User data directory is required to launch a persistent chromium context and was not provided with LaunchOptions [{}]', options);
|
|
25
|
+
throw new Error('User data directory is required to launch a persistent chromium context');
|
|
26
|
+
}
|
|
27
|
+
if (!options.downloadPath) {
|
|
28
|
+
loggingProvider_1.logger.error('Download path is required to launch a persistent chromium context and was not provided with LaunchOptions [{}]', options);
|
|
29
|
+
throw new Error('Download path is required to launch a persistent chromium context and was not provided with LaunchOptions');
|
|
30
|
+
}
|
|
21
31
|
const defaultContext = await test_1.chromium.launchPersistentContext(options.userDataDir, {
|
|
22
32
|
acceptDownloads: true,
|
|
23
33
|
args: options.args,
|
|
24
34
|
bypassCSP: options.bypassContentSecurityPolicy,
|
|
35
|
+
channel: browserTypes_1.SupportedBrowserTypeProperties[options.browserType]
|
|
36
|
+
.browserReleaseChannel,
|
|
25
37
|
deviceScaleFactor: (_a = options.defaultDeviceDescriptor) === null || _a === void 0 ? void 0 : _a.deviceScaleFactor,
|
|
26
38
|
downloadsPath: options.downloadPath,
|
|
27
|
-
executablePath: options.
|
|
39
|
+
executablePath: options.browserPath,
|
|
28
40
|
extraHTTPHeaders: options.extraHttpHeaders,
|
|
29
41
|
hasTouch: (_b = options.defaultDeviceDescriptor) === null || _b === void 0 ? void 0 : _b.hasTouch,
|
|
30
42
|
headless: options.headless,
|
|
@@ -304,10 +304,28 @@ class PlaywrightElementHandle extends PlaywrightJsHandle {
|
|
|
304
304
|
const result = await this.element.evaluate((el, attributeName) => el.getAttribute(attributeName), attributeName);
|
|
305
305
|
return (0, pureUtil_1.isNullish)(result) ? undefined : result;
|
|
306
306
|
}
|
|
307
|
+
async getElementText() {
|
|
308
|
+
const innerText = await this.getInnerText();
|
|
309
|
+
return innerText ? innerText : this.getSlotText();
|
|
310
|
+
}
|
|
307
311
|
async getInnerText() {
|
|
308
312
|
const result = await this.element.evaluate((el) => el.innerText);
|
|
309
313
|
return (0, pureUtil_1.isNullish)(result) ? undefined : result;
|
|
310
314
|
}
|
|
315
|
+
async getSlotText() {
|
|
316
|
+
const result = await this.element.evaluate((el) => {
|
|
317
|
+
const slots = el.querySelectorAll('slot');
|
|
318
|
+
if (slots.length !== 1) {
|
|
319
|
+
return '';
|
|
320
|
+
}
|
|
321
|
+
const textNode = slots
|
|
322
|
+
.item(0)
|
|
323
|
+
.assignedNodes()
|
|
324
|
+
.find((node) => node.nodeType === Node.TEXT_NODE);
|
|
325
|
+
return textNode === null || textNode === void 0 ? void 0 : textNode.data;
|
|
326
|
+
});
|
|
327
|
+
return (0, pureUtil_1.isNullish)(result) ? undefined : result;
|
|
328
|
+
}
|
|
311
329
|
getActionTimeout(options) {
|
|
312
330
|
var _a;
|
|
313
331
|
const defaultTimeout = (options === null || options === void 0 ? void 0 : options.trial)
|
package/browserLauncher/types.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WaitForOptions = exports.LifecycleEvent = exports.DefaultTimeouts = void 0;
|
|
3
|
+
exports.WaitForOptions = exports.LifecycleEvent = exports.RunnerType = exports.DefaultTimeouts = void 0;
|
|
4
4
|
class DefaultTimeouts {
|
|
5
5
|
}
|
|
6
6
|
exports.DefaultTimeouts = DefaultTimeouts;
|
|
7
7
|
DefaultTimeouts.defaultTrialTimeoutMs = 5000;
|
|
8
8
|
DefaultTimeouts.defaultWaitTimeoutMs = 5000;
|
|
9
9
|
DefaultTimeouts.defaultActionTimeoutMs = 0;
|
|
10
|
+
var RunnerType;
|
|
11
|
+
(function (RunnerType) {
|
|
12
|
+
RunnerType["Playwright"] = "playwright";
|
|
13
|
+
})(RunnerType = exports.RunnerType || (exports.RunnerType = {}));
|
|
10
14
|
var LifecycleEvent;
|
|
11
15
|
(function (LifecycleEvent) {
|
|
12
16
|
LifecycleEvent["DomContentLoaded"] = "domcontentloaded";
|
package/commands/browserTypes.js
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
var
|
|
5
|
-
(function (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
exports.DefaultBrowserProperties = exports.SupportedBrowserTypeProperties = exports.BrowserType = void 0;
|
|
4
|
+
var BrowserType;
|
|
5
|
+
(function (BrowserType) {
|
|
6
|
+
BrowserType["Chrome"] = "chrome";
|
|
7
|
+
BrowserType["Edge"] = "edge";
|
|
8
|
+
BrowserType["Firefox"] = "firefox";
|
|
9
|
+
BrowserType["InternetExplorer"] = "internet_explorer";
|
|
10
|
+
BrowserType["Safari"] = "safari";
|
|
11
|
+
})(BrowserType = exports.BrowserType || (exports.BrowserType = {}));
|
|
12
|
+
exports.SupportedBrowserTypeProperties = {
|
|
13
|
+
chrome: { browserName: 'chrome', browserReleaseChannel: 'chrome' },
|
|
14
|
+
edge: { browserName: 'edge', browserReleaseChannel: 'msedge' },
|
|
15
|
+
firefox: { browserName: 'firefox', browserReleaseChannel: 'firefox' },
|
|
16
|
+
safari: {
|
|
17
|
+
browserName: 'safari',
|
|
18
|
+
browserReleaseChannel: 'webkit',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
exports.DefaultBrowserProperties = exports.SupportedBrowserTypeProperties.chrome;
|
package/commands/constants.js
CHANGED
|
@@ -107,10 +107,11 @@ exports.DefaultOutputFormatChoices = [
|
|
|
107
107
|
OutputFormats.Yaml,
|
|
108
108
|
];
|
|
109
109
|
exports.DefaultBranchName = 'master';
|
|
110
|
-
exports.DefaultBrowserType = browserTypes_1.
|
|
110
|
+
exports.DefaultBrowserType = browserTypes_1.BrowserType.Chrome;
|
|
111
111
|
exports.BrowserTypeSelections = [
|
|
112
|
-
browserTypes_1.
|
|
113
|
-
browserTypes_1.
|
|
114
|
-
browserTypes_1.
|
|
115
|
-
browserTypes_1.
|
|
112
|
+
browserTypes_1.BrowserType.Chrome,
|
|
113
|
+
browserTypes_1.BrowserType.Edge,
|
|
114
|
+
browserTypes_1.BrowserType.Firefox,
|
|
115
|
+
browserTypes_1.BrowserType.InternetExplorer,
|
|
116
|
+
browserTypes_1.BrowserType.Safari,
|
|
116
117
|
].map((browser) => browser.toString());
|
|
@@ -84,6 +84,9 @@ function addUpdateEnvCommands(argv) {
|
|
|
84
84
|
return true;
|
|
85
85
|
})
|
|
86
86
|
.coerce('variables', (variables) => {
|
|
87
|
+
if (variables.length === 0) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
87
90
|
(0, util_1.validateArrayInputs)(variables, 'Variables must be SPACE delimited, e.g. --variables foo:bar baz:qux');
|
|
88
91
|
variables = (0, util_1.validateValuePairInputs)('Variable', variables);
|
|
89
92
|
return variables.reduce((variablesObject, item) => {
|
|
@@ -27,25 +27,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.toBasicHttpAuthenticationCredentials = exports.generateChromiumPreferencesFile = exports.logTestInfoIfPresent = exports.milliSecondsToSeconds = 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.createBrowserForExecutionEngine = exports.addExecutionEngineLaunchArgs = exports.createBrowser = exports.prepareChromePreferencesDirectory = exports.findChrome = exports.searchForChrome = exports.getFinalUrl = exports.getTempChromePrefDirectory = void 0;
|
|
30
|
-
const
|
|
30
|
+
const async_retry_1 = __importDefault(require("async-retry"));
|
|
31
|
+
const axios_1 = __importDefault(require("axios"));
|
|
32
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
31
33
|
const fs = __importStar(require("fs-extra"));
|
|
34
|
+
const os = __importStar(require("os"));
|
|
32
35
|
const path = __importStar(require("path"));
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const cliConfigProvider_1 = require("../../providers/cliConfigProvider");
|
|
36
|
-
const configKeys_1 = require("../config/config_cmds/configKeys");
|
|
36
|
+
const stream_1 = require("stream");
|
|
37
|
+
const browserLauncher_1 = require("../../browserLauncher/browserLauncher");
|
|
37
38
|
const trainingSessionActions_1 = require("../../core/messaging/actions/trainingSessionActions");
|
|
38
|
-
const
|
|
39
|
+
const logLineMessaging_1 = require("../../core/messaging/logLineMessaging");
|
|
40
|
+
const messaging_1 = require("../../core/messaging/messaging");
|
|
39
41
|
const env_1 = require("../../env/env");
|
|
40
|
-
const
|
|
41
|
-
const httpUtil_1 = require("../../util/httpUtil");
|
|
42
|
+
const cliConfigProvider_1 = require("../../providers/cliConfigProvider");
|
|
42
43
|
const loggingProvider_1 = require("../../providers/logging/loggingProvider");
|
|
43
|
-
const
|
|
44
|
-
const logLineMessaging_1 = require("../../core/messaging/logLineMessaging");
|
|
44
|
+
const httpUtil_1 = require("../../util/httpUtil");
|
|
45
45
|
const resourceUtil_1 = require("../../util/resourceUtil");
|
|
46
|
+
const configKeys_1 = require("../config/config_cmds/configKeys");
|
|
47
|
+
const constants_1 = require("../constants");
|
|
46
48
|
const mobileEmulationUtil_1 = require("./mobileEmulationUtil");
|
|
47
|
-
const browserLauncher_1 = require("../../browserLauncher/browserLauncher");
|
|
48
|
-
const stream_1 = require("stream");
|
|
49
49
|
const trainerUtil_1 = require("./tests_cmds/trainerUtil");
|
|
50
50
|
const chalk = require('chalk');
|
|
51
51
|
const chromeFinder = require('chrome-launcher/dist/chrome-finder');
|
|
@@ -61,6 +61,7 @@ const baseExecutionEngineLaunchArgs = [
|
|
|
61
61
|
'--v=0',
|
|
62
62
|
'--enable-features=NetworkService,NetworkServiceInProcess',
|
|
63
63
|
'--disable-features=site-per-process',
|
|
64
|
+
'--disable-component-update',
|
|
64
65
|
];
|
|
65
66
|
const ExecutionEngineFakeAudioFilePath = '/opt/media/mabl_test_audio.wav';
|
|
66
67
|
const ExecutionEngineFakeVideoFilePath = '/opt/media/mabl_test_pattern.y4m';
|
|
@@ -105,42 +106,23 @@ async function findChrome() {
|
|
|
105
106
|
return chromePath;
|
|
106
107
|
}
|
|
107
108
|
exports.findChrome = findChrome;
|
|
108
|
-
async function launchBrowserInstance(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
let proxy;
|
|
115
|
-
if (proxyServer) {
|
|
116
|
-
proxy = {
|
|
117
|
-
server: proxyServer,
|
|
109
|
+
async function launchBrowserInstance(launchArgs, userDataDir, headless, credentials, options) {
|
|
110
|
+
const optionsProxy = await maybeGetProxyOptions(options);
|
|
111
|
+
if (optionsProxy) {
|
|
112
|
+
options = {
|
|
113
|
+
...options,
|
|
114
|
+
proxy: optionsProxy,
|
|
118
115
|
};
|
|
119
116
|
}
|
|
117
|
+
let browser;
|
|
120
118
|
try {
|
|
121
|
-
browser = await maybeLaunchBrowser(
|
|
122
|
-
bypassContentSecurityPolicy,
|
|
123
|
-
defaultDeviceDescriptor,
|
|
124
|
-
disableFocusEmulation,
|
|
125
|
-
extraHttpHeaders,
|
|
126
|
-
ignoreDefaultArgs,
|
|
127
|
-
runnerType,
|
|
128
|
-
loggerFunc,
|
|
129
|
-
proxy,
|
|
130
|
-
userAgent,
|
|
131
|
-
});
|
|
119
|
+
browser = await maybeLaunchBrowser(launchArgs, userDataDir, headless, credentials, options);
|
|
132
120
|
}
|
|
133
121
|
catch (error) {
|
|
134
122
|
if (error.message.includes('Running as root without --no-sandbox is not supported')) {
|
|
135
123
|
launchArgs.push('--no-sandbox');
|
|
136
124
|
messaging_1.mablEventEmitter.log('Unable to initialize browser with standard settings, attempting to run with --no-sandbox setting', Date.now(), logLineMessaging_1.LogLineColor.yellow);
|
|
137
|
-
return maybeLaunchBrowser(
|
|
138
|
-
bypassContentSecurityPolicy,
|
|
139
|
-
defaultDeviceDescriptor,
|
|
140
|
-
ignoreDefaultArgs,
|
|
141
|
-
proxy,
|
|
142
|
-
runnerType,
|
|
143
|
-
}).catch((error) => {
|
|
125
|
+
return maybeLaunchBrowser(launchArgs, userDataDir, headless, credentials, options).catch((error) => {
|
|
144
126
|
messaging_1.mablEventEmitter.log('Browser launch failed', Date.now(), logLineMessaging_1.LogLineColor.red);
|
|
145
127
|
messaging_1.mablEventEmitter.log(error.message);
|
|
146
128
|
});
|
|
@@ -150,22 +132,31 @@ async function launchBrowserInstance(chromePath, launchArgs, userDataDir, headle
|
|
|
150
132
|
}
|
|
151
133
|
return browser;
|
|
152
134
|
}
|
|
153
|
-
function
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
135
|
+
async function maybeGetProxyOptions(options) {
|
|
136
|
+
var _a;
|
|
137
|
+
const proxyServer = (_a = (await cliConfigProvider_1.CliConfigProvider.getCliConfig()).http.test
|
|
138
|
+
.proxyHost) === null || _a === void 0 ? void 0 : _a.href;
|
|
139
|
+
let optionsProxy;
|
|
140
|
+
if (options === null || options === void 0 ? void 0 : options.proxy) {
|
|
141
|
+
optionsProxy = {
|
|
142
|
+
server: options.proxy.server,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
else if (proxyServer) {
|
|
146
|
+
optionsProxy = {
|
|
147
|
+
server: proxyServer,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return optionsProxy;
|
|
151
|
+
}
|
|
152
|
+
function maybeLaunchBrowser(launchArgs, userDataDir, headless, credentials, options) {
|
|
153
|
+
return browserLauncher_1.BrowserLauncherFactory.createRunner(options === null || options === void 0 ? void 0 : options.runnerType, options === null || options === void 0 ? void 0 : options.loggerFunc).launch({
|
|
154
|
+
...options,
|
|
161
155
|
headless,
|
|
162
156
|
args: launchArgs,
|
|
163
|
-
ignoreDefaultArgs,
|
|
164
157
|
userDataDir,
|
|
165
158
|
downloadPath: createDownloadDirectory(),
|
|
166
159
|
credentials,
|
|
167
|
-
proxy,
|
|
168
|
-
userAgent,
|
|
169
160
|
});
|
|
170
161
|
}
|
|
171
162
|
async function prepareChromePreferencesDirectory(browserPreferences) {
|
|
@@ -190,12 +181,8 @@ function removeTempBrowserPreferencesDirectory(tempDirPath) {
|
|
|
190
181
|
}
|
|
191
182
|
}
|
|
192
183
|
async function createBrowser(browserWidth, browserHeight, headless, containerTesting, tempBrowserPreferencesDirectory, options) {
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
if (!chromePath.length) {
|
|
196
|
-
messaging_1.mablEventEmitter.log(chalk.yellow('Could not find a local install of Chrome to use, please ensure you have it installed and try again'));
|
|
197
|
-
throw new Error('Chrome not found error');
|
|
198
|
-
}
|
|
184
|
+
var _a;
|
|
185
|
+
const { credentials, disableIsolation, ignoreCertificateErrors, emulationConfig, enableExtensions, resourcesDirectoryOverride, } = options || {};
|
|
199
186
|
const disableFeaturesFlags = [];
|
|
200
187
|
const launchArgs = [];
|
|
201
188
|
if (containerTesting) {
|
|
@@ -216,16 +203,11 @@ async function createBrowser(browserWidth, browserHeight, headless, containerTes
|
|
|
216
203
|
if (enableExtensions) {
|
|
217
204
|
ignoreDefaultArgs = ['--disable-extensions'];
|
|
218
205
|
}
|
|
219
|
-
const maybeBrowser = await launchBrowserInstance(
|
|
220
|
-
|
|
206
|
+
const maybeBrowser = await launchBrowserInstance(launchArgs, tempBrowserPreferencesDirectory, headless, credentials, {
|
|
207
|
+
...options,
|
|
221
208
|
defaultDeviceDescriptor,
|
|
222
|
-
disableFocusEmulation,
|
|
223
|
-
extraHttpHeaders,
|
|
224
209
|
ignoreDefaultArgs,
|
|
225
|
-
|
|
226
|
-
loggerFunc,
|
|
227
|
-
proxy,
|
|
228
|
-
userAgent: userAgent !== null && userAgent !== void 0 ? userAgent : emulationConfig === null || emulationConfig === void 0 ? void 0 : emulationConfig.device_config.user_agent,
|
|
210
|
+
userAgent: (_a = options === null || options === void 0 ? void 0 : options.userAgent) !== null && _a !== void 0 ? _a : emulationConfig === null || emulationConfig === void 0 ? void 0 : emulationConfig.device_config.user_agent,
|
|
229
211
|
});
|
|
230
212
|
if (!maybeBrowser) {
|
|
231
213
|
throw new Error('Unable to start Chrome session');
|
|
@@ -265,15 +247,18 @@ function addExecutionEngineLaunchArgs(browserWidth, browserHeight, proxyInfo, em
|
|
|
265
247
|
}
|
|
266
248
|
exports.addExecutionEngineLaunchArgs = addExecutionEngineLaunchArgs;
|
|
267
249
|
async function createBrowserForExecutionEngine(browserWidth, browserHeight, headless, tempBrowserPreferencesDirectory, proxyInfo, options) {
|
|
268
|
-
const { credentials,
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
250
|
+
const { credentials, deviceEmulationConfig, userAgent } = options;
|
|
251
|
+
if (deviceEmulationConfig && !userAgent) {
|
|
252
|
+
options = {
|
|
253
|
+
...options,
|
|
254
|
+
userAgent: deviceEmulationConfig.device_config.user_agent,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
const { launchArgs, defaultDeviceDescriptor } = addExecutionEngineLaunchArgs(browserWidth, browserHeight, proxyInfo, deviceEmulationConfig);
|
|
258
|
+
if (defaultDeviceDescriptor) {
|
|
259
|
+
options = { ...options, defaultDeviceDescriptor };
|
|
260
|
+
}
|
|
261
|
+
const maybeBrowser = await maybeLaunchBrowser(launchArgs, tempBrowserPreferencesDirectory, headless, credentials, options);
|
|
277
262
|
if (!maybeBrowser) {
|
|
278
263
|
throw new Error('Unable to start Chrome session');
|
|
279
264
|
}
|
|
@@ -593,7 +578,7 @@ function validateRunCommandWithLabels(testId, suppliedLabelsInclude, suppliedLab
|
|
|
593
578
|
}
|
|
594
579
|
exports.validateRunCommandWithLabels = validateRunCommandWithLabels;
|
|
595
580
|
async function pullDownTestRunConfig(testRunId, apiClient) {
|
|
596
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p
|
|
581
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
597
582
|
const journeyRun = await apiClient.getTestRun(testRunId);
|
|
598
583
|
const planRun = await apiClient.getPlanRun(journeyRun.parent_execution);
|
|
599
584
|
return {
|
|
@@ -608,16 +593,15 @@ async function pullDownTestRunConfig(testRunId, apiClient) {
|
|
|
608
593
|
deviceEmulation: (_g = journeyRun.journey_parameters) === null || _g === void 0 ? void 0 : _g.device_emulation,
|
|
609
594
|
environmentId: (_j = (_h = journeyRun.journey_parameters) === null || _h === void 0 ? void 0 : _h.deployment) === null || _j === void 0 ? void 0 : _j.environment_id,
|
|
610
595
|
filterHttpRequests: false,
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
url: (_r = (_q = journeyRun.journey_parameters) === null || _q === void 0 ? void 0 : _q.deployment) === null || _r === void 0 ? void 0 : _r.uri,
|
|
596
|
+
importedVariables: (_k = journeyRun.journey_parameters) === null || _k === void 0 ? void 0 : _k.imported_variables,
|
|
597
|
+
pageLoadWait: (_l = journeyRun.journey_parameters) === null || _l === void 0 ? void 0 : _l.page_load_wait,
|
|
598
|
+
testId: (_m = journeyRun.journey) === null || _m === void 0 ? void 0 : _m.invariant_id,
|
|
599
|
+
url: (_p = (_o = journeyRun.journey_parameters) === null || _o === void 0 ? void 0 : _o.deployment) === null || _p === void 0 ? void 0 : _p.uri,
|
|
616
600
|
};
|
|
617
601
|
}
|
|
618
602
|
exports.pullDownTestRunConfig = pullDownTestRunConfig;
|
|
619
603
|
async function extractTestRunConfig(executionMessage, apiClient) {
|
|
620
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q
|
|
604
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
621
605
|
const journeyRun = (_a = executionMessage.journey_run) !== null && _a !== void 0 ? _a : (await apiClient.getTestRun(executionMessage.journey_run_id));
|
|
622
606
|
const planRun = executionMessage.plan_run;
|
|
623
607
|
const maybeRunnerType = ((_b = planRun === null || planRun === void 0 ? void 0 : planRun.run_policy) === null || _b === void 0 ? void 0 : _b.nodejs_runtime_variant)
|
|
@@ -634,11 +618,10 @@ async function extractTestRunConfig(executionMessage, apiClient) {
|
|
|
634
618
|
environmentId: (_k = (_j = journeyRun === null || journeyRun === void 0 ? void 0 : journeyRun.journey_parameters) === null || _j === void 0 ? void 0 : _j.deployment) === null || _k === void 0 ? void 0 : _k.environment_id,
|
|
635
619
|
filterHttpRequests: true,
|
|
636
620
|
importedVariables: (_l = journeyRun.journey_parameters) === null || _l === void 0 ? void 0 : _l.imported_variables,
|
|
637
|
-
|
|
638
|
-
pageLoadWait: (_p = journeyRun.journey_parameters) === null || _p === void 0 ? void 0 : _p.page_load_wait,
|
|
621
|
+
pageLoadWait: (_m = journeyRun.journey_parameters) === null || _m === void 0 ? void 0 : _m.page_load_wait,
|
|
639
622
|
runnerType: maybeRunnerType,
|
|
640
|
-
testId: (
|
|
641
|
-
url: (
|
|
623
|
+
testId: (_o = journeyRun === null || journeyRun === void 0 ? void 0 : journeyRun.journey) === null || _o === void 0 ? void 0 : _o.invariant_id,
|
|
624
|
+
url: (_q = (_p = journeyRun === null || journeyRun === void 0 ? void 0 : journeyRun.journey_parameters) === null || _p === void 0 ? void 0 : _p.deployment) === null || _q === void 0 ? void 0 : _q.uri,
|
|
642
625
|
};
|
|
643
626
|
}
|
|
644
627
|
exports.extractTestRunConfig = extractTestRunConfig;
|
|
@@ -56,9 +56,9 @@ exports.builder = (yargs) => {
|
|
|
56
56
|
})
|
|
57
57
|
.option(constants_1.CommandArgBrowsers, {
|
|
58
58
|
alias: constants_1.CommandArgAliases.Browsers,
|
|
59
|
-
describe: 'Space delimited browsers to test against (e.g. "chrome firefox")',
|
|
59
|
+
describe: 'Space delimited browsers to test against (e.g. "chrome edge firefox")',
|
|
60
60
|
type: 'array',
|
|
61
|
-
default: constants_1.DefaultBrowserType
|
|
61
|
+
default: constants_1.DefaultBrowserType,
|
|
62
62
|
choices: constants_1.BrowserTypeSelections,
|
|
63
63
|
demand: 'Choose at least one browser to run on',
|
|
64
64
|
})
|
|
@@ -7,6 +7,7 @@ const constants_1 = require("../../constants");
|
|
|
7
7
|
const loggingProvider_1 = require("../../../providers/logging/loggingProvider");
|
|
8
8
|
const mablApi_1 = require("../../../mablApi");
|
|
9
9
|
const reporter_1 = require("../../../reporters/reporter");
|
|
10
|
+
const browserTypes_1 = require("../../browserTypes");
|
|
10
11
|
const chalk = require('chalk');
|
|
11
12
|
const execution = require('../../../execution/index');
|
|
12
13
|
exports.command = `run`;
|
|
@@ -188,6 +189,7 @@ async function run(parsed) {
|
|
|
188
189
|
_cliCreated: true,
|
|
189
190
|
basicAuthCredentialsId: parsed[constants_1.CommandArgBasicAuthCredentials],
|
|
190
191
|
branchName: parsed['mabl-branch'],
|
|
192
|
+
browserType: browserTypes_1.BrowserType.Chrome,
|
|
191
193
|
credentialsId: parsed['credentials-id'],
|
|
192
194
|
disableIsolation: parsed[constants_1.CommandArgBrowserDisableIsolation],
|
|
193
195
|
enableExtensions: parsed[constants_1.CommandArgBrowserEnableExtensions],
|