@mablhq/mabl-cli 1.26.5 → 1.29.5

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.
@@ -4,6 +4,7 @@ exports.Browser = void 0;
4
4
  var Browser;
5
5
  (function (Browser) {
6
6
  Browser["chrome"] = "chrome";
7
+ Browser["edge"] = "edge";
7
8
  Browser["firefox"] = "firefox";
8
9
  Browser["internet_explorer"] = "internet_explorer";
9
10
  Browser["safari"] = "safari";
@@ -745,6 +745,20 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
745
745
  throw toApiError(`Failed to get feature flags for workspace ${workspaceId}`, error);
746
746
  }
747
747
  }
748
+ async getUsers(workspaceId, limit) {
749
+ try {
750
+ const userQueryString = queryString.stringify({
751
+ organization_id: workspaceId,
752
+ limit,
753
+ });
754
+ const users = await this.makeGetRequest(`${this.baseApiUrl}/users/?${userQueryString}`).then((result) => { var _a; return (_a = result.users) !== null && _a !== void 0 ? _a : []; });
755
+ sortTemporallyAscending(users);
756
+ return users;
757
+ }
758
+ catch (error) {
759
+ throw toApiError(`Failed to get users`, error);
760
+ }
761
+ }
748
762
  }
749
763
  exports.MablApiClient = MablApiClient;
750
764
  function sortTemporallyAscending(entities) {
@@ -2,7 +2,10 @@
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");
8
+ const simplePlaywrightLogger_1 = require("./simplePlaywrightLogger");
6
9
  const BROWSER_LAUNCH_TIMEOUT_MS = 60000;
7
10
  class PlaywrightBrowserLauncher {
8
11
  async connect(options, currentDownloadPath) {
@@ -10,7 +13,7 @@ class PlaywrightBrowserLauncher {
10
13
  return playwrightBrowser_1.PlaywrightBrowser.create(browser.contexts()[0], currentDownloadPath, options.browserWSEndpoint);
11
14
  }
12
15
  async launch(options) {
13
- var _a, _b, _c;
16
+ var _a, _b, _c, _d;
14
17
  const viewport = options.defaultDeviceDescriptor
15
18
  ? {
16
19
  width: options.defaultDeviceDescriptor.width,
@@ -18,13 +21,26 @@ class PlaywrightBrowserLauncher {
18
21
  }
19
22
  :
20
23
  null;
24
+ const playwrightLogger = options.providerLogger
25
+ ? simplePlaywrightLogger_1.SimplePlaywrightLogger.createWarningLogger(options.providerLogger)
26
+ : undefined;
27
+ if (!options.userDataDir) {
28
+ loggingProvider_1.logger.error('User data directory is required to launch a persistent chromium context and was not provided with LaunchOptions [{}]', options);
29
+ throw new Error('User data directory is required to launch a persistent chromium context');
30
+ }
31
+ if (!options.downloadPath) {
32
+ loggingProvider_1.logger.error('Download path is required to launch a persistent chromium context and was not provided with LaunchOptions [{}]', options);
33
+ throw new Error('Download path is required to launch a persistent chromium context and was not provided with LaunchOptions');
34
+ }
21
35
  const defaultContext = await test_1.chromium.launchPersistentContext(options.userDataDir, {
22
36
  acceptDownloads: true,
23
37
  args: options.args,
24
38
  bypassCSP: options.bypassContentSecurityPolicy,
39
+ channel: browserTypes_1.SupportedBrowserTypeProperties[options.browserType]
40
+ .browserReleaseChannel,
25
41
  deviceScaleFactor: (_a = options.defaultDeviceDescriptor) === null || _a === void 0 ? void 0 : _a.deviceScaleFactor,
26
42
  downloadsPath: options.downloadPath,
27
- executablePath: options.executablePath,
43
+ executablePath: options.browserPath,
28
44
  extraHTTPHeaders: options.extraHttpHeaders,
29
45
  hasTouch: (_b = options.defaultDeviceDescriptor) === null || _b === void 0 ? void 0 : _b.hasTouch,
30
46
  headless: options.headless,
@@ -32,9 +48,10 @@ class PlaywrightBrowserLauncher {
32
48
  ignoreDefaultArgs: options.ignoreDefaultArgs,
33
49
  ignoreHTTPSErrors: true,
34
50
  isMobile: (_c = options.defaultDeviceDescriptor) === null || _c === void 0 ? void 0 : _c.isMobile,
51
+ logger: playwrightLogger,
35
52
  proxy: options.proxy,
36
53
  timeout: BROWSER_LAUNCH_TIMEOUT_MS,
37
- userAgent: options.userAgent,
54
+ userAgent: (_d = options.userAgent) !== null && _d !== void 0 ? _d : options.defaultUserAgent,
38
55
  viewport,
39
56
  });
40
57
  return playwrightBrowser_1.PlaywrightBrowser.create(defaultContext, options.downloadPath, '', options.disableFocusEmulation);
@@ -326,6 +326,9 @@ class PlaywrightElementHandle extends PlaywrightJsHandle {
326
326
  });
327
327
  return (0, pureUtil_1.isNullish)(result) ? undefined : result;
328
328
  }
329
+ async isInShadowRoot() {
330
+ return this.element.evaluate((el) => el.getRootNode().nodeName === '#document-fragment');
331
+ }
329
332
  getActionTimeout(options) {
330
333
  var _a;
331
334
  const defaultTimeout = (options === null || options === void 0 ? void 0 : options.trial)
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SimplePlaywrightLogger = void 0;
4
+ class SimplePlaywrightLogger {
5
+ constructor(logger, severityAllowList) {
6
+ this.logger = logger;
7
+ this.severityAllowList = severityAllowList;
8
+ }
9
+ static createWarningLogger(logger) {
10
+ return new SimplePlaywrightLogger(logger, new Set(['error', 'warning']));
11
+ }
12
+ isEnabled(_name, severity) {
13
+ return this.severityAllowList.has(severity);
14
+ }
15
+ log(name, severity, message, args, _hints) {
16
+ const msg = `[Playwright:${name}:${severity}] ${message} ${args}`;
17
+ switch (severity) {
18
+ case 'error':
19
+ this.logger.error(msg);
20
+ break;
21
+ case 'warning':
22
+ this.logger.warn(msg);
23
+ break;
24
+ case 'info':
25
+ this.logger.info(msg);
26
+ break;
27
+ case 'verbose':
28
+ this.logger.verbose(msg);
29
+ break;
30
+ default:
31
+ this.logger.info(msg);
32
+ break;
33
+ }
34
+ }
35
+ }
36
+ exports.SimplePlaywrightLogger = SimplePlaywrightLogger;
package/cli.js CHANGED
@@ -60,6 +60,7 @@ yargs
60
60
  .commandDir('./commands/plans')
61
61
  .commandDir('./commands/tests')
62
62
  .commandDir('./commands/test-runs')
63
+ .commandDir('./commands/users')
63
64
  .commandDir('./commands/workspaces')
64
65
  .demandCommand(1, '')
65
66
  .recommendCommands()
@@ -1,10 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BrowserTypes = void 0;
4
- var BrowserTypes;
5
- (function (BrowserTypes) {
6
- BrowserTypes["Chrome"] = "chrome";
7
- BrowserTypes["Firefox"] = "firefox";
8
- BrowserTypes["InternetExplorer"] = "internet_explorer";
9
- BrowserTypes["Safari"] = "safari";
10
- })(BrowserTypes = exports.BrowserTypes || (exports.BrowserTypes = {}));
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;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.validateValuePairInputs = exports.validateArrayInputs = exports.getWorkspaceIdFromAppOrEnv = exports.getJourneyFlowArray = exports.TEST_INFO_NOT_FOUND = exports.getWorkspaceId = exports.failWrapper = exports.getDescribeDescriptions = void 0;
6
+ exports.parseColinJoinedVariablePair = exports.validateValuePairInputs = exports.validateArrayInputs = exports.getWorkspaceIdFromAppOrEnv = exports.getJourneyFlowArray = exports.TEST_INFO_NOT_FOUND = exports.getWorkspaceId = exports.failWrapper = exports.getDescribeDescriptions = void 0;
7
7
  const cliConfigProvider_1 = require("../../providers/cliConfigProvider");
8
8
  const constants_1 = require("../constants");
9
9
  const loggingProvider_1 = require("../../providers/logging/loggingProvider");
@@ -91,10 +91,10 @@ function validateValuePairInputs(inputName, inputs) {
91
91
  }
92
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
- const cleanFunction = (header) => header
95
- .split(':', 2)
96
- .map((part) => part.trim())
97
- .join(':');
94
+ const cleanFunction = (header) => {
95
+ const { name, value } = parseColinJoinedVariablePair(header);
96
+ return [name, value].map((part) => part.trim()).join(':');
97
+ };
98
98
  const cleaned = inputs.map(cleanFunction);
99
99
  const cleanedAffectedHeaders = wrappingWhitespace.map(cleanFunction);
100
100
  loggingProvider_1.logger.info(chalk.yellow.bold(`${inputName} wrapping whitespace detected. Whitespace has been trimmed to [`) +
@@ -106,3 +106,9 @@ function validateValuePairInputs(inputName, inputs) {
106
106
  return inputs;
107
107
  }
108
108
  exports.validateValuePairInputs = validateValuePairInputs;
109
+ function parseColinJoinedVariablePair(input) {
110
+ const name = input.substring(0, input.indexOf(':'));
111
+ const value = input.substring(input.indexOf(':') + 1);
112
+ return { name, value };
113
+ }
114
+ exports.parseColinJoinedVariablePair = parseColinJoinedVariablePair;
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CommandArgUrlApp = exports.CommandArgUrl = exports.CommandArgTrainerVersion = exports.CommandArgTo = exports.CommandArgSilent = exports.CommandArgRevision = exports.CommandArgMaxHeartbeatAge = exports.CommandArgPlanId = exports.CommandArgContentTypes = exports.CommandArgPreview = exports.CommandArgOutputFilePath = exports.CommandArgOutput = exports.CommandArgNoPrompt = exports.CommandArgPrompt = exports.CommandArgPortNumber = exports.CommandArgName = exports.CommandArgMablBranchChangesOnly = exports.CommandArgMablBranch = exports.CommandArgMablAutoLogin = exports.CommandArgMablAutoBranch = exports.CommandArgLinkBypass = exports.CommandArgLinkLabel = exports.CommandArgLimitOutput = exports.CommandArgLabels = exports.CommandArgLabelsInclude = exports.CommandArgLabelsExclude = exports.CommandArgTestInteractionSpeed = exports.CommandArgTestRunId = exports.CommandArgTestFile = exports.CommandArgId = exports.CommandArgUserAgent = exports.CommandArgHttpHeaders = exports.CommandArgHelp = exports.CommandArgFromPlanId = exports.CommandArgFrom = exports.CommandArgFormat = exports.CommandArgFastFailure = exports.CommandArgOverrideEnvironmentId = exports.CommandArgEnvironmentId = exports.CommandArgEnableLink = exports.CommandArgDetailLevel = exports.CommandArgDescription = exports.CommandArgDeploymentId = exports.CommandArgDecrypt = exports.CommandArgDataTables = exports.CommandArgCredentials = exports.CommandArgBasicAuthCredentials = exports.CommandArgBrowsers = exports.CommandArgApplicationId = exports.CommandArgApiKey = void 0;
4
- exports.BrowserTypeSelections = exports.DefaultBrowserType = exports.DefaultBranchName = exports.DefaultOutputFormatChoices = exports.DetailLevelFormats = exports.ReporterOptions = exports.OutputFormats = exports.CommandArgAliases = exports.CommandArgBrowserEnableExtensions = exports.CommandArgBrowserIgnoreCertificateErrors = exports.CommandArgBrowserDisableIsolation = exports.ListTimeFormat = exports.CommandArgReporterOptions = exports.CommandArgReporter = exports.CommandArgWorkspaceId = exports.CommandArgVersion = exports.CommandArgVariables = exports.CommandArgUrlApi = void 0;
3
+ exports.CommandArgUrl = exports.CommandArgTrainerVersion = exports.CommandArgTo = exports.CommandArgSilent = exports.CommandArgRevision = exports.CommandArgMaxHeartbeatAge = exports.CommandArgPlanId = exports.CommandArgContentTypes = exports.CommandArgPreview = exports.CommandArgOutputFilePath = exports.CommandArgOutput = exports.CommandArgNoPrompt = exports.CommandArgPrompt = exports.CommandArgPortNumber = exports.CommandArgName = exports.CommandArgMablBranchChangesOnly = exports.CommandArgMablBranch = exports.CommandArgMablAutoLogin = exports.CommandArgMablAutoBranch = exports.CommandArgLinkBypass = exports.CommandArgLinkLabel = exports.CommandArgLimitOutput = exports.CommandArgLabels = exports.CommandArgLabelsInclude = exports.CommandArgLabelsExclude = exports.CommandArgTestInteractionSpeed = exports.CommandArgTestRunId = exports.CommandArgTestFile = exports.CommandArgId = exports.CommandArgUserAgent = exports.CommandArgHttpHeaders = exports.CommandArgHelp = exports.CommandArgFromPlanId = exports.CommandArgFrom = exports.CommandArgFormat = exports.CommandArgFastFailure = exports.CommandArgOverrideEnvironmentId = exports.CommandArgEnvironmentId = exports.CommandArgEnableLink = exports.CommandArgDetailLevel = exports.CommandArgDescription = exports.CommandArgDeploymentId = exports.CommandArgDecrypt = exports.CommandArgDataTables = exports.CommandArgCredentials = exports.CommandArgBasicAuthCredentials = exports.CommandArgBrowsers = exports.CommandArgBrowser = exports.CommandArgApplicationId = exports.CommandArgApiKey = void 0;
4
+ exports.BrowserTypeSelections = exports.DefaultBrowserType = exports.DefaultBranchName = exports.DefaultOutputFormatChoices = exports.DetailLevelFormats = exports.ReporterOptions = exports.OutputFormats = exports.CommandArgAliases = exports.CommandArgBrowserEnableExtensions = exports.CommandArgBrowserIgnoreCertificateErrors = exports.CommandArgBrowserDisableIsolation = exports.ListTimeFormat = exports.CommandArgReporterOptions = exports.CommandArgReporter = exports.CommandArgWorkspaceId = exports.CommandArgVersion = exports.CommandArgVariables = exports.CommandArgUrlApi = exports.CommandArgUrlApp = void 0;
5
5
  const browserTypes_1 = require("./browserTypes");
6
6
  exports.CommandArgApiKey = 'api-key';
7
7
  exports.CommandArgApplicationId = 'application-id';
8
+ exports.CommandArgBrowser = 'browser';
8
9
  exports.CommandArgBrowsers = 'browsers';
9
10
  exports.CommandArgBasicAuthCredentials = 'basic-auth-credentials-id';
10
11
  exports.CommandArgCredentials = 'credentials-id';
@@ -107,10 +108,11 @@ exports.DefaultOutputFormatChoices = [
107
108
  OutputFormats.Yaml,
108
109
  ];
109
110
  exports.DefaultBranchName = 'master';
110
- exports.DefaultBrowserType = browserTypes_1.BrowserTypes.Chrome;
111
+ exports.DefaultBrowserType = browserTypes_1.BrowserType.Chrome;
111
112
  exports.BrowserTypeSelections = [
112
- browserTypes_1.BrowserTypes.Chrome,
113
- browserTypes_1.BrowserTypes.Firefox,
114
- browserTypes_1.BrowserTypes.InternetExplorer,
115
- browserTypes_1.BrowserTypes.Safari,
113
+ browserTypes_1.BrowserType.Chrome,
114
+ browserTypes_1.BrowserType.Edge,
115
+ browserTypes_1.BrowserType.Firefox,
116
+ browserTypes_1.BrowserType.InternetExplorer,
117
+ browserTypes_1.BrowserType.Safari,
116
118
  ].map((browser) => browser.toString());
@@ -88,10 +88,10 @@ function addUpdateEnvCommands(argv) {
88
88
  return undefined;
89
89
  }
90
90
  (0, util_1.validateArrayInputs)(variables, 'Variables must be SPACE delimited, e.g. --variables foo:bar baz:qux');
91
- variables = (0, util_1.validateValuePairInputs)('Variable', variables);
92
- return variables.reduce((variablesObject, item) => {
93
- const parts = item.split(':', 2);
94
- variablesObject[parts[0]] = parts[1];
91
+ const validVariables = (0, util_1.validateValuePairInputs)('Variable', variables);
92
+ return validVariables.reduce((variablesObject, item) => {
93
+ const { name, value } = (0, util_1.parseColinJoinedVariablePair)(item);
94
+ variablesObject[name] = value;
95
95
  return variablesObject;
96
96
  }, {});
97
97
  });
@@ -106,39 +106,23 @@ async function findChrome() {
106
106
  return chromePath;
107
107
  }
108
108
  exports.findChrome = findChrome;
109
- async function launchBrowserInstance(chromePath, launchArgs, userDataDir, headless, credentials, options) {
110
- var _a;
111
- let browser;
112
- const proxyServer = (_a = (await cliConfigProvider_1.CliConfigProvider.getCliConfig()).http.test
113
- .proxyHost) === null || _a === void 0 ? void 0 : _a.href;
114
- let optionsProxy;
115
- if ((options === null || options === void 0 ? void 0 : options.proxy) !== undefined) {
116
- optionsProxy = {
117
- server: options.proxy.server,
118
- };
119
- }
120
- else if (proxyServer !== undefined) {
121
- optionsProxy = {
122
- 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,
123
115
  };
124
116
  }
117
+ let browser;
125
118
  try {
126
- browser = await maybeLaunchBrowser(chromePath, launchArgs, userDataDir, headless, credentials, {
127
- ...options,
128
- proxy: optionsProxy,
129
- });
119
+ browser = await maybeLaunchBrowser(launchArgs, userDataDir, headless, credentials, options);
130
120
  }
131
121
  catch (error) {
132
122
  if (error.message.includes('Running as root without --no-sandbox is not supported')) {
133
123
  launchArgs.push('--no-sandbox');
134
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);
135
- return maybeLaunchBrowser(chromePath, launchArgs, userDataDir, headless, credentials, {
136
- bypassContentSecurityPolicy: options === null || options === void 0 ? void 0 : options.bypassContentSecurityPolicy,
137
- defaultDeviceDescriptor: options === null || options === void 0 ? void 0 : options.defaultDeviceDescriptor,
138
- ignoreDefaultArgs: options === null || options === void 0 ? void 0 : options.ignoreDefaultArgs,
139
- proxy: options === null || options === void 0 ? void 0 : options.proxy,
140
- runnerType: options === null || options === void 0 ? void 0 : options.runnerType,
141
- }).catch((error) => {
125
+ return maybeLaunchBrowser(launchArgs, userDataDir, headless, credentials, options).catch((error) => {
142
126
  messaging_1.mablEventEmitter.log('Browser launch failed', Date.now(), logLineMessaging_1.LogLineColor.red);
143
127
  messaging_1.mablEventEmitter.log(error.message);
144
128
  });
@@ -148,10 +132,29 @@ async function launchBrowserInstance(chromePath, launchArgs, userDataDir, headle
148
132
  }
149
133
  return browser;
150
134
  }
151
- function maybeLaunchBrowser(chromePath, launchArgs, userDataDir, headless, credentials, options) {
135
+ async function maybeGetProxyOptions(options) {
136
+ const proxyServer = (await cliConfigProvider_1.CliConfigProvider.getCliConfig()).http.test
137
+ .proxyHost;
138
+ let optionsProxy;
139
+ if (options === null || options === void 0 ? void 0 : options.proxy) {
140
+ optionsProxy = {
141
+ server: options.proxy.server,
142
+ username: options.proxy.username,
143
+ password: options.proxy.password,
144
+ };
145
+ }
146
+ else if (proxyServer) {
147
+ optionsProxy = {
148
+ server: proxyServer.href,
149
+ username: proxyServer.username,
150
+ password: proxyServer.password,
151
+ };
152
+ }
153
+ return optionsProxy;
154
+ }
155
+ function maybeLaunchBrowser(launchArgs, userDataDir, headless, credentials, options) {
152
156
  return browserLauncher_1.BrowserLauncherFactory.createRunner(options === null || options === void 0 ? void 0 : options.runnerType, options === null || options === void 0 ? void 0 : options.loggerFunc).launch({
153
157
  ...options,
154
- executablePath: chromePath,
155
158
  headless,
156
159
  args: launchArgs,
157
160
  userDataDir,
@@ -182,12 +185,7 @@ function removeTempBrowserPreferencesDirectory(tempDirPath) {
182
185
  }
183
186
  async function createBrowser(browserWidth, browserHeight, headless, containerTesting, tempBrowserPreferencesDirectory, options) {
184
187
  var _a;
185
- const { credentials, browserPath, disableIsolation, ignoreCertificateErrors, emulationConfig, enableExtensions, resourcesDirectoryOverride, } = options || {};
186
- const chromePath = browserPath !== null && browserPath !== void 0 ? browserPath : (await findChrome());
187
- if (!chromePath.length) {
188
- 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'));
189
- throw new Error('Chrome not found error');
190
- }
188
+ const { credentials, disableIsolation, ignoreCertificateErrors, emulationConfig, enableExtensions, resourcesDirectoryOverride, } = options || {};
191
189
  const disableFeaturesFlags = [];
192
190
  const launchArgs = [];
193
191
  if (containerTesting) {
@@ -208,11 +206,12 @@ async function createBrowser(browserWidth, browserHeight, headless, containerTes
208
206
  if (enableExtensions) {
209
207
  ignoreDefaultArgs = ['--disable-extensions'];
210
208
  }
211
- const maybeBrowser = await launchBrowserInstance(chromePath, launchArgs, tempBrowserPreferencesDirectory, headless, credentials, {
209
+ const maybeBrowser = await launchBrowserInstance(launchArgs, tempBrowserPreferencesDirectory, headless, credentials, {
212
210
  ...options,
213
211
  defaultDeviceDescriptor,
214
212
  ignoreDefaultArgs,
215
213
  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,
214
+ defaultUserAgent: options === null || options === void 0 ? void 0 : options.defaultUserAgent,
216
215
  });
217
216
  if (!maybeBrowser) {
218
217
  throw new Error('Unable to start Chrome session');
@@ -252,15 +251,18 @@ function addExecutionEngineLaunchArgs(browserWidth, browserHeight, proxyInfo, em
252
251
  }
253
252
  exports.addExecutionEngineLaunchArgs = addExecutionEngineLaunchArgs;
254
253
  async function createBrowserForExecutionEngine(browserWidth, browserHeight, headless, tempBrowserPreferencesDirectory, proxyInfo, options) {
255
- const { credentials, browserPath, emulationConfig, runnerType, loggerFunc } = options || {};
256
- const chromePath = browserPath !== null && browserPath !== void 0 ? browserPath : (await findChrome());
257
- const { launchArgs, defaultDeviceDescriptor } = addExecutionEngineLaunchArgs(browserWidth, browserHeight, proxyInfo, emulationConfig);
258
- const maybeBrowser = await maybeLaunchBrowser(chromePath, launchArgs, tempBrowserPreferencesDirectory, headless, credentials, {
259
- defaultDeviceDescriptor,
260
- runnerType,
261
- loggerFunc,
262
- userAgent: emulationConfig === null || emulationConfig === void 0 ? void 0 : emulationConfig.device_config.user_agent,
263
- });
254
+ const { credentials, deviceEmulationConfig, userAgent } = options;
255
+ if (deviceEmulationConfig && !userAgent) {
256
+ options = {
257
+ ...options,
258
+ userAgent: deviceEmulationConfig.device_config.user_agent,
259
+ };
260
+ }
261
+ const { launchArgs, defaultDeviceDescriptor } = addExecutionEngineLaunchArgs(browserWidth, browserHeight, proxyInfo, deviceEmulationConfig);
262
+ if (defaultDeviceDescriptor) {
263
+ options = { ...options, defaultDeviceDescriptor };
264
+ }
265
+ const maybeBrowser = await maybeLaunchBrowser(launchArgs, tempBrowserPreferencesDirectory, headless, credentials, options);
264
266
  if (!maybeBrowser) {
265
267
  throw new Error('Unable to start Chrome session');
266
268
  }
@@ -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.toString(),
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`;
@@ -141,7 +142,7 @@ exports.builder = (yargs) => {
141
142
  type: 'boolean',
142
143
  })
143
144
  .option(constants_1.CommandArgBrowserEnableExtensions, {
144
- describe: 'Enable browser extensions on [Chrome]',
145
+ describe: 'Enable browser extensions on [Chrome] and [Edge]',
145
146
  default: false,
146
147
  type: 'boolean',
147
148
  })
@@ -157,14 +158,27 @@ exports.builder = (yargs) => {
157
158
  describe: 'Set the speed that mabl interacts with webpages. Overrides test run settings if specified.',
158
159
  type: 'string',
159
160
  choices: Object.keys(mablApi_1.JourneyParameters.PageLoadWaitEnum).map((pageLoadWait) => pageLoadWait.toLowerCase()),
161
+ })
162
+ .option(constants_1.CommandArgBrowser, {
163
+ describe: 'Target browser to execute the test against [chrome,edge]',
164
+ type: 'string',
165
+ nargs: 1,
166
+ choices: [browserTypes_1.BrowserType.Chrome, browserTypes_1.BrowserType.Edge],
167
+ hidden: true,
160
168
  })
161
169
  .check((argv) => {
162
170
  (0, testsUtil_1.validateRunCommandWithLabels)(argv[constants_1.CommandArgId], argv[constants_1.CommandArgLabelsInclude], argv[constants_1.CommandArgLabelsExclude], argv[constants_1.CommandArgTestRunId], argv[constants_1.CommandArgFromPlanId], true, argv[constants_1.CommandArgTestFile]);
171
+ validateBrowserInput(argv[constants_1.CommandArgBrowser]);
163
172
  const httpHeaders = argv[constants_1.CommandArgHttpHeaders];
164
173
  (0, util_1.validateArrayInputs)(httpHeaders, 'HTTP headers must be SPACE delimited, e.g. "--http-headers "foo:bar" "baz:qux"');
165
174
  argv[constants_1.CommandArgHttpHeaders] = (0, util_1.validateValuePairInputs)('HTTP header', httpHeaders);
166
175
  return true;
167
176
  });
177
+ function validateBrowserInput(browser) {
178
+ if (browser && !['chrome', 'edge'].includes(browser)) {
179
+ throw new Error('invalid browser type, valid browser types are [chrome,edge]');
180
+ }
181
+ }
168
182
  };
169
183
  const exitCodeOnError = 1;
170
184
  exports.handler = (0, util_1.failWrapper)(run, exitCodeOnError);
@@ -184,10 +198,19 @@ async function run(parsed) {
184
198
  extraHttpHeaders[headerParts[0].toLowerCase()] = headerParts[1];
185
199
  }
186
200
  });
201
+ let browserType;
202
+ switch (parsed[constants_1.CommandArgBrowser]) {
203
+ case 'edge':
204
+ browserType = browserTypes_1.BrowserType.Edge;
205
+ break;
206
+ default:
207
+ browserType = browserTypes_1.BrowserType.Chrome;
208
+ }
187
209
  const testRunnerConfig = {
188
210
  _cliCreated: true,
189
211
  basicAuthCredentialsId: parsed[constants_1.CommandArgBasicAuthCredentials],
190
212
  branchName: parsed['mabl-branch'],
213
+ browserType,
191
214
  credentialsId: parsed['credentials-id'],
192
215
  disableIsolation: parsed[constants_1.CommandArgBrowserDisableIsolation],
193
216
  enableExtensions: parsed[constants_1.CommandArgBrowserEnableExtensions],
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = 'users <command>';
4
+ exports.describe = 'mabl users related commands';
5
+ exports.builder = (yargs) => yargs.commandDir('users_cmds').demandCommand();
@@ -0,0 +1,58 @@
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
+ const js_yaml_1 = require("js-yaml");
7
+ const mablApiClientFactory_1 = require("../../../api/mablApiClientFactory");
8
+ const cli_table3_1 = __importDefault(require("cli-table3"));
9
+ const moment = require("moment");
10
+ const util_1 = require("../../commandUtil/util");
11
+ const constants_1 = require("../../constants");
12
+ const loggingProvider_1 = require("../../../providers/logging/loggingProvider");
13
+ const list_1 = require("../../commandUtil/list");
14
+ exports.command = 'list';
15
+ exports.describe = 'List users from a workspace';
16
+ exports.builder = (0, list_1.getListBuilderOptions)('users');
17
+ exports.handler = (0, util_1.failWrapper)(listUsers);
18
+ async function listUsers(parsed) {
19
+ const output = parsed.output;
20
+ const workspaceId = await (0, util_1.getWorkspaceId)(parsed);
21
+ const limit = parsed.limit;
22
+ const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClient();
23
+ const users = await apiClient.getUsers(workspaceId, limit);
24
+ printUsers(users, output, workspaceId);
25
+ return users.length;
26
+ }
27
+ function printUsers(users, outputFormat, workspaceId) {
28
+ switch (outputFormat) {
29
+ case 'json':
30
+ loggingProvider_1.logger.info(JSON.stringify(users, null, 2));
31
+ break;
32
+ case 'yaml':
33
+ loggingProvider_1.logger.info((0, js_yaml_1.dump)(users));
34
+ break;
35
+ default:
36
+ const table = new cli_table3_1.default({
37
+ head: ['ID', 'Name', 'Role', 'Email', 'Created time'],
38
+ wordWrap: true,
39
+ });
40
+ users.forEach((user) => {
41
+ var _a, _b, _c;
42
+ const userRole = (_c = (_b = (_a = user.roles) === null || _a === void 0 ? void 0 : _a.find((role) => role.organization_id === workspaceId)) === null || _b === void 0 ? void 0 : _b.role) !== null && _c !== void 0 ? _c : 'unknown';
43
+ table.push([
44
+ { rowSpan: 1, content: user.id, vAlign: 'center' },
45
+ { rowSpan: 1, content: user.name, vAlign: 'center' },
46
+ { rowSpan: 1, content: userRole, vAlign: 'center' },
47
+ { rowSpan: 1, content: user.email, vAlign: 'center' },
48
+ {
49
+ rowSpan: 1,
50
+ content: moment.utc(user.created_time).format(constants_1.ListTimeFormat),
51
+ vAlign: 'center',
52
+ },
53
+ ]);
54
+ });
55
+ loggingProvider_1.logger.info(table.toString());
56
+ break;
57
+ }
58
+ }