@midscene/test 1.17.5 → 1.17.7
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/cli/index.mjs +73 -39
- package/dist/es/cli/index.mjs.map +1 -1
- package/dist/es/index.mjs +5 -0
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/test-cli.mjs +76 -40
- package/dist/es/test-cli.mjs.map +1 -1
- package/dist/lib/cli/index.js +73 -39
- package/dist/lib/cli/index.js.map +1 -1
- package/dist/lib/index.js +5 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/test-cli.js +76 -40
- package/dist/lib/test-cli.js.map +1 -1
- package/dist/templates/test/android/README.md +1 -1
- package/dist/templates/test/android/README.zh.md +1 -1
- package/dist/templates/test/android/gitignore +0 -1
- package/dist/templates/test/computer/README.md +1 -1
- package/dist/templates/test/computer/README.zh.md +1 -1
- package/dist/templates/test/computer/gitignore +0 -1
- package/dist/templates/test/harmony/README.md +1 -1
- package/dist/templates/test/harmony/README.zh.md +1 -1
- package/dist/templates/test/harmony/gitignore +0 -1
- package/dist/templates/test/ios/README.md +1 -1
- package/dist/templates/test/ios/README.zh.md +1 -1
- package/dist/templates/test/ios/gitignore +0 -1
- package/dist/templates/test/web/README.md +1 -1
- package/dist/templates/test/web/README.zh.md +1 -1
- package/dist/templates/test/web/gitignore +0 -1
- package/dist/types/cli/index.d.ts +2 -1
- package/package.json +13 -13
package/dist/lib/index.js
CHANGED
|
@@ -388,6 +388,9 @@ function collectWorkflowDocument(source, options) {
|
|
|
388
388
|
};
|
|
389
389
|
}
|
|
390
390
|
const promises_namespaceObject = require("node:fs/promises");
|
|
391
|
+
function renderTestBadge(summary) {
|
|
392
|
+
return ``;
|
|
393
|
+
}
|
|
391
394
|
const result_markdown_text = (value)=>value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll('|', '|').replaceAll('[', '[').replaceAll(']', ']').replaceAll('*', '*').replaceAll('_', '_').replaceAll('`', '`').replaceAll('\\', '\').replace(/[\r\n]+/g, ' ');
|
|
392
395
|
const duration = (ms)=>{
|
|
393
396
|
const seconds = Math.round(ms / 1000);
|
|
@@ -400,6 +403,8 @@ function renderTestResultMarkdown(dump, options = {}) {
|
|
|
400
403
|
const lines = [
|
|
401
404
|
'## Midscene Test',
|
|
402
405
|
'',
|
|
406
|
+
renderTestBadge(summary),
|
|
407
|
+
'',
|
|
403
408
|
`${outcome} · ${duration(dump.durationMs)}`,
|
|
404
409
|
''
|
|
405
410
|
];
|
package/dist/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/engine/case-runner.ts","../../src/engine/document-runtime.ts","../../src/engine/registry.ts","../../src/engine/run-workflow-document.ts","../../src/node/define-node.ts","../../src/parser/identifiers.ts","../../src/parser/normalize.ts","../../src/parser/source.ts","../../src/parser/variables.ts","../../src/parser/collect.ts","../../src/report/result-markdown.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import {\n CaseRunner as CoreCaseRunner,\n createCaseRunner as coreCreateCaseRunner,\n} from '@midscene/core/internal/test-runner';\nimport type { NodeDefinition } from '../node/types';\nimport type { CaseInput } from '../parser/types';\nimport type { NodeRegistry } from './registry';\nimport type { CaseRunResult, CaseRunnerOptions } from './types';\n\nexport type CaseRunner<TContext = undefined> = Omit<\n CoreCaseRunner<TContext>,\n 'run' | 'register' | 'registry'\n> & {\n readonly registry: NodeRegistry;\n register<TInput, TData>(\n node: NodeDefinition<TInput, TData, TContext>,\n ): CaseRunner<TContext>;\n run(input: CaseInput): Promise<CaseRunResult>;\n};\nexport const CaseRunner: {\n new <TContext = undefined>(\n options?: CaseRunnerOptions<TContext>,\n ): CaseRunner<TContext>;\n} = CoreCaseRunner;\nexport const createCaseRunner: <TContext = undefined>(\n options?: CaseRunnerOptions<TContext>,\n) => CaseRunner<TContext> = coreCreateCaseRunner;\n","import { createDocumentRuntime as coreCreateDocumentRuntime } from '@midscene/core/internal/test-runner';\nimport type { CollectedWorkflowDocument } from '../parser/types';\nimport type {\n CreateDocumentRuntimeOptions,\n WorkflowDocumentRuntime,\n} from './types';\n\nexport const createDocumentRuntime: <TContext = undefined>(\n document: CollectedWorkflowDocument,\n options: CreateDocumentRuntimeOptions<TContext>,\n) => WorkflowDocumentRuntime<TContext> = coreCreateDocumentRuntime;\n","import { NodeRegistry as CoreNodeRegistry } from '@midscene/core/internal/test-runner';\nimport type { NodeDefinition } from '../node/types';\n\nexport type NodeRegistry = Omit<\n CoreNodeRegistry,\n 'get' | 'require' | 'register' | 'definitions'\n> & {\n get(name: string): NodeDefinition<any, any> | undefined;\n require(name: string): NodeDefinition<any, any>;\n register<TInput, TData>(node: NodeDefinition<TInput, TData>): NodeRegistry;\n definitions(): readonly NodeDefinition<any, any, any>[];\n};\nexport const NodeRegistry: {\n new (nodes?: readonly NodeDefinition<any, any>[]): NodeRegistry;\n} = CoreNodeRegistry;\n","import { runWorkflowDocument as coreRunWorkflowDocument } from '@midscene/core/internal/test-runner';\nimport type { CollectedWorkflowDocument } from '../parser/types';\nimport type {\n RunWorkflowDocumentOptions,\n WorkflowDocumentExecutionResult,\n} from './types';\n\nexport const runWorkflowDocument: <TContext = undefined>(\n document: CollectedWorkflowDocument,\n options: RunWorkflowDocumentOptions<TContext>,\n) => Promise<WorkflowDocumentExecutionResult> = coreRunWorkflowDocument;\n","import { defineNode as coreDefineNode } from '@midscene/core/internal/test-runner';\nimport type {\n DefineNodeOptions,\n DefineNodeWithSchemaOptions,\n NodeDefinition,\n NodeDefinitionWithSchema,\n NodeInputSchema,\n} from './types';\n\n// A type-only facade: validation and execution still belong to the shared kernel.\ninterface DefineNativeNode {\n <TSchema extends NodeInputSchema, TData = unknown, TContext = unknown>(\n options: DefineNodeWithSchemaOptions<TSchema, TData, TContext>,\n ): NodeDefinitionWithSchema<TSchema, TData, TContext>;\n <TInput = unknown, TData = unknown, TContext = unknown>(\n options: DefineNodeOptions<TInput, TData, TContext>,\n ): NodeDefinition<TInput, TData, TContext>;\n}\nexport const defineNode: DefineNativeNode = coreDefineNode;\n","import { createHash } from 'node:crypto';\n\n/** Internal invocation identity keeps repeated legacy files distinct. */\nexport const createCaseInvocationId = (\n projectId: string,\n sourcePath: string,\n caseIndex: number,\n invocationIndex = 0,\n): string =>\n createHash('sha256')\n .update(\n JSON.stringify([\n projectId,\n sourcePath,\n caseIndex,\n ...(invocationIndex ? [invocationIndex] : []),\n ]),\n )\n .digest('hex');\n\nexport const createDocumentInvocationId = (\n projectId: string,\n sourcePath: string,\n invocationIndex = 0,\n): string =>\n createHash('sha256')\n .update(\n JSON.stringify([\n projectId,\n sourcePath,\n ...(invocationIndex ? [invocationIndex] : []),\n ]),\n )\n .digest('hex');\n","import {\n type ResolveNodeForNormalization,\n normalizeStep as coreNormalizeStep,\n normalizeSteps as coreNormalizeSteps,\n} from '@midscene/core/internal/test-runner';\nimport type { NormalizedStep } from './types';\nexport type { ResolveNodeForNormalization } from '@midscene/core/internal/test-runner';\n\nexport const normalizeStep: (\n value: unknown,\n index?: number,\n resolveNode?: ResolveNodeForNormalization,\n) => NormalizedStep = coreNormalizeStep;\nexport const normalizeSteps: (\n values: unknown,\n resolveNode?: ResolveNodeForNormalization,\n) => NormalizedStep[] = coreNormalizeSteps;\n","import type { TestRunReportValue } from '@midscene/core';\nimport {\n isReportSecretKey,\n sanitizeReportText,\n} from '@midscene/core/internal/test-runner';\nimport { JSON_SCHEMA, load } from 'js-yaml';\n\ninterface SourceNode {\n start: number;\n end: number;\n value: unknown;\n children: SourceNode[];\n kind: string | null;\n}\n\n/** Keep author formatting while redacting values by parsed YAML keys, including aliases. */\nexport function parseWorkflowSource(source: string): {\n parsed: unknown;\n sourceYaml: TestRunReportValue;\n locate(\n path: readonly (string | number)[],\n ): { line: number; column: number } | undefined;\n} {\n const stack: SourceNode[] = [];\n const nodes: SourceNode[] = [];\n const sensitiveNodes = new Set<SourceNode>();\n const sensitiveValues = new Set<unknown>();\n const redactedPaths = new Set<string>();\n // js-yaml removes the BOM before reporting source positions.\n const sourceOffset = source.charCodeAt(0) === 0xfeff ? 1 : 0;\n const parsed = load(source, {\n schema: JSON_SCHEMA,\n listener(event, state) {\n if (event === 'open') {\n stack.push({\n start: state.position + sourceOffset,\n end: 0,\n value: null,\n children: [],\n kind: null,\n });\n return;\n }\n const node = stack.pop()!;\n node.end = state.position + sourceOffset;\n node.value = state.result;\n node.kind = state.kind;\n stack.at(-1)?.children.push(node);\n nodes.push(node);\n if (state.kind !== 'mapping') return;\n for (let index = 0; index < node.children.length; index += 2) {\n const key = node.children[index].value;\n const value = node.children[index + 1];\n if (typeof key !== 'string' || !isReportSecretKey(key) || !value)\n continue;\n sensitiveNodes.add(value);\n if (value.value !== null) sensitiveValues.add(value.value);\n redactedPaths.add(`$..[${JSON.stringify(key)}]`);\n }\n },\n });\n // Redact the definition as well when a secret value refers to a YAML anchor.\n const ranges = nodes\n .filter(\n (node) => sensitiveNodes.has(node) || sensitiveValues.has(node.value),\n )\n .sort((left, right) => left.start - right.start || right.end - left.end);\n let offset = 0;\n let redacted = '';\n for (const range of ranges) {\n if (range.start < offset) continue;\n const text = source.slice(range.start, range.end);\n const leading = text.match(/^\\s*/)?.[0] ?? '';\n const trailing = text.slice(leading.length).match(/\\s*$/)?.[0] ?? '';\n redacted += `${source.slice(offset, range.start)}${leading}\"[REDACTED]\"${trailing}`;\n offset = range.end;\n }\n redacted += source.slice(offset);\n const value = sanitizeReportText(redacted, 64 * 1024);\n return {\n parsed,\n locate(path) {\n let node = nodes.at(-1);\n for (const part of path) {\n if (!node) return undefined;\n // js-yaml can emit a wrapper around a block collection.\n while (\n node.children.length === 1 &&\n node.children[0].value === node.value\n )\n node = node.children[0];\n if (typeof part === 'number' && node.kind === 'sequence')\n node = node.children[part];\n else if (typeof part === 'string' && node.kind === 'mapping') {\n const children = node.children;\n node = undefined;\n for (let index = 0; index < children.length; index += 2)\n if (children[index].value === part) {\n node = children[index + 1];\n break;\n }\n } else return undefined;\n }\n if (!node) return undefined;\n let start = node.start;\n while (start < node.end) {\n if (/\\s/.test(source[start])) start++;\n else if (source[start] === '#') {\n const end = source.indexOf('\\n', start);\n if (end < 0) return undefined;\n start = end + 1;\n } else break;\n }\n const prefix = source.slice(0, start).split(/\\r\\n|\\r|\\n/);\n return { line: prefix.length, column: prefix.at(-1)!.length + 1 };\n },\n sourceYaml: {\n value,\n ...(redactedPaths.size ? { redactedPaths: [...redactedPaths] } : {}),\n ...(value !== redacted ? { truncatedPaths: ['$'] } : {}),\n },\n };\n}\n","import type { JsonValue } from '../cli/test-project';\nimport { WorkflowParseError } from '../errors';\n\nexport interface VariableResolutionLocation {\n projectName: string;\n sourcePath: string;\n phase: 'beforeAll' | 'beforeEach' | 'steps' | 'afterEach' | 'afterAll';\n stepIndex: number;\n caseIndex?: number;\n}\n\nexport interface ResolveWorkflowVariablesOptions {\n variables?: Readonly<Record<string, JsonValue>>;\n env?: Readonly<NodeJS.ProcessEnv>;\n location: VariableResolutionLocation;\n}\n\nconst interpolationExpression =\n /\\$\\{\\{([A-Za-z_][A-Za-z0-9_]*)\\}\\}|\\$\\{([^{}]+)\\}/g;\nconst exactEnvExpression = /^\\$\\{\\{([A-Za-z_][A-Za-z0-9_]*)\\}\\}$/;\nconst exactProjectExpression = /^\\$\\{([^{}]+)\\}$/;\n\nconst missingVariable = (\n kind: 'environment' | 'project',\n name: string,\n options: ResolveWorkflowVariablesOptions,\n): never => {\n throw new WorkflowParseError(\n `Undefined ${kind} variable \"${name}\" in ${options.location.sourcePath}.`,\n { ...options.location, variable: name, variableKind: kind },\n );\n};\n\nconst projectVariable = (\n name: string,\n options: ResolveWorkflowVariablesOptions,\n): JsonValue => {\n if (!Object.hasOwn(options.variables ?? {}, name)) {\n return missingVariable('project', name, options);\n }\n return options.variables![name];\n};\n\nconst environmentVariable = (\n name: string,\n options: ResolveWorkflowVariablesOptions,\n): string => {\n const value = options.env?.[name];\n if (value === undefined) return missingVariable('environment', name, options);\n return value;\n};\n\nconst interpolationValue = (\n name: string,\n value: JsonValue,\n options: ResolveWorkflowVariablesOptions,\n): string => {\n if (typeof value === 'object' && value !== null) {\n throw new WorkflowParseError(\n `Project variable \"${name}\" must be a primitive when embedded in a string.`,\n {\n ...options.location,\n variable: name,\n variableKind: 'project',\n },\n );\n }\n return String(value);\n};\n\nconst resolveString = (\n value: string,\n options: ResolveWorkflowVariablesOptions,\n): JsonValue => {\n const exactEnv = exactEnvExpression.exec(value);\n if (exactEnv) return environmentVariable(exactEnv[1], options);\n const exactProject = exactProjectExpression.exec(value);\n if (exactProject) return projectVariable(exactProject[1], options);\n\n return value.replace(\n interpolationExpression,\n (_match, environmentName: string | undefined, projectName: string) =>\n environmentName\n ? environmentVariable(environmentName, options)\n : interpolationValue(\n projectName,\n projectVariable(projectName, options),\n options,\n ),\n );\n};\n\nexport const resolveWorkflowVariables = (\n value: unknown,\n options: ResolveWorkflowVariablesOptions,\n): unknown => {\n if (typeof value === 'string') return resolveString(value, options);\n if (Array.isArray(value)) {\n return value.map((child) => resolveWorkflowVariables(child, options));\n }\n if (typeof value === 'object' && value !== null) {\n return Object.fromEntries(\n Object.entries(value).map(([key, child]) => [\n key,\n resolveWorkflowVariables(child, options),\n ]),\n );\n }\n return value;\n};\n","import { readFileSync } from 'node:fs';\nimport { sep } from 'node:path';\nimport { classifyWorkflowDocumentFormat } from '@midscene/core/internal/test-runner';\nimport type { JsonValue } from '../cli/test-project';\nimport { WorkflowParseError } from '../errors';\nimport type { NodeDefinition } from '../node/types';\nimport {\n createCaseInvocationId,\n createDocumentInvocationId,\n} from './identifiers';\nimport { normalizeSteps } from './normalize';\nimport { parseWorkflowSource } from './source';\nimport type {\n CollectedCase,\n CollectedWorkflowDocument,\n WorkflowDocumentSource,\n} from './types';\nimport { resolveWorkflowVariables } from './variables';\n\nexport interface CollectWorkflowDocumentOptions {\n resolveNode(name: string): NodeDefinition<any, any> | undefined;\n variables?: Readonly<Record<string, JsonValue>>;\n env?: Readonly<NodeJS.ProcessEnv>;\n}\n\nconst isMapping = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nexport class NativeWorkflowFormatError extends WorkflowParseError {\n readonly actualFormat: 'legacy' | 'legacy-batch' | 'mixed';\n\n constructor(\n actualFormat: 'legacy' | 'legacy-batch' | 'mixed',\n sourcePath: string,\n ) {\n super(\n actualFormat === 'legacy'\n ? `Legacy tasks/flow YAML is not supported by midscene-test: ${sourcePath}. Run it with \\`midscene ${sourcePath}\\`, or migrate the file to cases/steps.`\n : actualFormat === 'legacy-batch'\n ? `Legacy YAML batch configuration is not a midscene-test workflow document: ${sourcePath}. Run it with \\`midscene --config ${sourcePath}\\`, or migrate it to a native project config.`\n : `A workflow file cannot mix legacy tasks/flow with native cases/steps or lifecycle hooks: ${sourcePath}. Keep the formats in separate files and run each file with its matching command.`,\n { sourcePath, actualFormat, expectedFormat: 'native' },\n );\n this.actualFormat = actualFormat;\n }\n}\n\nconst rejectUnknownKeys = (\n value: Record<string, unknown>,\n allowed: readonly string[],\n label: string,\n) => {\n const allowedSet = new Set(allowed);\n const unknown = Object.keys(value).filter((key) => !allowedSet.has(key));\n if (unknown.length) {\n throw new WorkflowParseError(\n `${label} has unsupported field \"${unknown[0]}\".`,\n { field: unknown[0] },\n );\n }\n};\n\nexport const createCaseId = (\n projectId: string,\n sourcePath: string,\n caseIndex: number,\n): string => createCaseInvocationId(projectId, sourcePath, caseIndex);\n\nexport const createWorkflowDocumentId = (\n projectId: string,\n sourcePath: string,\n): string => createDocumentInvocationId(projectId, sourcePath);\n\nexport function collectWorkflowDocument(\n source: WorkflowDocumentSource,\n options: CollectWorkflowDocumentOptions,\n): CollectedWorkflowDocument {\n let snapshot: ReturnType<typeof parseWorkflowSource>;\n try {\n snapshot = parseWorkflowSource(readFileSync(source.absolutePath, 'utf8'));\n } catch (error) {\n throw new WorkflowParseError(\n `Failed to parse workflow document \"${source.sourcePath}\".`,\n { sourcePath: source.sourcePath },\n error,\n );\n }\n const { parsed, sourceYaml } = snapshot;\n\n if (!isMapping(parsed)) {\n throw new WorkflowParseError('Workflow document must be a mapping.');\n }\n const format = classifyWorkflowDocumentFormat(parsed);\n if (format === 'legacy' || format === 'legacy-batch' || format === 'mixed') {\n throw new NativeWorkflowFormatError(format, source.sourcePath);\n }\n rejectUnknownKeys(\n parsed,\n ['beforeAll', 'beforeEach', 'cases', 'afterEach', 'afterAll'],\n 'Workflow document',\n );\n if (!Array.isArray(parsed.cases) || parsed.cases.length === 0) {\n throw new WorkflowParseError(\n 'Workflow document must contain a non-empty cases array.',\n );\n }\n\n const sourcePath = source.sourcePath.split(sep).join('/');\n const resolveStepVariables = (\n step: ReturnType<typeof normalizeSteps>[number],\n phase: 'beforeAll' | 'beforeEach' | 'steps' | 'afterEach' | 'afterAll',\n stepIndex: number,\n caseIndex?: number,\n ) => ({\n ...step,\n meta: {\n ...step.meta,\n sourceLocation: snapshot.locate(\n phase === 'steps'\n ? ['cases', caseIndex!, 'steps', stepIndex]\n : [phase, stepIndex],\n ),\n },\n templateInput: step.input,\n input: resolveWorkflowVariables(step.input, {\n variables: options.variables,\n env: options.env ?? process.env,\n location: {\n projectName: source.projectName ?? source.projectId,\n sourcePath,\n phase,\n stepIndex,\n ...(caseIndex === undefined ? {} : { caseIndex }),\n },\n }) as typeof step.input,\n });\n const normalizeLifecycle = (\n phase: 'beforeAll' | 'beforeEach' | 'afterEach' | 'afterAll',\n ) => {\n const value = parsed[phase];\n if (value === undefined) return [];\n if (!Array.isArray(value)) {\n throw new WorkflowParseError(\n `Workflow document ${phase} must be an array.`,\n { phase },\n );\n }\n return normalizeSteps(value, options.resolveNode).map(\n (normalized, stepIndex) => {\n const resolved = options.resolveNode(normalized.node);\n if (!resolved) {\n throw new WorkflowParseError(\n `Workflow document ${phase} step ${stepIndex + 1} references unknown node \"${normalized.node}\".`,\n { phase, stepIndex, node: normalized.node },\n );\n }\n return resolveStepVariables(normalized, phase, stepIndex);\n },\n );\n };\n const lifecycle = {\n beforeAll: normalizeLifecycle('beforeAll'),\n beforeEach: normalizeLifecycle('beforeEach'),\n afterEach: normalizeLifecycle('afterEach'),\n afterAll: normalizeLifecycle('afterAll'),\n };\n const ids = new Set<string>();\n const cases: CollectedCase[] = parsed.cases.map((definition, caseIndex) => {\n if (!isMapping(definition)) {\n throw new WorkflowParseError(`Case ${caseIndex + 1} must be a mapping.`, {\n caseIndex,\n });\n }\n rejectUnknownKeys(\n definition,\n ['name', 'tags', 'steps'],\n `Case ${caseIndex + 1}`,\n );\n if (\n typeof definition.name !== 'string' ||\n definition.name.trim().length === 0\n ) {\n throw new WorkflowParseError(\n `Case ${caseIndex + 1} name must be a non-empty string.`,\n { caseIndex },\n );\n }\n if (!Array.isArray(definition.steps) || definition.steps.length === 0) {\n throw new WorkflowParseError(\n `Case ${caseIndex + 1} steps must be a non-empty array.`,\n { caseIndex },\n );\n }\n const tags = definition.tags ?? [];\n if (\n !Array.isArray(tags) ||\n tags.some((tag) => typeof tag !== 'string' || tag.trim().length === 0)\n ) {\n throw new WorkflowParseError(\n `Case ${caseIndex + 1} tags must be an array of non-empty strings.`,\n { caseIndex },\n );\n }\n\n const steps = normalizeSteps(definition.steps, options.resolveNode).map(\n (normalized, stepIndex) => {\n if (!options.resolveNode(normalized.node)) {\n throw new WorkflowParseError(\n `Case ${caseIndex + 1} step ${stepIndex + 1} references unknown node \"${normalized.node}\".`,\n { caseIndex, stepIndex, node: normalized.node },\n );\n }\n return resolveStepVariables(normalized, 'steps', stepIndex, caseIndex);\n },\n );\n const caseId = createCaseId(source.projectId, sourcePath, caseIndex);\n if (ids.has(caseId)) {\n throw new WorkflowParseError(`Case id collision: ${caseId}.`, {\n caseId,\n });\n }\n ids.add(caseId);\n\n return {\n caseId,\n projectId: source.projectId,\n sourcePath,\n caseIndex,\n definition: {\n name: definition.name,\n tags: tags as string[],\n steps,\n },\n };\n });\n\n return {\n documentId: createWorkflowDocumentId(source.projectId, sourcePath),\n projectId: source.projectId,\n sourcePath,\n sourceYaml,\n lifecycle,\n cases,\n } satisfies CollectedWorkflowDocument;\n}\n","import { writeFile } from 'node:fs/promises';\nimport { dirname, join, relative, sep } from 'node:path';\nimport type {\n TestRunReportDump,\n TestRunReportSourceIndex,\n TestRunReportStep,\n} from '@midscene/core';\nimport type { TestProjectRunResult } from '../cli/types';\nimport { buildTestRunReportDump } from './test-run-report';\n\nconst text = (value: string): string =>\n value\n .replaceAll('&', '&')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('\"', '"')\n .replaceAll('|', '|')\n .replaceAll('[', '[')\n .replaceAll(']', ']')\n .replaceAll('*', '*')\n .replaceAll('_', '_')\n .replaceAll('`', '`')\n .replaceAll('\\\\', '\')\n .replace(/[\\r\\n]+/g, ' ');\n\nconst duration = (ms: number): string => {\n const seconds = Math.round(ms / 1000);\n return seconds < 60\n ? `${seconds}s`\n : `${Math.floor(seconds / 60)}m ${seconds % 60}s`;\n};\nconst href = (from: string, target: string): string =>\n relative(dirname(from), target).split(sep).map(encodeURIComponent).join('/');\n\nexport interface TestResultMarkdownOptions {\n /** Relative or hosted URL of the HTML report. */\n reportHref?: string;\n}\n\n/** Render the same sanitized execution facts used by the HTML report. */\nexport function renderTestResultMarkdown(\n dump: TestRunReportDump,\n options: TestResultMarkdownOptions = {},\n): string {\n const { summary } = dump;\n const outcome =\n dump.status === 'success'\n ? `✅ **${summary.passed}/${summary.total} passed**`\n : `❌ **${summary.failed} failed** · ${summary.passed} passed · ${summary.notRun} not run`;\n const lines = [\n '## Midscene Test',\n '',\n `${outcome} · ${duration(dump.durationMs)}`,\n '',\n ];\n if (summary.filtered) lines.push(`**Filtered:** ${summary.filtered}`, '');\n const infrastructure = [\n summary.collectionErrors\n ? `${summary.collectionErrors} collection errors`\n : '',\n summary.documentFailures\n ? `${summary.documentFailures} document failures`\n : '',\n summary.projectFailures\n ? `${summary.projectFailures} project failures`\n : '',\n ].filter(Boolean);\n if (infrastructure.length)\n lines.push(`**Infrastructure:** ${infrastructure.join(' · ')}`, '');\n const groups: { name: string; rows: string[] }[] = [];\n const errors: string[] = [];\n const recordSteps = (label: string, steps: readonly TestRunReportStep[]) => {\n for (const step of steps) {\n if (step.status === 'failed')\n errors.push(\n `${label} / ${step.node}: ${step.error?.message ?? 'Step failed'}`,\n );\n }\n };\n for (const project of dump.projects) {\n if (project.lifecycle?.setupError)\n errors.push(`${project.name}: ${project.lifecycle.setupError.message}`);\n for (const error of project.lifecycle?.teardownErrors ?? [])\n errors.push(`${project.name}: ${error.message}`);\n for (const error of project.collectionErrors)\n errors.push(\n `${project.name} / ${error.sourcePath}: ${error.error.message}`,\n );\n for (const document of project.documents) {\n const name = document.sourcePath\n .replace(/\\\\/g, '/')\n .replace(/\\.(?:yaml|yml)$/, '');\n const group = {\n name: dump.projects.length > 1 ? `${project.name} / ${name}` : name,\n rows: [] as string[],\n };\n groups.push(group);\n recordSteps(`${project.name} / ${document.sourcePath}`, [\n ...document.beforeAll,\n ...document.afterAll,\n ]);\n for (const error of document.teardownErrors ?? [])\n errors.push(`${document.sourcePath}: ${error.message}`);\n for (const failure of document.hostErrors ?? [])\n errors.push(\n `${document.sourcePath} / ${failure.phase}: ${failure.error.message}`,\n );\n for (const testCase of document.cases) {\n group.rows.push(\n ` - ${testCase.status === 'success' ? '✅' : testCase.status === 'not-run' ? '⏭️' : '❌'} ${text(testCase.name)}`,\n );\n }\n }\n }\n for (const diagnostic of dump.diagnostics ?? []) {\n if (diagnostic.level === 'error') errors.push(diagnostic.message);\n }\n if (errors.length)\n lines.push(\n '### Execution errors',\n '',\n ...errors.map((error) => `- ${text(error)}`),\n '',\n );\n for (const group of groups) {\n if (group.rows.length) lines.push(`- ${text(group.name)}`, ...group.rows);\n }\n if (!groups.some((group) => group.rows.length))\n lines.push('No cases were reported.');\n if (options.reportHref)\n lines.push(\n '',\n `[Open the Midscene Test report ↗](<${options.reportHref}>)`,\n );\n return `${lines.join('\\n')}\\n`;\n}\n\nconst emptyIndex = (): TestRunReportSourceIndex => ({\n sources: [],\n metrics: {\n modelCallCount: 0,\n modelTimeMs: 0,\n promptTokens: 0,\n cachedInputTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n },\n});\n\n/** Write a per-run Markdown artifact even when HTML publication fails or is disabled. */\nexport async function writeTestResultMarkdown(\n result: TestProjectRunResult,\n index: TestRunReportSourceIndex = emptyIndex(),\n): Promise<string> {\n const output = join(dirname(result.summaryPath), 'result.md');\n const dump = buildTestRunReportDump(result, index);\n await writeFile(\n output,\n renderTestResultMarkdown(dump, {\n ...(result.reportPath\n ? { reportHref: href(output, result.reportPath) }\n : {}),\n }),\n );\n return output;\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","CaseRunner","CoreCaseRunner","createCaseRunner","coreCreateCaseRunner","createDocumentRuntime","coreCreateDocumentRuntime","NodeRegistry","CoreNodeRegistry","runWorkflowDocument","coreRunWorkflowDocument","defineNode","coreDefineNode","createCaseInvocationId","projectId","sourcePath","caseIndex","invocationIndex","createHash","JSON","createDocumentInvocationId","normalizeStep","coreNormalizeStep","normalizeSteps","coreNormalizeSteps","parseWorkflowSource","source","stack","nodes","sensitiveNodes","Set","sensitiveValues","redactedPaths","sourceOffset","parsed","load","JSON_SCHEMA","event","state","node","index","value","isReportSecretKey","ranges","left","right","offset","redacted","range","text","leading","trailing","sanitizeReportText","path","part","children","undefined","start","end","prefix","interpolationExpression","exactEnvExpression","exactProjectExpression","missingVariable","kind","name","options","WorkflowParseError","projectVariable","environmentVariable","interpolationValue","String","resolveString","exactEnv","exactProject","_match","environmentName","projectName","resolveWorkflowVariables","Array","child","isMapping","NativeWorkflowFormatError","actualFormat","rejectUnknownKeys","allowed","label","allowedSet","unknown","createCaseId","createWorkflowDocumentId","collectWorkflowDocument","snapshot","readFileSync","error","sourceYaml","format","classifyWorkflowDocumentFormat","sep","resolveStepVariables","step","phase","stepIndex","process","normalizeLifecycle","normalized","resolved","lifecycle","ids","cases","tags","tag","steps","caseId","duration","ms","seconds","Math","href","from","target","relative","dirname","encodeURIComponent","renderTestResultMarkdown","dump","summary","outcome","lines","infrastructure","Boolean","groups","errors","recordSteps","project","document","group","failure","testCase","diagnostic","emptyIndex","writeTestResultMarkdown","result","output","join","buildTestRunReportDump","writeFile"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/engine/case-runner.ts","../../src/engine/document-runtime.ts","../../src/engine/registry.ts","../../src/engine/run-workflow-document.ts","../../src/node/define-node.ts","../../src/parser/identifiers.ts","../../src/parser/normalize.ts","../../src/parser/source.ts","../../src/parser/variables.ts","../../src/parser/collect.ts","../../src/report/badge.ts","../../src/report/result-markdown.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import {\n CaseRunner as CoreCaseRunner,\n createCaseRunner as coreCreateCaseRunner,\n} from '@midscene/core/internal/test-runner';\nimport type { NodeDefinition } from '../node/types';\nimport type { CaseInput } from '../parser/types';\nimport type { NodeRegistry } from './registry';\nimport type { CaseRunResult, CaseRunnerOptions } from './types';\n\nexport type CaseRunner<TContext = undefined> = Omit<\n CoreCaseRunner<TContext>,\n 'run' | 'register' | 'registry'\n> & {\n readonly registry: NodeRegistry;\n register<TInput, TData>(\n node: NodeDefinition<TInput, TData, TContext>,\n ): CaseRunner<TContext>;\n run(input: CaseInput): Promise<CaseRunResult>;\n};\nexport const CaseRunner: {\n new <TContext = undefined>(\n options?: CaseRunnerOptions<TContext>,\n ): CaseRunner<TContext>;\n} = CoreCaseRunner;\nexport const createCaseRunner: <TContext = undefined>(\n options?: CaseRunnerOptions<TContext>,\n) => CaseRunner<TContext> = coreCreateCaseRunner;\n","import { createDocumentRuntime as coreCreateDocumentRuntime } from '@midscene/core/internal/test-runner';\nimport type { CollectedWorkflowDocument } from '../parser/types';\nimport type {\n CreateDocumentRuntimeOptions,\n WorkflowDocumentRuntime,\n} from './types';\n\nexport const createDocumentRuntime: <TContext = undefined>(\n document: CollectedWorkflowDocument,\n options: CreateDocumentRuntimeOptions<TContext>,\n) => WorkflowDocumentRuntime<TContext> = coreCreateDocumentRuntime;\n","import { NodeRegistry as CoreNodeRegistry } from '@midscene/core/internal/test-runner';\nimport type { NodeDefinition } from '../node/types';\n\nexport type NodeRegistry = Omit<\n CoreNodeRegistry,\n 'get' | 'require' | 'register' | 'definitions'\n> & {\n get(name: string): NodeDefinition<any, any> | undefined;\n require(name: string): NodeDefinition<any, any>;\n register<TInput, TData>(node: NodeDefinition<TInput, TData>): NodeRegistry;\n definitions(): readonly NodeDefinition<any, any, any>[];\n};\nexport const NodeRegistry: {\n new (nodes?: readonly NodeDefinition<any, any>[]): NodeRegistry;\n} = CoreNodeRegistry;\n","import { runWorkflowDocument as coreRunWorkflowDocument } from '@midscene/core/internal/test-runner';\nimport type { CollectedWorkflowDocument } from '../parser/types';\nimport type {\n RunWorkflowDocumentOptions,\n WorkflowDocumentExecutionResult,\n} from './types';\n\nexport const runWorkflowDocument: <TContext = undefined>(\n document: CollectedWorkflowDocument,\n options: RunWorkflowDocumentOptions<TContext>,\n) => Promise<WorkflowDocumentExecutionResult> = coreRunWorkflowDocument;\n","import { defineNode as coreDefineNode } from '@midscene/core/internal/test-runner';\nimport type {\n DefineNodeOptions,\n DefineNodeWithSchemaOptions,\n NodeDefinition,\n NodeDefinitionWithSchema,\n NodeInputSchema,\n} from './types';\n\n// A type-only facade: validation and execution still belong to the shared kernel.\ninterface DefineNativeNode {\n <TSchema extends NodeInputSchema, TData = unknown, TContext = unknown>(\n options: DefineNodeWithSchemaOptions<TSchema, TData, TContext>,\n ): NodeDefinitionWithSchema<TSchema, TData, TContext>;\n <TInput = unknown, TData = unknown, TContext = unknown>(\n options: DefineNodeOptions<TInput, TData, TContext>,\n ): NodeDefinition<TInput, TData, TContext>;\n}\nexport const defineNode: DefineNativeNode = coreDefineNode;\n","import { createHash } from 'node:crypto';\n\n/** Internal invocation identity keeps repeated legacy files distinct. */\nexport const createCaseInvocationId = (\n projectId: string,\n sourcePath: string,\n caseIndex: number,\n invocationIndex = 0,\n): string =>\n createHash('sha256')\n .update(\n JSON.stringify([\n projectId,\n sourcePath,\n caseIndex,\n ...(invocationIndex ? [invocationIndex] : []),\n ]),\n )\n .digest('hex');\n\nexport const createDocumentInvocationId = (\n projectId: string,\n sourcePath: string,\n invocationIndex = 0,\n): string =>\n createHash('sha256')\n .update(\n JSON.stringify([\n projectId,\n sourcePath,\n ...(invocationIndex ? [invocationIndex] : []),\n ]),\n )\n .digest('hex');\n","import {\n type ResolveNodeForNormalization,\n normalizeStep as coreNormalizeStep,\n normalizeSteps as coreNormalizeSteps,\n} from '@midscene/core/internal/test-runner';\nimport type { NormalizedStep } from './types';\nexport type { ResolveNodeForNormalization } from '@midscene/core/internal/test-runner';\n\nexport const normalizeStep: (\n value: unknown,\n index?: number,\n resolveNode?: ResolveNodeForNormalization,\n) => NormalizedStep = coreNormalizeStep;\nexport const normalizeSteps: (\n values: unknown,\n resolveNode?: ResolveNodeForNormalization,\n) => NormalizedStep[] = coreNormalizeSteps;\n","import type { TestRunReportValue } from '@midscene/core';\nimport {\n isReportSecretKey,\n sanitizeReportText,\n} from '@midscene/core/internal/test-runner';\nimport { JSON_SCHEMA, load } from 'js-yaml';\n\ninterface SourceNode {\n start: number;\n end: number;\n value: unknown;\n children: SourceNode[];\n kind: string | null;\n}\n\n/** Keep author formatting while redacting values by parsed YAML keys, including aliases. */\nexport function parseWorkflowSource(source: string): {\n parsed: unknown;\n sourceYaml: TestRunReportValue;\n locate(\n path: readonly (string | number)[],\n ): { line: number; column: number } | undefined;\n} {\n const stack: SourceNode[] = [];\n const nodes: SourceNode[] = [];\n const sensitiveNodes = new Set<SourceNode>();\n const sensitiveValues = new Set<unknown>();\n const redactedPaths = new Set<string>();\n // js-yaml removes the BOM before reporting source positions.\n const sourceOffset = source.charCodeAt(0) === 0xfeff ? 1 : 0;\n const parsed = load(source, {\n schema: JSON_SCHEMA,\n listener(event, state) {\n if (event === 'open') {\n stack.push({\n start: state.position + sourceOffset,\n end: 0,\n value: null,\n children: [],\n kind: null,\n });\n return;\n }\n const node = stack.pop()!;\n node.end = state.position + sourceOffset;\n node.value = state.result;\n node.kind = state.kind;\n stack.at(-1)?.children.push(node);\n nodes.push(node);\n if (state.kind !== 'mapping') return;\n for (let index = 0; index < node.children.length; index += 2) {\n const key = node.children[index].value;\n const value = node.children[index + 1];\n if (typeof key !== 'string' || !isReportSecretKey(key) || !value)\n continue;\n sensitiveNodes.add(value);\n if (value.value !== null) sensitiveValues.add(value.value);\n redactedPaths.add(`$..[${JSON.stringify(key)}]`);\n }\n },\n });\n // Redact the definition as well when a secret value refers to a YAML anchor.\n const ranges = nodes\n .filter(\n (node) => sensitiveNodes.has(node) || sensitiveValues.has(node.value),\n )\n .sort((left, right) => left.start - right.start || right.end - left.end);\n let offset = 0;\n let redacted = '';\n for (const range of ranges) {\n if (range.start < offset) continue;\n const text = source.slice(range.start, range.end);\n const leading = text.match(/^\\s*/)?.[0] ?? '';\n const trailing = text.slice(leading.length).match(/\\s*$/)?.[0] ?? '';\n redacted += `${source.slice(offset, range.start)}${leading}\"[REDACTED]\"${trailing}`;\n offset = range.end;\n }\n redacted += source.slice(offset);\n const value = sanitizeReportText(redacted, 64 * 1024);\n return {\n parsed,\n locate(path) {\n let node = nodes.at(-1);\n for (const part of path) {\n if (!node) return undefined;\n // js-yaml can emit a wrapper around a block collection.\n while (\n node.children.length === 1 &&\n node.children[0].value === node.value\n )\n node = node.children[0];\n if (typeof part === 'number' && node.kind === 'sequence')\n node = node.children[part];\n else if (typeof part === 'string' && node.kind === 'mapping') {\n const children = node.children;\n node = undefined;\n for (let index = 0; index < children.length; index += 2)\n if (children[index].value === part) {\n node = children[index + 1];\n break;\n }\n } else return undefined;\n }\n if (!node) return undefined;\n let start = node.start;\n while (start < node.end) {\n if (/\\s/.test(source[start])) start++;\n else if (source[start] === '#') {\n const end = source.indexOf('\\n', start);\n if (end < 0) return undefined;\n start = end + 1;\n } else break;\n }\n const prefix = source.slice(0, start).split(/\\r\\n|\\r|\\n/);\n return { line: prefix.length, column: prefix.at(-1)!.length + 1 };\n },\n sourceYaml: {\n value,\n ...(redactedPaths.size ? { redactedPaths: [...redactedPaths] } : {}),\n ...(value !== redacted ? { truncatedPaths: ['$'] } : {}),\n },\n };\n}\n","import type { JsonValue } from '../cli/test-project';\nimport { WorkflowParseError } from '../errors';\n\nexport interface VariableResolutionLocation {\n projectName: string;\n sourcePath: string;\n phase: 'beforeAll' | 'beforeEach' | 'steps' | 'afterEach' | 'afterAll';\n stepIndex: number;\n caseIndex?: number;\n}\n\nexport interface ResolveWorkflowVariablesOptions {\n variables?: Readonly<Record<string, JsonValue>>;\n env?: Readonly<NodeJS.ProcessEnv>;\n location: VariableResolutionLocation;\n}\n\nconst interpolationExpression =\n /\\$\\{\\{([A-Za-z_][A-Za-z0-9_]*)\\}\\}|\\$\\{([^{}]+)\\}/g;\nconst exactEnvExpression = /^\\$\\{\\{([A-Za-z_][A-Za-z0-9_]*)\\}\\}$/;\nconst exactProjectExpression = /^\\$\\{([^{}]+)\\}$/;\n\nconst missingVariable = (\n kind: 'environment' | 'project',\n name: string,\n options: ResolveWorkflowVariablesOptions,\n): never => {\n throw new WorkflowParseError(\n `Undefined ${kind} variable \"${name}\" in ${options.location.sourcePath}.`,\n { ...options.location, variable: name, variableKind: kind },\n );\n};\n\nconst projectVariable = (\n name: string,\n options: ResolveWorkflowVariablesOptions,\n): JsonValue => {\n if (!Object.hasOwn(options.variables ?? {}, name)) {\n return missingVariable('project', name, options);\n }\n return options.variables![name];\n};\n\nconst environmentVariable = (\n name: string,\n options: ResolveWorkflowVariablesOptions,\n): string => {\n const value = options.env?.[name];\n if (value === undefined) return missingVariable('environment', name, options);\n return value;\n};\n\nconst interpolationValue = (\n name: string,\n value: JsonValue,\n options: ResolveWorkflowVariablesOptions,\n): string => {\n if (typeof value === 'object' && value !== null) {\n throw new WorkflowParseError(\n `Project variable \"${name}\" must be a primitive when embedded in a string.`,\n {\n ...options.location,\n variable: name,\n variableKind: 'project',\n },\n );\n }\n return String(value);\n};\n\nconst resolveString = (\n value: string,\n options: ResolveWorkflowVariablesOptions,\n): JsonValue => {\n const exactEnv = exactEnvExpression.exec(value);\n if (exactEnv) return environmentVariable(exactEnv[1], options);\n const exactProject = exactProjectExpression.exec(value);\n if (exactProject) return projectVariable(exactProject[1], options);\n\n return value.replace(\n interpolationExpression,\n (_match, environmentName: string | undefined, projectName: string) =>\n environmentName\n ? environmentVariable(environmentName, options)\n : interpolationValue(\n projectName,\n projectVariable(projectName, options),\n options,\n ),\n );\n};\n\nexport const resolveWorkflowVariables = (\n value: unknown,\n options: ResolveWorkflowVariablesOptions,\n): unknown => {\n if (typeof value === 'string') return resolveString(value, options);\n if (Array.isArray(value)) {\n return value.map((child) => resolveWorkflowVariables(child, options));\n }\n if (typeof value === 'object' && value !== null) {\n return Object.fromEntries(\n Object.entries(value).map(([key, child]) => [\n key,\n resolveWorkflowVariables(child, options),\n ]),\n );\n }\n return value;\n};\n","import { readFileSync } from 'node:fs';\nimport { sep } from 'node:path';\nimport { classifyWorkflowDocumentFormat } from '@midscene/core/internal/test-runner';\nimport type { JsonValue } from '../cli/test-project';\nimport { WorkflowParseError } from '../errors';\nimport type { NodeDefinition } from '../node/types';\nimport {\n createCaseInvocationId,\n createDocumentInvocationId,\n} from './identifiers';\nimport { normalizeSteps } from './normalize';\nimport { parseWorkflowSource } from './source';\nimport type {\n CollectedCase,\n CollectedWorkflowDocument,\n WorkflowDocumentSource,\n} from './types';\nimport { resolveWorkflowVariables } from './variables';\n\nexport interface CollectWorkflowDocumentOptions {\n resolveNode(name: string): NodeDefinition<any, any> | undefined;\n variables?: Readonly<Record<string, JsonValue>>;\n env?: Readonly<NodeJS.ProcessEnv>;\n}\n\nconst isMapping = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nexport class NativeWorkflowFormatError extends WorkflowParseError {\n readonly actualFormat: 'legacy' | 'legacy-batch' | 'mixed';\n\n constructor(\n actualFormat: 'legacy' | 'legacy-batch' | 'mixed',\n sourcePath: string,\n ) {\n super(\n actualFormat === 'legacy'\n ? `Legacy tasks/flow YAML is not supported by midscene-test: ${sourcePath}. Run it with \\`midscene ${sourcePath}\\`, or migrate the file to cases/steps.`\n : actualFormat === 'legacy-batch'\n ? `Legacy YAML batch configuration is not a midscene-test workflow document: ${sourcePath}. Run it with \\`midscene --config ${sourcePath}\\`, or migrate it to a native project config.`\n : `A workflow file cannot mix legacy tasks/flow with native cases/steps or lifecycle hooks: ${sourcePath}. Keep the formats in separate files and run each file with its matching command.`,\n { sourcePath, actualFormat, expectedFormat: 'native' },\n );\n this.actualFormat = actualFormat;\n }\n}\n\nconst rejectUnknownKeys = (\n value: Record<string, unknown>,\n allowed: readonly string[],\n label: string,\n) => {\n const allowedSet = new Set(allowed);\n const unknown = Object.keys(value).filter((key) => !allowedSet.has(key));\n if (unknown.length) {\n throw new WorkflowParseError(\n `${label} has unsupported field \"${unknown[0]}\".`,\n { field: unknown[0] },\n );\n }\n};\n\nexport const createCaseId = (\n projectId: string,\n sourcePath: string,\n caseIndex: number,\n): string => createCaseInvocationId(projectId, sourcePath, caseIndex);\n\nexport const createWorkflowDocumentId = (\n projectId: string,\n sourcePath: string,\n): string => createDocumentInvocationId(projectId, sourcePath);\n\nexport function collectWorkflowDocument(\n source: WorkflowDocumentSource,\n options: CollectWorkflowDocumentOptions,\n): CollectedWorkflowDocument {\n let snapshot: ReturnType<typeof parseWorkflowSource>;\n try {\n snapshot = parseWorkflowSource(readFileSync(source.absolutePath, 'utf8'));\n } catch (error) {\n throw new WorkflowParseError(\n `Failed to parse workflow document \"${source.sourcePath}\".`,\n { sourcePath: source.sourcePath },\n error,\n );\n }\n const { parsed, sourceYaml } = snapshot;\n\n if (!isMapping(parsed)) {\n throw new WorkflowParseError('Workflow document must be a mapping.');\n }\n const format = classifyWorkflowDocumentFormat(parsed);\n if (format === 'legacy' || format === 'legacy-batch' || format === 'mixed') {\n throw new NativeWorkflowFormatError(format, source.sourcePath);\n }\n rejectUnknownKeys(\n parsed,\n ['beforeAll', 'beforeEach', 'cases', 'afterEach', 'afterAll'],\n 'Workflow document',\n );\n if (!Array.isArray(parsed.cases) || parsed.cases.length === 0) {\n throw new WorkflowParseError(\n 'Workflow document must contain a non-empty cases array.',\n );\n }\n\n const sourcePath = source.sourcePath.split(sep).join('/');\n const resolveStepVariables = (\n step: ReturnType<typeof normalizeSteps>[number],\n phase: 'beforeAll' | 'beforeEach' | 'steps' | 'afterEach' | 'afterAll',\n stepIndex: number,\n caseIndex?: number,\n ) => ({\n ...step,\n meta: {\n ...step.meta,\n sourceLocation: snapshot.locate(\n phase === 'steps'\n ? ['cases', caseIndex!, 'steps', stepIndex]\n : [phase, stepIndex],\n ),\n },\n templateInput: step.input,\n input: resolveWorkflowVariables(step.input, {\n variables: options.variables,\n env: options.env ?? process.env,\n location: {\n projectName: source.projectName ?? source.projectId,\n sourcePath,\n phase,\n stepIndex,\n ...(caseIndex === undefined ? {} : { caseIndex }),\n },\n }) as typeof step.input,\n });\n const normalizeLifecycle = (\n phase: 'beforeAll' | 'beforeEach' | 'afterEach' | 'afterAll',\n ) => {\n const value = parsed[phase];\n if (value === undefined) return [];\n if (!Array.isArray(value)) {\n throw new WorkflowParseError(\n `Workflow document ${phase} must be an array.`,\n { phase },\n );\n }\n return normalizeSteps(value, options.resolveNode).map(\n (normalized, stepIndex) => {\n const resolved = options.resolveNode(normalized.node);\n if (!resolved) {\n throw new WorkflowParseError(\n `Workflow document ${phase} step ${stepIndex + 1} references unknown node \"${normalized.node}\".`,\n { phase, stepIndex, node: normalized.node },\n );\n }\n return resolveStepVariables(normalized, phase, stepIndex);\n },\n );\n };\n const lifecycle = {\n beforeAll: normalizeLifecycle('beforeAll'),\n beforeEach: normalizeLifecycle('beforeEach'),\n afterEach: normalizeLifecycle('afterEach'),\n afterAll: normalizeLifecycle('afterAll'),\n };\n const ids = new Set<string>();\n const cases: CollectedCase[] = parsed.cases.map((definition, caseIndex) => {\n if (!isMapping(definition)) {\n throw new WorkflowParseError(`Case ${caseIndex + 1} must be a mapping.`, {\n caseIndex,\n });\n }\n rejectUnknownKeys(\n definition,\n ['name', 'tags', 'steps'],\n `Case ${caseIndex + 1}`,\n );\n if (\n typeof definition.name !== 'string' ||\n definition.name.trim().length === 0\n ) {\n throw new WorkflowParseError(\n `Case ${caseIndex + 1} name must be a non-empty string.`,\n { caseIndex },\n );\n }\n if (!Array.isArray(definition.steps) || definition.steps.length === 0) {\n throw new WorkflowParseError(\n `Case ${caseIndex + 1} steps must be a non-empty array.`,\n { caseIndex },\n );\n }\n const tags = definition.tags ?? [];\n if (\n !Array.isArray(tags) ||\n tags.some((tag) => typeof tag !== 'string' || tag.trim().length === 0)\n ) {\n throw new WorkflowParseError(\n `Case ${caseIndex + 1} tags must be an array of non-empty strings.`,\n { caseIndex },\n );\n }\n\n const steps = normalizeSteps(definition.steps, options.resolveNode).map(\n (normalized, stepIndex) => {\n if (!options.resolveNode(normalized.node)) {\n throw new WorkflowParseError(\n `Case ${caseIndex + 1} step ${stepIndex + 1} references unknown node \"${normalized.node}\".`,\n { caseIndex, stepIndex, node: normalized.node },\n );\n }\n return resolveStepVariables(normalized, 'steps', stepIndex, caseIndex);\n },\n );\n const caseId = createCaseId(source.projectId, sourcePath, caseIndex);\n if (ids.has(caseId)) {\n throw new WorkflowParseError(`Case id collision: ${caseId}.`, {\n caseId,\n });\n }\n ids.add(caseId);\n\n return {\n caseId,\n projectId: source.projectId,\n sourcePath,\n caseIndex,\n definition: {\n name: definition.name,\n tags: tags as string[],\n steps,\n },\n };\n });\n\n return {\n documentId: createWorkflowDocumentId(source.projectId, sourcePath),\n projectId: source.projectId,\n sourcePath,\n sourceYaml,\n lifecycle,\n cases,\n } satisfies CollectedWorkflowDocument;\n}\n","import type { TestRunReportSummary } from '@midscene/core';\n\n/** Use final Case outcomes, not attempts or infrastructure errors. */\nexport function renderTestBadge(\n summary: Pick<TestRunReportSummary, 'passed' | 'failed'>,\n): string {\n return ``;\n}\n","import { writeFile } from 'node:fs/promises';\nimport { dirname, join, relative, sep } from 'node:path';\nimport type {\n TestRunReportDump,\n TestRunReportSourceIndex,\n TestRunReportStep,\n} from '@midscene/core';\nimport type { TestProjectRunResult } from '../cli/types';\nimport { renderTestBadge } from './badge';\nimport { buildTestRunReportDump } from './test-run-report';\n\nconst text = (value: string): string =>\n value\n .replaceAll('&', '&')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('\"', '"')\n .replaceAll('|', '|')\n .replaceAll('[', '[')\n .replaceAll(']', ']')\n .replaceAll('*', '*')\n .replaceAll('_', '_')\n .replaceAll('`', '`')\n .replaceAll('\\\\', '\')\n .replace(/[\\r\\n]+/g, ' ');\n\nconst duration = (ms: number): string => {\n const seconds = Math.round(ms / 1000);\n return seconds < 60\n ? `${seconds}s`\n : `${Math.floor(seconds / 60)}m ${seconds % 60}s`;\n};\nconst href = (from: string, target: string): string =>\n relative(dirname(from), target).split(sep).map(encodeURIComponent).join('/');\n\nexport interface TestResultMarkdownOptions {\n /** Relative or hosted URL of the HTML report. */\n reportHref?: string;\n}\n\n/** Render the same sanitized execution facts used by the HTML report. */\nexport function renderTestResultMarkdown(\n dump: TestRunReportDump,\n options: TestResultMarkdownOptions = {},\n): string {\n const { summary } = dump;\n const outcome =\n dump.status === 'success'\n ? `✅ **${summary.passed}/${summary.total} passed**`\n : `❌ **${summary.failed} failed** · ${summary.passed} passed · ${summary.notRun} not run`;\n const lines = [\n '## Midscene Test',\n '',\n renderTestBadge(summary),\n '',\n `${outcome} · ${duration(dump.durationMs)}`,\n '',\n ];\n if (summary.filtered) lines.push(`**Filtered:** ${summary.filtered}`, '');\n const infrastructure = [\n summary.collectionErrors\n ? `${summary.collectionErrors} collection errors`\n : '',\n summary.documentFailures\n ? `${summary.documentFailures} document failures`\n : '',\n summary.projectFailures\n ? `${summary.projectFailures} project failures`\n : '',\n ].filter(Boolean);\n if (infrastructure.length)\n lines.push(`**Infrastructure:** ${infrastructure.join(' · ')}`, '');\n const groups: { name: string; rows: string[] }[] = [];\n const errors: string[] = [];\n const recordSteps = (label: string, steps: readonly TestRunReportStep[]) => {\n for (const step of steps) {\n if (step.status === 'failed')\n errors.push(\n `${label} / ${step.node}: ${step.error?.message ?? 'Step failed'}`,\n );\n }\n };\n for (const project of dump.projects) {\n if (project.lifecycle?.setupError)\n errors.push(`${project.name}: ${project.lifecycle.setupError.message}`);\n for (const error of project.lifecycle?.teardownErrors ?? [])\n errors.push(`${project.name}: ${error.message}`);\n for (const error of project.collectionErrors)\n errors.push(\n `${project.name} / ${error.sourcePath}: ${error.error.message}`,\n );\n for (const document of project.documents) {\n const name = document.sourcePath\n .replace(/\\\\/g, '/')\n .replace(/\\.(?:yaml|yml)$/, '');\n const group = {\n name: dump.projects.length > 1 ? `${project.name} / ${name}` : name,\n rows: [] as string[],\n };\n groups.push(group);\n recordSteps(`${project.name} / ${document.sourcePath}`, [\n ...document.beforeAll,\n ...document.afterAll,\n ]);\n for (const error of document.teardownErrors ?? [])\n errors.push(`${document.sourcePath}: ${error.message}`);\n for (const failure of document.hostErrors ?? [])\n errors.push(\n `${document.sourcePath} / ${failure.phase}: ${failure.error.message}`,\n );\n for (const testCase of document.cases) {\n group.rows.push(\n ` - ${testCase.status === 'success' ? '✅' : testCase.status === 'not-run' ? '⏭️' : '❌'} ${text(testCase.name)}`,\n );\n }\n }\n }\n for (const diagnostic of dump.diagnostics ?? []) {\n if (diagnostic.level === 'error') errors.push(diagnostic.message);\n }\n if (errors.length)\n lines.push(\n '### Execution errors',\n '',\n ...errors.map((error) => `- ${text(error)}`),\n '',\n );\n for (const group of groups) {\n if (group.rows.length) lines.push(`- ${text(group.name)}`, ...group.rows);\n }\n if (!groups.some((group) => group.rows.length))\n lines.push('No cases were reported.');\n if (options.reportHref)\n lines.push(\n '',\n `[Open the Midscene Test report ↗](<${options.reportHref}>)`,\n );\n return `${lines.join('\\n')}\\n`;\n}\n\nconst emptyIndex = (): TestRunReportSourceIndex => ({\n sources: [],\n metrics: {\n modelCallCount: 0,\n modelTimeMs: 0,\n promptTokens: 0,\n cachedInputTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n },\n});\n\n/** Write a per-run Markdown artifact even when HTML publication fails or is disabled. */\nexport async function writeTestResultMarkdown(\n result: TestProjectRunResult,\n index: TestRunReportSourceIndex = emptyIndex(),\n): Promise<string> {\n const output = join(dirname(result.summaryPath), 'result.md');\n const dump = buildTestRunReportDump(result, index);\n await writeFile(\n output,\n renderTestResultMarkdown(dump, {\n ...(result.reportPath\n ? { reportHref: href(output, result.reportPath) }\n : {}),\n }),\n );\n return output;\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","CaseRunner","CoreCaseRunner","createCaseRunner","coreCreateCaseRunner","createDocumentRuntime","coreCreateDocumentRuntime","NodeRegistry","CoreNodeRegistry","runWorkflowDocument","coreRunWorkflowDocument","defineNode","coreDefineNode","createCaseInvocationId","projectId","sourcePath","caseIndex","invocationIndex","createHash","JSON","createDocumentInvocationId","normalizeStep","coreNormalizeStep","normalizeSteps","coreNormalizeSteps","parseWorkflowSource","source","stack","nodes","sensitiveNodes","Set","sensitiveValues","redactedPaths","sourceOffset","parsed","load","JSON_SCHEMA","event","state","node","index","value","isReportSecretKey","ranges","left","right","offset","redacted","range","text","leading","trailing","sanitizeReportText","path","part","children","undefined","start","end","prefix","interpolationExpression","exactEnvExpression","exactProjectExpression","missingVariable","kind","name","options","WorkflowParseError","projectVariable","environmentVariable","interpolationValue","String","resolveString","exactEnv","exactProject","_match","environmentName","projectName","resolveWorkflowVariables","Array","child","isMapping","NativeWorkflowFormatError","actualFormat","rejectUnknownKeys","allowed","label","allowedSet","unknown","createCaseId","createWorkflowDocumentId","collectWorkflowDocument","snapshot","readFileSync","error","sourceYaml","format","classifyWorkflowDocumentFormat","sep","resolveStepVariables","step","phase","stepIndex","process","normalizeLifecycle","normalized","resolved","lifecycle","ids","cases","tags","tag","steps","caseId","renderTestBadge","summary","duration","ms","seconds","Math","href","from","target","relative","dirname","encodeURIComponent","renderTestResultMarkdown","dump","outcome","lines","infrastructure","Boolean","groups","errors","recordSteps","project","document","group","failure","testCase","diagnostic","emptyIndex","writeTestResultMarkdown","result","output","join","buildTestRunReportDump","writeFile"],"mappings":"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"}
|
package/dist/lib/test-cli.js
CHANGED
|
@@ -29,7 +29,7 @@ var __webpack_modules__ = {
|
|
|
29
29
|
},
|
|
30
30
|
"./package.json" (module) {
|
|
31
31
|
module.exports = {
|
|
32
|
-
rE: "1.17.
|
|
32
|
+
rE: "1.17.7"
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
};
|
|
@@ -92,6 +92,9 @@ var __webpack_exports__ = {};
|
|
|
92
92
|
(()=>{
|
|
93
93
|
var external_node_fs_ = __webpack_require__("node:fs");
|
|
94
94
|
var external_node_path_ = __webpack_require__("node:path");
|
|
95
|
+
function renderTestBadge(summary) {
|
|
96
|
+
return ``;
|
|
97
|
+
}
|
|
95
98
|
const external_node_util_namespaceObject = require("node:util");
|
|
96
99
|
var external_chalk_ = __webpack_require__("chalk");
|
|
97
100
|
var external_chalk_default = /*#__PURE__*/ __webpack_require__.n(external_chalk_);
|
|
@@ -1090,6 +1093,8 @@ var __webpack_exports__ = {};
|
|
|
1090
1093
|
const summary = [
|
|
1091
1094
|
'## Midscene Test',
|
|
1092
1095
|
'',
|
|
1096
|
+
renderTestBadge(result.summary),
|
|
1097
|
+
'',
|
|
1093
1098
|
'| Passed | Failed | Not run | Passed after retry | Duration |',
|
|
1094
1099
|
'| ---: | ---: | ---: | ---: | ---: |',
|
|
1095
1100
|
`| ${result.summary.passed} | ${result.summary.failed} | ${result.summary.notRun} | ${result.summary.passedAfterRetry} | ${formatDuration(result.durationMs)} |`,
|
|
@@ -1510,8 +1515,7 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
1510
1515
|
testTimeout: validatePositiveInteger(candidate.testTimeout, 120000, 'test.testTimeout')
|
|
1511
1516
|
});
|
|
1512
1517
|
};
|
|
1513
|
-
const validateOutputPath = (value,
|
|
1514
|
-
if (void 0 === value) return fallback;
|
|
1518
|
+
const validateOutputPath = (value, label)=>{
|
|
1515
1519
|
if ('string' != typeof value || 0 === value.trim().length) throw new TypeError(`Midscene config ${label} must be non-empty.`);
|
|
1516
1520
|
return value;
|
|
1517
1521
|
};
|
|
@@ -1525,7 +1529,9 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
1525
1529
|
if (void 0 !== candidate.reportFormat && 'single-html' !== candidate.reportFormat && 'html-and-external-assets' !== candidate.reportFormat) throw new TypeError('Midscene config output.reportFormat must be single-html or html-and-external-assets.');
|
|
1526
1530
|
return Object.freeze({
|
|
1527
1531
|
reportFormat: candidate.reportFormat ?? 'single-html',
|
|
1528
|
-
|
|
1532
|
+
...void 0 === candidate.reportDir ? {} : {
|
|
1533
|
+
reportDir: validateOutputPath(candidate.reportDir, 'output.reportDir')
|
|
1534
|
+
}
|
|
1529
1535
|
});
|
|
1530
1536
|
};
|
|
1531
1537
|
const validateTestProjectDefinition = (definition)=>{
|
|
@@ -2117,8 +2123,16 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
2117
2123
|
]
|
|
2118
2124
|
};
|
|
2119
2125
|
const project_preparation_toPosix = (value)=>value.split(external_node_path_.sep).join('/');
|
|
2120
|
-
const discoverResolvedTestFiles = (projectRoot, selection)=>{
|
|
2126
|
+
const discoverResolvedTestFiles = (projectRoot, selection, excludedDirectories = [])=>{
|
|
2121
2127
|
const root = (0, external_node_path_.resolve)(projectRoot);
|
|
2128
|
+
const outputPatterns = excludedDirectories.flatMap((directory)=>{
|
|
2129
|
+
const withinRoot = (0, external_node_path_.relative)(root, directory);
|
|
2130
|
+
if (!withinRoot || (0, external_node_path_.isAbsolute)(withinRoot) || '..' === withinRoot || withinRoot.startsWith(`..${external_node_path_.sep}`)) return [];
|
|
2131
|
+
const literal = project_preparation_toPosix(withinRoot).replace(/([*?{}[\]()!])/g, '\\$1');
|
|
2132
|
+
return [
|
|
2133
|
+
`${literal}/**`
|
|
2134
|
+
];
|
|
2135
|
+
});
|
|
2122
2136
|
const match = (patterns)=>(0, external_tinyglobby_namespaceObject.globSync)(patterns, {
|
|
2123
2137
|
absolute: true,
|
|
2124
2138
|
caseSensitiveMatch: false,
|
|
@@ -2128,6 +2142,7 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
2128
2142
|
followSymbolicLinks: false,
|
|
2129
2143
|
ignore: [
|
|
2130
2144
|
...ALWAYS_IGNORED_PATTERNS,
|
|
2145
|
+
...outputPatterns,
|
|
2131
2146
|
...selection.exclude ?? []
|
|
2132
2147
|
],
|
|
2133
2148
|
onlyFiles: true
|
|
@@ -2197,7 +2212,7 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
2197
2212
|
const platform = options.platform?.trim();
|
|
2198
2213
|
const fileSelection = project.files ?? DEFAULT_TEST_FILE_SELECTION;
|
|
2199
2214
|
const prerequisiteFile = options.prerequisiteFile ? (0, external_node_path_.resolve)(options.prerequisiteFile) : void 0;
|
|
2200
|
-
const mainFiles = options.files ?? discoverResolvedTestFiles(projectRoot, fileSelection);
|
|
2215
|
+
const mainFiles = options.files ?? discoverResolvedTestFiles(projectRoot, fileSelection, options.excludedDirectories);
|
|
2201
2216
|
const files = [
|
|
2202
2217
|
...prerequisiteFile ? [
|
|
2203
2218
|
prerequisiteFile
|
|
@@ -2321,6 +2336,7 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
2321
2336
|
filteredCaseCount
|
|
2322
2337
|
};
|
|
2323
2338
|
}
|
|
2339
|
+
const common_namespaceObject = require("@midscene/shared/common");
|
|
2324
2340
|
const padDatePart = (value)=>String(value).padStart(2, '0');
|
|
2325
2341
|
const createTestRunId = (date = new Date(), uuid = (0, external_node_crypto_namespaceObject.randomUUID)())=>{
|
|
2326
2342
|
const timestamp = [
|
|
@@ -2362,40 +2378,58 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
2362
2378
|
if (options.configPath && /\.ya?ml$/i.test(configPath)) throw new Error(`midscene-test --config only accepts a native TypeScript or JavaScript project config: ${configPath}. Run legacy batch YAML with \`midscene --config ${options.configPath}\`.`);
|
|
2363
2379
|
if (options.configPath && !(0, external_node_fs_.existsSync)(configPath)) throw new Error(`Midscene config does not exist: ${configPath}`);
|
|
2364
2380
|
const definition = await loadTestProject(configPath);
|
|
2365
|
-
const
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2381
|
+
const artifactDir = (0, common_namespaceObject.resolveMidsceneRunDir)(input.projectRoot);
|
|
2382
|
+
return (0, common_namespaceObject.runWithMidsceneRunDir)(artifactDir, async ()=>{
|
|
2383
|
+
const resultDir = options.resultDir ? (0, external_node_path_.resolve)(input.cwd, options.resultDir) : (0, external_node_path_.join)(artifactDir, 'test-results');
|
|
2384
|
+
const runDir = (0, external_node_path_.join)(resultDir, runId);
|
|
2385
|
+
const summaryPath = (0, external_node_path_.join)(runDir, 'summary.json');
|
|
2386
|
+
const reportDir = definition.output.reportDir ? (0, external_node_path_.resolve)(input.projectRoot, definition.output.reportDir) : (0, external_node_path_.join)(artifactDir, 'report');
|
|
2387
|
+
(0, external_node_fs_.mkdirSync)(resultDir, {
|
|
2388
|
+
recursive: true
|
|
2389
|
+
});
|
|
2390
|
+
(0, external_node_fs_.mkdirSync)(runDir);
|
|
2391
|
+
const projects = [];
|
|
2392
|
+
for (const project of selectProjects(definition.projects, options.projectNames))projects.push(await prepareProject(project, input.projectRoot, runDir, definition.test.testTimeout, {
|
|
2393
|
+
...input.singleFile ? {
|
|
2394
|
+
files: [
|
|
2395
|
+
input.singleFile
|
|
2396
|
+
]
|
|
2397
|
+
} : {},
|
|
2398
|
+
excludedDirectories: [
|
|
2399
|
+
artifactDir,
|
|
2400
|
+
resultDir,
|
|
2401
|
+
reportDir,
|
|
2402
|
+
...[
|
|
2403
|
+
'cache',
|
|
2404
|
+
'log',
|
|
2405
|
+
'output',
|
|
2406
|
+
'tmp',
|
|
2407
|
+
'dump'
|
|
2408
|
+
].map((name)=>(0, external_node_path_.join)(artifactDir, name))
|
|
2409
|
+
]
|
|
2410
|
+
}));
|
|
2411
|
+
const hasFormatMismatch = projects.some((project)=>project.collectionErrors.some(({ error })=>error instanceof NativeWorkflowFormatError));
|
|
2412
|
+
return {
|
|
2413
|
+
startedAt,
|
|
2414
|
+
runId,
|
|
2415
|
+
projectRoot: input.projectRoot,
|
|
2416
|
+
artifactDir,
|
|
2417
|
+
...configPath ? {
|
|
2418
|
+
configPath
|
|
2419
|
+
} : {},
|
|
2420
|
+
resultDir,
|
|
2421
|
+
runDir,
|
|
2422
|
+
summaryPath,
|
|
2423
|
+
reportDir,
|
|
2424
|
+
definition,
|
|
2425
|
+
projects,
|
|
2426
|
+
preflightScope: hasFormatMismatch ? 'run' : 'project',
|
|
2427
|
+
reportEnabled: true,
|
|
2428
|
+
publications: [],
|
|
2429
|
+
onProgress: options.onProgress ?? (()=>{}),
|
|
2430
|
+
onEvent: options.onEvent
|
|
2431
|
+
};
|
|
2371
2432
|
});
|
|
2372
|
-
(0, external_node_fs_.mkdirSync)(runDir);
|
|
2373
|
-
const projects = [];
|
|
2374
|
-
for (const project of selectProjects(definition.projects, options.projectNames))projects.push(await prepareProject(project, input.projectRoot, runDir, definition.test.testTimeout, input.singleFile ? {
|
|
2375
|
-
files: [
|
|
2376
|
-
input.singleFile
|
|
2377
|
-
]
|
|
2378
|
-
} : void 0));
|
|
2379
|
-
const hasFormatMismatch = projects.some((project)=>project.collectionErrors.some(({ error })=>error instanceof NativeWorkflowFormatError));
|
|
2380
|
-
return {
|
|
2381
|
-
startedAt,
|
|
2382
|
-
runId,
|
|
2383
|
-
projectRoot: input.projectRoot,
|
|
2384
|
-
...configPath ? {
|
|
2385
|
-
configPath
|
|
2386
|
-
} : {},
|
|
2387
|
-
resultDir,
|
|
2388
|
-
runDir,
|
|
2389
|
-
summaryPath,
|
|
2390
|
-
reportDir,
|
|
2391
|
-
definition,
|
|
2392
|
-
projects,
|
|
2393
|
-
preflightScope: hasFormatMismatch ? 'run' : 'project',
|
|
2394
|
-
reportEnabled: true,
|
|
2395
|
-
publications: [],
|
|
2396
|
-
onProgress: options.onProgress ?? (()=>{}),
|
|
2397
|
-
onEvent: options.onEvent
|
|
2398
|
-
};
|
|
2399
2433
|
}
|
|
2400
2434
|
const external_node_events_namespaceObject = require("node:events");
|
|
2401
2435
|
const report_namespaceObject = require("@midscene/core/report");
|
|
@@ -2411,6 +2445,8 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
2411
2445
|
const lines = [
|
|
2412
2446
|
'## Midscene Test',
|
|
2413
2447
|
'',
|
|
2448
|
+
renderTestBadge(summary),
|
|
2449
|
+
'',
|
|
2414
2450
|
`${outcome} · ${result_markdown_duration(dump.durationMs)}`,
|
|
2415
2451
|
''
|
|
2416
2452
|
];
|
|
@@ -3113,7 +3149,7 @@ Each Node's returned \`data\` is saved on that Step's result. Results are not na
|
|
|
3113
3149
|
const notRunSuite = (prepared, reason)=>prepared.documents.flatMap((document)=>document.cases.map((item)=>asNotRun(document.documentId, item, prepared.project.name, reason)));
|
|
3114
3150
|
async function runPreparedTestProject(plan) {
|
|
3115
3151
|
const reports = new report_namespaceObject.ReportSession((0, external_node_path_.join)(plan.runDir, 'records'));
|
|
3116
|
-
return reports.run(()=>runWithReportSession(plan, reports));
|
|
3152
|
+
return (0, common_namespaceObject.runWithMidsceneRunDir)(plan.artifactDir, ()=>reports.run(()=>runWithReportSession(plan, reports)));
|
|
3117
3153
|
}
|
|
3118
3154
|
async function runWithReportSession(plan, reports) {
|
|
3119
3155
|
const { startedAt, runId, projectRoot, configPath, resultDir, runDir, summaryPath, reportDir, definition, projects: preparedProjects } = plan;
|