@midscene/cli 1.10.12-beta-20260813050119.0 → 1.10.12
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/dist/es/framework/index.mjs +27 -77
- package/dist/es/framework/index.mjs.map +1 -1
- package/dist/es/index.mjs +31 -79
- package/dist/es/index.mjs.map +1 -1
- package/dist/lib/framework/index.js +26 -76
- package/dist/lib/framework/index.js.map +1 -1
- package/dist/lib/index.js +30 -78
- package/dist/lib/index.js.map +1 -1
- package/package.json +8 -8
|
@@ -7,7 +7,7 @@ import { ReportMergingTool } from "@midscene/core";
|
|
|
7
7
|
import { getMidsceneRunSubDir } from "@midscene/shared/common";
|
|
8
8
|
import { getDebug } from "@midscene/shared/logger";
|
|
9
9
|
import { ScriptPlayer, parseYamlScript, resolveWebTarget } from "@midscene/core/yaml";
|
|
10
|
-
import { buildChromeArgs, buildDownloadBehavior,
|
|
10
|
+
import { buildChromeArgs, buildDownloadBehavior, defaultViewportHeight, defaultViewportWidth, puppeteerAgentForTarget } from "@midscene/web/puppeteer-agent-launcher";
|
|
11
11
|
import lodash_merge from "lodash.merge";
|
|
12
12
|
import puppeteer from "puppeteer";
|
|
13
13
|
import { createServer } from "http-server";
|
|
@@ -2403,13 +2403,10 @@ function createNotExecutedYamlResult(file) {
|
|
|
2403
2403
|
error: notExecutedError
|
|
2404
2404
|
};
|
|
2405
2405
|
}
|
|
2406
|
-
function isYamlPlayerSuccessful(player) {
|
|
2407
|
-
return 'error' !== player.status && !player.taskStatusList?.some((task)=>'error' === task.status);
|
|
2408
|
-
}
|
|
2409
2406
|
function createExecutedYamlResult(options) {
|
|
2410
2407
|
const { file, player, duration } = options;
|
|
2408
|
+
const hasFailedTasks = player.taskStatusList?.some((task)=>'error' === task.status) ?? false;
|
|
2411
2409
|
const hasPlayerError = 'error' === player.status;
|
|
2412
|
-
const hasFailedTasks = !isYamlPlayerSuccessful(player) && !hasPlayerError;
|
|
2413
2410
|
let success;
|
|
2414
2411
|
let resultType;
|
|
2415
2412
|
if (hasPlayerError) {
|
|
@@ -2823,7 +2820,7 @@ async function createYamlPlayer(file, script, options) {
|
|
|
2823
2820
|
const { agent, freeFn: newFreeFn } = await puppeteerAgentForTarget(webTarget, {
|
|
2824
2821
|
...preference,
|
|
2825
2822
|
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
2826
|
-
}, cdpBrowser, options?.page
|
|
2823
|
+
}, cdpBrowser, options?.page);
|
|
2827
2824
|
const cleanFreeFn = newFreeFn.filter((f)=>'puppeteer_browser' !== f.name);
|
|
2828
2825
|
if (!options?.browser) cleanFreeFn.push({
|
|
2829
2826
|
name: 'cdp_browser_disconnect',
|
|
@@ -2839,7 +2836,7 @@ async function createYamlPlayer(file, script, options) {
|
|
|
2839
2836
|
const { agent, freeFn: newFreeFn } = await puppeteerAgentForTarget(webTarget, {
|
|
2840
2837
|
...preference,
|
|
2841
2838
|
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
2842
|
-
}, options?.browser, options?.page
|
|
2839
|
+
}, options?.browser, options?.page);
|
|
2843
2840
|
freeFn.push(...newFreeFn);
|
|
2844
2841
|
return {
|
|
2845
2842
|
agent,
|
|
@@ -3418,9 +3415,6 @@ function yaml_batch_executor_define_property(obj, key, value) {
|
|
|
3418
3415
|
else obj[key] = value;
|
|
3419
3416
|
return obj;
|
|
3420
3417
|
}
|
|
3421
|
-
const batchWarning = getDebug('yaml-batch-executor', {
|
|
3422
|
-
console: true
|
|
3423
|
-
});
|
|
3424
3418
|
class YamlBatchExecutor {
|
|
3425
3419
|
async run(options = {}) {
|
|
3426
3420
|
const generateSummary = options.generateSummary ?? true;
|
|
@@ -3432,6 +3426,7 @@ class YamlBatchExecutor {
|
|
|
3432
3426
|
let setupContext;
|
|
3433
3427
|
const fileContextList = [];
|
|
3434
3428
|
let browser = null;
|
|
3429
|
+
let sharedPage = null;
|
|
3435
3430
|
try {
|
|
3436
3431
|
if (setup) {
|
|
3437
3432
|
const fileConfig = await this.loadFileConfig(setup);
|
|
@@ -3487,7 +3482,11 @@ class YamlBatchExecutor {
|
|
|
3487
3482
|
acceptInsecureCerts: globalWebConfig?.acceptInsecureCerts
|
|
3488
3483
|
});
|
|
3489
3484
|
}
|
|
3490
|
-
|
|
3485
|
+
sharedPage = await browser.newPage();
|
|
3486
|
+
for (const context of allContexts){
|
|
3487
|
+
context.options.browser = browser;
|
|
3488
|
+
context.options.page = sharedPage;
|
|
3489
|
+
}
|
|
3491
3490
|
}
|
|
3492
3491
|
const { executedResults, notExecutedContexts } = await this.executeFiles(setupContext, fileContextList);
|
|
3493
3492
|
this.results = await this.processResults(executedResults, notExecutedContexts);
|
|
@@ -3545,7 +3544,7 @@ class YamlBatchExecutor {
|
|
|
3545
3544
|
ttyRenderer.start();
|
|
3546
3545
|
}
|
|
3547
3546
|
try {
|
|
3548
|
-
const executeFile = async (context
|
|
3547
|
+
const executeFile = async (context)=>{
|
|
3549
3548
|
const allFileContext = allFileContexts.find((c)=>c.file === context.file);
|
|
3550
3549
|
if (!allFileContext) throw new Error(`Player not found for file: ${context.file}`);
|
|
3551
3550
|
if (!isTTY) {
|
|
@@ -3553,44 +3552,23 @@ class YamlBatchExecutor {
|
|
|
3553
3552
|
console.log(mergedText);
|
|
3554
3553
|
}
|
|
3555
3554
|
if (context.outputPath) allFileContext.player.output = context.outputPath;
|
|
3556
|
-
const
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
};
|
|
3568
|
-
if (!isTTY) console.log(contextTaskListSummary(allFileContext.player.taskStatusList, executedContext));
|
|
3569
|
-
return executedContext;
|
|
3570
|
-
} catch (error) {
|
|
3571
|
-
executionFailed = true;
|
|
3572
|
-
throw error;
|
|
3573
|
-
} finally{
|
|
3574
|
-
if (ownedPage && !keepPageOpen && !this.config.keepWindow) await this.closePage(ownedPage, executionFailed);
|
|
3575
|
-
}
|
|
3555
|
+
const startTime = Date.now();
|
|
3556
|
+
await allFileContext.player.run();
|
|
3557
|
+
const endTime = Date.now();
|
|
3558
|
+
const duration = endTime - startTime;
|
|
3559
|
+
const executedContext = {
|
|
3560
|
+
file: context.file,
|
|
3561
|
+
player: allFileContext.player,
|
|
3562
|
+
duration
|
|
3563
|
+
};
|
|
3564
|
+
if (!isTTY) console.log(contextTaskListSummary(allFileContext.player.taskStatusList, executedContext));
|
|
3565
|
+
return executedContext;
|
|
3576
3566
|
};
|
|
3577
3567
|
let setupFailed = false;
|
|
3578
3568
|
if (setupContext) {
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
executedResults.push(executedContext);
|
|
3583
|
-
setupFailed = !isYamlPlayerSuccessful(executedContext.player);
|
|
3584
|
-
if (!setupFailed && setupContext.options.page) {
|
|
3585
|
-
const sessionStorageSnapshot = await captureSessionStorageSnapshot(setupContext.options.page);
|
|
3586
|
-
for (const context of fileContextList)context.options.sessionStorageSnapshot = sessionStorageSnapshot;
|
|
3587
|
-
}
|
|
3588
|
-
} catch (error) {
|
|
3589
|
-
setupExecutionFailed = true;
|
|
3590
|
-
throw error;
|
|
3591
|
-
} finally{
|
|
3592
|
-
if (setupContext.options.page && !this.config.keepWindow) await this.closePage(setupContext.options.page, setupExecutionFailed);
|
|
3593
|
-
}
|
|
3569
|
+
const executedContext = await executeFile(setupContext);
|
|
3570
|
+
executedResults.push(executedContext);
|
|
3571
|
+
setupFailed = 'error' === executedContext.player.status;
|
|
3594
3572
|
}
|
|
3595
3573
|
if (setupFailed) for (const context of fileContextList)notExecutedContexts.push({
|
|
3596
3574
|
file: context.file,
|
|
@@ -3609,32 +3587,6 @@ class YamlBatchExecutor {
|
|
|
3609
3587
|
notExecutedContexts
|
|
3610
3588
|
};
|
|
3611
3589
|
}
|
|
3612
|
-
async createPageForContext(context) {
|
|
3613
|
-
const webTarget = resolveWebTarget(context.executionConfig)?.target;
|
|
3614
|
-
if (!context.options.browser || !webTarget || webTarget.bridgeMode) return;
|
|
3615
|
-
const page = await context.options.browser.newPage();
|
|
3616
|
-
context.options.page = page;
|
|
3617
|
-
return page;
|
|
3618
|
-
}
|
|
3619
|
-
async closePage(page, preservePriorError = false) {
|
|
3620
|
-
try {
|
|
3621
|
-
if (!page.isClosed()) await page.close();
|
|
3622
|
-
} catch (error) {
|
|
3623
|
-
if (preservePriorError) return void batchWarning('failed to close a YAML execution page after execution had already failed; preserving the original error', error);
|
|
3624
|
-
throw new Error('Failed to close a YAML execution page', {
|
|
3625
|
-
cause: error
|
|
3626
|
-
});
|
|
3627
|
-
}
|
|
3628
|
-
}
|
|
3629
|
-
throwUnexpectedExecutionError(settledResults) {
|
|
3630
|
-
const rejected = settledResults.find((result)=>'rejected' === result.status);
|
|
3631
|
-
if (rejected) {
|
|
3632
|
-
if (rejected.reason instanceof Error) throw rejected.reason;
|
|
3633
|
-
throw new Error('Unexpected YAML execution failure', {
|
|
3634
|
-
cause: rejected.reason
|
|
3635
|
-
});
|
|
3636
|
-
}
|
|
3637
|
-
}
|
|
3638
3590
|
async executeConcurrently(fileContextList, executeFile, executedResults, notExecutedContexts) {
|
|
3639
3591
|
const limit = pLimit(this.config.concurrent);
|
|
3640
3592
|
if (this.config.continueOnError) {
|
|
@@ -3642,8 +3594,7 @@ class YamlBatchExecutor {
|
|
|
3642
3594
|
const executedContext = await executeFile(context);
|
|
3643
3595
|
executedResults.push(executedContext);
|
|
3644
3596
|
}));
|
|
3645
|
-
|
|
3646
|
-
this.throwUnexpectedExecutionError(settledResults);
|
|
3597
|
+
await Promise.allSettled(tasks);
|
|
3647
3598
|
} else {
|
|
3648
3599
|
let shouldStop = false;
|
|
3649
3600
|
const stopLock = {
|
|
@@ -3661,8 +3612,7 @@ class YamlBatchExecutor {
|
|
|
3661
3612
|
shouldStop = true;
|
|
3662
3613
|
}
|
|
3663
3614
|
}));
|
|
3664
|
-
|
|
3665
|
-
this.throwUnexpectedExecutionError(settledResults);
|
|
3615
|
+
await Promise.allSettled(tasks);
|
|
3666
3616
|
if (shouldStop) {
|
|
3667
3617
|
for (const context of fileContextList)if (!executedResults.some((r)=>r.file === context.file) && !notExecutedContexts.some((ctx)=>ctx.file === context.file)) notExecutedContexts.push({
|
|
3668
3618
|
file: context.file,
|