@mablhq/mabl-cli 1.10.10 → 1.11.15
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/browserLauncher/elementHandle.js +11 -0
- package/browserLauncher/playwrightBrowserLauncher/internals.js +2 -0
- package/browserLauncher/playwrightBrowserLauncher/playwrightBrowser.js +9 -13
- package/browserLauncher/playwrightBrowserLauncher/playwrightBrowserLauncher.js +16 -8
- package/browserLauncher/playwrightBrowserLauncher/playwrightFrame.js +1 -1
- package/browserLauncher/playwrightBrowserLauncher/playwrightHttpRequest.js +46 -8
- package/browserLauncher/playwrightBrowserLauncher/playwrightHttpResponse.js +6 -5
- package/browserLauncher/playwrightBrowserLauncher/playwrightPage.js +55 -28
- package/browserLauncher/puppeteerBrowserLauncher/internals.js +2 -0
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerBrowserLauncher.js +4 -1
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerHttpRequest.js +3 -0
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerPage.js +24 -10
- package/commands/commandUtil/awaitCompletion.js +4 -2
- package/commands/commandUtil/codeInsights.js +5 -2
- package/commands/deploy/deploy_cmds/create.js +2 -2
- package/commands/tests/mobileEmulationUtil.js +3 -3
- package/commands/tests/testsUtil.js +33 -21
- package/commands/tests/tests_cmds/import.js +10 -1
- package/core/execution/ApiTestUtils.js +18 -0
- package/domUtil/index.js +2 -0
- package/domUtil/index.js.LICENSE.txt +14 -0
- package/execution/index.js +1 -1
- package/mablscript/actions/JavaScriptAction.js +101 -38
- package/mablscript/types/ConditionDescriptor.js +6 -1
- package/mablscript/types/JavaScriptDescriptor.js +25 -9
- package/package.json +2 -2
- package/providers/exportRequestProvider.js +4 -2
|
@@ -42,6 +42,7 @@ const logLineMessaging_1 = require("../../core/messaging/logLineMessaging");
|
|
|
42
42
|
const resourceUtil_1 = require("../../util/resourceUtil");
|
|
43
43
|
const mobileEmulationUtil_1 = require("./mobileEmulationUtil");
|
|
44
44
|
const browserLauncher_1 = require("../../browserLauncher/browserLauncher");
|
|
45
|
+
const stream_1 = require("stream");
|
|
45
46
|
const chalk = require('chalk');
|
|
46
47
|
const chromeFinder = require('chrome-launcher/dist/chrome-finder');
|
|
47
48
|
const launchUtils = require('chrome-launcher/dist/utils');
|
|
@@ -128,16 +129,16 @@ async function createBrowserWithAuthedExtension(accessToken, browserWidth, brows
|
|
|
128
129
|
return maybeBrowser;
|
|
129
130
|
}
|
|
130
131
|
exports.createBrowserWithAuthedExtension = createBrowserWithAuthedExtension;
|
|
131
|
-
async function launchBrowserInstance(chromePath, launchArgs, userDataDir, headless, credentials,
|
|
132
|
+
async function launchBrowserInstance(chromePath, launchArgs, userDataDir, headless, credentials, defaultDeviceDescriptor, ignoreDefaultArgs) {
|
|
132
133
|
let browser;
|
|
133
134
|
try {
|
|
134
|
-
browser = await maybeLaunchBrowser(chromePath, launchArgs, userDataDir, headless, credentials,
|
|
135
|
+
browser = await maybeLaunchBrowser(chromePath, launchArgs, userDataDir, headless, credentials, defaultDeviceDescriptor, ignoreDefaultArgs);
|
|
135
136
|
}
|
|
136
137
|
catch (error) {
|
|
137
138
|
if (error.message.includes('Running as root without --no-sandbox is not supported')) {
|
|
138
139
|
launchArgs.push('--no-sandbox');
|
|
139
140
|
messaging_1.mablEventEmitter.log('Unable to initialize browser with standard settings, attempting to run with --no-sandbox setting', Date.now(), logLineMessaging_1.LogLineColor.yellow);
|
|
140
|
-
return maybeLaunchBrowser(chromePath, launchArgs, userDataDir, headless, credentials,
|
|
141
|
+
return maybeLaunchBrowser(chromePath, launchArgs, userDataDir, headless, credentials, defaultDeviceDescriptor, ignoreDefaultArgs).catch(error => {
|
|
141
142
|
messaging_1.mablEventEmitter.log('Browser launch failed', Date.now(), logLineMessaging_1.LogLineColor.red);
|
|
142
143
|
messaging_1.mablEventEmitter.log(error.message);
|
|
143
144
|
});
|
|
@@ -145,9 +146,9 @@ async function launchBrowserInstance(chromePath, launchArgs, userDataDir, headle
|
|
|
145
146
|
}
|
|
146
147
|
return browser;
|
|
147
148
|
}
|
|
148
|
-
function maybeLaunchBrowser(chromePath, launchArgs, userDataDir, headless, credentials,
|
|
149
|
+
function maybeLaunchBrowser(chromePath, launchArgs, userDataDir, headless, credentials, defaultDeviceDescriptor, ignoreDefaultArgs) {
|
|
149
150
|
return browserLauncher_1.BrowserLauncherFactory.createRunner().launch({
|
|
150
|
-
|
|
151
|
+
defaultDeviceDescriptor,
|
|
151
152
|
executablePath: chromePath,
|
|
152
153
|
headless,
|
|
153
154
|
args: launchArgs,
|
|
@@ -196,12 +197,12 @@ async function createBrowser(browserWidth, browserHeight, headless, containerTes
|
|
|
196
197
|
launchArgs.push(`--disable-features=${disableFeaturesFlags.join(',')}`);
|
|
197
198
|
const fakeMicrophoneMedia = resourceUtil_1.findResource('media/mabl_test_audio.wav');
|
|
198
199
|
const fakeWebcamMedia = resourceUtil_1.findResource('media/mabl_test_pattern.y4m');
|
|
199
|
-
const
|
|
200
|
+
const defaultDeviceDescriptor = addLaunchArgs(launchArgs, browserWidth, browserHeight, fakeMicrophoneMedia, fakeWebcamMedia, ignoreCertificateErrors, emulationConfig);
|
|
200
201
|
let ignoreDefaultArgs;
|
|
201
202
|
if (enableExtensions) {
|
|
202
203
|
ignoreDefaultArgs = ['--disable-extensions'];
|
|
203
204
|
}
|
|
204
|
-
const maybeBrowser = await launchBrowserInstance(chromePath, launchArgs, tempBrowserPreferencesDirectory, headless, credentials,
|
|
205
|
+
const maybeBrowser = await launchBrowserInstance(chromePath, launchArgs, tempBrowserPreferencesDirectory, headless, credentials, defaultDeviceDescriptor, ignoreDefaultArgs);
|
|
205
206
|
if (!maybeBrowser) {
|
|
206
207
|
throw new Error('Unable to start Chrome session');
|
|
207
208
|
}
|
|
@@ -211,8 +212,8 @@ async function createBrowser(browserWidth, browserHeight, headless, containerTes
|
|
|
211
212
|
exports.createBrowser = createBrowser;
|
|
212
213
|
function addLaunchArgs(launchArgs, browserWidth, browserHeight, fakeMicrophoneMediaPath, fakeWebcamMediaPath, ignoreCertificateErrors, emulationConfig) {
|
|
213
214
|
var _a, _b;
|
|
214
|
-
const
|
|
215
|
-
launchArgs.push(`--window-size=${(_a =
|
|
215
|
+
const defaultDeviceDescriptor = mobileEmulationUtil_1.getDeviceDescriptorForEmulation(emulationConfig);
|
|
216
|
+
launchArgs.push(`--window-size=${(_a = defaultDeviceDescriptor === null || defaultDeviceDescriptor === void 0 ? void 0 : defaultDeviceDescriptor.width) !== null && _a !== void 0 ? _a : browserWidth},${(_b = defaultDeviceDescriptor === null || defaultDeviceDescriptor === void 0 ? void 0 : defaultDeviceDescriptor.height) !== null && _b !== void 0 ? _b : browserHeight}`);
|
|
216
217
|
if (emulationConfig === null || emulationConfig === void 0 ? void 0 : emulationConfig.device_config.user_agent) {
|
|
217
218
|
launchArgs.push(`--user-agent=${emulationConfig === null || emulationConfig === void 0 ? void 0 : emulationConfig.device_config.user_agent}`);
|
|
218
219
|
}
|
|
@@ -224,7 +225,7 @@ function addLaunchArgs(launchArgs, browserWidth, browserHeight, fakeMicrophoneMe
|
|
|
224
225
|
if (ignoreCertificateErrors) {
|
|
225
226
|
launchArgs.push('--ignore-certificate-errors');
|
|
226
227
|
}
|
|
227
|
-
return
|
|
228
|
+
return defaultDeviceDescriptor;
|
|
228
229
|
}
|
|
229
230
|
function addExecutionEngineLaunchArgs(browserWidth, browserHeight, proxyInfo, emulationConfig) {
|
|
230
231
|
const launchArgs = [...baseExecutionEngineLaunchArgs];
|
|
@@ -237,15 +238,15 @@ function addExecutionEngineLaunchArgs(browserWidth, browserHeight, proxyInfo, em
|
|
|
237
238
|
else {
|
|
238
239
|
throw new Error('no proxy provided for cloud run');
|
|
239
240
|
}
|
|
240
|
-
const
|
|
241
|
+
const defaultDeviceDescriptor = addLaunchArgs(launchArgs, browserWidth, browserHeight, ExecutionEngineFakeAudioFilePath, ExecutionEngineFakeVideoFilePath, true, emulationConfig);
|
|
241
242
|
loggingProvider_1.logger.debug(`launchArgs: ${JSON.stringify(launchArgs)}`);
|
|
242
|
-
return {
|
|
243
|
+
return { defaultDeviceDescriptor, launchArgs };
|
|
243
244
|
}
|
|
244
245
|
exports.addExecutionEngineLaunchArgs = addExecutionEngineLaunchArgs;
|
|
245
246
|
async function createBrowserForExecutionEngine(browserWidth, browserHeight, headless, tempBrowserPreferencesDirectory, proxyInfo, credentials, browserPath, emulationConfig) {
|
|
246
247
|
const chromePath = browserPath !== null && browserPath !== void 0 ? browserPath : findChrome();
|
|
247
|
-
const { launchArgs,
|
|
248
|
-
const maybeBrowser = await maybeLaunchBrowser(chromePath, launchArgs, tempBrowserPreferencesDirectory, headless, credentials,
|
|
248
|
+
const { launchArgs, defaultDeviceDescriptor } = addExecutionEngineLaunchArgs(browserWidth, browserHeight, proxyInfo, emulationConfig);
|
|
249
|
+
const maybeBrowser = await maybeLaunchBrowser(chromePath, launchArgs, tempBrowserPreferencesDirectory, headless, credentials, defaultDeviceDescriptor);
|
|
249
250
|
if (!maybeBrowser) {
|
|
250
251
|
throw new Error('Unable to start Chrome session');
|
|
251
252
|
}
|
|
@@ -253,18 +254,18 @@ async function createBrowserForExecutionEngine(browserWidth, browserHeight, head
|
|
|
253
254
|
}
|
|
254
255
|
exports.createBrowserForExecutionEngine = createBrowserForExecutionEngine;
|
|
255
256
|
async function connectToExistingBrowser(port, browserHeight, browserWidth, currentDownloadPath) {
|
|
256
|
-
const
|
|
257
|
+
const defaultDeviceDescriptor = {
|
|
257
258
|
width: browserWidth,
|
|
258
259
|
height: browserHeight,
|
|
259
260
|
};
|
|
260
261
|
const response = await axios_1.default.get(`http://localhost:${port}/json/version`);
|
|
261
262
|
const url = response.data.webSocketDebuggerUrl;
|
|
262
|
-
return connectToExistingBrowserWebsocket(url, currentDownloadPath,
|
|
263
|
+
return connectToExistingBrowserWebsocket(url, currentDownloadPath, defaultDeviceDescriptor);
|
|
263
264
|
}
|
|
264
265
|
exports.connectToExistingBrowser = connectToExistingBrowser;
|
|
265
|
-
function connectToExistingBrowserWebsocket(websocketEndpoint, currentDownloadPath,
|
|
266
|
+
function connectToExistingBrowserWebsocket(websocketEndpoint, currentDownloadPath, defaultDeviceDescriptor) {
|
|
266
267
|
return browserLauncher_1.BrowserLauncherFactory.createRunner().connect({
|
|
267
|
-
|
|
268
|
+
defaultDeviceDescriptor,
|
|
268
269
|
browserWSEndpoint: websocketEndpoint,
|
|
269
270
|
}, currentDownloadPath);
|
|
270
271
|
}
|
|
@@ -505,8 +506,14 @@ function handleExtensionMessage(message, trainingBrowser) {
|
|
|
505
506
|
break;
|
|
506
507
|
}
|
|
507
508
|
}
|
|
508
|
-
async function downloadUploadFile(fileUploadUrl, fileUpload, downloadDirectory) {
|
|
509
|
-
|
|
509
|
+
async function downloadUploadFile(fileUploadUrl, fileUpload, downloadDirectory, mablApiClient) {
|
|
510
|
+
let client;
|
|
511
|
+
if (mablApiClient) {
|
|
512
|
+
client = mablApiClient.httpClient;
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
client = axios_1.default.create(httpUtil_1.currentProxyConfig());
|
|
516
|
+
}
|
|
510
517
|
try {
|
|
511
518
|
const finalDirectory = path.normalize(`${downloadDirectory}/${fileUpload.id}`);
|
|
512
519
|
try {
|
|
@@ -522,7 +529,12 @@ async function downloadUploadFile(fileUploadUrl, fileUpload, downloadDirectory)
|
|
|
522
529
|
const response = await client.get(fileUploadUrl, {
|
|
523
530
|
responseType: 'stream',
|
|
524
531
|
});
|
|
525
|
-
response.data.pipe
|
|
532
|
+
if (response.data.pipe) {
|
|
533
|
+
response.data.pipe(writer);
|
|
534
|
+
}
|
|
535
|
+
else if (!(response.status >= 400)) {
|
|
536
|
+
stream_1.Readable.from(response.data).pipe(writer);
|
|
537
|
+
}
|
|
526
538
|
return new Promise((resolve, reject) => {
|
|
527
539
|
writer.on('finish', () => resolve(finalPath));
|
|
528
540
|
writer.on('error', reject);
|
|
@@ -161,7 +161,16 @@ async function importTests(port, debug, importMultipleTests) {
|
|
|
161
161
|
loggingProvider_1.logger.info('Import will end automatically when the Selenium session is closed or CTRL+C is pressed');
|
|
162
162
|
await Promise.race([importCancelPromise, sessionClosedPromise]);
|
|
163
163
|
}
|
|
164
|
-
Timers.setImmediate(() =>
|
|
164
|
+
Timers.setImmediate(async () => {
|
|
165
|
+
try {
|
|
166
|
+
await seleniumProxy.stop();
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
if (debug) {
|
|
170
|
+
loggingProvider_1.logger.error(`Error stopping selenium proxy: ${error}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
});
|
|
165
174
|
return importedTests;
|
|
166
175
|
}
|
|
167
176
|
async function handlePostImportActions(workspaceId, name, apiClient, importedTests, autoSave) {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deduplicateApiTestExecutionResults = void 0;
|
|
4
|
+
function deduplicateApiTestExecutionResults(postmanResult) {
|
|
5
|
+
var _a;
|
|
6
|
+
const executionsById = {};
|
|
7
|
+
const orderedExecutionIds = [];
|
|
8
|
+
(_a = postmanResult.run.executions) === null || _a === void 0 ? void 0 : _a.forEach(execution => {
|
|
9
|
+
const executionId = execution.id;
|
|
10
|
+
if (!executionsById[executionId]) {
|
|
11
|
+
orderedExecutionIds.push(executionId);
|
|
12
|
+
}
|
|
13
|
+
executionsById[executionId] = execution;
|
|
14
|
+
});
|
|
15
|
+
postmanResult.run.executions = orderedExecutionIds.map(executionId => executionsById[executionId]);
|
|
16
|
+
return postmanResult;
|
|
17
|
+
}
|
|
18
|
+
exports.deduplicateApiTestExecutionResults = deduplicateApiTestExecutionResults;
|