@mablhq/mabl-cli 1.58.20 → 1.58.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/basicApiClient.js +21 -15
- package/api/mablApiClient.js +40 -48
- package/api/mablApiClientFactory.js +1 -1
- package/auth/OktaClient.js +1 -2
- package/browserEngines/chromiumBrowserEngine.js +1 -2
- package/browserEngines/firefoxBrowserEngine.js +2 -2
- package/browserEngines/webkitBrowerEngine.js +2 -2
- package/browserLauncher/browserLauncherFactory.js +2 -3
- package/browserLauncher/elementHandle.js +1 -2
- package/browserLauncher/playwrightBrowserLauncher/chromium/chromiumElementHandleDelegate.js +12 -20
- package/browserLauncher/playwrightBrowserLauncher/chromium/chromiumFrameDelegate.js +1 -1
- package/browserLauncher/playwrightBrowserLauncher/chromium/chromiumPageDelegate.js +7 -10
- package/browserLauncher/playwrightBrowserLauncher/firefox/firefoxFrameDelegate.js +3 -4
- package/browserLauncher/playwrightBrowserLauncher/nonChromium/nonChromiumAbstractElementHandleDelegate.js +4 -5
- package/browserLauncher/playwrightBrowserLauncher/nonChromium/nonChromiumAbstractPageDelegate.js +4 -7
- package/browserLauncher/playwrightBrowserLauncher/playwrightBrowser.js +1 -1
- package/browserLauncher/playwrightBrowserLauncher/playwrightBrowserLauncher.js +6 -5
- package/browserLauncher/playwrightBrowserLauncher/playwrightDom.js +31 -37
- package/browserLauncher/playwrightBrowserLauncher/playwrightFrame.js +8 -9
- package/browserLauncher/playwrightBrowserLauncher/playwrightHttpRequest.js +4 -8
- package/browserLauncher/playwrightBrowserLauncher/playwrightPage.js +4 -6
- package/browserLauncher/playwrightBrowserLauncher/webkit/webkitElementHandleDelegate.js +1 -2
- package/browserLauncher/playwrightBrowserLauncher/webkit/webkitFrameDelegate.js +1 -1
- package/browserTestMonitoring/metricsRecorder.js +6 -6
- package/commands/commandUtil/branches.js +2 -3
- package/commands/commandUtil/codeInsights.js +13 -16
- package/commands/commandUtil/fileUtil.js +1 -1
- package/commands/commandUtil/util.js +3 -4
- package/commands/commandUtil/versionUtil.js +4 -5
- package/commands/config/config_cmds/list.js +2 -2
- package/commands/constants.js +3 -1
- package/commands/datatables/datatables_cmds/create.js +2 -3
- package/commands/datatables/datatables_cmds/export.js +3 -5
- package/commands/datatables/datatables_cmds/list.js +1 -2
- package/commands/datatables/datatables_cmds/scenarios.js +1 -2
- package/commands/datatables/datatables_cmds/update.js +11 -11
- package/commands/datatables/utils.js +9 -9
- package/commands/deploy/deploy_cmds/awaitDeploymentCompletion.js +6 -8
- package/commands/deploy/deploy_cmds/create.js +11 -13
- package/commands/deploy/deploy_cmds/executionResultPresenter.js +8 -11
- package/commands/deploy/deploy_cmds/list.js +3 -4
- package/commands/deploy/deploy_cmds/watch.js +1 -2
- package/commands/environments/environments_cmds/create.js +1 -2
- package/commands/environments/environments_cmds/delete.js +1 -2
- package/commands/environments/environments_cmds/update.js +1 -2
- package/commands/environments/environments_cmds/urls_cmds/list.js +1 -2
- package/commands/flows/flows_cmds/export.js +1 -2
- package/commands/plans/plans_cmds/describe.js +1 -2
- package/commands/tests/mobileEmulationUtil.js +5 -7
- package/commands/tests/testsUtil.js +40 -42
- package/commands/tests/tests_cmds/export.js +1 -2
- package/commands/tests/tests_cmds/import.js +4 -5
- package/commands/tests/tests_cmds/run-cloud.js +12 -13
- package/commands/tests/tests_cmds/run.js +30 -11
- package/commands/users/users_cmds/list.js +2 -2
- package/commands/workspaces/workspace_cmds/copy.js +1 -2
- package/core/execution/ApiTestUtils.js +82 -94
- package/core/execution/LocalizationOptionsLists.js +1253 -0
- package/core/messaging/logLineMessaging.js +2 -3
- package/core/messaging/messaging.js +6 -7
- package/core/trainer/trainingSessions.js +15 -15
- package/coreWebVitals/index.js +14 -18
- package/domUtil/index.js +1 -1
- package/execution/index.js +1 -1
- package/functions/apiTest/utils.js +4 -5
- package/http/MablHttpAgent.js +4 -6
- package/http/RequestSecurityError.js +1 -1
- package/http/axiosProxyConfig.js +3 -5
- package/http/httpUtil.js +2 -3
- package/http/requestInterceptor.js +11 -15
- package/mablApi/index.js +1 -1
- package/mablscript/MablAction.js +2 -3
- package/mablscript/MablStep.js +2 -4
- package/mablscript/MablSymbol.js +1 -1
- package/mablscript/actions/ConditionAction.js +2 -4
- package/mablscript/actions/FindAction.js +2 -4
- package/mablscript/diffing/diffingUtil.js +8 -7
- package/mablscript/importer.js +1 -2
- package/mablscript/steps/AccessibilityCheck.js +7 -9
- package/mablscript/steps/AssertStep.js +11 -16
- package/mablscript/steps/ClickAndHoldStep.js +1 -2
- package/mablscript/steps/CookieUtils.js +40 -7
- package/mablscript/steps/CreateVariableStep.js +1 -2
- package/mablscript/steps/DownloadStep.js +1 -2
- package/mablscript/steps/EnterTextStep.js +1 -2
- package/mablscript/steps/EvaluateFlowStep.js +1 -1
- package/mablscript/steps/IfConditionStep.js +4 -6
- package/mablscript/steps/ReleaseStep.js +1 -2
- package/mablscript/steps/SendHttpRequestStep.js +2 -4
- package/mablscript/steps/SendKeyStep.js +1 -1
- package/mablscript/steps/SetCookieStep.js +35 -20
- package/mablscript/steps/SetViewportStep.js +1 -1
- package/mablscript/steps/SwitchContextStep.js +3 -6
- package/mablscript/steps/SyntheticStep.js +1 -2
- package/mablscriptFind/index.js +1 -1
- package/middleware.js +1 -2
- package/package.json +2 -2
- package/popupDismissal/index.js +4 -5
- package/providers/authenticationProvider.js +5 -6
- package/providers/cliConfigProvider.js +10 -12
- package/providers/exportRequestProvider.js +3 -5
- package/providers/logging/loggingProvider.js +1 -1
- package/reporters/mochAwesome/mochAwesomeReporter.js +12 -14
- package/resources/mablFind.js +1 -1
- package/util/actionabilityUtil.js +1 -1
- package/util/analytics.js +6 -9
- package/util/browserTestUtils.js +1 -2
- package/util/markdownUtil.js +9 -11
package/api/basicApiClient.js
CHANGED
|
@@ -56,9 +56,8 @@ const RETRYABLE_NODEJS_ERRORS = [
|
|
|
56
56
|
const DEFAULT_SSL_VERIFY = false;
|
|
57
57
|
class BasicApiClient {
|
|
58
58
|
constructor(options) {
|
|
59
|
-
var _a, _b, _c, _d, _e;
|
|
60
59
|
const config = (0, axiosProxyConfig_1.axiosProxyConfig)({
|
|
61
|
-
sslVerify:
|
|
60
|
+
sslVerify: options.sslVerify ?? DEFAULT_SSL_VERIFY,
|
|
62
61
|
proxyHost: options.proxyUrl,
|
|
63
62
|
proxyType: options.proxyType,
|
|
64
63
|
});
|
|
@@ -66,7 +65,9 @@ class BasicApiClient {
|
|
|
66
65
|
config.headers = {};
|
|
67
66
|
}
|
|
68
67
|
config.timeout =
|
|
69
|
-
|
|
68
|
+
options.requestTimeoutMillis ??
|
|
69
|
+
options.retryConfig?.requestTimeoutMillis ??
|
|
70
|
+
DEFAULT_RETRYABLE_REQUEST_TIMEOUT_MILLISECONDS;
|
|
70
71
|
config.maxBodyLength = Infinity;
|
|
71
72
|
config.maxContentLength = Infinity;
|
|
72
73
|
switch (options.authType) {
|
|
@@ -105,7 +106,7 @@ class BasicApiClient {
|
|
|
105
106
|
this.httpClient = axios_1.default.create(config);
|
|
106
107
|
this.httpClient.defaults.headers.common = { ...config.headers };
|
|
107
108
|
this.retryConfig = options.retryConfig;
|
|
108
|
-
this.debugLogger =
|
|
109
|
+
this.debugLogger = options.debugLogger ?? logUtils_1.logInternal;
|
|
109
110
|
}
|
|
110
111
|
static async create() {
|
|
111
112
|
const httpConfig = (await cliConfigProvider_1.CliConfigProvider.getCliConfig()).http.mabl;
|
|
@@ -118,7 +119,7 @@ class BasicApiClient {
|
|
|
118
119
|
});
|
|
119
120
|
}
|
|
120
121
|
getNonRetryableRequestConfig(override) {
|
|
121
|
-
const overrideWithTimeout = { ...(override
|
|
122
|
+
const overrideWithTimeout = { ...(override ?? {}) };
|
|
122
123
|
if (!overrideWithTimeout.timeout) {
|
|
123
124
|
overrideWithTimeout.timeout =
|
|
124
125
|
DEFAULT_NONRETRYABLE_REQUEST_TIMEOUT_MILLISECONDS;
|
|
@@ -126,9 +127,8 @@ class BasicApiClient {
|
|
|
126
127
|
return { ...this.httpRequestConfig, ...overrideWithTimeout };
|
|
127
128
|
}
|
|
128
129
|
getRetryableRequestConfig(retryConfig) {
|
|
129
|
-
var _a;
|
|
130
130
|
return this.getNonRetryableRequestConfig({
|
|
131
|
-
timeout:
|
|
131
|
+
timeout: retryConfig?.requestTimeoutMillis ?? this.httpRequestConfig.timeout,
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
134
|
makeGetRequest(path, retryConfig, axiosConfig) {
|
|
@@ -146,12 +146,11 @@ class BasicApiClient {
|
|
|
146
146
|
return this.retryWrappedRequest(`makeGetRequestWithETag('${path}')`, () => this.getRequestWithETag(path, this.getRetryableRequestConfig(retryConfig)), retryConfig);
|
|
147
147
|
}
|
|
148
148
|
async getRequestWithETag(path, config) {
|
|
149
|
-
var _a;
|
|
150
149
|
const response = await this.debugRequest('GET', path, () => this.httpClient.get(path, config));
|
|
151
150
|
BasicApiClient.checkResponseStatusCode(response);
|
|
152
151
|
const headers = response.headers;
|
|
153
152
|
const result = response.data;
|
|
154
|
-
const versionHeader =
|
|
153
|
+
const versionHeader = headers[MABL_ENTITY_VERSION_HEADER]?.toString();
|
|
155
154
|
if (!versionHeader) {
|
|
156
155
|
throw new Error(`Missing ${MABL_ENTITY_VERSION_HEADER} header`);
|
|
157
156
|
}
|
|
@@ -208,7 +207,7 @@ class BasicApiClient {
|
|
|
208
207
|
throw e;
|
|
209
208
|
}
|
|
210
209
|
finally {
|
|
211
|
-
this.debugLogger(`API Client: ${method} ${path} ${error ? 'failed' : 'completed'} in ${Date.now() - startTimeMillis}ms with ${responseCode
|
|
210
|
+
this.debugLogger(`API Client: ${method} ${path} ${error ? 'failed' : 'completed'} in ${Date.now() - startTimeMillis}ms with ${responseCode ?? error}`);
|
|
212
211
|
}
|
|
213
212
|
}
|
|
214
213
|
static checkResponseStatusCode(response) {
|
|
@@ -218,12 +217,19 @@ class BasicApiClient {
|
|
|
218
217
|
}
|
|
219
218
|
}
|
|
220
219
|
retryWrappedRequest(description, requestFunc, retryConfigOverride) {
|
|
221
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
222
220
|
const retryOptions = {
|
|
223
|
-
retries:
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
221
|
+
retries: retryConfigOverride?.retryCount ??
|
|
222
|
+
this.retryConfig?.retryCount ??
|
|
223
|
+
DEFAULT_RETRIES,
|
|
224
|
+
minTimeout: retryConfigOverride?.minRetryIntervalMillis ??
|
|
225
|
+
this.retryConfig?.minRetryIntervalMillis ??
|
|
226
|
+
DEFAULT_MIN_RETRY_INTERVAL_MILLISECONDS,
|
|
227
|
+
maxTimeout: retryConfigOverride?.maxRetryIntervalMillis ??
|
|
228
|
+
this.retryConfig?.maxRetryIntervalMillis ??
|
|
229
|
+
DEFAULT_MAX_RETRY_INTERVAL_MILLISECONDS,
|
|
230
|
+
maxRetryTime: retryConfigOverride?.maxRetryTimeMillis ??
|
|
231
|
+
this.retryConfig?.maxRetryTimeMillis ??
|
|
232
|
+
DEFAULT_MAX_TOTAL_RETRY_TIME_MILLISECONDS,
|
|
227
233
|
onRetry: (error) => {
|
|
228
234
|
this.debugLogger(`Retrying failed API request "${description}"`, error);
|
|
229
235
|
},
|
package/api/mablApiClient.js
CHANGED
|
@@ -13,9 +13,8 @@ const query_string_1 = __importDefault(require("query-string"));
|
|
|
13
13
|
const featureSet_1 = require("./featureSet");
|
|
14
14
|
class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
15
15
|
constructor(options) {
|
|
16
|
-
var _a;
|
|
17
16
|
super(options);
|
|
18
|
-
this.baseApiUrl =
|
|
17
|
+
this.baseApiUrl = options.apiUrl ?? env_1.BASE_API_URL;
|
|
19
18
|
}
|
|
20
19
|
async getPlan(planId) {
|
|
21
20
|
try {
|
|
@@ -26,12 +25,11 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
27
|
async getPlans(options) {
|
|
29
|
-
var _a, _b;
|
|
30
28
|
try {
|
|
31
29
|
const queryArg = query_string_1.default.stringify(options);
|
|
32
30
|
const plans = await this.makeGetRequest(`${this.baseApiUrl}/schedule/runPolicy/?${queryArg}`);
|
|
33
|
-
sortTemporallyAscending(
|
|
34
|
-
return
|
|
31
|
+
sortTemporallyAscending(plans.run_policies ?? []);
|
|
32
|
+
return plans.run_policies ?? [];
|
|
35
33
|
}
|
|
36
34
|
catch (error) {
|
|
37
35
|
throw toApiError(`Failed to get plans (workspace: ${options.organization_id})`, error);
|
|
@@ -51,7 +49,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
51
49
|
organization_id: workspaceId,
|
|
52
50
|
limit,
|
|
53
51
|
});
|
|
54
|
-
const applications = await this.makeGetRequest(`${this.baseApiUrl}/applications?${applicationQueryString}`).then((result) =>
|
|
52
|
+
const applications = await this.makeGetRequest(`${this.baseApiUrl}/applications?${applicationQueryString}`).then((result) => result.applications ?? []);
|
|
55
53
|
sortTemporallyAscending(applications);
|
|
56
54
|
return applications;
|
|
57
55
|
}
|
|
@@ -101,7 +99,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
101
99
|
organization_id: workspaceId,
|
|
102
100
|
limit,
|
|
103
101
|
});
|
|
104
|
-
const environments = await this.makeGetRequest(`${this.baseApiUrl}/v1/environments/?${environmentQueryString}`).then((result) =>
|
|
102
|
+
const environments = await this.makeGetRequest(`${this.baseApiUrl}/v1/environments/?${environmentQueryString}`).then((result) => result.environments ?? []);
|
|
105
103
|
sortTemporallyAscending(environments);
|
|
106
104
|
return environments;
|
|
107
105
|
}
|
|
@@ -138,9 +136,8 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
138
136
|
}
|
|
139
137
|
}
|
|
140
138
|
async getLinkAgentsWithRecentHeartbeats(workspaceId, limit, maxHeartbeatAgeSeconds) {
|
|
141
|
-
var _a;
|
|
142
139
|
try {
|
|
143
|
-
return ((
|
|
140
|
+
return ((await this.makeGetRequest(`${env_1.BASE_API_URL}/link/agents?workspace_id=${workspaceId}&limit=${limit}&max_heartbeat_age_sec=${maxHeartbeatAgeSeconds}`)).link_agents ?? []);
|
|
144
141
|
}
|
|
145
142
|
catch (error) {
|
|
146
143
|
throw toApiError(`Failed to get active link agents`, error);
|
|
@@ -171,7 +168,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
171
168
|
organization_id: workspaceId,
|
|
172
169
|
limit,
|
|
173
170
|
});
|
|
174
|
-
return await this.makeGetRequest(`${this.baseApiUrl}/credentials?${credentialsQueryString}`).then((result) =>
|
|
171
|
+
return await this.makeGetRequest(`${this.baseApiUrl}/credentials?${credentialsQueryString}`).then((result) => result.credentials ?? []);
|
|
175
172
|
}
|
|
176
173
|
catch (error) {
|
|
177
174
|
throw toApiError(`Failed to get credentials`, error);
|
|
@@ -195,7 +192,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
195
192
|
workspace_id: workspaceId,
|
|
196
193
|
limit,
|
|
197
194
|
});
|
|
198
|
-
return await this.makeGetRequest(`${this.baseApiUrl}/events/deployment?${deploymentQueryString}`).then((result) =>
|
|
195
|
+
return await this.makeGetRequest(`${this.baseApiUrl}/events/deployment?${deploymentQueryString}`).then((result) => result.deployments ?? []);
|
|
199
196
|
}
|
|
200
197
|
catch (error) {
|
|
201
198
|
throw toApiError(`Failed to get deployment events`, error);
|
|
@@ -242,7 +239,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
242
239
|
}
|
|
243
240
|
async getTestFindSummaries(testId, environmentId) {
|
|
244
241
|
try {
|
|
245
|
-
return await this.makeGetRequest(`${this.baseApiUrl}/findSummary?journey_id=${testId}&environment_id=${environmentId}`).then((result) =>
|
|
242
|
+
return await this.makeGetRequest(`${this.baseApiUrl}/findSummary?journey_id=${testId}&environment_id=${environmentId}`).then((result) => result.findsummaries ?? []);
|
|
246
243
|
}
|
|
247
244
|
catch (error) {
|
|
248
245
|
throw toApiError(`Failed to get test find summaries results`, error);
|
|
@@ -250,7 +247,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
250
247
|
}
|
|
251
248
|
async getTestFindModels(testId, environmentId) {
|
|
252
249
|
try {
|
|
253
|
-
return await this.makeGetRequest(`${this.baseApiUrl}/findModel/test/${testId}?environment_id=${environmentId}`).then((result) =>
|
|
250
|
+
return await this.makeGetRequest(`${this.baseApiUrl}/findModel/test/${testId}?environment_id=${environmentId}`).then((result) => result.findModels ?? []);
|
|
254
251
|
}
|
|
255
252
|
catch (error) {
|
|
256
253
|
throw toApiError(`Failed to get test find model results`, error);
|
|
@@ -258,7 +255,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
258
255
|
}
|
|
259
256
|
async getTestOverrides(testId, environmentId, selectorOverrideLimit = 10) {
|
|
260
257
|
try {
|
|
261
|
-
return await this.makeGetRequest(`${this.baseApiUrl}/tests/testScripts/${testId}/overrides?environment_id=${environmentId}&selector_override_limit=${selectorOverrideLimit}`).then((result) =>
|
|
258
|
+
return await this.makeGetRequest(`${this.baseApiUrl}/tests/testScripts/${testId}/overrides?environment_id=${environmentId}&selector_override_limit=${selectorOverrideLimit}`).then((result) => result.overrides ?? []);
|
|
262
259
|
}
|
|
263
260
|
catch (error) {
|
|
264
261
|
throw toApiError(`Failed to get selector overrides`, error);
|
|
@@ -281,10 +278,11 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
281
278
|
}
|
|
282
279
|
}
|
|
283
280
|
async getWorkspaces(limit) {
|
|
284
|
-
var _a, _b;
|
|
285
281
|
try {
|
|
286
282
|
const userInfo = await this.getSelf();
|
|
287
|
-
const requests =
|
|
283
|
+
const requests = userInfo.roles
|
|
284
|
+
?.slice(0, limit)
|
|
285
|
+
.map((role) => this.getWorkspace(role.organization_id)) ?? [];
|
|
288
286
|
const workspaces = await Promise.all(requests);
|
|
289
287
|
sortTemporallyAscending(workspaces);
|
|
290
288
|
return workspaces;
|
|
@@ -326,15 +324,14 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
326
324
|
}
|
|
327
325
|
}
|
|
328
326
|
async getSelf() {
|
|
329
|
-
var _a, _b;
|
|
330
327
|
try {
|
|
331
328
|
const selfInfo = await this.makeGetRequest(`${this.baseApiUrl}/self`);
|
|
332
|
-
if (
|
|
329
|
+
if (selfInfo.preferences?.default_workspace_id &&
|
|
333
330
|
!(await cliConfigProvider_1.CliConfigProvider.getWorkspace())) {
|
|
334
331
|
const workspace = await this.getWorkspace(selfInfo.preferences.default_workspace_id);
|
|
335
332
|
await cliConfigProvider_1.CliConfigProvider.setWorkspace(workspace);
|
|
336
333
|
}
|
|
337
|
-
else if (
|
|
334
|
+
else if (selfInfo.roles?.length === 1) {
|
|
338
335
|
const workspace = await this.getWorkspace(selfInfo.roles[0].organization_id);
|
|
339
336
|
await cliConfigProvider_1.CliConfigProvider.setWorkspace(workspace);
|
|
340
337
|
}
|
|
@@ -358,10 +355,9 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
358
355
|
}
|
|
359
356
|
}
|
|
360
357
|
async getJourneys(options) {
|
|
361
|
-
var _a;
|
|
362
358
|
try {
|
|
363
359
|
const queryArg = query_string_1.default.stringify(options);
|
|
364
|
-
const journeys = (
|
|
360
|
+
const journeys = (await this.makeGetRequest(`${this.baseApiUrl}/test/journeys?${queryArg}`)).journeys ?? [];
|
|
365
361
|
sortTemporallyAscending(journeys);
|
|
366
362
|
return journeys;
|
|
367
363
|
}
|
|
@@ -382,10 +378,9 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
382
378
|
}
|
|
383
379
|
}
|
|
384
380
|
async getFlows(options) {
|
|
385
|
-
var _a;
|
|
386
381
|
try {
|
|
387
382
|
const queryArg = query_string_1.default.stringify(options);
|
|
388
|
-
const flows = (
|
|
383
|
+
const flows = (await this.makeGetRequest(`${this.baseApiUrl}/flows?${queryArg}`)).flows ?? [];
|
|
389
384
|
sortTemporallyAscending(flows);
|
|
390
385
|
return flows;
|
|
391
386
|
}
|
|
@@ -427,7 +422,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
427
422
|
limit,
|
|
428
423
|
status: statusFilter,
|
|
429
424
|
});
|
|
430
|
-
return await this.makeGetRequest(`${this.baseApiUrl}/branch?${branchQueryString}`).then((result) =>
|
|
425
|
+
return await this.makeGetRequest(`${this.baseApiUrl}/branch?${branchQueryString}`).then((result) => result.branches ?? []);
|
|
431
426
|
}
|
|
432
427
|
catch (error) {
|
|
433
428
|
throw toApiError(`Failed to get Branches`, error);
|
|
@@ -502,7 +497,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
502
497
|
async getSessionEmails(sessionId) {
|
|
503
498
|
try {
|
|
504
499
|
const emailQueryString = query_string_1.default.stringify({
|
|
505
|
-
context_id: sessionId
|
|
500
|
+
context_id: sessionId?.slice(0, 8),
|
|
506
501
|
});
|
|
507
502
|
return await this.makeGetRequest(`${this.baseApiUrl}/execution/inputs?${emailQueryString}`);
|
|
508
503
|
}
|
|
@@ -523,7 +518,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
523
518
|
}
|
|
524
519
|
}
|
|
525
520
|
async createMailboxAddress(workspaceId, sessionId) {
|
|
526
|
-
const contextId = sessionId
|
|
521
|
+
const contextId = sessionId?.slice(0, 8);
|
|
527
522
|
try {
|
|
528
523
|
const body = {
|
|
529
524
|
context_id: contextId,
|
|
@@ -600,7 +595,6 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
600
595
|
}
|
|
601
596
|
}
|
|
602
597
|
buildDeploymentRequestBody(options) {
|
|
603
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
604
598
|
const requestBody = { properties: {} };
|
|
605
599
|
if (options.environmentId) {
|
|
606
600
|
requestBody.environment_id = options.environmentId;
|
|
@@ -608,26 +602,26 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
608
602
|
if (options.applicationId) {
|
|
609
603
|
requestBody.application_id = options.applicationId;
|
|
610
604
|
}
|
|
611
|
-
requestBody.revision =
|
|
605
|
+
requestBody.revision = options.sourceControlMetadata?.revision;
|
|
612
606
|
if (options.mablBranch) {
|
|
613
607
|
requestBody.source_control_tag = options.mablBranch;
|
|
614
608
|
}
|
|
615
609
|
requestBody.properties.repository_branch_name =
|
|
616
|
-
|
|
610
|
+
options.sourceControlMetadata?.branchName;
|
|
617
611
|
requestBody.properties.repository_tag_name =
|
|
618
|
-
|
|
612
|
+
options.sourceControlMetadata?.branchName;
|
|
619
613
|
requestBody.properties.repository_url =
|
|
620
|
-
|
|
614
|
+
options.sourceControlMetadata?.repoUrl;
|
|
621
615
|
requestBody.properties.repository_name =
|
|
622
|
-
|
|
616
|
+
options.sourceControlMetadata?.repoName;
|
|
623
617
|
const planOverrides = {};
|
|
624
|
-
if (
|
|
618
|
+
if (options.browserTypes?.length) {
|
|
625
619
|
planOverrides.browser_types = options.browserTypes;
|
|
626
620
|
}
|
|
627
621
|
if (options.runnerType) {
|
|
628
622
|
planOverrides.nodejs_runtime_variant = options.runnerType;
|
|
629
623
|
}
|
|
630
|
-
if (
|
|
624
|
+
if (options.labels?.length) {
|
|
631
625
|
requestBody.plan_labels = options.labels;
|
|
632
626
|
}
|
|
633
627
|
if (options.uri) {
|
|
@@ -642,7 +636,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
642
636
|
if (options.deploymentIds) {
|
|
643
637
|
planOverrides.deployment_ids = options.deploymentIds;
|
|
644
638
|
}
|
|
645
|
-
if (
|
|
639
|
+
if (options.httpHeaders?.length) {
|
|
646
640
|
planOverrides.http_headers = options.httpHeaders.map((header) => {
|
|
647
641
|
const parts = header.split(':', 2);
|
|
648
642
|
return {
|
|
@@ -700,7 +694,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
700
694
|
if (deploymentId) {
|
|
701
695
|
planOverrides.deployment_id = deploymentId;
|
|
702
696
|
}
|
|
703
|
-
if (browserTypes
|
|
697
|
+
if (browserTypes?.length) {
|
|
704
698
|
planOverrides.browser_types = browserTypes;
|
|
705
699
|
}
|
|
706
700
|
if (appUrl) {
|
|
@@ -805,20 +799,18 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
805
799
|
});
|
|
806
800
|
}
|
|
807
801
|
async getEffectiveFeaturesByWorkspaceId(workspaceId) {
|
|
808
|
-
var _a;
|
|
809
802
|
try {
|
|
810
803
|
const account = await this.getAccountByWorkspaceId(workspaceId);
|
|
811
|
-
return new featureSet_1.FeatureSet(new Set(
|
|
804
|
+
return new featureSet_1.FeatureSet(new Set(account.effective_features ?? []));
|
|
812
805
|
}
|
|
813
806
|
catch (error) {
|
|
814
807
|
throw toApiError(`Failed to get feature flags for workspace ${workspaceId}`, error);
|
|
815
808
|
}
|
|
816
809
|
}
|
|
817
810
|
async getEnabledLabsFeaturesForWorkspace(workspaceId) {
|
|
818
|
-
var _a;
|
|
819
811
|
try {
|
|
820
812
|
const workspace = await this.getWorkspace(workspaceId);
|
|
821
|
-
return new featureSet_1.FeatureSet(new Set(
|
|
813
|
+
return new featureSet_1.FeatureSet(new Set(workspace.labs_features ?? []));
|
|
822
814
|
}
|
|
823
815
|
catch (error) {
|
|
824
816
|
throw toApiError(`Failed to get labs features for workspace ${workspaceId}`, error);
|
|
@@ -830,7 +822,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
830
822
|
organization_id: workspaceId,
|
|
831
823
|
limit,
|
|
832
824
|
});
|
|
833
|
-
const users = await this.makeGetRequest(`${this.baseApiUrl}/users/?${userQueryString}`).then((result) =>
|
|
825
|
+
const users = await this.makeGetRequest(`${this.baseApiUrl}/users/?${userQueryString}`).then((result) => result.users ?? []);
|
|
834
826
|
sortTemporallyAscending(users);
|
|
835
827
|
return users;
|
|
836
828
|
}
|
|
@@ -843,7 +835,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
843
835
|
const stepIdsQueryString = query_string_1.default.stringify({
|
|
844
836
|
flow_variant_ids: [flowIds],
|
|
845
837
|
});
|
|
846
|
-
return await this.makeGetRequest(`${this.baseApiUrl}/test/journey/${journeyInvariantId}/stepIdsByFlow?${stepIdsQueryString}`).then((result) => result
|
|
838
|
+
return await this.makeGetRequest(`${this.baseApiUrl}/test/journey/${journeyInvariantId}/stepIdsByFlow?${stepIdsQueryString}`).then((result) => result ?? []);
|
|
847
839
|
}
|
|
848
840
|
catch (error) {
|
|
849
841
|
throw toApiError(`Failed to get step ids in journey by flow`, error);
|
|
@@ -858,7 +850,7 @@ class MablApiClient extends basicApiClient_1.BasicApiClient {
|
|
|
858
850
|
}
|
|
859
851
|
}
|
|
860
852
|
async recordWorkspaceTimeSeriesMetricMeasurement(type, value, workspaceId, options) {
|
|
861
|
-
const labels = { ...options
|
|
853
|
+
const labels = { ...options?.labels, workspaceId };
|
|
862
854
|
return this.recordTimeSeriesMetricMeasurement(type, value, {
|
|
863
855
|
...options,
|
|
864
856
|
labels,
|
|
@@ -870,9 +862,9 @@ function sortTemporallyAscending(entities) {
|
|
|
870
862
|
entities.sort((a, b) => (a.created_time >= b.created_time ? 1 : -1));
|
|
871
863
|
}
|
|
872
864
|
function toApiError(summary, cause) {
|
|
873
|
-
const errorResponse = cause
|
|
874
|
-
const code = errorResponse
|
|
875
|
-
const mablError = errorResponse
|
|
865
|
+
const errorResponse = cause?.response;
|
|
866
|
+
const code = errorResponse?.status;
|
|
867
|
+
const mablError = errorResponse?.data;
|
|
876
868
|
const message = `${summary}: ${mablError
|
|
877
869
|
? `${mablError.code}: ${mablError.message} (${mablError.id})`
|
|
878
870
|
: cause.toString()}`;
|
|
@@ -880,8 +872,8 @@ function toApiError(summary, cause) {
|
|
|
880
872
|
}
|
|
881
873
|
function createTimeSeriesMetricMeasurement(type, numberValue, options) {
|
|
882
874
|
return {
|
|
883
|
-
labels: options
|
|
884
|
-
event_time: options
|
|
875
|
+
labels: options?.labels,
|
|
876
|
+
event_time: options?.event_time,
|
|
885
877
|
type,
|
|
886
878
|
value: Number.isInteger(numberValue)
|
|
887
879
|
? { int64_value: numberValue }
|
|
@@ -47,7 +47,7 @@ class MablApiClientFactory {
|
|
|
47
47
|
}
|
|
48
48
|
const authProvider = new authenticationProvider_1.AuthenticationProvider();
|
|
49
49
|
const authConfig = await authProvider.getAuthConfigWithAutoRenew();
|
|
50
|
-
if (authConfig
|
|
50
|
+
if (authConfig?.accessToken) {
|
|
51
51
|
return new mablApiClient_1.MablApiClient({
|
|
52
52
|
...optsFromCliHttpConfig,
|
|
53
53
|
authType: authConfig.authType,
|
package/auth/OktaClient.js
CHANGED
|
@@ -64,7 +64,6 @@ class OktaClient extends AuthClient_1.AuthClient {
|
|
|
64
64
|
return authInfo;
|
|
65
65
|
}
|
|
66
66
|
exchangeRefreshTokenForAccessToken(refreshToken) {
|
|
67
|
-
var _a;
|
|
68
67
|
try {
|
|
69
68
|
return this.getBearerAuthInfo(queryString.stringify({
|
|
70
69
|
grant_type: 'refresh_token',
|
|
@@ -77,7 +76,7 @@ class OktaClient extends AuthClient_1.AuthClient {
|
|
|
77
76
|
if (!axios_1.default.isAxiosError(error)) {
|
|
78
77
|
throw error;
|
|
79
78
|
}
|
|
80
|
-
const data =
|
|
79
|
+
const data = error.response?.data;
|
|
81
80
|
if (!(0, authenticationProvider_1.isOidcError)(data)) {
|
|
82
81
|
throw error;
|
|
83
82
|
}
|
|
@@ -102,8 +102,7 @@ class ChromiumBrowserEngine {
|
|
|
102
102
|
return { commandLineArgs, defaultDeviceDescriptor };
|
|
103
103
|
}
|
|
104
104
|
addBasicLaunchArgs(launchArgs, browserWidth, browserHeight, fakeMicrophoneMediaPath, fakeWebcamMediaPath, ignoreCertificateErrors, deviceDescriptor) {
|
|
105
|
-
|
|
106
|
-
launchArgs.push(`--window-size=${(_a = deviceDescriptor === null || deviceDescriptor === void 0 ? void 0 : deviceDescriptor.width) !== null && _a !== void 0 ? _a : browserWidth},${(_b = deviceDescriptor === null || deviceDescriptor === void 0 ? void 0 : deviceDescriptor.height) !== null && _b !== void 0 ? _b : browserHeight}`);
|
|
105
|
+
launchArgs.push(`--window-size=${deviceDescriptor?.width ?? browserWidth},${deviceDescriptor?.height ?? browserHeight}`);
|
|
107
106
|
launchArgs.push('--use-fake-ui-for-media-stream');
|
|
108
107
|
launchArgs.push('--use-fake-device-for-media-stream');
|
|
109
108
|
launchArgs.push(`--use-file-for-fake-audio-capture=${fakeMicrophoneMediaPath}`);
|
|
@@ -52,11 +52,11 @@ class FirefoxBrowserEngine {
|
|
|
52
52
|
}
|
|
53
53
|
prepareBrowserPreferencesDirectory(_windowPlacement, proxyInfo) {
|
|
54
54
|
const customPreferences = {};
|
|
55
|
-
if (proxyInfo
|
|
55
|
+
if (proxyInfo?.pacProxy) {
|
|
56
56
|
customPreferences['network.proxy.autoconfig_url'] = proxyInfo.pacProxy;
|
|
57
57
|
customPreferences['network.proxy.type'] = 2;
|
|
58
58
|
}
|
|
59
|
-
else if (proxyInfo
|
|
59
|
+
else if (proxyInfo?.socksProxy) {
|
|
60
60
|
const socksUrl = new URL(proxyInfo.socksProxy);
|
|
61
61
|
customPreferences['network.proxy.socks'] = socksUrl.hostname;
|
|
62
62
|
customPreferences['network.proxy.socks_port'] = Number.parseInt(socksUrl.port);
|
|
@@ -37,11 +37,11 @@ class WebkitBrowserEngine {
|
|
|
37
37
|
}
|
|
38
38
|
getProxySpec(proxyInfo) {
|
|
39
39
|
const { httpProxy, socksProxy, excludeFromProxy } = proxyInfo;
|
|
40
|
-
const server = httpProxy
|
|
40
|
+
const server = httpProxy ?? socksProxy;
|
|
41
41
|
if (!server) {
|
|
42
42
|
throw new Error('no proxy provided for cloud run');
|
|
43
43
|
}
|
|
44
|
-
const bypass =
|
|
44
|
+
const bypass = excludeFromProxy?.length
|
|
45
45
|
? excludeFromProxy.join(',')
|
|
46
46
|
: undefined;
|
|
47
47
|
return { server, bypass };
|
|
@@ -11,14 +11,13 @@ const loggingProvider_1 = require("../providers/logging/loggingProvider");
|
|
|
11
11
|
const chalk_1 = __importDefault(require("chalk"));
|
|
12
12
|
class BrowserLauncherFactory {
|
|
13
13
|
static getRunnerFromEnvironment() {
|
|
14
|
-
|
|
15
|
-
return (_a = process.env.MABL_RUNNER) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
14
|
+
return process.env.MABL_RUNNER?.toLowerCase();
|
|
16
15
|
}
|
|
17
16
|
static createRunner(runnerType = types_1.RunnerType.Playwright, loggerFunc) {
|
|
18
17
|
const runnerFromEnv = BrowserLauncherFactory.getRunnerFromEnvironment();
|
|
19
18
|
const runner = runnerFromEnv ? runnerFromEnv : runnerType;
|
|
20
19
|
loggerFunc =
|
|
21
|
-
loggerFunc
|
|
20
|
+
loggerFunc ?? ((line) => (0, logUtils_1.logCliOutput)(loggingProvider_1.LogLevel.Info, line));
|
|
22
21
|
if (runner === types_1.RunnerType.Playwright) {
|
|
23
22
|
loggerFunc(chalk_1.default.cyan(`Browser launcher:`, chalk_1.default.magenta('Playwright')));
|
|
24
23
|
return new playwrightBrowserLauncher_1.PlaywrightBrowserLauncher();
|
|
@@ -11,9 +11,8 @@ const getHighlightColor = (transparency) => ({
|
|
|
11
11
|
exports.getHighlightColor = getHighlightColor;
|
|
12
12
|
function commonFocusAndSelect(element) {
|
|
13
13
|
return element.evaluate((element) => {
|
|
14
|
-
var _a;
|
|
15
14
|
element.focus();
|
|
16
|
-
|
|
15
|
+
element.select?.();
|
|
17
16
|
return element.value;
|
|
18
17
|
});
|
|
19
18
|
}
|
|
@@ -48,14 +48,13 @@ class ChromiumElementHandleDelegate {
|
|
|
48
48
|
return this.elementImpl;
|
|
49
49
|
}
|
|
50
50
|
checkCDPSession() {
|
|
51
|
-
var _a, _b, _c;
|
|
52
51
|
if (this.elementImpl === undefined) {
|
|
53
52
|
(0, logUtils_1.logInternal)(`Unable to get the Element's internal implementation. Some functionality, such as getting the clickable point or element highlighting might not work.`);
|
|
54
53
|
}
|
|
55
54
|
else if (this.getInternalCDPSession() === undefined) {
|
|
56
|
-
const undefinedField =
|
|
55
|
+
const undefinedField = this.elementImpl?._context?._delegate !== undefined
|
|
57
56
|
? '_client'
|
|
58
|
-
:
|
|
57
|
+
: this.elementImpl?._context !== undefined
|
|
59
58
|
? '_delegate'
|
|
60
59
|
: '_context';
|
|
61
60
|
(0, logUtils_1.logInternal)(`Unable to get the CDP Session of the element handle. ${undefinedField} is undefined. Some functionality, such as element highlighting will not work.`);
|
|
@@ -66,14 +65,13 @@ class ChromiumElementHandleDelegate {
|
|
|
66
65
|
return this.getInternalCDPSession();
|
|
67
66
|
}
|
|
68
67
|
async highlight(highlightDurationMillis, highlightPhases) {
|
|
69
|
-
var _a;
|
|
70
68
|
await this.enableDom();
|
|
71
69
|
await this.enableOverlay();
|
|
72
|
-
const nodeInfo = await
|
|
70
|
+
const nodeInfo = await this.getInternalCDPSession()?.send('DOM.describeNode', {
|
|
73
71
|
objectId: this.getRemoteObjectId(),
|
|
74
72
|
depth: -1,
|
|
75
73
|
pierce: true,
|
|
76
|
-
})
|
|
74
|
+
});
|
|
77
75
|
if (!nodeInfo) {
|
|
78
76
|
return;
|
|
79
77
|
}
|
|
@@ -89,43 +87,37 @@ class ChromiumElementHandleDelegate {
|
|
|
89
87
|
await this.hideHighlight();
|
|
90
88
|
}
|
|
91
89
|
async fadeInOutHighlight(highlightConfig, highlightDurationMillis, highlightPhases) {
|
|
92
|
-
var _a, _b;
|
|
93
90
|
if (highlightPhases <= 0) {
|
|
94
91
|
throw new Error('Highlight phases must be greater than 0');
|
|
95
92
|
}
|
|
96
93
|
const phaseIntervalMilliseconds = highlightDurationMillis / highlightPhases;
|
|
97
94
|
for (let iteration = 0; iteration < highlightPhases; iteration++) {
|
|
98
|
-
if (
|
|
95
|
+
if (highlightConfig.highlightConfig.contentColor?.a !== undefined) {
|
|
99
96
|
const x = iteration / highlightPhases;
|
|
100
97
|
highlightConfig.highlightConfig.contentColor.a =
|
|
101
98
|
x * (1 - x) * 4 * elementHandle_1.MAX_HIGHLIGHT_OPACITY;
|
|
102
99
|
}
|
|
103
|
-
await
|
|
100
|
+
await this.getInternalCDPSession()?.send('Overlay.highlightNode', highlightConfig);
|
|
104
101
|
await (0, testsUtil_1.sleep)(phaseIntervalMilliseconds);
|
|
105
102
|
}
|
|
106
103
|
}
|
|
107
104
|
async enableDom() {
|
|
108
|
-
|
|
109
|
-
await ((_a = this.getInternalCDPSession()) === null || _a === void 0 ? void 0 : _a.send('DOM.enable'));
|
|
105
|
+
await this.getInternalCDPSession()?.send('DOM.enable');
|
|
110
106
|
}
|
|
111
107
|
async enableOverlay() {
|
|
112
|
-
|
|
113
|
-
await ((_a = this.getInternalCDPSession()) === null || _a === void 0 ? void 0 : _a.send('Overlay.enable'));
|
|
108
|
+
await this.getInternalCDPSession()?.send('Overlay.enable');
|
|
114
109
|
}
|
|
115
110
|
async hideHighlight() {
|
|
116
|
-
|
|
117
|
-
await ((_a = this.getInternalCDPSession()) === null || _a === void 0 ? void 0 : _a.send('Overlay.hideHighlight'));
|
|
111
|
+
await this.getInternalCDPSession()?.send('Overlay.hideHighlight');
|
|
118
112
|
}
|
|
119
113
|
getRemoteObjectId() {
|
|
120
|
-
|
|
121
|
-
if (((_a = this.getElementImpl()) === null || _a === void 0 ? void 0 : _a._objectId) === undefined) {
|
|
114
|
+
if (this.getElementImpl()?._objectId === undefined) {
|
|
122
115
|
(0, logUtils_1.logInternal)('ObjectId of an element handle was not found.');
|
|
123
116
|
}
|
|
124
|
-
return
|
|
117
|
+
return this.getElementImpl()?._objectId ?? '';
|
|
125
118
|
}
|
|
126
119
|
getInternalCDPSession() {
|
|
127
|
-
|
|
128
|
-
return (_c = (_b = (_a = this.elementImpl) === null || _a === void 0 ? void 0 : _a._context) === null || _b === void 0 ? void 0 : _b._delegate) === null || _c === void 0 ? void 0 : _c._client;
|
|
120
|
+
return this.elementImpl?._context?._delegate?._client;
|
|
129
121
|
}
|
|
130
122
|
}
|
|
131
123
|
exports.ChromiumElementHandleDelegate = ChromiumElementHandleDelegate;
|
|
@@ -14,7 +14,7 @@ class ChromiumFrameDelegate {
|
|
|
14
14
|
}
|
|
15
15
|
getLifecycleEventStrategy(value) {
|
|
16
16
|
const waitForNetworkIdle = value === types_1.LifecycleEvent.NetworkIdle;
|
|
17
|
-
let waitUntil = value
|
|
17
|
+
let waitUntil = value ?? types_1.LifecycleEvent.Load;
|
|
18
18
|
if (waitForNetworkIdle) {
|
|
19
19
|
waitUntil = types_1.LifecycleEvent.Load;
|
|
20
20
|
}
|