@midscene/cli 1.12.10-beta-20260920072249.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/es/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*! For license information please see index.mjs.LICENSE.txt */
|
|
2
2
|
import { ReportMergingTool, createReportCliCommands, runConnectivityTest } from "@midscene/core";
|
|
3
3
|
import { runToolsCLI } from "@midscene/shared/cli";
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
4
|
+
import { basename, dirname as external_node_path_dirname, extname, join, posix, relative as external_node_path_relative, resolve as external_node_path_resolve, sep as external_node_path_sep, win32 } from "node:path";
|
|
5
|
+
import { interpolateEnvVars, midsceneYamlTargetKeys, parseYamlScript as yaml_parseYamlScript, resolveWebTarget } from "@midscene/core/yaml";
|
|
6
6
|
import { getDebug } from "@midscene/shared/logger";
|
|
7
7
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
8
|
import { lstat, readdir, readlink, realpath } from "node:fs/promises";
|
|
@@ -14,16 +14,13 @@ import node_process, { cwd as external_node_process_cwd } from "node:process";
|
|
|
14
14
|
import lodash_merge from "lodash.merge";
|
|
15
15
|
import { createHash } from "node:crypto";
|
|
16
16
|
import { getMidsceneRunSubDir } from "@midscene/shared/common";
|
|
17
|
-
import { buildChromeArgs, buildDownloadBehavior, defaultViewportHeight, defaultViewportWidth
|
|
17
|
+
import { buildChromeArgs, buildDownloadBehavior, defaultViewportHeight, defaultViewportWidth } from "@midscene/web/puppeteer-agent-launcher";
|
|
18
18
|
import puppeteer from "puppeteer";
|
|
19
|
-
import {
|
|
20
|
-
import node_assert from "node:assert";
|
|
21
|
-
import { createAgent, getReportFileName } from "@midscene/core/agent";
|
|
22
|
-
import { processCacheConfig } from "@midscene/core/utils";
|
|
23
|
-
import { AgentOverChromeBridge } from "@midscene/web/bridge-mode";
|
|
19
|
+
import { createYamlPlayer as yaml_runtime_createYamlPlayer } from "@midscene/test/internal/yaml-runtime";
|
|
24
20
|
import { stripVTControlCharacters } from "node:util";
|
|
25
21
|
import { createRequire } from "node:module";
|
|
26
22
|
import { globalModelConfigManager } from "@midscene/shared/env";
|
|
23
|
+
import { classifyWorkflowDocumentFormat } from "@midscene/core/internal/test-runner";
|
|
27
24
|
import * as __rspack_external_assert from "assert";
|
|
28
25
|
import * as __rspack_external_crypto from "crypto";
|
|
29
26
|
import * as __rspack_external_fs from "fs";
|
|
@@ -3025,7 +3022,9 @@ var __webpack_modules__ = {
|
|
|
3025
3022
|
module.exports = (string, columns, options)=>String(string).normalize().replace(/\r\n/g, '\n').split('\n').map((line)=>exec(line, columns, options)).join('\n');
|
|
3026
3023
|
},
|
|
3027
3024
|
"./src/index.ts" (__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
|
|
3028
|
-
var package_namespaceObject =
|
|
3025
|
+
var package_namespaceObject = {
|
|
3026
|
+
rE: "1.13.0"
|
|
3027
|
+
};
|
|
3029
3028
|
var brace_expansion = __webpack_require__("../../node_modules/.pnpm/brace-expansion@2.0.1/node_modules/brace-expansion/index.js");
|
|
3030
3029
|
const MAX_PATTERN_LENGTH = 65536;
|
|
3031
3030
|
const assertValidPattern = (pattern)=>{
|
|
@@ -8630,7 +8629,7 @@ var __webpack_modules__ = {
|
|
|
8630
8629
|
const parseProcessArgs = async ()=>{
|
|
8631
8630
|
const args = yargs(hideBin(process.argv)).parserConfiguration({
|
|
8632
8631
|
'dot-notation': true
|
|
8633
|
-
}).usage(`Midscene
|
|
8632
|
+
}).usage(`Midscene legacy YAML runner executes tasks/flow scripts with AI.
|
|
8634
8633
|
Homepage: https://midscenejs.com
|
|
8635
8634
|
Github: https://github.com/web-infra-dev/midscene
|
|
8636
8635
|
|
|
@@ -8649,7 +8648,7 @@ Usage:
|
|
|
8649
8648
|
},
|
|
8650
8649
|
config: {
|
|
8651
8650
|
type: 'string',
|
|
8652
|
-
description: 'Path to a configuration file. Options in this file are used as defaults.'
|
|
8651
|
+
description: 'Path to a legacy YAML batch configuration file. Options in this file are used as defaults.'
|
|
8653
8652
|
},
|
|
8654
8653
|
summary: {
|
|
8655
8654
|
type: 'string',
|
|
@@ -8691,7 +8690,7 @@ Usage:
|
|
|
8691
8690
|
type: 'boolean',
|
|
8692
8691
|
description: 'Whether to dismiss the HarmonyOS keyboard after text input'
|
|
8693
8692
|
}
|
|
8694
|
-
}).version('version', 'Show version number', "1.
|
|
8693
|
+
}).version('version', 'Show version number', "1.13.0").help().epilogue(`For complete list of configuration options, please visit:
|
|
8695
8694
|
• Web options: https://midscenejs.com/automate-with-scripts-in-yaml#the-web-part
|
|
8696
8695
|
• Android options: https://midscenejs.com/automate-with-scripts-in-yaml#the-android-part
|
|
8697
8696
|
• HarmonyOS options: https://midscenejs.com/automate-with-scripts-in-yaml#the-harmony-part
|
|
@@ -8702,7 +8701,9 @@ Examples:
|
|
|
8702
8701
|
$0 script.yaml --android.device-id emulator-5554 --android.ime-strategy yadb-for-non-ascii
|
|
8703
8702
|
$0 script.yaml --android.device-id emulator-5554 --android.screenshot-strategy always-yadb
|
|
8704
8703
|
$0 script.yaml --harmony.device-id 127.0.0.1:5555
|
|
8705
|
-
$0 script.yaml --ios.wda-port 8100 --ios.auto-dismiss-keyboard
|
|
8704
|
+
$0 script.yaml --ios.wda-port 8100 --ios.auto-dismiss-keyboard
|
|
8705
|
+
|
|
8706
|
+
Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().terminalWidth());
|
|
8706
8707
|
const argv = await args.argv;
|
|
8707
8708
|
debug('argv', argv);
|
|
8708
8709
|
const transformedArgv = {
|
|
@@ -10812,6 +10813,7 @@ Examples:
|
|
|
10812
10813
|
throw new Error('Function yaml.' + from + " is removed in js-yaml 4. Use yaml." + to + ' instead, which is now safe by default.');
|
|
10813
10814
|
};
|
|
10814
10815
|
}
|
|
10816
|
+
var JSON_SCHEMA = json;
|
|
10815
10817
|
var load = loader.load;
|
|
10816
10818
|
loader.loadAll;
|
|
10817
10819
|
dumper.dump;
|
|
@@ -11396,276 +11398,6 @@ Examples:
|
|
|
11396
11398
|
function validateConcurrency(concurrency) {
|
|
11397
11399
|
if (!((Number.isInteger(concurrency) || concurrency === 1 / 0) && concurrency > 0)) throw new TypeError('Expected `concurrency` to be a number from 1 and up');
|
|
11398
11400
|
}
|
|
11399
|
-
const create_yaml_player_debug = getDebug('create-yaml-player');
|
|
11400
|
-
const cleanupWarning = getDebug('create-yaml-player', {
|
|
11401
|
-
console: true
|
|
11402
|
-
});
|
|
11403
|
-
async function cleanupFailedPlayerSetup(freeFn) {
|
|
11404
|
-
for (const cleanup of [
|
|
11405
|
-
...freeFn
|
|
11406
|
-
].reverse())try {
|
|
11407
|
-
await cleanup.fn();
|
|
11408
|
-
} catch (error) {
|
|
11409
|
-
cleanupWarning(`failed to run ${cleanup.name} after YAML player setup failed`, error);
|
|
11410
|
-
}
|
|
11411
|
-
}
|
|
11412
|
-
const launchServer = async (dir)=>new Promise((resolve)=>{
|
|
11413
|
-
const server = createServer({
|
|
11414
|
-
root: dir
|
|
11415
|
-
});
|
|
11416
|
-
server.listen(0, '127.0.0.1', ()=>{
|
|
11417
|
-
resolve(server);
|
|
11418
|
-
});
|
|
11419
|
-
});
|
|
11420
|
-
function resolveReportFileName(yamlReportFileName, cliTestId, yamlTestId, fileName) {
|
|
11421
|
-
if (void 0 !== yamlReportFileName) return yamlReportFileName;
|
|
11422
|
-
const baseName = cliTestId ?? yamlTestId ?? fileName;
|
|
11423
|
-
return getReportFileName(baseName);
|
|
11424
|
-
}
|
|
11425
|
-
function buildAgentOptions(yamlAgent, reportFileName, fileName) {
|
|
11426
|
-
return {
|
|
11427
|
-
...yamlAgent || {},
|
|
11428
|
-
cache: processCacheConfig(yamlAgent?.cache, fileName),
|
|
11429
|
-
reportFileName
|
|
11430
|
-
};
|
|
11431
|
-
}
|
|
11432
|
-
async function create_yaml_player_createYamlPlayer(file, script, options) {
|
|
11433
|
-
const yamlScript = script || yaml_parseYamlScript((0, __rspack_external_node_fs_5ea92f0c.readFileSync)(file, 'utf-8'), file);
|
|
11434
|
-
const clonedYamlScript = structuredClone(yamlScript);
|
|
11435
|
-
const fileName = basename(file, extname(file));
|
|
11436
|
-
const preference = {
|
|
11437
|
-
headed: options?.headed,
|
|
11438
|
-
keepWindow: options?.keepWindow,
|
|
11439
|
-
reportFileName: resolveReportFileName(clonedYamlScript.agent?.reportFileName, options?.testId, clonedYamlScript.agent?.testId, fileName)
|
|
11440
|
-
};
|
|
11441
|
-
const player = new ScriptPlayer(clonedYamlScript, async ()=>{
|
|
11442
|
-
const freeFn = [];
|
|
11443
|
-
try {
|
|
11444
|
-
const resolvedWebTarget = resolveWebTarget(clonedYamlScript);
|
|
11445
|
-
const webTarget = resolvedWebTarget?.target;
|
|
11446
|
-
const targetCount = [
|
|
11447
|
-
void 0 !== resolvedWebTarget,
|
|
11448
|
-
void 0 !== clonedYamlScript.android,
|
|
11449
|
-
void 0 !== clonedYamlScript.ios,
|
|
11450
|
-
void 0 !== clonedYamlScript.harmony,
|
|
11451
|
-
void 0 !== clonedYamlScript.computer,
|
|
11452
|
-
void 0 !== clonedYamlScript.interface
|
|
11453
|
-
].filter(Boolean).length;
|
|
11454
|
-
if (targetCount > 1) {
|
|
11455
|
-
const specifiedTargets = [
|
|
11456
|
-
resolvedWebTarget?.source ?? null,
|
|
11457
|
-
void 0 !== clonedYamlScript.android ? 'android' : null,
|
|
11458
|
-
void 0 !== clonedYamlScript.ios ? 'ios' : null,
|
|
11459
|
-
void 0 !== clonedYamlScript.harmony ? 'harmony' : null,
|
|
11460
|
-
void 0 !== clonedYamlScript.computer ? 'computer' : null,
|
|
11461
|
-
void 0 !== clonedYamlScript.interface ? 'interface' : null
|
|
11462
|
-
].filter(Boolean);
|
|
11463
|
-
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.`);
|
|
11464
|
-
}
|
|
11465
|
-
if (void 0 !== webTarget) {
|
|
11466
|
-
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.");
|
|
11467
|
-
let localServer;
|
|
11468
|
-
let urlToVisit;
|
|
11469
|
-
if (webTarget.serve) {
|
|
11470
|
-
node_assert('string' == typeof webTarget.url, 'url is required in serve mode');
|
|
11471
|
-
localServer = await launchServer(webTarget.serve);
|
|
11472
|
-
const serverAddress = localServer.server.address();
|
|
11473
|
-
freeFn.push({
|
|
11474
|
-
name: 'local_server',
|
|
11475
|
-
fn: async ()=>{
|
|
11476
|
-
if (!localServer) return;
|
|
11477
|
-
await new Promise((resolve, reject)=>{
|
|
11478
|
-
localServer?.server.close((error)=>{
|
|
11479
|
-
if (error) reject(error);
|
|
11480
|
-
else resolve();
|
|
11481
|
-
});
|
|
11482
|
-
});
|
|
11483
|
-
}
|
|
11484
|
-
});
|
|
11485
|
-
urlToVisit = webTarget.url.startsWith('/') ? `http://${serverAddress?.address}:${serverAddress?.port}${webTarget.url}` : `http://${serverAddress?.address}:${serverAddress?.port}/${webTarget.url}`;
|
|
11486
|
-
webTarget.url = urlToVisit;
|
|
11487
|
-
}
|
|
11488
|
-
if (webTarget.cdpEndpoint && webTarget.bridgeMode) throw new Error('cdpEndpoint and bridgeMode are mutually exclusive. Please specify only one.');
|
|
11489
|
-
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.');
|
|
11490
|
-
if (webTarget.cdpEndpoint) {
|
|
11491
|
-
const ownsCdpBrowser = !options?.browser;
|
|
11492
|
-
const cdpBrowser = options?.browser ?? await puppeteer.connect({
|
|
11493
|
-
browserWSEndpoint: webTarget.cdpEndpoint,
|
|
11494
|
-
defaultViewport: null,
|
|
11495
|
-
downloadBehavior: buildDownloadBehavior(webTarget.downloadPath)
|
|
11496
|
-
});
|
|
11497
|
-
if (webTarget.chromeArgs) console.warn('chromeArgs are not supported in CDP mode (browser is already running). They will be ignored.');
|
|
11498
|
-
let launchedAgent;
|
|
11499
|
-
try {
|
|
11500
|
-
launchedAgent = await puppeteerAgentForTarget(webTarget, {
|
|
11501
|
-
...preference,
|
|
11502
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
11503
|
-
}, cdpBrowser, options?.page, options?.browserContext);
|
|
11504
|
-
} catch (error) {
|
|
11505
|
-
if (ownsCdpBrowser) try {
|
|
11506
|
-
cdpBrowser.disconnect();
|
|
11507
|
-
} catch (cleanupError) {
|
|
11508
|
-
cleanupWarning('failed to disconnect the CDP browser after agent setup failed', cleanupError);
|
|
11509
|
-
}
|
|
11510
|
-
throw error;
|
|
11511
|
-
}
|
|
11512
|
-
const { agent, freeFn: newFreeFn } = launchedAgent;
|
|
11513
|
-
const cleanFreeFn = newFreeFn.filter((f)=>'puppeteer_browser' !== f.name);
|
|
11514
|
-
freeFn.push(...cleanFreeFn);
|
|
11515
|
-
if (ownsCdpBrowser) freeFn.push({
|
|
11516
|
-
name: 'cdp_browser_disconnect',
|
|
11517
|
-
fn: ()=>cdpBrowser.disconnect()
|
|
11518
|
-
});
|
|
11519
|
-
return {
|
|
11520
|
-
agent,
|
|
11521
|
-
freeFn
|
|
11522
|
-
};
|
|
11523
|
-
}
|
|
11524
|
-
if (!webTarget.bridgeMode) {
|
|
11525
|
-
const { agent, freeFn: newFreeFn } = await puppeteerAgentForTarget(webTarget, {
|
|
11526
|
-
...preference,
|
|
11527
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
11528
|
-
}, options?.browser, options?.page, options?.browserContext);
|
|
11529
|
-
freeFn.push(...newFreeFn);
|
|
11530
|
-
return {
|
|
11531
|
-
agent,
|
|
11532
|
-
freeFn
|
|
11533
|
-
};
|
|
11534
|
-
}
|
|
11535
|
-
node_assert('newTabWithUrl' === webTarget.bridgeMode || 'currentTab' === webTarget.bridgeMode, `bridgeMode config value must be either "newTabWithUrl" or "currentTab", but got ${webTarget.bridgeMode}`);
|
|
11536
|
-
const bridgeUnsupportedKeys = [
|
|
11537
|
-
'userAgent',
|
|
11538
|
-
'viewportWidth',
|
|
11539
|
-
'viewportHeight',
|
|
11540
|
-
'deviceScaleFactor',
|
|
11541
|
-
'waitForNetworkIdle',
|
|
11542
|
-
'cookie',
|
|
11543
|
-
'extraHTTPHeaders',
|
|
11544
|
-
'downloadPath',
|
|
11545
|
-
'chromeArgs'
|
|
11546
|
-
];
|
|
11547
|
-
const ignoredKeys = bridgeUnsupportedKeys.filter((key)=>null != webTarget[key]);
|
|
11548
|
-
if (ignoredKeys.length > 0) console.warn(`puppeteer options (${ignoredKeys.join(', ')}) are not supported in bridge mode. They will be ignored.`);
|
|
11549
|
-
const agent = new AgentOverChromeBridge({
|
|
11550
|
-
closeNewTabsAfterDisconnect: webTarget.closeNewTabsAfterDisconnect,
|
|
11551
|
-
closeConflictServer: true,
|
|
11552
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
11553
|
-
});
|
|
11554
|
-
if ('newTabWithUrl' === webTarget.bridgeMode) await agent.connectNewTabWithUrl(webTarget.url);
|
|
11555
|
-
else {
|
|
11556
|
-
if (webTarget.url) console.warn('url will be ignored in bridge mode with "currentTab"');
|
|
11557
|
-
await agent.connectCurrentTab();
|
|
11558
|
-
}
|
|
11559
|
-
freeFn.push({
|
|
11560
|
-
name: 'destroy_agent_over_chrome_bridge',
|
|
11561
|
-
fn: ()=>agent.destroy()
|
|
11562
|
-
});
|
|
11563
|
-
return {
|
|
11564
|
-
agent,
|
|
11565
|
-
freeFn
|
|
11566
|
-
};
|
|
11567
|
-
}
|
|
11568
|
-
if (void 0 !== clonedYamlScript.android) {
|
|
11569
|
-
const androidTarget = clonedYamlScript.android;
|
|
11570
|
-
const { agentFromAdbDevice } = await import("@midscene/android");
|
|
11571
|
-
const agent = await agentFromAdbDevice(androidTarget?.deviceId, {
|
|
11572
|
-
...androidTarget,
|
|
11573
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
11574
|
-
});
|
|
11575
|
-
if (androidTarget?.launch) await agent.launch(androidTarget.launch);
|
|
11576
|
-
freeFn.push({
|
|
11577
|
-
name: 'destroy_android_agent',
|
|
11578
|
-
fn: ()=>agent.destroy()
|
|
11579
|
-
});
|
|
11580
|
-
return {
|
|
11581
|
-
agent,
|
|
11582
|
-
freeFn
|
|
11583
|
-
};
|
|
11584
|
-
}
|
|
11585
|
-
if (void 0 !== clonedYamlScript.ios) {
|
|
11586
|
-
const iosTarget = clonedYamlScript.ios;
|
|
11587
|
-
const { agentFromWebDriverAgent } = await import("@midscene/ios");
|
|
11588
|
-
const agent = await agentFromWebDriverAgent({
|
|
11589
|
-
...iosTarget,
|
|
11590
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
11591
|
-
});
|
|
11592
|
-
if (iosTarget?.launch) await agent.launch(iosTarget.launch);
|
|
11593
|
-
freeFn.push({
|
|
11594
|
-
name: 'destroy_ios_agent',
|
|
11595
|
-
fn: ()=>agent.destroy()
|
|
11596
|
-
});
|
|
11597
|
-
return {
|
|
11598
|
-
agent,
|
|
11599
|
-
freeFn
|
|
11600
|
-
};
|
|
11601
|
-
}
|
|
11602
|
-
if (void 0 !== clonedYamlScript.harmony) {
|
|
11603
|
-
const harmonyTarget = clonedYamlScript.harmony;
|
|
11604
|
-
const { agentFromHdcDevice } = await import("@midscene/harmony");
|
|
11605
|
-
const agent = await agentFromHdcDevice(harmonyTarget?.deviceId, {
|
|
11606
|
-
...harmonyTarget,
|
|
11607
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
11608
|
-
});
|
|
11609
|
-
if (harmonyTarget?.launch) await agent.launch(harmonyTarget.launch);
|
|
11610
|
-
freeFn.push({
|
|
11611
|
-
name: 'destroy_harmony_agent',
|
|
11612
|
-
fn: ()=>agent.destroy()
|
|
11613
|
-
});
|
|
11614
|
-
return {
|
|
11615
|
-
agent,
|
|
11616
|
-
freeFn
|
|
11617
|
-
};
|
|
11618
|
-
}
|
|
11619
|
-
if (void 0 !== clonedYamlScript.computer) {
|
|
11620
|
-
const computerTarget = clonedYamlScript.computer;
|
|
11621
|
-
const { agentForComputer } = await import("@midscene/computer");
|
|
11622
|
-
const agent = await agentForComputer({
|
|
11623
|
-
...computerTarget,
|
|
11624
|
-
...buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName)
|
|
11625
|
-
});
|
|
11626
|
-
freeFn.push({
|
|
11627
|
-
name: 'destroy_computer_agent',
|
|
11628
|
-
fn: ()=>agent.destroy()
|
|
11629
|
-
});
|
|
11630
|
-
return {
|
|
11631
|
-
agent,
|
|
11632
|
-
freeFn
|
|
11633
|
-
};
|
|
11634
|
-
}
|
|
11635
|
-
if (void 0 !== clonedYamlScript.interface) {
|
|
11636
|
-
const interfaceTarget = clonedYamlScript.interface;
|
|
11637
|
-
const moduleSpecifier = interfaceTarget.module;
|
|
11638
|
-
let finalModuleSpecifier;
|
|
11639
|
-
if (moduleSpecifier.startsWith('./') || moduleSpecifier.startsWith('../') || node_path.isAbsolute(moduleSpecifier)) {
|
|
11640
|
-
const resolvedPath = join(process.cwd(), moduleSpecifier);
|
|
11641
|
-
finalModuleSpecifier = resolvedPath;
|
|
11642
|
-
} else finalModuleSpecifier = moduleSpecifier;
|
|
11643
|
-
create_yaml_player_debug('importing module config', interfaceTarget.module, 'with export config', interfaceTarget.export, 'final module specifier', finalModuleSpecifier);
|
|
11644
|
-
const importedModule = await import(finalModuleSpecifier);
|
|
11645
|
-
const DeviceClass = interfaceTarget.export ? importedModule[interfaceTarget.export] : importedModule.default || importedModule;
|
|
11646
|
-
create_yaml_player_debug('DeviceClass', DeviceClass, 'with param', interfaceTarget.param);
|
|
11647
|
-
const device = new DeviceClass(interfaceTarget.param || {});
|
|
11648
|
-
create_yaml_player_debug('creating agent from device', device);
|
|
11649
|
-
const agent = createAgent(device, buildAgentOptions(clonedYamlScript.agent, preference.reportFileName, fileName));
|
|
11650
|
-
freeFn.push({
|
|
11651
|
-
name: 'destroy_general_interface_agent',
|
|
11652
|
-
fn: ()=>{
|
|
11653
|
-
agent.destroy();
|
|
11654
|
-
}
|
|
11655
|
-
});
|
|
11656
|
-
return {
|
|
11657
|
-
agent,
|
|
11658
|
-
freeFn
|
|
11659
|
-
};
|
|
11660
|
-
}
|
|
11661
|
-
throw new Error('No valid interface configuration found in the yaml script, should be either "web", "android", "ios", "harmony", "computer", or "interface"');
|
|
11662
|
-
} catch (error) {
|
|
11663
|
-
await cleanupFailedPlayerSetup(freeFn);
|
|
11664
|
-
throw error;
|
|
11665
|
-
}
|
|
11666
|
-
}, void 0, file);
|
|
11667
|
-
return player;
|
|
11668
|
-
}
|
|
11669
11401
|
var chalk_source = __webpack_require__("../../node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/index.js");
|
|
11670
11402
|
var source_default = /*#__PURE__*/ __webpack_require__.n(chalk_source);
|
|
11671
11403
|
function resolveIsTTY(env = process.env, stdoutIsTTY = process.stdout.isTTY) {
|
|
@@ -12310,7 +12042,7 @@ Examples:
|
|
|
12310
12042
|
const createFilePlayerContext = async (context)=>{
|
|
12311
12043
|
const fileContext = {
|
|
12312
12044
|
file: context.file,
|
|
12313
|
-
player: await
|
|
12045
|
+
player: await yaml_runtime_createYamlPlayer(context.file, context.executionConfig, context.options)
|
|
12314
12046
|
};
|
|
12315
12047
|
fileContextsByCaseId.set(context.caseId, fileContext);
|
|
12316
12048
|
return fileContext;
|
|
@@ -12355,7 +12087,7 @@ Examples:
|
|
|
12355
12087
|
if (attempt > 1) {
|
|
12356
12088
|
if (context.executionConfig.agent?.reportFileName) attempts[attempts.length - 1] = execution_summary_preserveYamlAttemptReport(attempts[attempts.length - 1]);
|
|
12357
12089
|
await beforeRetry?.();
|
|
12358
|
-
allFileContext.player = await
|
|
12090
|
+
allFileContext.player = await yaml_runtime_createYamlPlayer(context.file, context.executionConfig, context.options);
|
|
12359
12091
|
}
|
|
12360
12092
|
if (onProgress) reportProgressSnapshot(allFileContext, attempt, totalAttempts);
|
|
12361
12093
|
else if (!isTTY) {
|
|
@@ -13127,6 +12859,41 @@ defineYamlBatchTest(test, testOptions);
|
|
|
13127
12859
|
io.stderr(`Unknown midscene model command: ${action}\n\n${MODEL_COMMAND_USAGE}`);
|
|
13128
12860
|
return 1;
|
|
13129
12861
|
}
|
|
12862
|
+
const probeWorkflowFormat = (file)=>{
|
|
12863
|
+
try {
|
|
12864
|
+
const content = (0, __rspack_external_node_fs_5ea92f0c.readFileSync)(file, 'utf8').replace(/\$\{[^}\r\n]*\}/g, 'MIDSCENE_ENV');
|
|
12865
|
+
return classifyWorkflowDocumentFormat(load(content, {
|
|
12866
|
+
schema: JSON_SCHEMA
|
|
12867
|
+
}));
|
|
12868
|
+
} catch {
|
|
12869
|
+
return 'unknown';
|
|
12870
|
+
}
|
|
12871
|
+
};
|
|
12872
|
+
const assertLegacyBatchConfigPath = (configPath)=>{
|
|
12873
|
+
if (![
|
|
12874
|
+
'.yaml',
|
|
12875
|
+
'.yml'
|
|
12876
|
+
].includes(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}\`.`);
|
|
12877
|
+
};
|
|
12878
|
+
const assertLegacyWorkflowSelection = (files)=>{
|
|
12879
|
+
const nativeFiles = [];
|
|
12880
|
+
const mixedFiles = [];
|
|
12881
|
+
for (const file of new Set(files.map((item)=>external_node_path_resolve(item)))){
|
|
12882
|
+
const format = probeWorkflowFormat(file);
|
|
12883
|
+
if ('native' === format) nativeFiles.push(file);
|
|
12884
|
+
else if ('mixed' === format) mixedFiles.push(file);
|
|
12885
|
+
}
|
|
12886
|
+
if (0 === nativeFiles.length && 0 === mixedFiles.length) return;
|
|
12887
|
+
const details = [
|
|
12888
|
+
...nativeFiles.map((file)=>`- native cases/steps: ${file}`),
|
|
12889
|
+
...mixedFiles.map((file)=>`- mixed tasks/flow and cases/steps: ${file}`)
|
|
12890
|
+
];
|
|
12891
|
+
throw new Error([
|
|
12892
|
+
'midscene only runs legacy tasks/flow YAML.',
|
|
12893
|
+
...details,
|
|
12894
|
+
'Run native files with `midscene-test`, and keep legacy and native formats in separate files and command invocations.'
|
|
12895
|
+
].join('\n'));
|
|
12896
|
+
};
|
|
13130
12897
|
Promise.resolve((async ()=>{
|
|
13131
12898
|
const rawArgs = process.argv.slice(2);
|
|
13132
12899
|
const [firstArg] = rawArgs;
|
|
@@ -13172,6 +12939,7 @@ defineYamlBatchTest(test, testOptions);
|
|
|
13172
12939
|
};
|
|
13173
12940
|
let config;
|
|
13174
12941
|
if (configFile) {
|
|
12942
|
+
assertLegacyBatchConfigPath(configFile);
|
|
13175
12943
|
config = await createConfig(configFile, configOptions);
|
|
13176
12944
|
console.log(` Config file: ${configFile}`);
|
|
13177
12945
|
} else if (cmdFiles && cmdFiles.length > 0) {
|
|
@@ -13190,6 +12958,12 @@ defineYamlBatchTest(test, testOptions);
|
|
|
13190
12958
|
console.error('Could not create a valid configuration.');
|
|
13191
12959
|
process.exit(1);
|
|
13192
12960
|
}
|
|
12961
|
+
assertLegacyWorkflowSelection([
|
|
12962
|
+
...config.setup ? [
|
|
12963
|
+
config.setup
|
|
12964
|
+
] : [],
|
|
12965
|
+
...config.files
|
|
12966
|
+
]);
|
|
13193
12967
|
loadDotenvConfig({
|
|
13194
12968
|
dotenvDebug: config.dotenvDebug,
|
|
13195
12969
|
dotenvOverride: config.dotenvOverride,
|