@midscene/test 1.12.5-beta-20260908034641.0 → 1.12.5

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.
@@ -104,12 +104,12 @@ var __webpack_exports__ = {};
104
104
  sections.push(`**Config file:** ${location.configPath ? `\`${location.configPath}\`` : 'No config file loaded.'}`);
105
105
  for (const project of location.projects){
106
106
  const patterns = project.files.include.map((pattern)=>`\`${pattern}\``).join(', ');
107
- const projectLabel = location.projects.length > 1 || 'default' !== project.name ? ` (Execution Project: ${project.name})` : '';
107
+ const projectLabel = location.projects.length > 1 ? ` (Execution Project: ${project.name})` : '';
108
108
  const excludes = project.files.exclude?.length ? `; excludes: ${project.files.exclude.map((pattern)=>`\`${pattern}\``).join(', ')}` : '';
109
109
  sections.push(`**Case files:** ${patterns}${projectLabel}${excludes}`);
110
110
  }
111
111
  }
112
- sections.push('Files matching `files.exclude` are not selected. Midscene Test always ignores `.git/`, `.midscene/`, `midscene_run/`, and `node_modules/` directories, including nested ones.', 'Call a Node in `cases[].steps`, or in the Workflow Document lifecycle steps `beforeAll`, `beforeEach`, `afterEach`, and `afterAll`. Root Nodes are shared defaults; `projects[].nodes` adds local Nodes and overrides same-named root Nodes only within that Execution Project. Each Execution Project supplies its own runtime environment.');
112
+ sections.push('Files matching `files.exclude` are not selected. Midscene Test always ignores `.git/`, `.midscene/`, `midscene_run/`, and `node_modules/` directories, including nested ones.', 'Call a Node in `cases[].steps`, or in the Workflow Document lifecycle steps `beforeAll`, `beforeEach`, `afterEach`, and `afterAll`. Node registrations are shared across the Test Project; each Execution Project supplies its own runtime environment.');
113
113
  return sections.join('\n\n');
114
114
  };
115
115
  const WORKFLOW_STEP_CONTRACT = `## Workflow Step Contract
@@ -601,7 +601,7 @@ A Node may map a string step value to one declared input field. Each Node sectio
601
601
  if (!Number.isInteger(value) || value < 0) throw new TypeError(`Midscene config ${label} must be a non-negative integer.`);
602
602
  return value;
603
603
  };
604
- const validateExecutionProjects = (value, defaultSetup, globalNodes)=>{
604
+ const validateExecutionProjects = (value, defaultSetup)=>{
605
605
  if (void 0 === value) {
606
606
  let platform = 'web';
607
607
  if (void 0 !== defaultSetup) {
@@ -627,8 +627,7 @@ A Node may map a string step value to one declared input field. Each Node sectio
627
627
  exclude: []
628
628
  }),
629
629
  retry: 0,
630
- variables: Object.freeze({}),
631
- nodes: new NodeRegistry(globalNodes.definitions())
630
+ variables: Object.freeze({})
632
631
  })
633
632
  ])
634
633
  };
@@ -643,7 +642,6 @@ A Node may map a string step value to one declared input field. Each Node sectio
643
642
  'name',
644
643
  'platform',
645
644
  'setup',
646
- 'nodes',
647
645
  'files',
648
646
  'tags',
649
647
  'retry',
@@ -654,17 +652,10 @@ A Node may map a string step value to one declared input field. Each Node sectio
654
652
  names.add(candidate.name);
655
653
  const platform = validatePlatform(candidate.platform, `${label}.platform`);
656
654
  const files = validateTestFileSelection(candidate.files, `${label}.files`);
657
- if (void 0 !== candidate.nodes && !Array.isArray(candidate.nodes)) throw new TypeError(`Midscene config ${label}.nodes must be an array.`);
658
- const localNodes = new NodeRegistry(candidate.nodes);
659
- const nodes = new NodeRegistry([
660
- ...globalNodes.definitions().filter((node)=>!localNodes.has(node.name)),
661
- ...localNodes.definitions()
662
- ]);
663
655
  return Object.freeze({
664
656
  projectId: projectIdFromIndex(index),
665
657
  name: candidate.name,
666
658
  platform,
667
- nodes,
668
659
  ...files ? {
669
660
  files
670
661
  } : {},
@@ -706,8 +697,7 @@ A Node may map a string step value to one declared input field. Each Node sectio
706
697
  });
707
698
  };
708
699
  const validateTestProjectDefinition = (definition)=>{
709
- if (!isRecord(definition)) throw new TypeError('Midscene config must default export an object.');
710
- if (void 0 !== definition.nodes && !Array.isArray(definition.nodes)) throw new TypeError('Midscene config nodes must be an array.');
700
+ if (!isRecord(definition) || !('nodes' in definition) || !Array.isArray(definition.nodes)) throw new TypeError('Midscene config must default export an object with a nodes array.');
711
701
  if ('setupWorkflow' in definition) throw new TypeError('Midscene config setupWorkflow is no longer supported. Use setup or projects[].setup instead.');
712
702
  if ('setupDocument' in definition) throw new TypeError('Midscene config setupDocument is not supported. Use setup or projects[].setup for resources, and beforeAll/afterAll for document lifecycle steps.');
713
703
  if ('root' in definition) throw new TypeError('Midscene config root is not supported. Pass the Test Project directory to midscene-test instead.');
@@ -720,8 +710,8 @@ A Node may map a string step value to one declared input field. Each Node sectio
720
710
  'output',
721
711
  'nodes'
722
712
  ], 'root');
713
+ const resolvedProjects = validateExecutionProjects(definition.projects, definition.setup);
723
714
  const nodes = new NodeRegistry(definition.nodes);
724
- const resolvedProjects = validateExecutionProjects(definition.projects, definition.setup, nodes);
725
715
  return {
726
716
  ...resolvedProjects,
727
717
  test: validateTestOptions(definition.test),
@@ -1930,7 +1920,7 @@ A Node may map a string step value to one declared input field. Each Node sectio
1930
1920
  if (unknown) throw new Error(`Unknown Midscene project: ${unknown}`);
1931
1921
  return projects.filter((project)=>requested.has(project.name));
1932
1922
  };
1933
- const prepareProject = (project, projectRoot, runDir)=>{
1923
+ const prepareProject = (project, projectRoot, resolveNode, runDir)=>{
1934
1924
  const fileSelection = project.files ?? DEFAULT_TEST_FILE_SELECTION;
1935
1925
  const files = discoverTestFiles(projectRoot, fileSelection);
1936
1926
  const sources = files.map((absolutePath)=>({
@@ -1952,7 +1942,7 @@ A Node may map a string step value to one declared input field. Each Node sectio
1952
1942
  }
1953
1943
  for (const source of sources)try {
1954
1944
  const collected = collectWorkflowDocument(source, {
1955
- resolveNode: project.nodes.get.bind(project.nodes),
1945
+ resolveNode,
1956
1946
  variables: project.variables,
1957
1947
  env: process.env
1958
1948
  });
@@ -1996,7 +1986,7 @@ A Node may map a string step value to one declared input field. Each Node sectio
1996
1986
  });
1997
1987
  (0, external_node_fs_.mkdirSync)(runDir);
1998
1988
  const selectedProjects = selectProjects(definition.projects, options.projectNames);
1999
- const preparedProjects = selectedProjects.map((project)=>prepareProject(project, projectRoot, runDir));
1989
+ const preparedProjects = selectedProjects.map((project)=>prepareProject(project, projectRoot, definition.resolveNode, runDir));
2000
1990
  const progress = options.onProgress ?? (()=>{});
2001
1991
  const totalDocuments = preparedProjects.reduce((total, prepared)=>total + prepared.documents.length, 0);
2002
1992
  const totalCases = preparedProjects.reduce((total, prepared)=>total + prepared.selectedCaseCount, 0);
@@ -2089,7 +2079,7 @@ A Node may map a string step value to one declared input field. Each Node sectio
2089
2079
  }
2090
2080
  projectProgress(` [document ${documentIndex + 1}/${prepared.documents.length}] ${document.sourcePath}`);
2091
2081
  const execution = await runWorkflowDocument(document, {
2092
- resolveNode: project.nodes.require.bind(project.nodes),
2082
+ resolveNode: definition.nodes.require.bind(definition.nodes),
2093
2083
  project,
2094
2084
  projectContext: runtime.context,
2095
2085
  retry: project.retry,
@@ -2228,7 +2218,7 @@ A Node may map a string step value to one declared input field. Each Node sectio
2228
2218
  } else throw new Error(`Unknown option: ${arg}`);
2229
2219
  }
2230
2220
  if ('nodes' === command && resultDir) throw new Error('--result-dir is not supported by nodes.');
2231
- if ('nodes' === command && projectNames.length > 1) throw new Error('nodes accepts only one --project name.');
2221
+ if ('nodes' === command && projectNames.length > 0) throw new Error('--project is not supported by nodes.');
2232
2222
  return {
2233
2223
  ...command ? {
2234
2224
  command
@@ -2259,15 +2249,10 @@ A Node may map a string step value to one declared input field. Each Node sectio
2259
2249
  const configPath = options.configPath ? (0, external_node_path_.resolve)(configSearchRoot, options.configPath) : discoverTestConfig(configSearchRoot);
2260
2250
  if (options.configPath && (!configPath || !(0, external_node_fs_.existsSync)(configPath))) throw new Error(`Midscene config does not exist: ${configPath}`);
2261
2251
  const project = await loadTestProject(configPath);
2262
- const projectName = options.projectNames?.[0];
2263
- const selectedProjects = projectName ? project.projects.filter((candidate)=>candidate.name === projectName) : project.projects;
2264
- if (0 === selectedProjects.length) throw new Error(`Unknown Midscene project: ${projectName}`);
2265
- const registry = selectedProjects[0].nodes;
2266
- if (selectedProjects.some((candidate)=>candidate.nodes.names().length !== registry.names().length || candidate.nodes.definitions().some((node)=>registry.get(node.name) !== node))) throw new Error('Projects have different Nodes. Use nodes --project <name> to select one.');
2267
- const nodes = sortNodesForReference(registry.definitions());
2252
+ const nodes = sortNodesForReference(project.nodes.definitions());
2268
2253
  const document = renderNodeReference(nodes, {
2269
2254
  configPath: configPath ? (0, external_node_path_.relative)(configSearchRoot, configPath).split(external_node_path_.sep).join('/') : void 0,
2270
- projects: selectedProjects.map((executionProject)=>({
2255
+ projects: project.projects.map((executionProject)=>({
2271
2256
  name: executionProject.name,
2272
2257
  files: executionProject.files ?? DEFAULT_TEST_FILE_SELECTION
2273
2258
  }))
@@ -2275,7 +2260,6 @@ A Node may map a string step value to one declared input field. Each Node sectio
2275
2260
  for (const warning of document.warnings)io.error(`midscene-test nodes: ${warning}`);
2276
2261
  const referencePath = (0, external_node_path_.resolve)(configSearchRoot, 'midscene-node-reference.md');
2277
2262
  (0, external_node_fs_.writeFileSync)(referencePath, document.markdown);
2278
- if (projectName) io.log(`Execution Project: ${projectName}`);
2279
2263
  io.log(`Registered Nodes (${nodes.length}):`);
2280
2264
  if (0 === nodes.length) io.log('No nodes are registered by the current Test Project.');
2281
2265
  for (const node of nodes)io.log(`- ${node.name}: ${node.description?.trim() || "Description not declared."}`);