@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/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 node_path, { 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 { ScriptPlayer, interpolateEnvVars, midsceneYamlTargetKeys, parseYamlScript as yaml_parseYamlScript, resolveWebTarget } from "@midscene/core/yaml";
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, puppeteerAgentForTarget } from "@midscene/web/puppeteer-agent-launcher";
17
+ import { buildChromeArgs, buildDownloadBehavior, defaultViewportHeight, defaultViewportWidth } from "@midscene/web/puppeteer-agent-launcher";
18
18
  import puppeteer from "puppeteer";
19
- import { createServer } from "http-server";
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 = JSON.parse('{"rE":"1.12.10-beta-20260920072249.0"}');
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.js helps you automate browser actions, assertions, and data extraction by AI.
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.12.10-beta-20260920072249.0").help().epilogue(`For complete list of configuration options, please visit:
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`).wrap(yargs().terminalWidth());
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 create_yaml_player_createYamlPlayer(context.file, context.executionConfig, context.options)
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 create_yaml_player_createYamlPlayer(context.file, context.executionConfig, context.options);
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,