@midscene/cli 1.12.10-beta-20260920031616.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/framework/index.mjs +16 -279
- package/dist/es/framework/index.mjs.map +1 -1
- package/dist/es/index.mjs +59 -285
- package/dist/es/index.mjs.map +1 -1
- package/dist/lib/framework/index.js +16 -281
- package/dist/lib/framework/index.js.map +1 -1
- package/dist/lib/index.js +56 -284
- package/dist/lib/index.js.map +1 -1
- package/package.json +22 -8
package/dist/lib/index.js
CHANGED
|
@@ -3014,7 +3014,6 @@ var __webpack_modules__ = {
|
|
|
3014
3014
|
});
|
|
3015
3015
|
var external_node_fs_ = __webpack_require__("node:fs");
|
|
3016
3016
|
var external_node_path_ = __webpack_require__("node:path");
|
|
3017
|
-
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_);
|
|
3018
3017
|
const external_node_crypto_namespaceObject = require("node:crypto");
|
|
3019
3018
|
var core_ = __webpack_require__("@midscene/core");
|
|
3020
3019
|
const common_namespaceObject = require("@midscene/shared/common");
|
|
@@ -3479,282 +3478,7 @@ var __webpack_modules__ = {
|
|
|
3479
3478
|
}
|
|
3480
3479
|
const external_puppeteer_namespaceObject = require("puppeteer");
|
|
3481
3480
|
var external_puppeteer_default = /*#__PURE__*/ __webpack_require__.n(external_puppeteer_namespaceObject);
|
|
3482
|
-
const
|
|
3483
|
-
const external_node_assert_namespaceObject = require("node:assert");
|
|
3484
|
-
var external_node_assert_default = /*#__PURE__*/ __webpack_require__.n(external_node_assert_namespaceObject);
|
|
3485
|
-
const agent_namespaceObject = require("@midscene/core/agent");
|
|
3486
|
-
const utils_namespaceObject = require("@midscene/core/utils");
|
|
3487
|
-
const bridge_mode_namespaceObject = require("@midscene/web/bridge-mode");
|
|
3488
|
-
const debug = (0, logger_.getDebug)('create-yaml-player');
|
|
3489
|
-
const cleanupWarning = (0, logger_.getDebug)('create-yaml-player', {
|
|
3490
|
-
console: true
|
|
3491
|
-
});
|
|
3492
|
-
async function cleanupFailedPlayerSetup(freeFn) {
|
|
3493
|
-
for (const cleanup of [
|
|
3494
|
-
...freeFn
|
|
3495
|
-
].reverse())try {
|
|
3496
|
-
await cleanup.fn();
|
|
3497
|
-
} catch (error) {
|
|
3498
|
-
cleanupWarning(`failed to run ${cleanup.name} after YAML player setup failed`, error);
|
|
3499
|
-
}
|
|
3500
|
-
}
|
|
3501
|
-
const launchServer = async (dir)=>new Promise((resolve)=>{
|
|
3502
|
-
const server = (0, external_http_server_namespaceObject.createServer)({
|
|
3503
|
-
root: dir
|
|
3504
|
-
});
|
|
3505
|
-
server.listen(0, '127.0.0.1', ()=>{
|
|
3506
|
-
resolve(server);
|
|
3507
|
-
});
|
|
3508
|
-
});
|
|
3509
|
-
function resolveReportFileName(yamlReportFileName, cliTestId, yamlTestId, fileName) {
|
|
3510
|
-
if (void 0 !== yamlReportFileName) return yamlReportFileName;
|
|
3511
|
-
const baseName = cliTestId ?? yamlTestId ?? fileName;
|
|
3512
|
-
return (0, agent_namespaceObject.getReportFileName)(baseName);
|
|
3513
|
-
}
|
|
3514
|
-
function buildAgentOptions(yamlAgent, reportFileName, fileName) {
|
|
3515
|
-
return {
|
|
3516
|
-
...yamlAgent || {},
|
|
3517
|
-
cache: (0, utils_namespaceObject.processCacheConfig)(yamlAgent?.cache, fileName),
|
|
3518
|
-
reportFileName
|
|
3519
|
-
};
|
|
3520
|
-
}
|
|
3521
|
-
async function create_yaml_player_createYamlPlayer(file, script, options) {
|
|
3522
|
-
const yamlScript = script || (0, yaml_.parseYamlScript)((0, external_node_fs_.readFileSync)(file, 'utf-8'), file);
|
|
3523
|
-
const clonedYamlScript = structuredClone(yamlScript);
|
|
3524
|
-
const fileName = (0, external_node_path_.basename)(file, (0, external_node_path_.extname)(file));
|
|
3525
|
-
const preference = {
|
|
3526
|
-
headed: options?.headed,
|
|
3527
|
-
keepWindow: options?.keepWindow,
|
|
3528
|
-
reportFileName: resolveReportFileName(clonedYamlScript.agent?.reportFileName, options?.testId, clonedYamlScript.agent?.testId, fileName)
|
|
3529
|
-
};
|
|
3530
|
-
const player = new yaml_.ScriptPlayer(clonedYamlScript, async ()=>{
|
|
3531
|
-
const freeFn = [];
|
|
3532
|
-
try {
|
|
3533
|
-
const resolvedWebTarget = (0, yaml_.resolveWebTarget)(clonedYamlScript);
|
|
3534
|
-
const webTarget = resolvedWebTarget?.target;
|
|
3535
|
-
const targetCount = [
|
|
3536
|
-
void 0 !== resolvedWebTarget,
|
|
3537
|
-
void 0 !== clonedYamlScript.android,
|
|
3538
|
-
void 0 !== clonedYamlScript.ios,
|
|
3539
|
-
void 0 !== clonedYamlScript.harmony,
|
|
3540
|
-
void 0 !== clonedYamlScript.computer,
|
|
3541
|
-
void 0 !== clonedYamlScript.interface
|
|
3542
|
-
].filter(Boolean).length;
|
|
3543
|
-
if (targetCount > 1) {
|
|
3544
|
-
const specifiedTargets = [
|
|
3545
|
-
resolvedWebTarget?.source ?? null,
|
|
3546
|
-
void 0 !== clonedYamlScript.android ? 'android' : null,
|
|
3547
|
-
void 0 !== clonedYamlScript.ios ? 'ios' : null,
|
|
3548
|
-
void 0 !== clonedYamlScript.harmony ? 'harmony' : null,
|
|
3549
|
-
void 0 !== clonedYamlScript.computer ? 'computer' : null,
|
|
3550
|
-
void 0 !== clonedYamlScript.interface ? 'interface' : null
|
|
3551
|
-
].filter(Boolean);
|
|
3552
|
-
throw new Error(`Only one target type can be specified, but found multiple: ${specifiedTargets.join(', ')}. Please specify only one of: page, browser, web, android, ios, harmony, computer, or interface.`);
|
|
3553
|
-
}
|
|
3554
|
-
if (void 0 !== webTarget) {
|
|
3555
|
-
if (resolvedWebTarget?.source === 'target') console.warn("target is deprecated, please use page or browser instead. See https://midscenejs.com/automate-with-scripts-in-yaml for more information. Sorry for the inconvenience.");
|
|
3556
|
-
let localServer;
|
|
3557
|
-
let urlToVisit;
|
|
3558
|
-
if (webTarget.serve) {
|
|
3559
|
-
external_node_assert_default()('string' == typeof webTarget.url, 'url is required in serve mode');
|
|
3560
|
-
localServer = await launchServer(webTarget.serve);
|
|
3561
|
-
const serverAddress = localServer.server.address();
|
|
3562
|
-
freeFn.push({
|
|
3563
|
-
name: 'local_server',
|
|
3564
|
-
fn: async ()=>{
|
|
3565
|
-
if (!localServer) return;
|
|
3566
|
-
await new Promise((resolve, reject)=>{
|
|
3567
|
-
localServer?.server.close((error)=>{
|
|
3568
|
-
if (error) reject(error);
|
|
3569
|
-
else resolve();
|
|
3570
|
-
});
|
|
3571
|
-
});
|
|
3572
|
-
}
|
|
3573
|
-
});
|
|
3574
|
-
urlToVisit = webTarget.url.startsWith('/') ? `http://${serverAddress?.address}:${serverAddress?.port}${webTarget.url}` : `http://${serverAddress?.address}:${serverAddress?.port}/${webTarget.url}`;
|
|
3575
|
-
webTarget.url = urlToVisit;
|
|
3576
|
-
}
|
|
3577
|
-
if (webTarget.cdpEndpoint && webTarget.bridgeMode) throw new Error('cdpEndpoint and bridgeMode are mutually exclusive. Please specify only one.');
|
|
3578
|
-
if ('browser' === webTarget.mode && webTarget.bridgeMode) throw new Error('[midscene] browser mode does not support bridgeMode. Use page: or web.mode: page for bridge mode.');
|
|
3579
|
-
if (webTarget.cdpEndpoint) {
|
|
3580
|
-
const ownsCdpBrowser = !options?.browser;
|
|
3581
|
-
const cdpBrowser = options?.browser ?? await external_puppeteer_default().connect({
|
|
3582
|
-
browserWSEndpoint: webTarget.cdpEndpoint,
|
|
3583
|
-
defaultViewport: null,
|
|
3584
|
-
downloadBehavior: (0, puppeteer_agent_launcher_namespaceObject.buildDownloadBehavior)(webTarget.downloadPath)
|
|
3585
|
-
});
|
|
3586
|
-
if (webTarget.chromeArgs) console.warn('chromeArgs are not supported in CDP mode (browser is already running). They will be ignored.');
|
|
3587
|
-
let launchedAgent;
|
|
3588
|
-
try {
|
|
3589
|
-
launchedAgent = await (0, puppeteer_agent_launcher_namespaceObject.puppeteerAgentForTarget)(webTarget, {
|
|
3590
|
-
...preference,
|
|
3591
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
3592
|
-
}, cdpBrowser, options?.page, options?.browserContext);
|
|
3593
|
-
} catch (error) {
|
|
3594
|
-
if (ownsCdpBrowser) try {
|
|
3595
|
-
cdpBrowser.disconnect();
|
|
3596
|
-
} catch (cleanupError) {
|
|
3597
|
-
cleanupWarning('failed to disconnect the CDP browser after agent setup failed', cleanupError);
|
|
3598
|
-
}
|
|
3599
|
-
throw error;
|
|
3600
|
-
}
|
|
3601
|
-
const { agent, freeFn: newFreeFn } = launchedAgent;
|
|
3602
|
-
const cleanFreeFn = newFreeFn.filter((f)=>'puppeteer_browser' !== f.name);
|
|
3603
|
-
freeFn.push(...cleanFreeFn);
|
|
3604
|
-
if (ownsCdpBrowser) freeFn.push({
|
|
3605
|
-
name: 'cdp_browser_disconnect',
|
|
3606
|
-
fn: ()=>cdpBrowser.disconnect()
|
|
3607
|
-
});
|
|
3608
|
-
return {
|
|
3609
|
-
agent,
|
|
3610
|
-
freeFn
|
|
3611
|
-
};
|
|
3612
|
-
}
|
|
3613
|
-
if (!webTarget.bridgeMode) {
|
|
3614
|
-
const { agent, freeFn: newFreeFn } = await (0, puppeteer_agent_launcher_namespaceObject.puppeteerAgentForTarget)(webTarget, {
|
|
3615
|
-
...preference,
|
|
3616
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
3617
|
-
}, options?.browser, options?.page, options?.browserContext);
|
|
3618
|
-
freeFn.push(...newFreeFn);
|
|
3619
|
-
return {
|
|
3620
|
-
agent,
|
|
3621
|
-
freeFn
|
|
3622
|
-
};
|
|
3623
|
-
}
|
|
3624
|
-
external_node_assert_default()('newTabWithUrl' === webTarget.bridgeMode || 'currentTab' === webTarget.bridgeMode, `bridgeMode config value must be either "newTabWithUrl" or "currentTab", but got ${webTarget.bridgeMode}`);
|
|
3625
|
-
const bridgeUnsupportedKeys = [
|
|
3626
|
-
'userAgent',
|
|
3627
|
-
'viewportWidth',
|
|
3628
|
-
'viewportHeight',
|
|
3629
|
-
'deviceScaleFactor',
|
|
3630
|
-
'waitForNetworkIdle',
|
|
3631
|
-
'cookie',
|
|
3632
|
-
'extraHTTPHeaders',
|
|
3633
|
-
'downloadPath',
|
|
3634
|
-
'chromeArgs'
|
|
3635
|
-
];
|
|
3636
|
-
const ignoredKeys = bridgeUnsupportedKeys.filter((key)=>null != webTarget[key]);
|
|
3637
|
-
if (ignoredKeys.length > 0) console.warn(`puppeteer options (${ignoredKeys.join(', ')}) are not supported in bridge mode. They will be ignored.`);
|
|
3638
|
-
const agent = new bridge_mode_namespaceObject.AgentOverChromeBridge({
|
|
3639
|
-
closeNewTabsAfterDisconnect: webTarget.closeNewTabsAfterDisconnect,
|
|
3640
|
-
closeConflictServer: true,
|
|
3641
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
3642
|
-
});
|
|
3643
|
-
if ('newTabWithUrl' === webTarget.bridgeMode) await agent.connectNewTabWithUrl(webTarget.url);
|
|
3644
|
-
else {
|
|
3645
|
-
if (webTarget.url) console.warn('url will be ignored in bridge mode with "currentTab"');
|
|
3646
|
-
await agent.connectCurrentTab();
|
|
3647
|
-
}
|
|
3648
|
-
freeFn.push({
|
|
3649
|
-
name: 'destroy_agent_over_chrome_bridge',
|
|
3650
|
-
fn: ()=>agent.destroy()
|
|
3651
|
-
});
|
|
3652
|
-
return {
|
|
3653
|
-
agent,
|
|
3654
|
-
freeFn
|
|
3655
|
-
};
|
|
3656
|
-
}
|
|
3657
|
-
if (void 0 !== clonedYamlScript.android) {
|
|
3658
|
-
const androidTarget = clonedYamlScript.android;
|
|
3659
|
-
const { agentFromAdbDevice } = await import("@midscene/android");
|
|
3660
|
-
const agent = await agentFromAdbDevice(androidTarget?.deviceId, {
|
|
3661
|
-
...androidTarget,
|
|
3662
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
3663
|
-
});
|
|
3664
|
-
if (androidTarget?.launch) await agent.launch(androidTarget.launch);
|
|
3665
|
-
freeFn.push({
|
|
3666
|
-
name: 'destroy_android_agent',
|
|
3667
|
-
fn: ()=>agent.destroy()
|
|
3668
|
-
});
|
|
3669
|
-
return {
|
|
3670
|
-
agent,
|
|
3671
|
-
freeFn
|
|
3672
|
-
};
|
|
3673
|
-
}
|
|
3674
|
-
if (void 0 !== clonedYamlScript.ios) {
|
|
3675
|
-
const iosTarget = clonedYamlScript.ios;
|
|
3676
|
-
const { agentFromWebDriverAgent } = await import("@midscene/ios");
|
|
3677
|
-
const agent = await agentFromWebDriverAgent({
|
|
3678
|
-
...iosTarget,
|
|
3679
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
3680
|
-
});
|
|
3681
|
-
if (iosTarget?.launch) await agent.launch(iosTarget.launch);
|
|
3682
|
-
freeFn.push({
|
|
3683
|
-
name: 'destroy_ios_agent',
|
|
3684
|
-
fn: ()=>agent.destroy()
|
|
3685
|
-
});
|
|
3686
|
-
return {
|
|
3687
|
-
agent,
|
|
3688
|
-
freeFn
|
|
3689
|
-
};
|
|
3690
|
-
}
|
|
3691
|
-
if (void 0 !== clonedYamlScript.harmony) {
|
|
3692
|
-
const harmonyTarget = clonedYamlScript.harmony;
|
|
3693
|
-
const { agentFromHdcDevice } = await import("@midscene/harmony");
|
|
3694
|
-
const agent = await agentFromHdcDevice(harmonyTarget?.deviceId, {
|
|
3695
|
-
...harmonyTarget,
|
|
3696
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
3697
|
-
});
|
|
3698
|
-
if (harmonyTarget?.launch) await agent.launch(harmonyTarget.launch);
|
|
3699
|
-
freeFn.push({
|
|
3700
|
-
name: 'destroy_harmony_agent',
|
|
3701
|
-
fn: ()=>agent.destroy()
|
|
3702
|
-
});
|
|
3703
|
-
return {
|
|
3704
|
-
agent,
|
|
3705
|
-
freeFn
|
|
3706
|
-
};
|
|
3707
|
-
}
|
|
3708
|
-
if (void 0 !== clonedYamlScript.computer) {
|
|
3709
|
-
const computerTarget = clonedYamlScript.computer;
|
|
3710
|
-
const { agentForComputer } = await import("@midscene/computer");
|
|
3711
|
-
const agent = await agentForComputer({
|
|
3712
|
-
...computerTarget,
|
|
3713
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
3714
|
-
});
|
|
3715
|
-
freeFn.push({
|
|
3716
|
-
name: 'destroy_computer_agent',
|
|
3717
|
-
fn: ()=>agent.destroy()
|
|
3718
|
-
});
|
|
3719
|
-
return {
|
|
3720
|
-
agent,
|
|
3721
|
-
freeFn
|
|
3722
|
-
};
|
|
3723
|
-
}
|
|
3724
|
-
if (void 0 !== clonedYamlScript.interface) {
|
|
3725
|
-
const interfaceTarget = clonedYamlScript.interface;
|
|
3726
|
-
const moduleSpecifier = interfaceTarget.module;
|
|
3727
|
-
let finalModuleSpecifier;
|
|
3728
|
-
if (moduleSpecifier.startsWith('./') || moduleSpecifier.startsWith('../') || external_node_path_default().isAbsolute(moduleSpecifier)) {
|
|
3729
|
-
const resolvedPath = (0, external_node_path_.join)(process.cwd(), moduleSpecifier);
|
|
3730
|
-
finalModuleSpecifier = resolvedPath;
|
|
3731
|
-
} else finalModuleSpecifier = moduleSpecifier;
|
|
3732
|
-
debug('importing module config', interfaceTarget.module, 'with export config', interfaceTarget.export, 'final module specifier', finalModuleSpecifier);
|
|
3733
|
-
const importedModule = await import(finalModuleSpecifier);
|
|
3734
|
-
const DeviceClass = interfaceTarget.export ? importedModule[interfaceTarget.export] : importedModule.default || importedModule;
|
|
3735
|
-
debug('DeviceClass', DeviceClass, 'with param', interfaceTarget.param);
|
|
3736
|
-
const device = new DeviceClass(interfaceTarget.param || {});
|
|
3737
|
-
debug('creating agent from device', device);
|
|
3738
|
-
const agent = (0, agent_namespaceObject.createAgent)(device, buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName));
|
|
3739
|
-
freeFn.push({
|
|
3740
|
-
name: 'destroy_general_interface_agent',
|
|
3741
|
-
fn: ()=>{
|
|
3742
|
-
agent.destroy();
|
|
3743
|
-
}
|
|
3744
|
-
});
|
|
3745
|
-
return {
|
|
3746
|
-
agent,
|
|
3747
|
-
freeFn
|
|
3748
|
-
};
|
|
3749
|
-
}
|
|
3750
|
-
throw new Error('No valid interface configuration found in the yaml script, should be either "web", "android", "ios", "harmony", "computer", or "interface"');
|
|
3751
|
-
} catch (error) {
|
|
3752
|
-
await cleanupFailedPlayerSetup(freeFn);
|
|
3753
|
-
throw error;
|
|
3754
|
-
}
|
|
3755
|
-
}, void 0, file);
|
|
3756
|
-
return player;
|
|
3757
|
-
}
|
|
3481
|
+
const yaml_runtime_namespaceObject = require("@midscene/test/internal/yaml-runtime");
|
|
3758
3482
|
var chalk_source = __webpack_require__("../../node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/index.js");
|
|
3759
3483
|
var source_default = /*#__PURE__*/ __webpack_require__.n(chalk_source);
|
|
3760
3484
|
function resolveIsTTY(env = process.env, stdoutIsTTY = process.stdout.isTTY) {
|
|
@@ -4401,7 +4125,7 @@ var __webpack_modules__ = {
|
|
|
4401
4125
|
const createFilePlayerContext = async (context)=>{
|
|
4402
4126
|
const fileContext = {
|
|
4403
4127
|
file: context.file,
|
|
4404
|
-
player: await
|
|
4128
|
+
player: await (0, yaml_runtime_namespaceObject.createYamlPlayer)(context.file, context.executionConfig, context.options)
|
|
4405
4129
|
};
|
|
4406
4130
|
fileContextsByCaseId.set(context.caseId, fileContext);
|
|
4407
4131
|
return fileContext;
|
|
@@ -4446,7 +4170,7 @@ var __webpack_modules__ = {
|
|
|
4446
4170
|
if (attempt > 1) {
|
|
4447
4171
|
if (context.executionConfig.agent?.reportFileName) attempts[attempts.length - 1] = execution_summary_preserveYamlAttemptReport(attempts[attempts.length - 1]);
|
|
4448
4172
|
await beforeRetry?.();
|
|
4449
|
-
allFileContext.player = await
|
|
4173
|
+
allFileContext.player = await (0, yaml_runtime_namespaceObject.createYamlPlayer)(context.file, context.executionConfig, context.options);
|
|
4450
4174
|
}
|
|
4451
4175
|
if (onProgress) reportProgressSnapshot(allFileContext, attempt, totalAttempts);
|
|
4452
4176
|
else if (!isTTY) {
|
|
@@ -5069,7 +4793,9 @@ defineYamlBatchTest(test, testOptions);
|
|
|
5069
4793
|
"use strict";
|
|
5070
4794
|
var core_ = __webpack_require__("@midscene/core");
|
|
5071
4795
|
const cli_namespaceObject = require("@midscene/shared/cli");
|
|
5072
|
-
var package_namespaceObject =
|
|
4796
|
+
var package_namespaceObject = {
|
|
4797
|
+
rE: "1.13.0"
|
|
4798
|
+
};
|
|
5073
4799
|
var external_node_fs_ = __webpack_require__("node:fs");
|
|
5074
4800
|
var external_node_fs_namespaceObject = /*#__PURE__*/ __webpack_require__.t(external_node_fs_, 2);
|
|
5075
4801
|
var external_node_path_ = __webpack_require__("node:path");
|
|
@@ -10685,7 +10411,7 @@ defineYamlBatchTest(test, testOptions);
|
|
|
10685
10411
|
const parseProcessArgs = async ()=>{
|
|
10686
10412
|
const args = yargs(hideBin(process.argv)).parserConfiguration({
|
|
10687
10413
|
'dot-notation': true
|
|
10688
|
-
}).usage(`Midscene
|
|
10414
|
+
}).usage(`Midscene legacy YAML runner executes tasks/flow scripts with AI.
|
|
10689
10415
|
Homepage: https://midscenejs.com
|
|
10690
10416
|
Github: https://github.com/web-infra-dev/midscene
|
|
10691
10417
|
|
|
@@ -10704,7 +10430,7 @@ Usage:
|
|
|
10704
10430
|
},
|
|
10705
10431
|
config: {
|
|
10706
10432
|
type: 'string',
|
|
10707
|
-
description: 'Path to a configuration file. Options in this file are used as defaults.'
|
|
10433
|
+
description: 'Path to a legacy YAML batch configuration file. Options in this file are used as defaults.'
|
|
10708
10434
|
},
|
|
10709
10435
|
summary: {
|
|
10710
10436
|
type: 'string',
|
|
@@ -10746,7 +10472,7 @@ Usage:
|
|
|
10746
10472
|
type: 'boolean',
|
|
10747
10473
|
description: 'Whether to dismiss the HarmonyOS keyboard after text input'
|
|
10748
10474
|
}
|
|
10749
|
-
}).version('version', 'Show version number', "1.
|
|
10475
|
+
}).version('version', 'Show version number', "1.13.0").help().epilogue(`For complete list of configuration options, please visit:
|
|
10750
10476
|
• Web options: https://midscenejs.com/automate-with-scripts-in-yaml#the-web-part
|
|
10751
10477
|
• Android options: https://midscenejs.com/automate-with-scripts-in-yaml#the-android-part
|
|
10752
10478
|
• HarmonyOS options: https://midscenejs.com/automate-with-scripts-in-yaml#the-harmony-part
|
|
@@ -10757,7 +10483,9 @@ Examples:
|
|
|
10757
10483
|
$0 script.yaml --android.device-id emulator-5554 --android.ime-strategy yadb-for-non-ascii
|
|
10758
10484
|
$0 script.yaml --android.device-id emulator-5554 --android.screenshot-strategy always-yadb
|
|
10759
10485
|
$0 script.yaml --harmony.device-id 127.0.0.1:5555
|
|
10760
|
-
$0 script.yaml --ios.wda-port 8100 --ios.auto-dismiss-keyboard
|
|
10486
|
+
$0 script.yaml --ios.wda-port 8100 --ios.auto-dismiss-keyboard
|
|
10487
|
+
|
|
10488
|
+
Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().terminalWidth());
|
|
10761
10489
|
const argv = await args.argv;
|
|
10762
10490
|
debug('argv', argv);
|
|
10763
10491
|
const transformedArgv = {
|
|
@@ -12868,6 +12596,7 @@ Examples:
|
|
|
12868
12596
|
throw new Error('Function yaml.' + from + " is removed in js-yaml 4. Use yaml." + to + ' instead, which is now safe by default.');
|
|
12869
12597
|
};
|
|
12870
12598
|
}
|
|
12599
|
+
var JSON_SCHEMA = json;
|
|
12871
12600
|
var load = loader.load;
|
|
12872
12601
|
loader.loadAll;
|
|
12873
12602
|
dumper.dump;
|
|
@@ -13170,6 +12899,42 @@ Examples:
|
|
|
13170
12899
|
io.stderr(`Unknown midscene model command: ${action}\n\n${MODEL_COMMAND_USAGE}`);
|
|
13171
12900
|
return 1;
|
|
13172
12901
|
}
|
|
12902
|
+
const test_runner_namespaceObject = require("@midscene/core/internal/test-runner");
|
|
12903
|
+
const probeWorkflowFormat = (file)=>{
|
|
12904
|
+
try {
|
|
12905
|
+
const content = (0, external_node_fs_.readFileSync)(file, 'utf8').replace(/\$\{[^}\r\n]*\}/g, 'MIDSCENE_ENV');
|
|
12906
|
+
return (0, test_runner_namespaceObject.classifyWorkflowDocumentFormat)(load(content, {
|
|
12907
|
+
schema: JSON_SCHEMA
|
|
12908
|
+
}));
|
|
12909
|
+
} catch {
|
|
12910
|
+
return 'unknown';
|
|
12911
|
+
}
|
|
12912
|
+
};
|
|
12913
|
+
const assertLegacyBatchConfigPath = (configPath)=>{
|
|
12914
|
+
if (![
|
|
12915
|
+
'.yaml',
|
|
12916
|
+
'.yml'
|
|
12917
|
+
].includes((0, external_node_path_.extname)(configPath).toLowerCase())) throw new Error(`midscene --config only accepts a legacy YAML batch config: ${configPath}. Run a native Test project config with \`midscene-test --config ${configPath}\`.`);
|
|
12918
|
+
};
|
|
12919
|
+
const assertLegacyWorkflowSelection = (files)=>{
|
|
12920
|
+
const nativeFiles = [];
|
|
12921
|
+
const mixedFiles = [];
|
|
12922
|
+
for (const file of new Set(files.map((item)=>(0, external_node_path_.resolve)(item)))){
|
|
12923
|
+
const format = probeWorkflowFormat(file);
|
|
12924
|
+
if ('native' === format) nativeFiles.push(file);
|
|
12925
|
+
else if ('mixed' === format) mixedFiles.push(file);
|
|
12926
|
+
}
|
|
12927
|
+
if (0 === nativeFiles.length && 0 === mixedFiles.length) return;
|
|
12928
|
+
const details = [
|
|
12929
|
+
...nativeFiles.map((file)=>`- native cases/steps: ${file}`),
|
|
12930
|
+
...mixedFiles.map((file)=>`- mixed tasks/flow and cases/steps: ${file}`)
|
|
12931
|
+
];
|
|
12932
|
+
throw new Error([
|
|
12933
|
+
'midscene only runs legacy tasks/flow YAML.',
|
|
12934
|
+
...details,
|
|
12935
|
+
'Run native files with `midscene-test`, and keep legacy and native formats in separate files and command invocations.'
|
|
12936
|
+
].join('\n'));
|
|
12937
|
+
};
|
|
13173
12938
|
Promise.resolve((async ()=>{
|
|
13174
12939
|
const rawArgs = process.argv.slice(2);
|
|
13175
12940
|
const [firstArg] = rawArgs;
|
|
@@ -13215,6 +12980,7 @@ Examples:
|
|
|
13215
12980
|
};
|
|
13216
12981
|
let config;
|
|
13217
12982
|
if (configFile) {
|
|
12983
|
+
assertLegacyBatchConfigPath(configFile);
|
|
13218
12984
|
config = await createConfig(configFile, configOptions);
|
|
13219
12985
|
console.log(` Config file: ${configFile}`);
|
|
13220
12986
|
} else if (cmdFiles && cmdFiles.length > 0) {
|
|
@@ -13233,6 +12999,12 @@ Examples:
|
|
|
13233
12999
|
console.error('Could not create a valid configuration.');
|
|
13234
13000
|
process.exit(1);
|
|
13235
13001
|
}
|
|
13002
|
+
assertLegacyWorkflowSelection([
|
|
13003
|
+
...config.setup ? [
|
|
13004
|
+
config.setup
|
|
13005
|
+
] : [],
|
|
13006
|
+
...config.files
|
|
13007
|
+
]);
|
|
13236
13008
|
loadDotenvConfig({
|
|
13237
13009
|
dotenvDebug: config.dotenvDebug,
|
|
13238
13010
|
dotenvOverride: config.dotenvOverride,
|